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
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
;
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
);
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
);
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
)));
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
);
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
));
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
);
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
);
120 IUnknown_Release(unk
);
121 hr2
= IMoniker_BindToObject(moniker
, NULL
, (IMoniker
*)0xdeadbeef,
122 &IID_IUnknown
, (void **)&unk
);
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
);
136 CoTaskMemFree(displayname
);
137 IPropertyBag_Release(prop_bag
);
138 IMoniker_Release(moniker
);
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)
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
);
162 skip("Cannot create SystemDeviceEnum object (%x)\n", res
);
166 res
= ICreateDevEnum_CreateClassEnumerator(create_devenum
, &CLSID_LegacyAmFilterCategory
, &enum_moniker0
, 0);
167 ok(SUCCEEDED(res
), "Cannot create enum moniker (res = %x)\n", 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
);
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
);
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
);
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
);
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
);
230 skip("Cannot get moniker for testing.\n");
232 IEnumMoniker_Release(enum_moniker0
);
233 IEnumMoniker_Release(enum_moniker1
);
235 ICreateDevEnum_Release(create_devenum
);
240 static BOOL
find_moniker(const GUID
*class, IMoniker
*needle
)
242 ICreateDevEnum
*devenum
;
243 IEnumMoniker
*enum_mon
;
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
)
255 IMoniker_Release(mon
);
258 IEnumMoniker_Release(enum_mon
);
260 ICreateDevEnum_Release(devenum
);
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};
273 hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC
, &IID_IFilterMapper2
, (void **)&mapper2
);
274 ok(hr
== S_OK
, "Failed to create FilterMapper2: %#x\n", hr
);
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
);
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
);
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
)
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
));
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
;
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
);
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");
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
)));
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
);
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
));
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
);
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
));
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
);
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
);
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
);
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
);
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
);
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
;
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
);
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
);
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
)));
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
)));
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
));
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
);
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
));
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");
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
;
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
);
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
);
638 ok(hr
== S_OK
, "got %#x\n", hr
);
640 ok(find_moniker(enum_category
, mon
), "DMO should be registered\n");
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
)));
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
);
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
);
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
)));
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
);
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
);
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
;
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");
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
);
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
)));
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
)));
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
);
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
;
788 wcscpy(name
, L
"DirectSound: ");
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
);
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
);
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
)));
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
)));
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
)));
853 IPropertyBag_Release(prop_bag
);
854 IMoniker_Release(mon
);
855 IParseDisplayName_Release(parser
);
859 static void test_waveout(void)
861 IParseDisplayName
*parser
;
862 IPropertyBag
*prop_bag
;
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";
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
);
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
)));
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
)));
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
;
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
);
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
)));
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
)));
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
;
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";
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
);
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
)));
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
)));
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
;
1105 if (broken(sizeof(void *) == 8))
1107 win_skip("VFW codecs are not enumerated on 64-bit Windows\n");
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
));
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
);
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
)));
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
)));
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
)));
1155 IPropertyBag_Release(prop_bag
);
1156 IMoniker_Release(mon
);
1159 IParseDisplayName_Release(parser
);
1169 test_moniker_isequal();
1170 test_register_filter();
1171 test_directshow_filter();
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
);