ReactOS 0.4.17-dev-966-gf06eace
devenum.c
Go to the documentation of this file.
1/*
2 * Some unit tests for devenum
3 *
4 * Copyright (C) 2012 Christian Costa
5 *
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.
10 *
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.
15 *
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
19 */
20
21#define COBJMACROS
22
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"
32
33DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
34
35static void test_devenum(void)
36{
37 IEnumMoniker *enum_cat, *enum_moniker;
38 ICreateDevEnum* create_devenum;
39 IPropertyBag *prop_bag;
41 GUID cat_guid, clsid;
42 WCHAR *displayname;
43 IBindCtx *bindctx;
44 HRESULT hr, hr2;
45 IUnknown *unk;
47 int count;
48
49 hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
50 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
51 ok(hr == S_OK, "Got hr %#lx.\n", hr);
52
53 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_ActiveMovieCategories, &enum_cat, 0);
54 ok(hr == S_OK, "Got hr %#lx.\n", hr);
55
56 while (IEnumMoniker_Next(enum_cat, 1, &moniker, NULL) == S_OK)
57 {
58 hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
59 ok(hr == S_OK, "Got hr %#lx.\n", hr);
60
62 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
63 ok(hr == S_OK, "Got hr %#lx.\n", hr);
64
65 hr = CLSIDFromString(V_BSTR(&var), &cat_guid);
66 ok(hr == S_OK, "Got hr %#lx.\n", hr);
67
69 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
70 ok(hr == S_OK, "Got hr %#lx.\n", hr);
71
72 if (winetest_debug > 1)
73 trace("%s %s:\n", wine_dbgstr_guid(&cat_guid), wine_dbgstr_w(V_BSTR(&var)));
74
76 IPropertyBag_Release(prop_bag);
77 IMoniker_Release(moniker);
78
79 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &cat_guid, &enum_moniker, 0);
80 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
81
82 if (hr == S_OK)
83 {
84 count = 0;
85
86 while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
87 {
88 hr = IMoniker_GetDisplayName(moniker, NULL, NULL, &displayname);
89 ok(hr == S_OK, "Got hr %#lx.\n", hr);
90
91 hr = IMoniker_GetClassID(moniker, NULL);
92 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
93
94 hr = IMoniker_GetClassID(moniker, &clsid);
95 ok(hr == S_OK, "Got hr %#lx.\n", hr);
96 ok(IsEqualGUID(&clsid, &CLSID_CDeviceMoniker),
97 "Expected CLSID_CDeviceMoniker got %s\n", wine_dbgstr_guid(&clsid));
98
100 hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
101 ok(hr == S_OK, "Got hr %#lx.\n", hr);
102
103 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
105 "Got hr %#lx.\n", hr);
106
107 if (winetest_debug > 1)
108 trace(" %s %s\n", wine_dbgstr_w(displayname), wine_dbgstr_w(V_BSTR(&var)));
109
110 hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IUnknown, NULL);
111 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
112
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}"))
117 {
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 %#lx, got %#lx.\n", hr, hr2);
126 }
127
128 hr = CreateBindCtx(0, &bindctx);
129 ok(hr == S_OK, "Got hr %#lx.\n", hr);
130 hr = IMoniker_BindToStorage(moniker, bindctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
132 IPropertyBag_Release(prop_bag);
133 IBindCtx_Release(bindctx);
134
136 CoTaskMemFree(displayname);
137 IPropertyBag_Release(prop_bag);
138 IMoniker_Release(moniker);
139 count++;
140 }
141 IEnumMoniker_Release(enum_moniker);
142
143 ok(count > 0, "CreateClassEnumerator() returned S_OK but no devices were enumerated.\n");
144 }
145 }
146
147 IEnumMoniker_Release(enum_cat);
148 ICreateDevEnum_Release(create_devenum);
149}
150
151static void test_moniker_isequal(void)
152{
153 ICreateDevEnum *create_devenum = NULL;
154 IEnumMoniker *enum_moniker0 = NULL, *enum_moniker1 = NULL;
155 IMoniker *moniker0 = NULL, *moniker1 = NULL;
156 HRESULT hr;
157
158 hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
159 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
160 ok(hr == S_OK, "Got hr %#lx.\n", hr);
161
162 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
163 ok(hr == S_OK, "Got hr %#lx.\n", hr);
164
165 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK
166 && IEnumMoniker_Next(enum_moniker0, 1, &moniker1, NULL) == S_OK)
167 {
168 hr = IMoniker_IsEqual(moniker0, moniker1);
169 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
170
171 hr = IMoniker_IsEqual(moniker1, moniker0);
172 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
173
174 IMoniker_Release(moniker0);
175 IMoniker_Release(moniker1);
176 }
177 else
178 {
179 skip("Cannot get moniker for testing.\n");
180 }
181 IEnumMoniker_Release(enum_moniker0);
182
183 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
185 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_AudioRendererCategory, &enum_moniker1, 0);
186 ok(hr == S_OK, "Got hr %#lx.\n", hr);
187
188 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK
189 && IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
190 {
191 hr = IMoniker_IsEqual(moniker0, moniker1);
192 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
193
194 hr = IMoniker_IsEqual(moniker1, moniker0);
195 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
196
197 IMoniker_Release(moniker0);
198 IMoniker_Release(moniker1);
199 }
200 else
201 {
202 skip("Cannot get moniker for testing.\n");
203 }
204 IEnumMoniker_Release(enum_moniker0);
205 IEnumMoniker_Release(enum_moniker1);
206
207 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
208 ok(hr == S_OK, "Got hr %#lx.\n", hr);
209 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker1, 0);
210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
211
212 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK
213 && IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
214 {
215 hr = IMoniker_IsEqual(moniker0, moniker1);
216 ok(hr == S_OK, "Got hr %#lx.\n", hr);
217
218 hr = IMoniker_IsEqual(moniker1, moniker0);
219 ok(hr == S_OK, "Got hr %#lx.\n", hr);
220
221 IMoniker_Release(moniker0);
222 IMoniker_Release(moniker1);
223 }
224 else
225 {
226 skip("Cannot get moniker for testing.\n");
227 }
228 IEnumMoniker_Release(enum_moniker0);
229 IEnumMoniker_Release(enum_moniker1);
230
231 ICreateDevEnum_Release(create_devenum);
232}
233
234static BOOL find_moniker(const GUID *class, IMoniker *needle)
235{
236 ICreateDevEnum *devenum;
237 IEnumMoniker *enum_mon;
238 IMoniker *mon;
239 BOOL found = FALSE;
240
241 CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void **)&devenum);
242 if (ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0) == S_OK)
243 {
244 while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK)
245 {
246 if (IMoniker_IsEqual(mon, needle) == S_OK)
247 found = TRUE;
248
249 IMoniker_Release(mon);
250 }
251
252 IEnumMoniker_Release(enum_mon);
253 }
254 ICreateDevEnum_Release(devenum);
255 return found;
256}
257
258DEFINE_GUID(CLSID_TestFilter, 0xdeadbeef,0xcf51,0x43e6,0xb6,0xc5,0x29,0x9e,0xa8,0xb6,0xb5,0x91);
259
260static void test_register_filter(void)
261{
262 IFilterMapper2 *mapper2;
263 IMoniker *mon = NULL;
264 REGFILTER2 rgf2 = {0};
265 HRESULT hr;
266
267 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper2, (void **)&mapper2);
268 ok(hr == S_OK, "Got hr %#lx.\n", hr);
269
270 rgf2.dwVersion = 2;
271 rgf2.dwMerit = MERIT_UNLIKELY;
272 rgf2.cPins2 = 0;
273
274
275 hr = IFilterMapper2_RegisterFilter(mapper2, &CLSID_TestFilter, L"devenum test", &mon, NULL, NULL, &rgf2);
276 if (hr == E_ACCESSDENIED)
277 {
278 skip("Not enough permissions to register filters\n");
279 IFilterMapper2_Release(mapper2);
280 return;
281 }
282 ok(hr == S_OK, "Got hr %#lx.\n", hr);
283
284 ok(find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should be registered\n");
285
286 hr = IFilterMapper2_UnregisterFilter(mapper2, NULL, NULL, &CLSID_TestFilter);
287 ok(hr == S_OK, "Got hr %#lx.\n", hr);
288
289 ok(!find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should not be registered\n");
290 IMoniker_Release(mon);
291
292 mon = NULL;
293 hr = IFilterMapper2_RegisterFilter(mapper2, &CLSID_TestFilter, L"devenum test", &mon, &CLSID_AudioRendererCategory, NULL, &rgf2);
294 ok(hr == S_OK, "Got hr %#lx.\n", hr);
295
296 ok(find_moniker(&CLSID_AudioRendererCategory, mon), "filter should be registered\n");
297
298 hr = IFilterMapper2_UnregisterFilter(mapper2, &CLSID_AudioRendererCategory, NULL, &CLSID_TestFilter);
299 ok(hr == S_OK, "Got hr %#lx.\n", hr);
300
301 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
302 IMoniker_Release(mon);
303
304 IFilterMapper2_Release(mapper2);
305}
306
308{
309 IMoniker *mon;
310 ULONG eaten;
311 HRESULT hr;
312 WCHAR *str;
313
314 hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
315 ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
316
317 hr = IMoniker_GetDisplayName(mon, NULL, NULL, &str);
318 ok_(__FILE__, line)(hr == S_OK, "Got hr %#lx.\n", hr);
319 ok_(__FILE__, line)(!wcscmp(str, buffer), "got %s\n", wine_dbgstr_w(str));
320
322
323 return mon;
324}
325#define check_display_name(parser, buffer) check_display_name_(__LINE__, parser, buffer)
326
327static void test_directshow_filter(void)
328{
329 SAFEARRAYBOUND bound = {.cElements = 10};
331 IPropertyBag *prop_bag;
332 void *array_data;
333 IMoniker *mon;
334 WCHAR buffer[200];
335 LRESULT res;
336 VARIANT var;
337 HRESULT hr;
338
339 /* Test ParseDisplayName and GetDisplayName */
340 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
341 ok(hr == S_OK, "Got hr %#lx.\n", hr);
342
343 wcscpy(buffer, L"@device:sw:");
344 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
345 wcscat(buffer, L"\\test");
347
348 /* Test writing and reading from the property bag */
349 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
350
351 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
352 ok(hr == S_OK, "Got hr %#lx.\n", hr);
353
355 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
356 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got hr %#lx.\n", hr);
357
358 /* writing causes the key to be created */
359 V_VT(&var) = VT_BSTR;
360 V_BSTR(&var) = SysAllocString(L"test");
361 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
362 if (hr != E_ACCESSDENIED)
363 {
364 ok(hr == S_OK, "Got hr %#lx.\n", hr);
365
366 ok(find_moniker(&CLSID_AudioRendererCategory, mon), "filter should be registered\n");
367
369 V_VT(&var) = VT_EMPTY;
370 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
371 ok(hr == S_OK, "Got hr %#lx.\n", hr);
372 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
373 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
374
376 V_VT(&var) = VT_LPWSTR;
377 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
378 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
379
380 V_VT(&var) = VT_BSTR;
381 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
382 ok(hr == S_OK, "Got hr %#lx.\n", hr);
383 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
384 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
385
386 V_VT(&var) = VT_LPWSTR;
387 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
388 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
390
391 V_VT(&var) = VT_I4;
392 V_I4(&var) = 0xdeadbeef;
393 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
394 ok(hr == S_OK, "Got hr %#lx.\n", hr);
395
396 V_VT(&var) = VT_EMPTY;
397 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
398 ok(hr == S_OK, "Got hr %#lx.\n", hr);
399 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
400 ok(V_I4(&var) == 0xdeadbeef, "Got value %#lx.\n", V_I4(&var));
401
402 V_VT(&var) = VT_UI4;
403 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
404 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
405 V_VT(&var) = VT_BSTR;
406 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
407 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
408
409 V_VT(&var) = VT_I4;
410 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
411 ok(hr == S_OK, "Got hr %#lx.\n", hr);
412 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
413 ok(V_I4(&var) == 0xdeadbeef, "Got value %#lx.\n", V_I4(&var));
414
415 V_VT(&var) = VT_UI4;
416 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
417 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
418
419 V_VT(&var) = VT_ARRAY | VT_UI1;
420 V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &bound);
421 SafeArrayAccessData(V_ARRAY(&var), &array_data);
422 memcpy(array_data, "test data", 10);
424 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
425 ok(hr == S_OK, "Got hr %#lx.\n", hr);
426
428 V_VT(&var) = VT_EMPTY;
429 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
431 ok(V_VT(&var) == (VT_ARRAY | VT_UI1), "Got type %#x.\n", V_VT(&var));
432 SafeArrayAccessData(V_ARRAY(&var), &array_data);
433 ok(!memcmp(array_data, "test data", 10), "Got wrong data.\n");
435
436 IMoniker_Release(mon);
437
438 /* devenum doesn't give us a way to unregister—we have to do that manually */
439 wcscpy(buffer, L"CLSID\\");
440 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
441 wcscat(buffer, L"\\Instance\\test");
443 ok(!res, "Failed to delete key, error %Iu.\n", res);
444 }
445
447 IPropertyBag_Release(prop_bag);
448
449 /* name can be anything */
450
451 wcscpy(buffer, L"@device:sw:test");
453
454 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
455 ok(hr == S_OK, "Got hr %#lx.\n", hr);
456
458 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
459 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got hr %#lx.\n", hr);
460
461 V_VT(&var) = VT_BSTR;
462 V_BSTR(&var) = SysAllocString(L"test");
463 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
464 if (hr != E_ACCESSDENIED)
465 {
466 ok(hr == S_OK, "Got hr %#lx.\n", hr);
467
469 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
470 ok(hr == S_OK, "Got hr %#lx.\n", hr);
471 ok(!wcscmp(V_BSTR(&var), L"test"), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
472
473 IMoniker_Release(mon);
474
475 /* vista+ stores it inside the Instance key */
476 RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\test\\Instance");
477
478 res = RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\test");
479 ok(!res, "Failed to delete key, error %Iu.\n", res);
480 }
481
483 IPropertyBag_Release(prop_bag);
484 IParseDisplayName_Release(parser);
485}
486
487static void test_codec(void)
488{
489 SAFEARRAYBOUND bound = {.cElements = 10};
491 IPropertyBag *prop_bag;
492 void *array_data;
493 IMoniker *mon;
494 WCHAR buffer[200];
495 VARIANT var;
496 HRESULT hr;
497
498 /* Test ParseDisplayName and GetDisplayName */
499 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
500 ok(hr == S_OK, "Got hr %#lx.\n", hr);
501
502 wcscpy(buffer, L"@device:cm:");
503 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
504 wcscat(buffer, L"\\test");
506
507 /* Test writing and reading from the property bag */
508 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
509
510 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
511 ok(hr == S_OK, "Got hr %#lx.\n", hr);
512
514 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
515 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got hr %#lx.\n", hr);
516
517 V_VT(&var) = VT_BSTR;
518 V_BSTR(&var) = SysAllocString(L"test");
519 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
520 ok(hr == S_OK, "Got hr %#lx.\n", hr);
521
522 V_VT(&var) = VT_LPWSTR;
523 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
524 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
525
527 V_VT(&var) = VT_EMPTY;
528 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
529 ok(hr == S_OK, "Got hr %#lx.\n", hr);
530 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
531 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
532
534 V_VT(&var) = VT_LPWSTR;
535 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
536 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
537
538 V_VT(&var) = VT_BSTR;
539 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
540 ok(hr == S_OK, "Got hr %#lx.\n", hr);
541 ok(V_VT(&var) == VT_BSTR, "Got type %#x.\n", V_VT(&var));
542 ok(!wcscmp(V_BSTR(&var), L"test"), "Got name %s.\n", wine_dbgstr_w(V_BSTR(&var)));
543
544 V_VT(&var) = VT_I4;
545 V_I4(&var) = 0xdeadbeef;
546 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
547 ok(hr == S_OK, "Got hr %#lx.\n", hr);
548
549 V_VT(&var) = VT_EMPTY;
550 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
551 ok(hr == S_OK, "Got hr %#lx.\n", hr);
552 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
553 ok(V_I4(&var) == 0xdeadbeef, "Got value %#lx.\n", V_I4(&var));
554
555 V_VT(&var) = VT_UI4;
556 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
557 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
558 V_VT(&var) = VT_BSTR;
559 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
560 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
561
562 V_VT(&var) = VT_I4;
563 hr = IPropertyBag_Read(prop_bag, L"foobar", &var, NULL);
564 ok(hr == S_OK, "Got hr %#lx.\n", hr);
565 ok(V_VT(&var) == VT_I4, "Got type %#x.\n", V_VT(&var));
566 ok(V_I4(&var) == 0xdeadbeef, "Got value %#lx.\n", V_I4(&var));
567
568 V_VT(&var) = VT_UI4;
569 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
570 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
571
572 V_VT(&var) = VT_ARRAY | VT_UI1;
573 V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &bound);
574 SafeArrayAccessData(V_ARRAY(&var), &array_data);
575 memcpy(array_data, "test data", 10);
577 hr = IPropertyBag_Write(prop_bag, L"foobar", &var);
578 ok(hr == S_OK, "Got hr %#lx.\n", hr);
579
580 /* unlike DirectShow filters, these are automatically generated, so
581 * enumerating them will destroy the key */
582 ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
583
585 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
586 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got hr %#lx.\n", hr);
587
588 IPropertyBag_Release(prop_bag);
589 IMoniker_Release(mon);
590
591 IParseDisplayName_Release(parser);
592}
593
594static void test_dmo(const GUID *dmo_category, const GUID *enum_category)
595{
597 IPropertyBag *prop_bag;
599 IMediaObject *dmo;
600 IEnumDMO *enumdmo;
601 WCHAR buffer[200];
602 IMoniker *mon;
603 VARIANT var;
604 WCHAR *name;
605 HRESULT hr;
606 GUID clsid;
607
608 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
609 ok(hr == S_OK, "Got hr %#lx.\n", hr);
610
611 wcscpy(buffer, L"@device:dmo:");
612 StringFromGUID2(&CLSID_TestFilter, buffer + wcslen(buffer), CHARS_IN_GUID);
615
616 ok(!find_moniker(enum_category, mon), "DMO should not be registered\n");
617
618 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
620
622 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
623 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
624
625 V_VT(&var) = VT_BSTR;
626 V_BSTR(&var) = SysAllocString(L"devenum test");
627 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
628 ok(hr == E_ACCESSDENIED, "Got hr %#lx.\n", hr);
629
630 hr = DMORegister(L"devenum test", &CLSID_TestFilter, dmo_category, 0, 0, NULL, 0, NULL);
631 if (hr != E_FAIL)
632 {
633 ok(hr == S_OK, "Got hr %#lx.\n", hr);
634
635 ok(find_moniker(enum_category, mon), "DMO should be registered\n");
636
638 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
639 ok(hr == S_OK, "Got hr %#lx.\n", hr);
640 ok(!wcscmp(V_BSTR(&var), L"devenum test"), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
641
643 V_VT(&var) = VT_BSTR;
644 V_BSTR(&var) = SysAllocString(L"devenum test");
645 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
646 ok(hr == E_ACCESSDENIED, "Got hr %#lx.\n", hr);
647
649 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
650 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got hr %#lx.\n", hr);
651
652 hr = DMOUnregister(&CLSID_TestFilter, dmo_category);
653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
654 }
655 IPropertyBag_Release(prop_bag);
656 IMoniker_Release(mon);
657
658 hr = DMOEnum(&DMOCATEGORY_AUDIO_DECODER, 0, 0, NULL, 0, NULL, &enumdmo);
659 ok(hr == S_OK, "Got hr %#lx.\n", hr);
660
661 while (IEnumDMO_Next(enumdmo, 1, &clsid, &name, NULL) == S_OK)
662 {
663 wcscpy(buffer, L"@device:dmo:");
665 StringFromGUID2(&DMOCATEGORY_AUDIO_DECODER, buffer + wcslen(buffer), CHARS_IN_GUID);
667 ok(find_moniker(&DMOCATEGORY_AUDIO_DECODER, mon), "DMO was not found.\n");
668
669 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
670 ok(hr == S_OK, "Got hr %#lx.\n", hr);
671
673 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
674 ok(hr == S_OK, "Got hr %#lx.\n", hr);
675 ok(!wcscmp(V_BSTR(&var), name), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
676
678 V_VT(&var) = VT_BSTR;
679 V_BSTR(&var) = SysAllocString(L"devenum test");
680 hr = IPropertyBag_Write(prop_bag, L"FriendlyName", &var);
681 ok(hr == E_ACCESSDENIED, "Got hr %#lx.\n", hr);
682
684 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
685 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Got hr %#lx.\n", hr);
686
687 IPropertyBag_Release(prop_bag);
689
690 hr = IMoniker_BindToObject(mon, NULL, NULL, &IID_IBaseFilter, (void **)&filter);
691 ok(hr == S_OK, "Got hr %#lx.\n", hr);
692
693 hr = IBaseFilter_GetClassID(filter, &clsid);
694 ok(hr == S_OK, "Got hr %#lx.\n", hr);
695 ok(IsEqualGUID(&clsid, &CLSID_DMOWrapperFilter), "Got CLSID %s.\n", debugstr_guid(&clsid));
696
697 hr = IBaseFilter_QueryInterface(filter, &IID_IMediaObject, (void **)&dmo);
698 ok(hr == S_OK, "Got hr %#lx.\n", hr);
699 IMediaObject_Release(dmo);
700
701 IBaseFilter_Release(filter);
702 }
703 IEnumDMO_Release(enumdmo);
704
705 IParseDisplayName_Release(parser);
706}
707
708static void test_legacy_filter(void)
709{
711 IPropertyBag *prop_bag;
712 IFilterMapper *mapper;
713 IMoniker *mon;
714 WCHAR buffer[200];
715 VARIANT var;
716 HRESULT hr;
717
718 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
719 ok(hr == S_OK, "Got hr %#lx.\n", hr);
720
721 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper, (void **)&mapper);
722 ok(hr == S_OK, "Got hr %#lx.\n", hr);
723
724 hr = IFilterMapper_RegisterFilter(mapper, CLSID_TestFilter, L"test", 0xdeadbeef);
725 if (hr == VFW_E_BAD_KEY)
726 {
727 win_skip("not enough permissions to register filters\n");
728 goto end;
729 }
730 ok(hr == S_OK, "Got hr %#lx.\n", hr);
731
732 wcscpy(buffer, L"@device:cm:");
733 StringFromGUID2(&CLSID_LegacyAmFilterCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
734 wcscat(buffer, L"\\");
735 StringFromGUID2(&CLSID_TestFilter, buffer + wcslen(buffer), CHARS_IN_GUID);
736
738 ok(find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should be registered\n");
739
740 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
741 ok(hr == S_OK, "Got hr %#lx.\n", hr);
742
744 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
746
747 StringFromGUID2(&CLSID_TestFilter, buffer, CHARS_IN_GUID);
748 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
750
752 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
753 ok(hr == S_OK, "Got hr %#lx.\n", hr);
754 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
756
758 IPropertyBag_Release(prop_bag);
759
760 hr = IFilterMapper_UnregisterFilter(mapper, CLSID_TestFilter);
761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
762
763 ok(!find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should not be registered\n");
764 IMoniker_Release(mon);
765
766end:
767 IFilterMapper_Release(mapper);
768 IParseDisplayName_Release(parser);
769}
770
772{
774 IPropertyBag *prop_bag;
775 IMoniker *mon;
776 WCHAR buffer[200];
777 WCHAR name[200];
778 VARIANT var;
779 HRESULT hr;
780
781 if (guid)
782 {
783 wcscpy(name, L"DirectSound: ");
784 wcscat(name, desc);
785 }
786 else
787 {
788 wcscpy(name, L"Default DirectSound Device");
789 guid = (GUID *)&GUID_NULL;
790 }
791
792 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
793 ok(hr == S_OK, "Got hr %#lx.\n", hr);
794
795 wcscpy(buffer, L"@device:cm:");
796 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
797 wcscat(buffer, L"\\");
799
801
802 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
803 ok(hr == S_OK, "Got hr %#lx.\n", hr);
804
806 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
808 {
809 /* Win8+ uses the GUID instead of the device name */
810 IPropertyBag_Release(prop_bag);
811 IMoniker_Release(mon);
812
813 wcscpy(buffer, L"@device:cm:");
814 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
815 wcscat(buffer, L"\\DirectSound: ");
817
819
820 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
821 ok(hr == S_OK, "Got hr %#lx.\n", hr);
822
824 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
825 }
826 ok(hr == S_OK, "Got hr %#lx.\n", hr);
827
828 ok(!wcscmp(name, V_BSTR(&var)), "expected %s, got %s\n",
830
832 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
833 ok(hr == S_OK, "Got hr %#lx.\n", hr);
834
835 StringFromGUID2(&CLSID_DSoundRender, buffer, CHARS_IN_GUID);
836 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
838
840 hr = IPropertyBag_Read(prop_bag, L"DSGuid", &var, NULL);
841 ok(hr == S_OK, "Got hr %#lx.\n", hr);
842
844 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
846
848 IPropertyBag_Release(prop_bag);
849 IMoniker_Release(mon);
850 IParseDisplayName_Release(parser);
851 return TRUE;
852}
853
854static void test_waveout(void)
855{
857 IPropertyBag *prop_bag;
858 IMoniker *mon;
859 WCHAR endpoint[200];
860 WAVEOUTCAPSW caps;
861 WCHAR buffer[200];
862 const WCHAR *name;
863 MMRESULT mmr;
864 int count, i;
865 VARIANT var;
866 HRESULT hr;
867
868 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
869 ok(hr == S_OK, "Got hr %#lx.\n", hr);
870
872
873 for (i = -1; i < count; i++)
874 {
875 waveOutGetDevCapsW(i, &caps, sizeof(caps));
876
877 if (i == -1) /* WAVE_MAPPER */
878 name = L"Default WaveOut Device";
879 else
880 name = caps.szPname;
881
882 wcscpy(buffer, L"@device:cm:");
883 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
884 wcscat(buffer, L"\\");
886
888
889 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
890 ok(hr == S_OK, "Got hr %#lx.\n", hr);
891
893 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
895 {
896 IPropertyBag_Release(prop_bag);
897 IMoniker_Release(mon);
898
899 /* Win8+ uses the endpoint GUID instead of the device name */
901 (DWORD_PTR) endpoint, sizeof(endpoint));
902 ok(!mmr, "waveOutMessage failed: %u\n", mmr);
903
904 wcscpy(buffer, L"@device:cm:");
905 StringFromGUID2(&CLSID_AudioRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
906 wcscat(buffer, L"\\wave:");
907 wcscat(buffer, wcschr(endpoint, '}') + 2);
908
910
911 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
912 ok(hr == S_OK, "Got hr %#lx.\n", hr);
913
914 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
915 }
916 ok(hr == S_OK, "Got hr %#lx.\n", hr);
917
918 ok(!wcsncmp(name, V_BSTR(&var), wcslen(name)), "expected %s, got %s\n",
920
922 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
923 ok(hr == S_OK, "Got hr %#lx.\n", hr);
924
925 StringFromGUID2(&CLSID_AudioRender, buffer, CHARS_IN_GUID);
926 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
928
930 hr = IPropertyBag_Read(prop_bag, L"WaveOutId", &var, NULL);
931 ok(hr == S_OK, "Got hr %#lx.\n", hr);
932
933 ok(V_I4(&var) == i, "Expected id %d, got %ld.\n", i, V_I4(&var));
934
935 IPropertyBag_Release(prop_bag);
936 IMoniker_Release(mon);
937 }
938
939 IParseDisplayName_Release(parser);
940}
941
942static void test_wavein(void)
943{
945 IPropertyBag *prop_bag;
946 IMoniker *mon;
947 WCHAR endpoint[200];
948 WCHAR buffer[200];
949 WAVEINCAPSW caps;
950 MMRESULT mmr;
951 int count, i;
952 VARIANT var;
953 HRESULT hr;
954
955 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
956 ok(hr == S_OK, "Got hr %#lx.\n", hr);
957
959
960 for (i = 0; i < count; i++)
961 {
962 waveInGetDevCapsW(i, &caps, sizeof(caps));
963
964 wcscpy(buffer, L"@device:cm:");
965 StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
966 wcscat(buffer, L"\\");
967 wcscat(buffer, caps.szPname);
968
970
971 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
972 ok(hr == S_OK, "Got hr %#lx.\n", hr);
973
975 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
977 {
978 IPropertyBag_Release(prop_bag);
979 IMoniker_Release(mon);
980
981 /* Win8+ uses the endpoint GUID instead of the device name */
983 (DWORD_PTR) endpoint, sizeof(endpoint));
984 ok(!mmr, "waveInMessage failed: %u\n", mmr);
985
986 wcscpy(buffer, L"@device:cm:");
987 StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
988 wcscat(buffer, L"\\wave:");
989 wcscat(buffer, wcschr(endpoint, '}') + 2);
990
992
993 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
994 ok(hr == S_OK, "Got hr %#lx.\n", hr);
995
996 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
997 }
998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
999
1000 ok(!wcsncmp(caps.szPname, V_BSTR(&var), wcslen(caps.szPname)), "expected %s, got %s\n",
1002
1003 VariantClear(&var);
1004 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1005 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1006
1007 StringFromGUID2(&CLSID_AudioRecord, buffer, CHARS_IN_GUID);
1008 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
1010
1011 VariantClear(&var);
1012 hr = IPropertyBag_Read(prop_bag, L"WaveInId", &var, NULL);
1013 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1014
1015 ok(V_I4(&var) == i, "Expected id %d, got %ld.\n", i, V_I4(&var));
1016
1017 IPropertyBag_Release(prop_bag);
1018 IMoniker_Release(mon);
1019 }
1020
1021 IParseDisplayName_Release(parser);
1022}
1023
1024static void test_midiout(void)
1025{
1027 IPropertyBag *prop_bag;
1028 IMoniker *mon;
1029 MIDIOUTCAPSW caps;
1030 WCHAR buffer[200];
1031 const WCHAR *name;
1032 int count, i;
1033 VARIANT var;
1034 HRESULT hr;
1035
1036 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
1037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1038
1040
1041 for (i = -1; i < count; i++)
1042 {
1043 midiOutGetDevCapsW(i, &caps, sizeof(caps));
1044
1045 if (i == -1) /* MIDI_MAPPER */
1046 name = L"Default MidiOut Device";
1047 else
1048 name = caps.szPname;
1049
1050 wcscpy(buffer, L"@device:cm:");
1051 StringFromGUID2(&CLSID_MidiRendererCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
1052 wcscat(buffer, L"\\");
1053 wcscat(buffer, name);
1054
1056
1057 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
1058 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1059
1060 VariantInit(&var);
1061 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
1062 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1063
1064 ok(!wcscmp(name, V_BSTR(&var)), "expected %s, got %s\n",
1066
1067 VariantClear(&var);
1068 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1069 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1070
1071 StringFromGUID2(&CLSID_AVIMIDIRender, buffer, CHARS_IN_GUID);
1072 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
1074
1075 VariantClear(&var);
1076 hr = IPropertyBag_Read(prop_bag, L"MidiOutId", &var, NULL);
1077 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1078
1079 ok(V_I4(&var) == i, "Expected id %d, got %ld.\n", i, V_I4(&var));
1080
1081 IPropertyBag_Release(prop_bag);
1082 IMoniker_Release(mon);
1083 }
1084
1085 IParseDisplayName_Release(parser);
1086}
1087
1088static void test_vfw(void)
1089{
1091 IPropertyBag *prop_bag;
1092 IMoniker *mon;
1093 WCHAR buffer[200];
1094 ICINFO info;
1095 VARIANT var;
1096 HRESULT hr;
1097 int i = 0;
1098 HIC hic;
1099
1100 if (broken(sizeof(void *) == 8))
1101 {
1102 win_skip("VFW codecs are not enumerated on 64-bit Windows\n");
1103 return;
1104 }
1105
1106 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
1107 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1108
1109 while (ICInfo(ICTYPE_VIDEO, i++, &info))
1110 {
1111 WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)),
1112 LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))};
1113
1114 hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY);
1115 ICGetInfo(hic, &info, sizeof(info));
1116 ICClose(hic);
1117
1118 wcscpy(buffer, L"@device:cm:");
1119 StringFromGUID2(&CLSID_VideoCompressorCategory, buffer + wcslen(buffer), CHARS_IN_GUID);
1120 wcscat(buffer, L"\\");
1121 wcscat(buffer, name);
1122
1124
1125 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
1126 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1127
1128 VariantInit(&var);
1129 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
1130 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1131
1132 ok(!wcscmp(info.szDescription, V_BSTR(&var)), "expected %s, got %s\n",
1133 wine_dbgstr_w(info.szDescription), wine_dbgstr_w(V_BSTR(&var)));
1134
1135 VariantClear(&var);
1136 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1138
1139 StringFromGUID2(&CLSID_AVICo, buffer, CHARS_IN_GUID);
1140 ok(!wcscmp(buffer, V_BSTR(&var)), "expected %s, got %s\n",
1142
1143 VariantClear(&var);
1144 hr = IPropertyBag_Read(prop_bag, L"FccHandler", &var, NULL);
1145 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1146 ok(!wcscmp(name, V_BSTR(&var)), "expected %s, got %s\n",
1148
1149 VariantClear(&var);
1150 IPropertyBag_Release(prop_bag);
1151 IMoniker_Release(mon);
1152 }
1153
1154 IParseDisplayName_Release(parser);
1155}
1156
1157static void test_video_input(void)
1158{
1159 ICreateDevEnum* create_devenum;
1160 IEnumMoniker *mon;
1162 IPropertyBag *prop_bag;
1163 GUID guid;
1164 VARIANT var;
1165 HRESULT hr;
1166
1167 hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
1168 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1169
1170 hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_VideoInputDeviceCategory, &mon, 0);
1171 if (hr == S_FALSE)
1172 {
1173 skip("No video capture devices present.\n");
1174 ICreateDevEnum_Release(create_devenum);
1176 return;
1177 }
1178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1179
1180 while (IEnumMoniker_Next(mon, 1, &moniker, NULL) == S_OK)
1181 {
1182 hr = IMoniker_BindToStorage(moniker, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
1183 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1184
1185 VariantInit(&var);
1186 hr = IPropertyBag_Read(prop_bag, L"CLSID", &var, NULL);
1187 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1188
1190 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1191
1192 VariantClear(&var);
1193 hr = IPropertyBag_Read(prop_bag, L"FriendlyName", &var, NULL);
1194 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1195
1196 VariantClear(&var);
1197 hr = IPropertyBag_Read(prop_bag, L"DevicePath", &var, NULL);
1198 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1199
1200 VariantClear(&var);
1201 IPropertyBag_Release(prop_bag);
1202 IMoniker_Release(moniker);
1203 }
1204
1205 IEnumMoniker_Release(mon);
1206 ICreateDevEnum_Release(create_devenum);
1207}
1208
1210{
1211 HRESULT hr;
1212
1214
1215 test_devenum();
1219 test_codec();
1220 test_dmo(&DMOCATEGORY_AUDIO_DECODER, &CLSID_LegacyAmFilterCategory);
1221 test_dmo(&DMOCATEGORY_VIDEO_DECODER, &CLSID_LegacyAmFilterCategory);
1222 test_dmo(&DMOCATEGORY_VIDEO_DECODER, &DMOCATEGORY_VIDEO_DECODER);
1223
1226 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1227 test_waveout();
1228 test_wavein();
1229 test_midiout();
1230 test_vfw();
1232
1234}
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
const GUID IID_IUnknown
#define CHARS_IN_GUID
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
const GUID IID_IBaseFilter
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
Definition: enum.c:210
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
#define wcschr
Definition: compat.h:17
#define CALLBACK
Definition: compat.h:35
@ VT_BSTR
Definition: compat.h:2303
@ VT_ARRAY
Definition: compat.h:2341
@ VT_LPWSTR
Definition: compat.h:2325
@ VT_I4
Definition: compat.h:2298
@ VT_UI4
Definition: compat.h:2313
@ VT_EMPTY
Definition: compat.h:2295
@ VT_UI1
Definition: compat.h:2311
GUID guid
Definition: version.c:147
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:523
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
HRESULT WINAPI DMOEnum(REFGUID category, DWORD flags, DWORD cInTypes, const DMO_PARTIAL_MEDIATYPE *pInTypes, DWORD cOutTypes, const DMO_PARTIAL_MEDIATYPE *pOutTypes, IEnumDMO **ppEnum)
Definition: dmoreg.c:674
HRESULT WINAPI DMORegister(LPCWSTR szName, REFCLSID clsidDMO, REFGUID guidCategory, DWORD dwFlags, DWORD cInTypes, const DMO_PARTIAL_MEDIATYPE *pInTypes, DWORD cOutTypes, const DMO_PARTIAL_MEDIATYPE *pOutTypes)
Definition: dmoreg.c:126
HRESULT WINAPI DMOUnregister(REFCLSID dmo, REFGUID category)
Definition: dmoreg.c:231
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define debugstr_guid
Definition: kernel32.h:35
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
int winetest_debug
#define win_skip
Definition: minitest.h:67
LONG_PTR LRESULT
Definition: minwindef.h:176
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ICTYPE_VIDEO
Definition: mmreg.h:531
UINT MMRESULT
Definition: mmsystem.h:964
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
const char * var
Definition: shader.c:5879
static void test_devenum(void)
Definition: devenum.c:35
static void test_midiout(void)
Definition: devenum.c:1024
static void test_legacy_filter(void)
Definition: devenum.c:708
#define check_display_name(parser, buffer)
Definition: devenum.c:325
static void test_video_input(void)
Definition: devenum.c:1157
static void test_register_filter(void)
Definition: devenum.c:260
static void test_moniker_isequal(void)
Definition: devenum.c:151
static IMoniker * check_display_name_(int line, IParseDisplayName *parser, WCHAR *buffer)
Definition: devenum.c:307
static void test_wavein(void)
Definition: devenum.c:942
static BOOL find_moniker(const GUID *class, IMoniker *needle)
Definition: devenum.c:234
static void test_codec(void)
Definition: devenum.c:487
static void test_directshow_filter(void)
Definition: devenum.c:327
static void test_vfw(void)
Definition: devenum.c:1088
static void test_waveout(void)
Definition: devenum.c:854
static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *module, void *context)
Definition: devenum.c:771
static void test_dmo(void)
Definition: filtermapper.c:611
const CLSID * clsid
Definition: msctf.cpp:50
HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
Definition: msvideo_main.c:428
LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb)
Definition: msvideo_main.c:581
BOOL VFWAPI ICInfo(DWORD type, DWORD handler, ICINFO *info)
Definition: msvideo_main.c:257
LRESULT WINAPI ICClose(HIC hic)
HRESULT WINAPI CreateBindCtx(DWORD reserved, IBindCtx **bind_context)
Definition: bindctx.c:491
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_I4(A)
Definition: oleauto.h:247
const GUID IID_IParseDisplayName
const GUID IID_IPropertyBag
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
const WCHAR * str
#define DRV_QUERYFUNCTIONINSTANCEID
Definition: mmddk.h:98
wcscat
wcscpy
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define ERROR_KEY_DOES_NOT_EXIST
Definition: setupapi.h:303
Definition: vfw.h:280
DWORD dwVersion
Definition: axextend.idl:238
DWORD dwMerit
Definition: axextend.idl:239
ULONG cPins2
Definition: axextend.idl:252
Definition: http.c:7252
Definition: nis.h:10
Definition: filter.c:165
Definition: parser.c:49
Definition: name.c:39
Definition: import.c:81
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1128
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1062
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1041
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:626
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:547
#define ICMODE_QUERY
Definition: vfw.h:271
#define VFW_E_BAD_KEY
Definition: vfwmsgs.h:170
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_ACCESSDENIED
Definition: winerror.h:4116
#define E_POINTER
Definition: winerror.h:3480
#define ERROR_NOT_FOUND
Definition: winerror.h:1014
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:806
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2173
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2565
UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:814
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2813
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2538
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2573
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10