Andrew Eikum : mmdevapi: Implement (Un)RegisterEndpointNotificationCallback .
Alexandre Julliard
julliard at winehq.org
Mon Dec 17 13:58:22 CST 2012
Module: wine
Branch: master
Commit: 8d775ec09b80bcc729743ed869fcee896dd399f5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8d775ec09b80bcc729743ed869fcee896dd399f5
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Fri Dec 14 11:41:53 2012 -0600
mmdevapi: Implement (Un)RegisterEndpointNotificationCallback.
---
dlls/mmdevapi/devenum.c | 59 ++++++++++++++++++++++++-
dlls/mmdevapi/tests/mmdevenum.c | 91 +++++++++++++++++++++++++++++++++++++++
2 files changed, 147 insertions(+), 3 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c
index d7c5a44..f9b9172 100644
--- a/dlls/mmdevapi/devenum.c
+++ b/dlls/mmdevapi/devenum.c
@@ -27,6 +27,7 @@
#include "winnls.h"
#include "winreg.h"
#include "wine/debug.h"
+#include "wine/list.h"
#include "wine/unicode.h"
#include "initguid.h"
@@ -1035,20 +1036,72 @@ static HRESULT WINAPI MMDevEnum_GetDevice(IMMDeviceEnumerator *iface, const WCHA
return E_INVALIDARG;
}
+struct NotificationClientWrapper {
+ IMMNotificationClient *client;
+ struct list entry;
+};
+
+static struct list g_notif_clients = LIST_INIT(g_notif_clients);
+
+static CRITICAL_SECTION g_notif_lock;
+static CRITICAL_SECTION_DEBUG g_notif_lock_debug =
+{
+ 0, 0, &g_notif_lock,
+ { &g_notif_lock_debug.ProcessLocksList, &g_notif_lock_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": g_notif_lock") }
+};
+static CRITICAL_SECTION g_notif_lock = { &g_notif_lock_debug, -1, 0, 0, 0, 0 };
+
static HRESULT WINAPI MMDevEnum_RegisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
{
MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface);
+ struct NotificationClientWrapper *wrapper;
+
TRACE("(%p)->(%p)\n", This, client);
- FIXME("stub\n");
+
+ if(!client)
+ return E_POINTER;
+
+ wrapper = HeapAlloc(GetProcessHeap(), 0, sizeof(*wrapper));
+ if(!wrapper)
+ return E_OUTOFMEMORY;
+
+ wrapper->client = client;
+
+ EnterCriticalSection(&g_notif_lock);
+
+ list_add_tail(&g_notif_clients, &wrapper->entry);
+
+ LeaveCriticalSection(&g_notif_lock);
+
return S_OK;
}
static HRESULT WINAPI MMDevEnum_UnregisterEndpointNotificationCallback(IMMDeviceEnumerator *iface, IMMNotificationClient *client)
{
MMDevEnumImpl *This = impl_from_IMMDeviceEnumerator(iface);
+ struct NotificationClientWrapper *wrapper, *wrapper2;
+
TRACE("(%p)->(%p)\n", This, client);
- FIXME("stub\n");
- return S_OK;
+
+ if(!client)
+ return E_POINTER;
+
+ EnterCriticalSection(&g_notif_lock);
+
+ LIST_FOR_EACH_ENTRY_SAFE(wrapper, wrapper2, &g_notif_clients,
+ struct NotificationClientWrapper, entry){
+ if(wrapper->client == client){
+ list_remove(&wrapper->entry);
+ HeapFree(GetProcessHeap(), 0, wrapper);
+ LeaveCriticalSection(&g_notif_lock);
+ return S_OK;
+ }
+ }
+
+ LeaveCriticalSection(&g_notif_lock);
+
+ return E_NOTFOUND;
}
static const IMMDeviceEnumeratorVtbl MMDevEnumVtbl =
diff --git a/dlls/mmdevapi/tests/mmdevenum.c b/dlls/mmdevapi/tests/mmdevenum.c
index 82dda40..12e2156 100644
--- a/dlls/mmdevapi/tests/mmdevenum.c
+++ b/dlls/mmdevapi/tests/mmdevenum.c
@@ -118,6 +118,73 @@ static void test_collection(IMMDeviceEnumerator *mme, IMMDeviceCollection *col)
IMMDeviceCollection_Release(col);
}
+static HRESULT WINAPI notif_QueryInterface(IMMNotificationClient *iface,
+ const GUID *riid, void **obj)
+{
+ ok(0, "Unexpected QueryInterface call\n");
+ return E_NOTIMPL;
+}
+
+static ULONG WINAPI notif_AddRef(IMMNotificationClient *iface)
+{
+ ok(0, "Unexpected AddRef call\n");
+ return 2;
+}
+
+static ULONG WINAPI notif_Release(IMMNotificationClient *iface)
+{
+ ok(0, "Unexpected Release call\n");
+ return 1;
+}
+
+static HRESULT WINAPI notif_OnDeviceStateChanged(IMMNotificationClient *iface,
+ const WCHAR *device_id, DWORD new_state)
+{
+ ok(0, "Unexpected OnDeviceStateChanged call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI notif_OnDeviceAdded(IMMNotificationClient *iface,
+ const WCHAR *device_id)
+{
+ ok(0, "Unexpected OnDeviceAdded call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI notif_OnDeviceRemoved(IMMNotificationClient *iface,
+ const WCHAR *device_id)
+{
+ ok(0, "Unexpected OnDeviceRemoved call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI notif_OnDefaultDeviceChanged(IMMNotificationClient *iface,
+ EDataFlow flow, ERole role, const WCHAR *device_id)
+{
+ ok(0, "Unexpected OnDefaultDeviceChanged call\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI notif_OnPropertyValueChanged(IMMNotificationClient *iface,
+ const WCHAR *device_id, const PROPERTYKEY key)
+{
+ ok(0, "Unexpected OnPropertyValueChanged call\n");
+ return E_NOTIMPL;
+}
+
+static IMMNotificationClientVtbl notif_vtbl = {
+ notif_QueryInterface,
+ notif_AddRef,
+ notif_Release,
+ notif_OnDeviceStateChanged,
+ notif_OnDeviceAdded,
+ notif_OnDeviceRemoved,
+ notif_OnDefaultDeviceChanged,
+ notif_OnPropertyValueChanged
+};
+
+static IMMNotificationClient notif = { ¬if_vtbl };
+
/* Only do parameter tests here, the actual MMDevice testing should be a separate test */
START_TEST(mmdevenum)
{
@@ -192,5 +259,29 @@ START_TEST(mmdevenum)
test_collection(mme, col);
}
+ hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, NULL);
+ ok(hr == E_POINTER, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, ¬if);
+ ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, ¬if);
+ ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, NULL);
+ ok(hr == E_POINTER, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, (IMMNotificationClient*)0xdeadbeef);
+ ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, ¬if);
+ ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, ¬if);
+ ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, ¬if);
+ ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
+
IMMDeviceEnumerator_Release(mme);
}
More information about the wine-cvs
mailing list