wined3d: Pass a wined3d_device_context to wined3d_cs_emit_set_index_buffer().
[wine.git] / dlls / devenum / tests / devenum.c
blob3e0d6f57dc307fd6fafeeda165b75a1d23ae7a12
1 /*
2 * Some unit tests for devenum
4 * Copyright (C) 2012 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "initguid.h"
24 #include "dshow.h"
25 #include "dmo.h"
26 #include "dmodshow.h"
27 #include "dsound.h"
28 #include "mmddk.h"
29 #include "vfw.h"
30 #include "setupapi.h"
31 #include "wine/test.h"
33 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
35 static void test_devenum(void)
37 IEnumMoniker *enum_cat, *enum_moniker;
38 ICreateDevEnum* create_devenum;
39 IPropertyBag *prop_bag;
40 IMoniker *moniker;
41 GUID cat_guid, clsid;
42 WCHAR *displayname;
43 IBindCtx *bindctx;
44 HRESULT hr, hr2;
45 IUnknown *unk;
46 VARIANT var;
47 int count;
49 hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
50 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
51 ok(hr == S_OK, "Failed to create devenum: %#x\n", hr);
53 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_ActiveMovieCategories, &enum_cat, 0);
54 ok(hr == S_OK, "Failed to enum categories: %#x\n", hr);
56 while (IEnumMoniker_Next(enum_cat, 1, &moniker, NULL) == S_OK)
58 hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
59 ok(hr == S_OK, "IMoniker_BindToStorage failed: %#x\n", hr);
61 VariantInit(&var);
62 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
63 ok(hr == S_OK, "Failed to read CLSID: %#x\n", hr);
65 hr = CLSIDFromString(V_BSTR(&var), &cat_guid);
66 ok(hr == S_OK, "got %#x\n", hr);
68 VariantClear(&var);
69 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
70 ok(hr == S_OK, "Failed to read FriendlyName: %#x\n", hr);
72 if (winetest_debug > 1)
73 trace("%s %s:\n", wine_dbgstr_guid(&cat_guid), wine_dbgstr_w(V_BSTR(&var)));
75 VariantClear(&var);
76 IPropertyBag_Release(prop_bag);
77 IMoniker_Release(moniker);
79 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &cat_guid, &enum_moniker, 0);
80 ok(SUCCEEDED(hr), "Failed to enum devices: %#x\n", hr);
82 if (hr == S_OK)
84 count = 0;
86 while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
88 hr = IMoniker_GetDisplayName(moniker, NULL, NULL, &displayname);
89 ok(hr == S_OK, "got %#x\n", hr);
91 hr = IMoniker_GetClassID(moniker, NULL);
92 ok(hr == E_INVALIDARG, "IMoniker_GetClassID should failed %x\n", hr);
94 hr = IMoniker_GetClassID(moniker, &clsid);
95 ok(hr == S_OK, "IMoniker_GetClassID failed with error %x\n", hr);
96 ok(IsEqualGUID(&clsid, &CLSID_CDeviceMoniker),
97 "Expected CLSID_CDeviceMoniker got %s\n", wine_dbgstr_guid(&clsid));
99 VariantInit(&var);
100 hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
101 ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);
103 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
104 ok((hr == S_OK) | (hr == ERROR_KEY_DOES_NOT_EXIST),
105 "IPropertyBag_Read failed: %#x\n", hr);
107 if (winetest_debug > 1)
108 trace(" %s %s\n", wine_dbgstr_w(displayname), wine_dbgstr_w(V_BSTR(&var)));
110 hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IUnknown, NULL);
111 ok(hr == E_POINTER, "got %#x\n", hr);
113 VariantClear(&var);
114 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
115 /* Instantiating the WMT Screen Capture Filter crashes on Windows XP. */
116 if (hr != S_OK || wcscmp(V_BSTR(&var), L"{31087270-D348-432C-899E-2D2F38FF29A0}"))
118 hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IUnknown, (void **)&unk);
119 if (hr == S_OK)
120 IUnknown_Release(unk);
121 hr2 = IMoniker_BindToObject(moniker, NULL, (IMoniker *)0xdeadbeef,
122 &IID_IUnknown, (void **)&unk);
123 if (hr2 == S_OK)
124 IUnknown_Release(unk);
125 ok(hr2 == hr, "Expected hr %#x, got %#x.\n", hr, hr2);
128 hr = CreateBindCtx(0, &bindctx);
129 ok(hr == S_OK, "Got hr %#x.\n", hr);
130 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
131 ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);
132 IPropertyBag_Release(prop_bag);
133 IBindCtx_Release(bindctx);
135 VariantClear(&var);
136 CoTaskMemFree(displayname);
137 IPropertyBag_Release(prop_bag);
138 IMoniker_Release(moniker);
139 count++;
141 IEnumMoniker_Release(enum_moniker);
143 ok(count > 0, "CreateClassEnumerator() returned S_OK but no devices were enumerated.\n");
147 IEnumMoniker_Release(enum_cat);
148 ICreateDevEnum_Release(create_devenum);
151 static void test_moniker_isequal(void)
153 HRESULT res;
154 ICreateDevEnum *create_devenum = NULL;
155 IEnumMoniker *enum_moniker0 = NULL, *enum_moniker1 = NULL;
156 IMoniker *moniker0 = NULL, *moniker1 = NULL;
158 res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
159 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
160 if (FAILED(res))
162 skip("Cannot create SystemDeviceEnum object (%x)\n", res);
163 return;
166 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
167 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
168 if (SUCCEEDED(res))
170 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
171 IEnumMoniker_Next(enum_moniker0, 1, &moniker1, NULL) == S_OK)
173 res = IMoniker_IsEqual(moniker0, moniker1);
174 ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
176 res = IMoniker_IsEqual(moniker1, moniker0);
177 ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
179 IMoniker_Release(moniker0);
180 IMoniker_Release(moniker1);
182 else
183 skip("Cannot get moniker for testing.\n");
185 IEnumMoniker_Release(enum_moniker0);
187 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
188 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
189 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_AudioRendererCategory, &enum_moniker1, 0);
190 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
191 if (SUCCEEDED(res))
193 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
194 IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
196 res = IMoniker_IsEqual(moniker0, moniker1);
197 ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
199 res = IMoniker_IsEqual(moniker1, moniker0);
200 ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
202 IMoniker_Release(moniker0);
203 IMoniker_Release(moniker1);
205 else
206 skip("Cannot get moniker for testing.\n");
208 IEnumMoniker_Release(enum_moniker0);
209 IEnumMoniker_Release(enum_moniker1);
211 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
212 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
213 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker1, 0);
214 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
215 if (SUCCEEDED(res))
217 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
218 IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
220 res = IMoniker_IsEqual(moniker0, moniker1);
221 ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
223 res = IMoniker_IsEqual(moniker1, moniker0);
224 ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
226 IMoniker_Release(moniker0);
227 IMoniker_Release(moniker1);
229 else
230 skip("Cannot get moniker for testing.\n");
232 IEnumMoniker_Release(enum_moniker0);
233 IEnumMoniker_Release(enum_moniker1);
235 ICreateDevEnum_Release(create_devenum);
237 return;
240 static BOOL find_moniker(const GUID *class, IMoniker *needle)
242 ICreateDevEnum *devenum;
243 IEnumMoniker *enum_mon;
244 IMoniker *mon;
245 BOOL found = FALSE;
247 CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void **)&devenum);
248 if (ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0) == S_OK)
250 while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK)
252 if (IMoniker_IsEqual(mon, needle) == S_OK)
253 found = TRUE;
255 IMoniker_Release(mon);
258 IEnumMoniker_Release(enum_mon);
260 ICreateDevEnum_Release(devenum);
261 return found;
264 DEFINE_GUID(CLSID_TestFilter, 0xdeadbeef,0xcf51,0x43e6,0xb6,0xc5,0x29,0x9e,0xa8,0xb6,0xb5,0x91);
266 static void test_register_filter(void)
268 IFilterMapper2 *mapper2;
269 IMoniker *mon = NULL;
270 REGFILTER2 rgf2 = {0};
271 HRESULT hr;
273 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper2, (void **)&mapper2);
274 ok(hr == S_OK, "Failed to create FilterMapper2: %#x\n", hr);
276 rgf2.dwVersion = 2;
277 rgf2.dwMerit = MERIT_UNLIKELY;
278 S2(U(rgf2)).cPins2 = 0;
280 hr = IFilterMapper2_RegisterFilter(mapper2, &CLSID_TestFilter, L"devenum test", &mon, NULL, NULL, &rgf2);
281 if (hr == E_ACCESSDENIED)
283 skip("Not enough permissions to register filters\n");
284 IFilterMapper2_Release(mapper2);
285 return;
287 ok(hr == S_OK, "RegisterFilter failed: %#x\n", hr);
289 ok(find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should be registered\n");
291 hr = IFilterMapper2_UnregisterFilter(mapper2, NULL, NULL, &CLSID_TestFilter);
292 ok(hr == S_OK, "UnregisterFilter failed: %#x\n", hr);
294 ok(!find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should not be registered\n");
295 IMoniker_Release(mon);
297 mon = NULL;
298 hr = IFilterMapper2_RegisterFilter(mapper2, &CLSID_TestFilter, L"devenum test", &mon, &CLSID_AudioRendererCategory, NULL, &rgf2);
299 ok(hr == S_OK, "RegisterFilter failed: %#x\n", hr);
301 ok(find_moniker(&CLSID_AudioRendererCategory, mon), "filter should be registered\n");
303 hr = IFilterMapper2_UnregisterFilter(mapper2, &CLSID_AudioRendererCategory, NULL, &CLSID_TestFilter);
304 ok(hr == S_OK, "UnregisterFilter failed: %#x\n", hr);
306 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
307 IMoniker_Release(mon);
309 IFilterMapper2_Release(mapper2);
312 static IMoniker *check_display_name_(int line, IParseDisplayName *parser, WCHAR *buffer)
314 IMoniker *mon;
315 ULONG eaten;
316 HRESULT hr;
317 WCHAR *str;
319 hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
320 ok_(__FILE__, line)(hr == S_OK, "ParseDisplayName failed: %#x\n", hr);
322 hr = IMoniker_GetDisplayName(mon, NULL, NULL, &str);
323 ok_(__FILE__, line)(hr == S_OK, "GetDisplayName failed: %#x\n", hr);
324 ok_(__FILE__, line)(!wcscmp(str, buffer), "got %s\n", wine_dbgstr_w(str));
326 CoTaskMemFree(str);
328 return mon;
330 #define check_display_name(parser, buffer) check_display_name_(__LINE__, parser, buffer)
332 static void test_directshow_filter(void)
334 SAFEARRAYBOUND bound = {.cElements = 10};
335 IParseDisplayName *parser;
336 IPropertyBag *prop_bag;
337 void *array_data;
338 IMoniker *mon;
339 WCHAR buffer[200];
340 LRESULT res;
341 VARIANT var;
342 HRESULT hr;
344 /* Test ParseDisplayName and GetDisplayName */
345 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
346 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
348 wcscpy(buffer, L"@device:sw:");
349 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
350 wcscat(buffer, L"\\test");
351 mon = check_display_name(parser, buffer);
353 /* Test writing and reading from the property bag */
354 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
356 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
357 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
359 VariantInit(&var);
360 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
361 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
363 /* writing causes the key to be created */
364 V_VT(&var) = VT_BSTR;
365 V_BSTR(&var) = SysAllocString(L"test");
366 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
367 if (hr != E_ACCESSDENIED)
369 ok(hr == S_OK, "Write failed: %#x\n", hr);
371 ok(find_moniker(&CLSID_AudioRendererCategory, mon), "filter should be registered\n");
373 VariantClear(&var);
374 V_VT(&var) = VT_EMPTY;
375 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
376 ok(hr == S_OK, "Got hr %#x.\n", hr);
377 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
378 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
380 VariantClear(&var);
381 V_VT(&var) = VT_LPWSTR;
382 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
383 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
385 V_VT(&var) = VT_BSTR;
386 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
387 ok(hr == S_OK, "Got hr %#x.\n", hr);
388 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
389 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
391 V_VT(&var) = VT_LPWSTR;
392 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
393 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
394 VariantClear(&var);
396 V_VT(&var) = VT_I4;
397 V_I4(&var) = 0xdeadbeef;
398 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
399 ok(hr == S_OK, "Got hr %#x.\n", hr);
401 V_VT(&var) = VT_EMPTY;
402 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
403 ok(hr == S_OK, "Got hr %#x.\n", hr);
404 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
405 ok(V_I4(&var) == 0xdeadbeef, "Got value %#x.\n", V_I4(&var));
407 V_VT(&var) = VT_UI4;
408 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
409 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
410 V_VT(&var) = VT_BSTR;
411 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
412 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
414 V_VT(&var) = VT_I4;
415 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
416 ok(hr == S_OK, "Got hr %#x.\n", hr);
417 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
418 ok(V_I4(&var) == 0xdeadbeef, "Got value %#x.\n", V_I4(&var));
420 V_VT(&var) = VT_UI4;
421 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
422 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
424 V_VT(&var) = VT_ARRAY | VT_UI1;
425 V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &bound);
426 SafeArrayAccessData(V_ARRAY(&var), &array_data);
427 memcpy(array_data, "test data", 10);
428 SafeArrayUnaccessData(V_ARRAY(&var));
429 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
430 ok(hr == S_OK, "Got hr %#x.\n", hr);
432 VariantClear(&var);
433 V_VT(&var) = VT_EMPTY;
434 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
435 ok(hr == S_OK, "Got hr %#x.\n", hr);
436 ok(V_VT(&var) == (VT_ARRAY | VT_UI1), "Got type %#x.\n", V_VT(&var));
437 SafeArrayAccessData(V_ARRAY(&var), &array_data);
438 ok(!memcmp(array_data, "test data", 10), "Got wrong data.\n");
439 SafeArrayUnaccessData(V_ARRAY(&var));
441 IMoniker_Release(mon);
443 /* devenum doesn't give us a way to unregister—we have to do that manually */
444 wcscpy(buffer, L"CLSID\\");
445 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
446 wcscat(buffer, L"\\Instance\\test");
447 res = RegDeleteKeyW(HKEY_CLASSES_ROOT, buffer);
448 ok(!res, "RegDeleteKey failed: %lu\n", res);
451 VariantClear(&var);
452 IPropertyBag_Release(prop_bag);
454 /* name can be anything */
456 wcscpy(buffer, L"@device:sw:test");
457 mon = check_display_name(parser, buffer);
459 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
460 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
462 VariantClear(&var);
463 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
464 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
466 V_VT(&var) = VT_BSTR;
467 V_BSTR(&var) = SysAllocString(L"test");
468 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
469 if (hr != E_ACCESSDENIED)
471 ok(hr == S_OK, "Write failed: %#x\n", hr);
473 VariantClear(&var);
474 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
475 ok(hr == S_OK, "Read failed: %#x\n", hr);
476 ok(!wcscmp(V_BSTR(&var), L"test"), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
478 IMoniker_Release(mon);
480 /* vista+ stores it inside the Instance key */
481 RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\test\\Instance");
483 res = RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\test");
484 ok(!res, "RegDeleteKey failed: %lu\n", res);
487 VariantClear(&var);
488 IPropertyBag_Release(prop_bag);
489 IParseDisplayName_Release(parser);
492 static void test_codec(void)
494 SAFEARRAYBOUND bound = {.cElements = 10};
495 IParseDisplayName *parser;
496 IPropertyBag *prop_bag;
497 void *array_data;
498 IMoniker *mon;
499 WCHAR buffer[200];
500 VARIANT var;
501 HRESULT hr;
503 /* Test ParseDisplayName and GetDisplayName */
504 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
505 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
507 wcscpy(buffer, L"@device:cm:");
508 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
509 wcscat(buffer, L"\\test");
510 mon = check_display_name(parser, buffer);
512 /* Test writing and reading from the property bag */
513 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
515 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
516 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
518 VariantInit(&var);
519 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
520 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
522 V_VT(&var) = VT_BSTR;
523 V_BSTR(&var) = SysAllocString(L"test");
524 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
525 ok(hr == S_OK, "Write failed: %#x\n", hr);
527 V_VT(&var) = VT_LPWSTR;
528 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
529 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
531 VariantClear(&var);
532 V_VT(&var) = VT_EMPTY;
533 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
534 ok(hr == S_OK, "Got hr %#x.\n", hr);
535 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
536 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
538 VariantClear(&var);
539 V_VT(&var) = VT_LPWSTR;
540 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
541 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
543 V_VT(&var) = VT_BSTR;
544 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
545 ok(hr == S_OK, "Got hr %#x.\n", hr);
546 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
547 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
549 V_VT(&var) = VT_I4;
550 V_I4(&var) = 0xdeadbeef;
551 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
552 ok(hr == S_OK, "Got hr %#x.\n", hr);
554 V_VT(&var) = VT_EMPTY;
555 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
556 ok(hr == S_OK, "Got hr %#x.\n", hr);
557 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
558 ok(V_I4(&var) == 0xdeadbeef, "Got value %#x.\n", V_I4(&var));
560 V_VT(&var) = VT_UI4;
561 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
562 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
563 V_VT(&var) = VT_BSTR;
564 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
565 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
567 V_VT(&var) = VT_I4;
568 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
569 ok(hr == S_OK, "Got hr %#x.\n", hr);
570 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
571 ok(V_I4(&var) == 0xdeadbeef, "Got value %#x.\n", V_I4(&var));
573 V_VT(&var) = VT_UI4;
574 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
575 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
577 V_VT(&var) = VT_ARRAY | VT_UI1;
578 V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &bound);
579 SafeArrayAccessData(V_ARRAY(&var), &array_data);
580 memcpy(array_data, "test data", 10);
581 SafeArrayUnaccessData(V_ARRAY(&var));
582 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
583 ok(hr == S_OK, "Got hr %#x.\n", hr);
585 /* unlike DirectShow filters, these are automatically generated, so
586 * enumerating them will destroy the key */
587 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
589 VariantClear(&var);
590 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
591 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
593 IPropertyBag_Release(prop_bag);
594 IMoniker_Release(mon);
596 IParseDisplayName_Release(parser);
599 static void test_dmo(const GUID *dmo_category, const GUID *enum_category)
601 IParseDisplayName *parser;
602 IPropertyBag *prop_bag;
603 IBaseFilter *filter;
604 IMediaObject *dmo;
605 IEnumDMO *enumdmo;
606 WCHAR buffer[200];
607 IMoniker *mon;
608 VARIANT var;
609 WCHAR *name;
610 HRESULT hr;
611 GUID clsid;
613 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
614 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
616 wcscpy(buffer, L"@device:dmo:");
617 StringFromGUID2(&CLSID_TestFilter, buffer + wcslen(buffer), CHARS_IN_GUID);
618 StringFromGUID2(dmo_category, buffer + wcslen(buffer), CHARS_IN_GUID);
619 mon = check_display_name(parser, buffer);
621 ok(!find_moniker(enum_category, mon), "DMO should not be registered\n");
623 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
624 ok(hr == S_OK, "got %#x\n", hr);
626 VariantInit(&var);
627 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
628 ok(hr == E_FAIL, "got %#x\n", hr);
630 V_VT(&var) = VT_BSTR;
631 V_BSTR(&var) = SysAllocString(L"devenum test");
632 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
633 ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
635 hr = DMORegister(L"devenum test", &CLSID_TestFilter, dmo_category, 0, 0, NULL, 0, NULL);
636 if (hr != E_FAIL)
638 ok(hr == S_OK, "got %#x\n", hr);
640 ok(find_moniker(enum_category, mon), "DMO should be registered\n");
642 VariantClear(&var);
643 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
644 ok(hr == S_OK, "got %#x\n", hr);
645 ok(!wcscmp(V_BSTR(&var), L"devenum test"), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
647 VariantClear(&var);
648 V_VT(&var) = VT_BSTR;
649 V_BSTR(&var) = SysAllocString(L"devenum test");
650 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
651 ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
653 VariantClear(&var);
654 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
655 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr);
657 hr = DMOUnregister(&CLSID_TestFilter, dmo_category);
658 ok(hr == S_OK, "got %#x\n", hr);
660 IPropertyBag_Release(prop_bag);
661 IMoniker_Release(mon);
663 hr = DMOEnum(&DMOCATEGORY_AUDIO_DECODER, 0, 0, NULL, 0, NULL, &enumdmo);
664 ok(hr == S_OK, "Got hr %#x.\n", hr);
666 while (IEnumDMO_Next(enumdmo, 1, &clsid, &name, NULL) == S_OK)
668 wcscpy(buffer, L"@device:dmo:");
669 StringFromGUID2(&clsid, buffer + wcslen(buffer), CHARS_IN_GUID);
670 StringFromGUID2(&DMOCATEGORY_AUDIO_DECODER, buffer + wcslen(buffer), CHARS_IN_GUID);
671 mon = check_display_name(parser, buffer);
672 ok(find_moniker(&DMOCATEGORY_AUDIO_DECODER, mon), "DMO was not found.\n");
674 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
675 ok(hr == S_OK, "Got hr %#x.\n", hr);
677 VariantClear(&var);
678 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
679 ok(hr == S_OK, "got %#x\n", hr);
680 ok(!wcscmp(V_BSTR(&var), name), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
682 VariantClear(&var);
683 V_VT(&var) = VT_BSTR;
684 V_BSTR(&var) = SysAllocString(L"devenum test");
685 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
686 ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
688 VariantClear(&var);
689 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
690 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr);
692 IPropertyBag_Release(prop_bag);
693 CoTaskMemFree(name);
695 hr = IMoniker_BindToObject(mon, NULL, NULL, &IID_IBaseFilter, (void **)&filter);
696 ok(hr == S_OK, "got %#x\n", hr);
698 hr = IBaseFilter_GetClassID(filter, &clsid);
699 ok(hr == S_OK, "got %#x\n", hr);
700 ok(IsEqualGUID(&clsid, &CLSID_DMOWrapperFilter), "Got CLSID %s.\n", debugstr_guid(&clsid));
702 hr = IBaseFilter_QueryInterface(filter, &IID_IMediaObject, (void **)&dmo);
703 ok(hr == S_OK, "got %#x\n", hr);
704 IMediaObject_Release(dmo);
706 IBaseFilter_Release(filter);
708 IEnumDMO_Release(enumdmo);
710 IParseDisplayName_Release(parser);
713 static void test_legacy_filter(void)
715 IParseDisplayName *parser;
716 IPropertyBag *prop_bag;
717 IFilterMapper *mapper;
718 IMoniker *mon;
719 WCHAR buffer[200];
720 VARIANT var;
721 HRESULT hr;
723 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
724 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
726 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper, (void **)&mapper);
727 ok(hr == S_OK, "Failed to create FilterMapper: %#x\n", hr);
729 hr = IFilterMapper_RegisterFilter(mapper, CLSID_TestFilter, L"test", 0xdeadbeef);
730 if (hr == VFW_E_BAD_KEY)
732 win_skip("not enough permissions to register filters\n");
733 goto end;
735 ok(hr == S_OK, "RegisterFilter failed: %#x\n", hr);
737 wcscpy(buffer, L"@device:cm:");
738 StringFromGUID2(&CLSID_LegacyAmFilterCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
739 wcscat(buffer, L"\\");
740 StringFromGUID2(&CLSID_TestFilter, buffer + wcslen(buffer), CHARS_IN_GUID);
742 mon = check_display_name(parser, buffer);
743 ok(find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should be registered\n");
745 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
746 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
748 VariantInit(&var);
749 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
750 ok(hr == S_OK, "Read failed: %#x\n", hr);
752 StringFromGUID2(&CLSID_TestFilter, buffer, CHARS_IN_GUID);
753 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
754 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
756 VariantClear(&var);
757 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
758 ok(hr == S_OK, "Read failed: %#x\n", hr);
759 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
760 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
762 VariantClear(&var);
763 IPropertyBag_Release(prop_bag);
765 hr = IFilterMapper_UnregisterFilter(mapper, CLSID_TestFilter);
766 ok(hr == S_OK, "UnregisterFilter failed: %#x\n", hr);
768 ok(!find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should not be registered\n");
769 IMoniker_Release(mon);
771 end:
772 IFilterMapper_Release(mapper);
773 IParseDisplayName_Release(parser);
776 static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *module, void *context)
778 IParseDisplayName *parser;
779 IPropertyBag *prop_bag;
780 IMoniker *mon;
781 WCHAR buffer[200];
782 WCHAR name[200];
783 VARIANT var;
784 HRESULT hr;
786 if (guid)
788 wcscpy(name, L"DirectSound: ");
789 wcscat(name, desc);
791 else
793 wcscpy(name, L"Default DirectSound Device");
794 guid = (GUID *)&GUID_NULL;
797 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
798 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
800 wcscpy(buffer, L"@device:cm:");
801 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
802 wcscat(buffer, L"\\");
803 wcscat(buffer, name);
805 mon = check_display_name(parser, buffer);
807 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
808 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
810 VariantInit(&var);
811 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
812 if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
814 /* Win8+ uses the GUID instead of the device name */
815 IPropertyBag_Release(prop_bag);
816 IMoniker_Release(mon);
818 wcscpy(buffer, L"@device:cm:");
819 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
820 wcscat(buffer, L"\\DirectSound: ");
821 StringFromGUID2(guid, buffer + wcslen(buffer) - 1, CHARS_IN_GUID);
823 mon = check_display_name(parser, buffer);
825 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
826 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
828 VariantInit(&var);
829 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
831 ok(hr == S_OK, "Read failed: %#x\n", hr);
833 ok(!wcscmp(name, V_BSTR(&var)), "expected %s, got %s\n",
834 wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
836 VariantClear(&var);
837 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
838 ok(hr == S_OK, "Read failed: %#x\n", hr);
840 StringFromGUID2(&CLSID_DSoundRender, buffer, CHARS_IN_GUID);
841 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
842 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
844 VariantClear(&var);
845 hr = IPropertyBag_Read(prop_bag, L"DSGuid", &var, NULL);
846 ok(hr == S_OK, "Read failed: %#x\n", hr);
848 StringFromGUID2(guid, buffer, CHARS_IN_GUID);
849 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
850 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
852 VariantClear(&var);
853 IPropertyBag_Release(prop_bag);
854 IMoniker_Release(mon);
855 IParseDisplayName_Release(parser);
856 return TRUE;
859 static void test_waveout(void)
861 IParseDisplayName *parser;
862 IPropertyBag *prop_bag;
863 IMoniker *mon;
864 WCHAR endpoint[200];
865 WAVEOUTCAPSW caps;
866 WCHAR buffer[200];
867 const WCHAR *name;
868 MMRESULT mmr;
869 int count, i;
870 VARIANT var;
871 HRESULT hr;
873 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
874 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
876 count = waveOutGetNumDevs();
878 for (i = -1; i < count; i++)
880 waveOutGetDevCapsW(i, &caps, sizeof(caps));
882 if (i == -1) /* WAVE_MAPPER */
883 name = L"Default WaveOut Device";
884 else
885 name = caps.szPname;
887 wcscpy(buffer, L"@device:cm:");
888 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
889 wcscat(buffer, L"\\");
890 wcscat(buffer, name);
892 mon = check_display_name(parser, buffer);
894 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
895 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
897 VariantInit(&var);
898 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
899 if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
901 IPropertyBag_Release(prop_bag);
902 IMoniker_Release(mon);
904 /* Win8+ uses the endpoint GUID instead of the device name */
905 mmr = waveOutMessage((HWAVEOUT)(DWORD_PTR) i, DRV_QUERYFUNCTIONINSTANCEID,
906 (DWORD_PTR) endpoint, sizeof(endpoint));
907 ok(!mmr, "waveOutMessage failed: %u\n", mmr);
909 wcscpy(buffer, L"@device:cm:");
910 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
911 wcscat(buffer, L"\\wave:");
912 wcscat(buffer, wcschr(endpoint, '}') + 2);
914 mon = check_display_name(parser, buffer);
916 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
917 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
919 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
921 ok(hr == S_OK, "Read failed: %#x\n", hr);
923 ok(!wcsncmp(name, V_BSTR(&var), wcslen(name)), "expected %s, got %s\n",
924 wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
926 VariantClear(&var);
927 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
928 ok(hr == S_OK, "Read failed: %#x\n", hr);
930 StringFromGUID2(&CLSID_AudioRender, buffer, CHARS_IN_GUID);
931 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
932 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
934 VariantClear(&var);
935 hr = IPropertyBag_Read(prop_bag, L"WaveOutId", &var, NULL);
936 ok(hr == S_OK, "Read failed: %#x\n", hr);
938 ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var));
940 IPropertyBag_Release(prop_bag);
941 IMoniker_Release(mon);
944 IParseDisplayName_Release(parser);
947 static void test_wavein(void)
949 IParseDisplayName *parser;
950 IPropertyBag *prop_bag;
951 IMoniker *mon;
952 WCHAR endpoint[200];
953 WCHAR buffer[200];
954 WAVEINCAPSW caps;
955 MMRESULT mmr;
956 int count, i;
957 VARIANT var;
958 HRESULT hr;
960 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
961 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
963 count = waveInGetNumDevs();
965 for (i = 0; i < count; i++)
967 waveInGetDevCapsW(i, &caps, sizeof(caps));
969 wcscpy(buffer, L"@device:cm:");
970 StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
971 wcscat(buffer, L"\\");
972 wcscat(buffer, caps.szPname);
974 mon = check_display_name(parser, buffer);
976 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
977 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
979 VariantInit(&var);
980 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
981 if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
983 IPropertyBag_Release(prop_bag);
984 IMoniker_Release(mon);
986 /* Win8+ uses the endpoint GUID instead of the device name */
987 mmr = waveInMessage((HWAVEIN)(DWORD_PTR) i, DRV_QUERYFUNCTIONINSTANCEID,
988 (DWORD_PTR) endpoint, sizeof(endpoint));
989 ok(!mmr, "waveInMessage failed: %u\n", mmr);
991 wcscpy(buffer, L"@device:cm:");
992 StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
993 wcscat(buffer, L"\\wave:");
994 wcscat(buffer, wcschr(endpoint, '}') + 2);
996 mon = check_display_name(parser, buffer);
998 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
999 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
1001 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
1003 ok(hr == S_OK, "Read failed: %#x\n", hr);
1005 ok(!wcsncmp(caps.szPname, V_BSTR(&var), wcslen(caps.szPname)), "expected %s, got %s\n",
1006 wine_dbgstr_w(caps.szPname), wine_dbgstr_w(V_BSTR(&var)));
1008 VariantClear(&var);
1009 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1010 ok(hr == S_OK, "Read failed: %#x\n", hr);
1012 StringFromGUID2(&CLSID_AudioRecord, buffer, CHARS_IN_GUID);
1013 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
1014 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
1016 VariantClear(&var);
1017 hr = IPropertyBag_Read(prop_bag, L"WaveInId", &var, NULL);
1018 ok(hr == S_OK, "Read failed: %#x\n", hr);
1020 ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var));
1022 IPropertyBag_Release(prop_bag);
1023 IMoniker_Release(mon);
1026 IParseDisplayName_Release(parser);
1029 static void test_midiout(void)
1031 IParseDisplayName *parser;
1032 IPropertyBag *prop_bag;
1033 IMoniker *mon;
1034 MIDIOUTCAPSW caps;
1035 WCHAR buffer[200];
1036 const WCHAR *name;
1037 int count, i;
1038 VARIANT var;
1039 HRESULT hr;
1041 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
1042 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
1044 count = midiOutGetNumDevs();
1046 for (i = -1; i < count; i++)
1048 midiOutGetDevCapsW(i, &caps, sizeof(caps));
1050 if (i == -1) /* MIDI_MAPPER */
1051 name = L"Default MidiOut Device";
1052 else
1053 name = caps.szPname;
1055 wcscpy(buffer, L"@device:cm:");
1056 StringFromGUID2(&CLSID_MidiRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
1057 wcscat(buffer, L"\\");
1058 wcscat(buffer, name);
1060 mon = check_display_name(parser, buffer);
1062 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
1063 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
1065 VariantInit(&var);
1066 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
1067 ok(hr == S_OK, "Read failed: %#x\n", hr);
1069 ok(!wcscmp(name, V_BSTR(&var)), "expected %s, got %s\n",
1070 wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
1072 VariantClear(&var);
1073 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1074 ok(hr == S_OK, "Read failed: %#x\n", hr);
1076 StringFromGUID2(&CLSID_AVIMIDIRender, buffer, CHARS_IN_GUID);
1077 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
1078 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
1080 VariantClear(&var);
1081 hr = IPropertyBag_Read(prop_bag, L"MidiOutId", &var, NULL);
1082 ok(hr == S_OK, "Read failed: %#x\n", hr);
1084 ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var));
1086 IPropertyBag_Release(prop_bag);
1087 IMoniker_Release(mon);
1090 IParseDisplayName_Release(parser);
1093 static void test_vfw(void)
1095 IParseDisplayName *parser;
1096 IPropertyBag *prop_bag;
1097 IMoniker *mon;
1098 WCHAR buffer[200];
1099 ICINFO info;
1100 VARIANT var;
1101 HRESULT hr;
1102 int i = 0;
1103 HIC hic;
1105 if (broken(sizeof(void *) == 8))
1107 win_skip("VFW codecs are not enumerated on 64-bit Windows\n");
1108 return;
1111 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
1112 ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
1114 while (ICInfo(ICTYPE_VIDEO, i++, &info))
1116 WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)),
1117 LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))};
1119 hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY);
1120 ICGetInfo(hic, &info, sizeof(info));
1121 ICClose(hic);
1123 wcscpy(buffer, L"@device:cm:");
1124 StringFromGUID2(&CLSID_VideoCompressorCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
1125 wcscat(buffer, L"\\");
1126 wcscat(buffer, name);
1128 mon = check_display_name(parser, buffer);
1130 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
1131 ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
1133 VariantInit(&var);
1134 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
1135 ok(hr == S_OK, "Read failed: %#x\n", hr);
1137 ok(!wcscmp(info.szDescription, V_BSTR(&var)), "expected %s, got %s\n",
1138 wine_dbgstr_w(info.szDescription), wine_dbgstr_w(V_BSTR(&var)));
1140 VariantClear(&var);
1141 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1142 ok(hr == S_OK, "Read failed: %#x\n", hr);
1144 StringFromGUID2(&CLSID_AVICo, buffer, CHARS_IN_GUID);
1145 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
1146 wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
1148 VariantClear(&var);
1149 hr = IPropertyBag_Read(prop_bag, L"FccHandler", &var, NULL);
1150 ok(hr == S_OK, "Read failed: %#x\n", hr);
1151 ok(!wcscmp(name, V_BSTR(&var)), "expected %s, got %s\n",
1152 wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
1154 VariantClear(&var);
1155 IPropertyBag_Release(prop_bag);
1156 IMoniker_Release(mon);
1159 IParseDisplayName_Release(parser);
1162 START_TEST(devenum)
1164 HRESULT hr;
1166 CoInitialize(NULL);
1168 test_devenum();
1169 test_moniker_isequal();
1170 test_register_filter();
1171 test_directshow_filter();
1172 test_codec();
1173 test_dmo(&DMOCATEGORY_AUDIO_DECODER, &CLSID_LegacyAmFilterCategory);
1174 test_dmo(&DMOCATEGORY_VIDEO_DECODER, &CLSID_LegacyAmFilterCategory);
1175 test_dmo(&DMOCATEGORY_VIDEO_DECODER, &DMOCATEGORY_VIDEO_DECODER);
1177 test_legacy_filter();
1178 hr = DirectSoundEnumerateW(test_dsound, NULL);
1179 ok(hr == S_OK, "got %#x\n", hr);
1180 test_waveout();
1181 test_wavein();
1182 test_midiout();
1183 test_vfw();
1185 CoUninitialize();