ReactOS 0.4.15-dev-7918-g2a2556c
mmdevenum.c File Reference
#include "wine/test.h"
#include "initguid.h"
#include "endpointvolume.h"
#include "mmdeviceapi.h"
#include "audioclient.h"
#include "audiopolicy.h"
#include "dshow.h"
#include "dsound.h"
#include "devpkey.h"
Include dependency graph for mmdevenum.c:

Go to the source code of this file.

Macros

#define COBJMACROS
 

Functions

 DEFINE_GUID (GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
 
static void test_collection (IMMDeviceEnumerator *mme, IMMDeviceCollection *col)
 
static HRESULT WINAPI notif_QueryInterface (IMMNotificationClient *iface, const GUID *riid, void **obj)
 
static ULONG WINAPI notif_AddRef (IMMNotificationClient *iface)
 
static ULONG WINAPI notif_Release (IMMNotificationClient *iface)
 
static HRESULT WINAPI notif_OnDeviceStateChanged (IMMNotificationClient *iface, const WCHAR *device_id, DWORD new_state)
 
static HRESULT WINAPI notif_OnDeviceAdded (IMMNotificationClient *iface, const WCHAR *device_id)
 
static HRESULT WINAPI notif_OnDeviceRemoved (IMMNotificationClient *iface, const WCHAR *device_id)
 
static HRESULT WINAPI notif_OnDefaultDeviceChanged (IMMNotificationClient *iface, EDataFlow flow, ERole role, const WCHAR *device_id)
 
static HRESULT WINAPI notif_OnPropertyValueChanged (IMMNotificationClient *iface, const WCHAR *device_id, const PROPERTYKEY key)
 
 START_TEST (mmdevenum)
 

Variables

static IMMNotificationClientVtbl notif_vtbl
 
static IMMNotificationClient notif = { &notif_vtbl }
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 21 of file mmdevenum.c.

Function Documentation

◆ DEFINE_GUID()

DEFINE_GUID ( GUID_NULL  ,
,
,
,
,
,
,
,
,
,
,
 
)

◆ notif_AddRef()

static ULONG WINAPI notif_AddRef ( IMMNotificationClient iface)
static

Definition at line 131 of file mmdevenum.c.

132{
133 ok(0, "Unexpected AddRef call\n");
134 return 2;
135}
#define ok(value,...)
Definition: atltest.h:57

◆ notif_OnDefaultDeviceChanged()

static HRESULT WINAPI notif_OnDefaultDeviceChanged ( IMMNotificationClient iface,
EDataFlow  flow,
ERole  role,
const WCHAR device_id 
)
static

Definition at line 164 of file mmdevenum.c.

166{
167 ok(0, "Unexpected OnDefaultDeviceChanged call\n");
168 return E_NOTIMPL;
169}
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ notif_OnDeviceAdded()

static HRESULT WINAPI notif_OnDeviceAdded ( IMMNotificationClient iface,
const WCHAR device_id 
)
static

Definition at line 150 of file mmdevenum.c.

152{
153 ok(0, "Unexpected OnDeviceAdded call\n");
154 return E_NOTIMPL;
155}

◆ notif_OnDeviceRemoved()

static HRESULT WINAPI notif_OnDeviceRemoved ( IMMNotificationClient iface,
const WCHAR device_id 
)
static

Definition at line 157 of file mmdevenum.c.

159{
160 ok(0, "Unexpected OnDeviceRemoved call\n");
161 return E_NOTIMPL;
162}

◆ notif_OnDeviceStateChanged()

static HRESULT WINAPI notif_OnDeviceStateChanged ( IMMNotificationClient iface,
const WCHAR device_id,
DWORD  new_state 
)
static

Definition at line 143 of file mmdevenum.c.

145{
146 ok(0, "Unexpected OnDeviceStateChanged call\n");
147 return E_NOTIMPL;
148}

◆ notif_OnPropertyValueChanged()

static HRESULT WINAPI notif_OnPropertyValueChanged ( IMMNotificationClient iface,
const WCHAR device_id,
const PROPERTYKEY  key 
)
static

Definition at line 171 of file mmdevenum.c.

173{
174 ok(0, "Unexpected OnPropertyValueChanged call\n");
175 return E_NOTIMPL;
176}

◆ notif_QueryInterface()

static HRESULT WINAPI notif_QueryInterface ( IMMNotificationClient iface,
const GUID riid,
void **  obj 
)
static

Definition at line 124 of file mmdevenum.c.

126{
127 ok(0, "Unexpected QueryInterface call\n");
128 return E_NOTIMPL;
129}

◆ notif_Release()

static ULONG WINAPI notif_Release ( IMMNotificationClient iface)
static

Definition at line 137 of file mmdevenum.c.

138{
139 ok(0, "Unexpected Release call\n");
140 return 1;
141}

◆ START_TEST()

START_TEST ( mmdevenum  )

Definition at line 192 of file mmdevenum.c.

193{
194 static const WCHAR not_a_deviceW[] = {'n','o','t','a','d','e','v','i','c','e',0};
195
196 HRESULT hr;
197 IUnknown *unk = NULL;
198 IMMDeviceEnumerator *mme, *mme2;
199 ULONG ref;
201 IMMDevice *dev;
202
204 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme);
205 if (FAILED(hr))
206 {
207 skip("mmdevapi not available: 0x%08x\n", hr);
208 return;
209 }
210
211 /* Odd behavior.. bug? */
212 ref = IMMDeviceEnumerator_AddRef(mme);
213 ok(ref == 3, "Invalid reference count after incrementing: %u\n", ref);
214 IMMDeviceEnumerator_Release(mme);
215
216 hr = IMMDeviceEnumerator_QueryInterface(mme, &IID_IUnknown, (void**)&unk);
217 ok(hr == S_OK, "returned 0x%08x\n", hr);
218 if (hr != S_OK) return;
219
220 ok( (LONG_PTR)mme == (LONG_PTR)unk, "Pointers are unequal %p/%p\n", unk, mme);
221 IUnknown_Release(unk);
222
223 /* Proving that it is static.. */
224 hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme2);
225 ok(hr == S_OK, "CoCreateInstance failed: 0x%08x\n", hr);
226 IMMDeviceEnumerator_Release(mme2);
227 ok(mme == mme2, "Pointers are not equal!\n");
228
229 hr = IMMDeviceEnumerator_QueryInterface(mme, &IID_IUnknown, NULL);
230 ok(hr == E_POINTER, "Null pointer on QueryInterface returned %08x\n", hr);
231
232 hr = IMMDeviceEnumerator_QueryInterface(mme, &GUID_NULL, (void**)&unk);
233 ok(!unk, "Unk not reset to null after invalid QI\n");
234 ok(hr == E_NOINTERFACE, "Invalid hr %08x returned on IID_NULL\n", hr);
235
236 hr = IMMDeviceEnumerator_GetDevice(mme, not_a_deviceW, NULL);
237 ok(hr == E_POINTER, "GetDevice gave wrong error: %08x\n", hr);
238
239 hr = IMMDeviceEnumerator_GetDevice(mme, NULL, &dev);
240 ok(hr == E_POINTER, "GetDevice gave wrong error: %08x\n", hr);
241
242 hr = IMMDeviceEnumerator_GetDevice(mme, not_a_deviceW, &dev);
243 ok(hr == E_INVALIDARG, "GetDevice gave wrong error: %08x\n", hr);
244
245 col = (void*)(LONG_PTR)0x12345678;
246 hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, 0xffff, DEVICE_STATEMASK_ALL, &col);
247 ok(hr == E_INVALIDARG, "Setting invalid data flow returned 0x%08x\n", hr);
248 ok(col == NULL, "Collection pointer non-null on failure\n");
249
250 hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL+1, &col);
251 ok(hr == E_INVALIDARG, "Setting invalid mask returned 0x%08x\n", hr);
252
253 hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL, NULL);
254 ok(hr == E_POINTER, "Invalid pointer returned: 0x%08x\n", hr);
255
256 hr = IMMDeviceEnumerator_EnumAudioEndpoints(mme, eAll, DEVICE_STATEMASK_ALL, &col);
257 ok(hr == S_OK, "Valid EnumAudioEndpoints returned 0x%08x\n", hr);
258 if (hr == S_OK)
259 {
260 ok(!!col, "Returned null pointer\n");
261 if (col)
262 test_collection(mme, col);
263 }
264
265 hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, NULL);
266 ok(hr == E_POINTER, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
267
268 hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, &notif);
269 ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
270
271 hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(mme, &notif);
272 ok(hr == S_OK, "RegisterEndpointNotificationCallback failed: %08x\n", hr);
273
274 hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, NULL);
275 ok(hr == E_POINTER, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
276
277 hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, (IMMNotificationClient*)0xdeadbeef);
278 ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
279
280 hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, &notif);
281 ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
282
283 hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, &notif);
284 ok(hr == S_OK, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
285
286 hr = IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(mme, &notif);
287 ok(hr == E_NOTFOUND, "UnregisterEndpointNotificationCallback failed: %08x\n", hr);
288
289 IMMDeviceEnumerator_Release(mme);
290}
#define skip(...)
Definition: atltest.h:64
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define GUID_NULL
Definition: ks.h:106
static void test_collection(IMMDeviceEnumerator *mme, IMMDeviceCollection *col)
Definition: mmdevenum.c:39
static IMMNotificationClient notif
Definition: mmdevenum.c:189
@ eAll
Definition: mmdeviceapi.idl:65
static IMMDeviceEnumerator * mme
Definition: render.c:63
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
@ COINIT_MULTITHREADED
Definition: objbase.h:279
HRESULT hr
Definition: shlfolder.c:183
Definition: send.c:48
uint32_t ULONG
Definition: typedefs.h:59
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_POINTER
Definition: winerror.h:2365
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ test_collection()

static void test_collection ( IMMDeviceEnumerator mme,
IMMDeviceCollection col 
)
static

Definition at line 39 of file mmdevenum.c.

40{
43 IUnknown *unk;
44 HRESULT hr;
45 ULONG ref;
46 UINT numdev;
48
49 /* collection doesn't keep a ref on parent */
50 IMMDeviceEnumerator_AddRef(mme);
51 ref = IMMDeviceEnumerator_Release(mme);
52 ok(ref == 2, "Reference count on parent is %u\n", ref);
53
54 ref = IMMDeviceCollection_AddRef(col);
55 IMMDeviceCollection_Release(col);
56 ok(ref == 2, "Invalid reference count %u on collection\n", ref);
57
58 hr = IMMDeviceCollection_QueryInterface(col, &IID_IUnknown, NULL);
59 ok(hr == E_POINTER, "Null ppv returns %08x\n", hr);
60
61 hr = IMMDeviceCollection_QueryInterface(col, &IID_IUnknown, (void**)&unk);
62 ok(hr == S_OK, "Cannot query for IID_IUnknown: 0x%08x\n", hr);
63 if (hr == S_OK)
64 {
65 ok((IUnknown*)col == unk, "Pointers are not identical %p/%p/%p\n", col, unk, mme);
66 IUnknown_Release(unk);
67 }
68
69 hr = IMMDeviceCollection_QueryInterface(col, &IID_IMMDeviceCollection, (void**)&col2);
70 ok(hr == S_OK, "Cannot query for IID_IMMDeviceCollection: 0x%08x\n", hr);
71 if (hr == S_OK)
72 IMMDeviceCollection_Release(col2);
73
74 hr = IMMDeviceCollection_QueryInterface(col, &IID_IMMDeviceEnumerator, (void**)&mme2);
75 ok(hr == E_NOINTERFACE, "Query for IID_IMMDeviceEnumerator returned: 0x%08x\n", hr);
76 if (hr == S_OK)
77 IMMDeviceEnumerator_Release(mme2);
78
79 hr = IMMDeviceCollection_GetCount(col, NULL);
80 ok(hr == E_POINTER, "GetCount returned 0x%08x\n", hr);
81
82 hr = IMMDeviceCollection_GetCount(col, &numdev);
83 ok(hr == S_OK, "GetCount returned 0x%08x\n", hr);
84
85 dev = (void*)(LONG_PTR)0x12345678;
86 hr = IMMDeviceCollection_Item(col, numdev, &dev);
87 ok(hr == E_INVALIDARG, "Asking for too high device returned 0x%08x\n", hr);
88 ok(dev == NULL, "Returned non-null device\n");
89
90 if (numdev)
91 {
92 hr = IMMDeviceCollection_Item(col, 0, NULL);
93 ok(hr == E_POINTER, "Query with null pointer returned 0x%08x\n", hr);
94
95 hr = IMMDeviceCollection_Item(col, 0, &dev);
96 ok(hr == S_OK, "Valid Item returned 0x%08x\n", hr);
97 ok(dev != NULL, "Device is null!\n");
98 if (dev != NULL)
99 {
100 char temp[128];
101 WCHAR *id = NULL;
102 if (IMMDevice_GetId(dev, &id) == S_OK)
103 {
104 IMMDevice *dev2;
105
106 temp[sizeof(temp)-1] = 0;
107 WideCharToMultiByte(CP_ACP, 0, id, -1, temp, sizeof(temp)-1, NULL, NULL);
108 trace("Device found: %s\n", temp);
109
110 hr = IMMDeviceEnumerator_GetDevice(mme, id, &dev2);
111 ok(hr == S_OK, "GetDevice failed: %08x\n", hr);
112
113 IMMDevice_Release(dev2);
114
115 CoTaskMemFree(id);
116 }
117 }
118 if (dev)
119 IMMDevice_Release(dev);
120 }
121 IMMDeviceCollection_Release(col);
122}
#define trace
Definition: atltest.h:70
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
unsigned int UINT
Definition: ndis.h:50
static calc_node_t temp
Definition: rpn_ieee.c:38

Referenced by START_TEST().

Variable Documentation

◆ notif

IMMNotificationClient notif = { &notif_vtbl }
static

Definition at line 189 of file mmdevenum.c.

Referenced by ANIMATE_Notify(), and START_TEST().

◆ notif_vtbl

IMMNotificationClientVtbl notif_vtbl
static
Initial value:
= {
}
static HRESULT WINAPI notif_OnDeviceAdded(IMMNotificationClient *iface, const WCHAR *device_id)
Definition: mmdevenum.c:150
static HRESULT WINAPI notif_OnPropertyValueChanged(IMMNotificationClient *iface, const WCHAR *device_id, const PROPERTYKEY key)
Definition: mmdevenum.c:171
static HRESULT WINAPI notif_OnDeviceStateChanged(IMMNotificationClient *iface, const WCHAR *device_id, DWORD new_state)
Definition: mmdevenum.c:143
static HRESULT WINAPI notif_QueryInterface(IMMNotificationClient *iface, const GUID *riid, void **obj)
Definition: mmdevenum.c:124
static HRESULT WINAPI notif_OnDeviceRemoved(IMMNotificationClient *iface, const WCHAR *device_id)
Definition: mmdevenum.c:157
static ULONG WINAPI notif_AddRef(IMMNotificationClient *iface)
Definition: mmdevenum.c:131
static HRESULT WINAPI notif_OnDefaultDeviceChanged(IMMNotificationClient *iface, EDataFlow flow, ERole role, const WCHAR *device_id)
Definition: mmdevenum.c:164
static ULONG WINAPI notif_Release(IMMNotificationClient *iface)
Definition: mmdevenum.c:137

Definition at line 178 of file mmdevenum.c.