[PATCH 3/7] mmdevapi: Add stubs for MMDevEnum, with tests
Maarten Lankhorst
m.b.lankhorst at gmail.com
Mon Dec 14 09:04:04 CST 2009
---
dlls/mmdevapi/devenum.c | 122 ++++++++++++++++++++++++++++++++++++++-
dlls/mmdevapi/main.c | 1 +
dlls/mmdevapi/mmdevapi.h | 1 +
dlls/mmdevapi/tests/mmdevenum.c | 24 +++++++-
4 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c
index e34c824..90347b1 100644
--- a/dlls/mmdevapi/devenum.c
+++ b/dlls/mmdevapi/devenum.c
@@ -33,8 +33,128 @@
WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);
+typedef struct MMDevEnumImpl
+{
+ IMMDeviceEnumeratorVtbl *lpVtbl;
+ LONG ref;
+} MMDevEnumImpl;
+
+static MMDevEnumImpl *MMDevEnumerator;
+static IMMDeviceEnumeratorVtbl MMDevEnumVtbl;
+
HRESULT MMDevEnum_Create(REFIID riid, void **ppv)
{
+ MMDevEnumImpl *This = MMDevEnumerator;
+
+ if (!This)
+ {
+ This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+ *ppv = NULL;
+ if (!This)
+ return E_OUTOFMEMORY;
+ This->ref = 1;
+ This->lpVtbl = &MMDevEnumVtbl;
+ MMDevEnumerator = This;
+ }
+ return IUnknown_QueryInterface((IUnknown*)This, riid, ppv);
+}
+
+void MMDevEnum_Free(void)
+{
+ HeapFree(GetProcessHeap(), 0, MMDevEnumerator);
+ MMDevEnumerator = NULL;
+}
+
+static HRESULT WINAPI MMDevEnum_QueryInterface(IMMDeviceEnumerator *iface, REFIID riid, void **ppv)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+
+ if (!ppv)
+ return E_POINTER;
+ if (IsEqualIID(riid, &IID_IUnknown)
+ || IsEqualIID(riid, &IID_IMMDeviceEnumerator))
+ *ppv = This;
+ else
+ *ppv = NULL;
+ if (!*ppv)
+ return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI MMDevEnum_AddRef(IMMDeviceEnumerator *iface)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ LONG ref = InterlockedIncrement(&This->ref);
+ TRACE("Refcount now %i\n", ref);
+ return ref;
+}
+
+static ULONG WINAPI MMDevEnum_Release(IMMDeviceEnumerator *iface)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ LONG ref = InterlockedDecrement(&This->ref);
+ if (!ref)
+ MMDevEnum_Free();
+ TRACE("Refcount now %i\n", ref);
+ return ref;
+}
+
+static HRESULT WINAPI MMDevEnum_EnumAudioEndpoints(IMMDeviceEnumerator *iface, EDataFlow flow, DWORD mask, IMMDeviceCollection **devices)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ TRACE("(%p)->(%u,%u,%p)\n", This, flow, mask, devices);
+ if (!devices)
+ return E_POINTER;
+ *devices = NULL;
+ if (flow >= EDataFlow_enum_count)
+ return E_INVALIDARG;
+ if (mask & ~DEVICE_STATEMASK_ALL)
+ return E_INVALIDARG;
+ FIXME("stub\n");
+ return E_NOTFOUND;
+}
+
+static HRESULT WINAPI MMDevEnum_GetDefaultAudioEndpoint(IMMDeviceEnumerator *iface, EDataFlow flow, ERole role, IMMDevice **device)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ TRACE("(%p)->(%u,%u,%p)\n", This, flow, role, device);
FIXME("stub\n");
- return CLASS_E_CLASSNOTAVAILABLE;
+ return E_NOTFOUND;
}
+
+static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHAR *name, IMMDevice **device)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ TRACE("(%p)->(%s,%p)\n", This, debugstr_w(name), device);
+ FIXME("stub\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ TRACE("(%p)->(%p)\n", This, client);
+ FIXME("stub\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
+{
+ MMDevEnumImpl *This = (MMDevEnumImpl*)iface;
+ TRACE("(%p)->(%p)\n", This, client);
+ FIXME("stub\n");
+ return E_NOTIMPL;
+}
+
+static IMMDeviceEnumeratorVtbl MMDevEnumVtbl =
+{
+ MMDevEnum_QueryInterface,
+ MMDevEnum_AddRef,
+ MMDevEnum_Release,
+ MMDevEnum_EnumAudioEndpoints,
+ MMDevEnum_GetDefaultAudioEndpoint,
+ MMDevEnum_GetDevice,
+ MMDevEnum_RegisterEndpointNotificationCallback,
+ MMDevEnum_UnregisterEndpointNotificationCallback
+};
diff --git a/dlls/mmdevapi/main.c b/dlls/mmdevapi/main.c
index d167d80..df5f9e7 100644
--- a/dlls/mmdevapi/main.c
+++ b/dlls/mmdevapi/main.c
@@ -44,6 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
DisableThreadLibraryCalls(hinstDLL);
break;
case DLL_PROCESS_DETACH:
+ MMDevEnum_Free();
break;
}
diff --git a/dlls/mmdevapi/mmdevapi.h b/dlls/mmdevapi/mmdevapi.h
index e6b878a..bab3af5 100644
--- a/dlls/mmdevapi/mmdevapi.h
+++ b/dlls/mmdevapi/mmdevapi.h
@@ -17,3 +17,4 @@
*/
extern HRESULT MMDevEnum_Create(REFIID riid, void **ppv);
+extern void MMDevEnum_Free(void);
diff --git a/dlls/mmdevapi/tests/mmdevenum.c b/dlls/mmdevapi/tests/mmdevenum.c
index 5ebd32a..17295df 100644
--- a/dlls/mmdevapi/tests/mmdevenum.c
+++ b/dlls/mmdevapi/tests/mmdevenum.c
@@ -82,13 +82,15 @@ static void test_collection(IMMDeviceEnumerator *mme, IMMDeviceCollection *col)
if (dev) IUnknown_Release(dev);
}
+/* Only do parameter tests here, the actual MMDevice testing should be a separate test */
START_TEST(mmdevenum)
{
HRESULT hr;
IUnknown *unk = NULL;
- IMMDeviceEnumerator *mme;
+ IMMDeviceEnumerator *mme, *mme2;
ULONG ref;
IMMDeviceCollection *col;
+ GUID null_guid = {};
CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
@@ -110,6 +112,24 @@ START_TEST(mmdevenum)
ok( (LONG_PTR)mme == (LONG_PTR)unk, "Pointers are unequal %p/%p\n", unk, mme);
IUnknown_Release(unk);
+ /* Proving that it is static.. */
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme2);
+ IUnknown_Release(mme2);
+ ok(mme == mme2, "Pointers are not equal!\n");
+
+#if 0 /* Crashes.. expectable since in C++ REFIID expands to IID & */
+ hr = IUnknown_QueryInterface(mme, NULL, (void**)&mme2);
+ ok(mme2 == NULL, "MME was not set to null\n");
+ ok(hr == E_POINTER, "Null iid on QueryInterface returned %08x\n", hr);
+#endif
+
+ hr = IUnknown_QueryInterface(mme, &IID_IUnknown, NULL);
+ ok(hr == E_POINTER, "Null pointer on QueryInterface returned %08x\n", hr);
+
+ hr = IUnknown_QueryInterface(mme, &null_guid, (void**)&unk);
+ ok(!unk, "Unk not reset to null after invalid QI\n");
+ ok(hr == E_NOINTERFACE, "Invalid hr %08x returned on IID_NULL\n", hr);
+
col = (void*)(LONG_PTR)0x12345678;
hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, 0xffff, DEVICE_STATEMASK_ALL, &col);
ok(hr == E_INVALIDARG, "Setting invalid data flow returned 0x%08x\n", hr);
@@ -122,7 +142,7 @@ START_TEST(mmdevenum)
ok(hr == E_POINTER, "Invalid pointer returned: 0x%08x\n", hr);
hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL, &col);
- ok(hr == S_OK, "Valid EnumAudioEndpoints returned 0x%08x\n", hr);
+ todo_wine ok(hr == S_OK, "Valid EnumAudioEndpoints returned 0x%08x\n", hr);
if (hr == S_OK)
{
ok(!!col, "Returned null pointer\n");
--
1.6.5.7
--------------070004070400020407030701--
More information about the wine-patches
mailing list