Module: wine Branch: master Commit: 3410ab8b7ce434bfbccb1429c0d802c2e53bb8ce URL: http://source.winehq.org/git/wine.git/?a=commit;h=3410ab8b7ce434bfbccb1429c0...
Author: Maarten Lankhorst m.b.lankhorst@gmail.com Date: Mon Dec 14 16:04:04 2009 +0100
mmdevapi: Add stubs for MMDevEnum with tests.
---
dlls/mmdevapi/devenum.c | 122 ++++++++++++++++++++++++++++++++++++++- dlls/mmdevapi/main.c | 1 + dlls/mmdevapi/mmdevapi.h | 1 + dlls/mmdevapi/tests/mmdevenum.c | 19 ++++++- 4 files changed, 140 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..06c106f 100644 --- a/dlls/mmdevapi/tests/mmdevenum.c +++ b/dlls/mmdevapi/tests/mmdevenum.c @@ -26,6 +26,8 @@ #include "dshow.h" #include "dsound.h"
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + /* Some of the QueryInterface tests are really just to check if I got the IID's right :) */
/* IMMDeviceCollection appears to have no QueryInterface method and instead forwards to mme */ @@ -82,11 +84,12 @@ 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;
@@ -110,6 +113,18 @@ 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"); + + hr = IUnknown_QueryInterface(mme, &IID_IUnknown, NULL); + ok(hr == E_POINTER, "Null pointer on QueryInterface returned %08x\n", hr); + + hr = IUnknown_QueryInterface(mme, &GUID_NULL, (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 +137,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");