mmdevapi: Implement (Un)RegisterEndpointNotificationCallback.

This commit is contained in:
Andrew Eikum 2012-12-14 11:41:53 -06:00 committed by Alexandre Julliard
parent 7f8825085d
commit 8d775ec09b
2 changed files with 147 additions and 3 deletions

View file

@ -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 =

View file

@ -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 = { &notif_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, &notif);
ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, &notif);
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, &notif);
ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, &notif);
ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, &notif);
ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
IMMDeviceEnumerator_Release(mme);
}