ReactOS 0.4.17-dev-966-gf06eace
createdevenum.c
Go to the documentation of this file.
1/*
2 * ICreateDevEnum implementation for DEVENUM.dll
3 *
4 * Copyright (C) 2002 Robert Shearman
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 * NOTES ON THIS FILE:
21 * - Implements ICreateDevEnum interface which creates an IEnumMoniker
22 * implementation
23 * - Also creates the special registry keys created at run-time
24 */
25
26#include "devenum_private.h"
27#include "vfw.h"
28#include "aviriff.h"
29#include "dsound.h"
30
31#include "wine/debug.h"
32#include "mmddk.h"
33
34#include "initguid.h"
35#include "wine/fil_data.h"
36
38
40{
41 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
42
43 if (!ppv)
44 return E_POINTER;
45
47 IsEqualGUID(riid, &IID_ICreateDevEnum))
48 {
49 *ppv = iface;
50 ICreateDevEnum_AddRef(iface);
51 return S_OK;
52 }
53
54 FIXME("- no interface IID: %s\n", debugstr_guid(riid));
55 *ppv = NULL;
56 return E_NOINTERFACE;
57}
58
60{
61 TRACE("\n");
62
63 return 2; /* non-heap based object */
64}
65
67{
68 TRACE("\n");
69
70 return 1; /* non-heap based object */
71}
72
73static HRESULT register_codec(const GUID *class, const WCHAR *name,
74 const GUID *clsid, const WCHAR *friendly_name, IPropertyBag **ret)
75{
76 WCHAR guidstr[CHARS_IN_GUID];
78 IPropertyBag *propbag;
79 IMoniker *mon;
82 ULONG eaten;
83 HRESULT hr;
84
85 hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
86 if (FAILED(hr))
87 return hr;
88
89 if (!(buffer = malloc((wcslen(L"@device:cm:") + CHARS_IN_GUID + wcslen(name) + 1) * sizeof(WCHAR))))
90 {
91 IParseDisplayName_Release(parser);
92 return E_OUTOFMEMORY;
93 }
94
95 wcscpy(buffer, L"@device:cm:");
97 wcscat(buffer, L"\\");
99
100 IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
101 IParseDisplayName_Release(parser);
102 free(buffer);
103
104 IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&propbag);
105 IMoniker_Release(mon);
106
107 V_VT(&var) = VT_BSTR;
108 V_BSTR(&var) = SysAllocString(friendly_name);
109 hr = IPropertyBag_Write(propbag, L"FriendlyName", &var);
111 if (FAILED(hr))
112 {
113 IPropertyBag_Release(propbag);
114 return hr;
115 }
116
117 V_VT(&var) = VT_BSTR;
118 StringFromGUID2(clsid, guidstr, ARRAY_SIZE(guidstr));
119 V_BSTR(&var) = SysAllocString(guidstr);
120 hr = IPropertyBag_Write(propbag, L"CLSID", &var);
122 if (FAILED(hr))
123 {
124 IPropertyBag_Release(propbag);
125 return hr;
126 }
127
128 *ret = propbag;
129 return S_OK;
130}
131
132static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
133{
134 HKEY hkeyTypes = NULL;
135 DWORD dwMajorTypes, i;
136 REGPINTYPES *lpMediaType = NULL;
137 DWORD dwMediaTypeSize = 0;
138
139 if (RegOpenKeyExW(hkeyPinKey, L"Types", 0, KEY_READ, &hkeyTypes) != ERROR_SUCCESS)
140 return ;
141
142 if (RegQueryInfoKeyW(hkeyTypes, NULL, NULL, NULL, &dwMajorTypes, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
143 != ERROR_SUCCESS)
144 {
145 RegCloseKey(hkeyTypes);
146 return ;
147 }
148
149 for (i = 0; i < dwMajorTypes; i++)
150 {
151 HKEY hkeyMajorType = NULL;
152 WCHAR wszMajorTypeName[64];
153 DWORD cName = ARRAY_SIZE(wszMajorTypeName);
154 DWORD dwMinorTypes, i1;
155
156 if (RegEnumKeyExW(hkeyTypes, i, wszMajorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
157
158 if (RegOpenKeyExW(hkeyTypes, wszMajorTypeName, 0, KEY_READ, &hkeyMajorType) != ERROR_SUCCESS) continue;
159
160 if (RegQueryInfoKeyW(hkeyMajorType, NULL, NULL, NULL, &dwMinorTypes, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
161 != ERROR_SUCCESS)
162 {
163 RegCloseKey(hkeyMajorType);
164 continue;
165 }
166
167 for (i1 = 0; i1 < dwMinorTypes; i1++)
168 {
169 WCHAR wszMinorTypeName[64];
170 CLSID *clsMajorType = NULL, *clsMinorType = NULL;
171 HRESULT hr;
172
173 cName = ARRAY_SIZE(wszMinorTypeName);
174 if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
175
177 if (!clsMinorType) continue;
178
179 clsMajorType = CoTaskMemAlloc(sizeof(CLSID));
180 if (!clsMajorType) goto error_cleanup_types;
181
182 hr = CLSIDFromString(wszMinorTypeName, clsMinorType);
183 if (FAILED(hr)) goto error_cleanup_types;
184
185 hr = CLSIDFromString(wszMajorTypeName, clsMajorType);
186 if (FAILED(hr)) goto error_cleanup_types;
187
188 if (rgPin->nMediaTypes == dwMediaTypeSize)
189 {
190 DWORD dwNewSize = dwMediaTypeSize + (dwMediaTypeSize < 2 ? 1 : dwMediaTypeSize / 2);
191 REGPINTYPES *lpNewMediaType;
192
193 lpNewMediaType = CoTaskMemRealloc(lpMediaType, sizeof(REGPINTYPES) * dwNewSize);
194 if (!lpNewMediaType) goto error_cleanup_types;
195
196 lpMediaType = lpNewMediaType;
197 dwMediaTypeSize = dwNewSize;
198 }
199
200 lpMediaType[rgPin->nMediaTypes].clsMajorType = clsMajorType;
201 lpMediaType[rgPin->nMediaTypes].clsMinorType = clsMinorType;
202 rgPin->nMediaTypes++;
203 continue;
204
205 error_cleanup_types:
206
207 CoTaskMemFree(clsMajorType);
209 }
210
211 RegCloseKey(hkeyMajorType);
212 }
213
214 RegCloseKey(hkeyTypes);
215
216 if (lpMediaType && !rgPin->nMediaTypes)
217 {
218 CoTaskMemFree(lpMediaType);
219 lpMediaType = NULL;
220 }
221
222 rgPin->lpMediaType = lpMediaType;
223}
224
225static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
226{
227 HKEY hkeyPins = NULL;
228 DWORD dwPinsSubkeys, i;
229 REGFILTERPINS2 *rgPins = NULL;
230
231 rgf2->dwVersion = 2;
232 rgf2->cPins2 = 0;
233 rgf2->rgPins2 = NULL;
234
235 if (RegOpenKeyExW(hkeyFilterClass, L"Pins", 0, KEY_READ, &hkeyPins) != ERROR_SUCCESS)
236 return ;
237
238 if (RegQueryInfoKeyW(hkeyPins, NULL, NULL, NULL, &dwPinsSubkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
239 != ERROR_SUCCESS)
240 {
241 RegCloseKey(hkeyPins);
242 return ;
243 }
244
245 if (dwPinsSubkeys)
246 {
247 rgPins = CoTaskMemAlloc(sizeof(REGFILTERPINS2) * dwPinsSubkeys);
248 if (!rgPins)
249 {
250 RegCloseKey(hkeyPins);
251 return ;
252 }
253 }
254
255 for (i = 0; i < dwPinsSubkeys; i++)
256 {
257 HKEY hkeyPinKey = NULL;
258 WCHAR wszPinName[MAX_PATH];
259 DWORD cName = ARRAY_SIZE(wszPinName);
260 REGFILTERPINS2 *rgPin = &rgPins[rgf2->cPins2];
262 LONG lRet;
263
264 memset(rgPin, 0, sizeof(*rgPin));
265
266 if (RegEnumKeyExW(hkeyPins, i, wszPinName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
267
268 if (RegOpenKeyExW(hkeyPins, wszPinName, 0, KEY_READ, &hkeyPinKey) != ERROR_SUCCESS) continue;
269
270 size = sizeof(DWORD);
271 lRet = RegQueryValueExW(hkeyPinKey, L"AllowedMany", NULL, &Type, (BYTE *)&value, &size);
272 if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
273 goto error_cleanup;
274 if (value)
275 rgPin->dwFlags |= REG_PINFLAG_B_MANY;
276
277 size = sizeof(DWORD);
278 lRet = RegQueryValueExW(hkeyPinKey, L"AllowedZero", NULL, &Type, (BYTE *)&value, &size);
279 if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
280 goto error_cleanup;
281 if (value)
282 rgPin->dwFlags |= REG_PINFLAG_B_ZERO;
283
284 size = sizeof(DWORD);
285 lRet = RegQueryValueExW(hkeyPinKey, L"Direction", NULL, &Type, (BYTE *)&value, &size);
286 if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
287 goto error_cleanup;
288 if (value)
290
291
292 size = sizeof(DWORD);
293 lRet = RegQueryValueExW(hkeyPinKey, L"IsRendered", NULL, &Type, (BYTE *)&value, &size);
294 if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
295 goto error_cleanup;
296 if (value)
298
299 DEVENUM_ReadPinTypes(hkeyPinKey, rgPin);
300
301 ++rgf2->cPins2;
302 continue;
303
304 error_cleanup:
305
306 RegCloseKey(hkeyPinKey);
307 }
308
309 RegCloseKey(hkeyPins);
310
311 if (rgPins && !rgf2->cPins2)
312 {
313 CoTaskMemFree(rgPins);
314 rgPins = NULL;
315 }
316
317 rgf2->rgPins2 = rgPins;
318}
319
321{
322 if (rgf->rgPins2)
323 {
324 UINT iPin;
325
326 for (iPin = 0; iPin < rgf->cPins2; iPin++)
327 {
328 if (rgf->rgPins2[iPin].lpMediaType)
329 {
330 UINT iType;
331
332 for (iType = 0; iType < rgf->rgPins2[iPin].nMediaTypes; iType++)
333 {
334 CoTaskMemFree((void *)rgf->rgPins2[iPin].lpMediaType[iType].clsMajorType);
335 CoTaskMemFree((void *)rgf->rgPins2[iPin].lpMediaType[iType].clsMinorType);
336 }
337
338 CoTaskMemFree((void *)rgf->rgPins2[iPin].lpMediaType);
339 }
340 }
341
342 CoTaskMemFree((void *)rgf->rgPins2);
343 }
344}
345
347{
348 IAMFilterData *fildata;
349 BYTE *data = NULL;
350 ULONG size;
351 HRESULT hr;
352
353 hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IAMFilterData, (void **)&fildata);
354 if (FAILED(hr))
355 return hr;
356
357 hr = IAMFilterData_CreateFilterData(fildata, rgf, &data, &size);
358 IAMFilterData_Release(fildata);
359 if (FAILED(hr))
360 return hr;
361
362 V_VT(var) = VT_ARRAY | VT_UI1;
364 {
367 return E_OUTOFMEMORY;
368 }
369
372 return S_OK;
373}
374
375static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
376{
377 VARIANT var;
378
379 if (SUCCEEDED(create_filter_data(&var, rgf)))
380 {
381 IPropertyBag_Write(prop_bag, L"FilterData", &var);
383 }
384}
385
386static void register_legacy_filters(void)
387{
388 HKEY hkeyFilter = NULL;
389 DWORD dwFilterSubkeys, i;
390 LONG lRet;
391 HRESULT hr;
392
393 lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"Filter", 0, KEY_READ, &hkeyFilter);
394 hr = HRESULT_FROM_WIN32(lRet);
395
396 if (SUCCEEDED(hr))
397 {
398 lRet = RegQueryInfoKeyW(hkeyFilter, NULL, NULL, NULL, &dwFilterSubkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
399 hr = HRESULT_FROM_WIN32(lRet);
400 }
401
402 if (SUCCEEDED(hr))
403 {
404 for (i = 0; i < dwFilterSubkeys; i++)
405 {
406 WCHAR wszFilterSubkeyName[64];
407 DWORD cName = ARRAY_SIZE(wszFilterSubkeyName);
408 IPropertyBag *prop_bag = NULL;
409 WCHAR wszRegKey[MAX_PATH];
410 HKEY classkey = NULL;
411 REGFILTER2 rgf2;
412 DWORD Type, len;
413 GUID clsid;
414
415 if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
416
417 TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
418
419 hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
420 if (FAILED(hr))
421 continue;
422
423 swprintf(wszRegKey, ARRAY_SIZE(wszRegKey), L"CLSID\\%s", wszFilterSubkeyName);
424 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
425 continue;
426
427 len = 0;
428 if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
429 {
430 WCHAR *friendlyname = malloc(len);
431 if (!friendlyname)
432 {
433 RegCloseKey(classkey);
434 continue;
435 }
436 RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len);
437
438 hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
439 &clsid, friendlyname, &prop_bag);
440
441 free(friendlyname);
442 }
443 else
444 hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName,
445 &clsid, wszFilterSubkeyName, &prop_bag);
446 if (FAILED(hr))
447 {
448 RegCloseKey(classkey);
449 continue;
450 }
451
452 /* write filter data */
453 rgf2.dwMerit = MERIT_NORMAL;
454
455 len = sizeof(rgf2.dwMerit);
456 RegQueryValueExW(classkey, L"Merit", NULL, &Type, (BYTE *)&rgf2.dwMerit, &len);
457
458 DEVENUM_ReadPins(classkey, &rgf2);
459
460 write_filter_data(prop_bag, &rgf2);
461
462 IPropertyBag_Release(prop_bag);
463 RegCloseKey(classkey);
464 free_regfilter2(&rgf2);
465 }
466 }
467
468 if (hkeyFilter) RegCloseKey(hkeyFilter);
469}
470
472{
473 static const WCHAR defaultW[] = L"Default DirectSound Device";
474 IPropertyBag *prop_bag = NULL;
475 REGFILTERPINS2 rgpins = {0};
476 REGPINTYPES rgtypes = {0};
477 REGFILTER2 rgf = {0};
479 VARIANT var;
480 HRESULT hr;
481
482 if (guid)
483 {
484 WCHAR *name = malloc(sizeof(defaultW) + wcslen(desc) * sizeof(WCHAR));
485 if (!name)
486 return FALSE;
487 wcscpy(name, L"DirectSound: ");
488 wcscat(name, desc);
489
490 hr = register_codec(&CLSID_AudioRendererCategory, name,
491 &CLSID_DSoundRender, name, &prop_bag);
492 free(name);
493 }
494 else
495 hr = register_codec(&CLSID_AudioRendererCategory, defaultW,
496 &CLSID_DSoundRender, defaultW, &prop_bag);
497 if (FAILED(hr))
498 return FALSE;
499
500 /* write filter data */
501 rgf.dwVersion = 2;
502 rgf.dwMerit = guid ? MERIT_DO_NOT_USE : MERIT_PREFERRED;
503 rgf.cPins2 = 1;
504 rgf.rgPins2 = &rgpins;
506 /* FIXME: native registers many more formats */
507 rgpins.nMediaTypes = 1;
508 rgpins.lpMediaType = &rgtypes;
509 rgtypes.clsMajorType = &MEDIATYPE_Audio;
510 rgtypes.clsMinorType = &MEDIASUBTYPE_PCM;
511
512 write_filter_data(prop_bag, &rgf);
513
514 /* write DSound guid */
515 V_VT(&var) = VT_BSTR;
517 if ((V_BSTR(&var) = SysAllocString(clsid)))
518 hr = IPropertyBag_Write(prop_bag, L"DSGuid", &var);
519
521 IPropertyBag_Release(prop_bag);
522 return TRUE;
523}
524
526{
527 IPropertyBag *prop_bag = NULL;
528 REGFILTERPINS2 rgpins = {0};
529 REGPINTYPES rgtypes = {0};
530 REGFILTER2 rgf = {0};
531 WAVEOUTCAPSW caps;
532 const WCHAR *name;
533 int i, count;
534 VARIANT var;
535 HRESULT hr;
536
538
539 for (i = -1; i < count; i++)
540 {
541 waveOutGetDevCapsW(i, &caps, sizeof(caps));
542
543 name = (i == -1) ? L"Default WaveOut Device" : caps.szPname;
544
545 hr = register_codec(&CLSID_AudioRendererCategory, name,
546 &CLSID_AudioRender, name, &prop_bag);
547 if (FAILED(hr))
548 continue;
549
550 /* write filter data */
551 rgf.dwVersion = 2;
553 rgf.cPins2 = 1;
554 rgf.rgPins2 = &rgpins;
556 rgpins.nMediaTypes = 1;
557 rgpins.lpMediaType = &rgtypes;
558 rgtypes.clsMajorType = &MEDIATYPE_Audio;
559 rgtypes.clsMinorType = &MEDIASUBTYPE_NULL;
560
561 write_filter_data(prop_bag, &rgf);
562
563 /* write WaveOutId */
564 V_VT(&var) = VT_I4;
565 V_I4(&var) = i;
566 IPropertyBag_Write(prop_bag, L"WaveOutId", &var);
567
569 if (prop_bag) IPropertyBag_Release(prop_bag);
570 }
571}
572
573static void register_wavein_devices(void)
574{
575 IPropertyBag *prop_bag = NULL;
576 REGFILTER2 rgf = {0};
577 WAVEINCAPSW caps;
578 int i, count;
579 VARIANT var;
580 HRESULT hr;
581
583
584 for (i = 0; i < count; i++)
585 {
586 waveInGetDevCapsW(i, &caps, sizeof(caps));
587
588 hr = register_codec(&CLSID_AudioInputDeviceCategory, caps.szPname,
589 &CLSID_AudioRecord, caps.szPname, &prop_bag);
590 if (FAILED(hr))
591 continue;
592
593 /* write filter data */
594 rgf.dwVersion = 2;
596
597 write_filter_data(prop_bag, &rgf);
598
599 /* write WaveInId */
600 V_VT(&var) = VT_I4;
601 V_I4(&var) = i;
602 IPropertyBag_Write(prop_bag, L"WaveInId", &var);
603
605 IPropertyBag_Release(prop_bag);
606 }
607}
608
610{
611 IPropertyBag *prop_bag = NULL;
612 REGFILTERPINS2 rgpins = {0};
613 REGPINTYPES rgtypes = {0};
614 REGFILTER2 rgf = {0};
615 MIDIOUTCAPSW caps;
616 const WCHAR *name;
617 int i, count;
618 VARIANT var;
619 HRESULT hr;
620
622
623 for (i = -1; i < count; i++)
624 {
625 midiOutGetDevCapsW(i, &caps, sizeof(caps));
626
627 name = (i == -1) ? L"Default MidiOut Device" : caps.szPname;
628
629 hr = register_codec(&CLSID_MidiRendererCategory, name,
630 &CLSID_AVIMIDIRender, name, &prop_bag);
631 if (FAILED(hr))
632 continue;
633
634 /* write filter data */
635 rgf.dwVersion = 2;
636 rgf.dwMerit = (i == -1) ? MERIT_PREFERRED : MERIT_DO_NOT_USE;
637 rgf.cPins2 = 1;
638 rgf.rgPins2 = &rgpins;
640 rgpins.nMediaTypes = 1;
641 rgpins.lpMediaType = &rgtypes;
642 rgtypes.clsMajorType = &MEDIATYPE_Midi;
643 rgtypes.clsMinorType = &MEDIASUBTYPE_NULL;
644
645 write_filter_data(prop_bag, &rgf);
646
647 /* write MidiOutId */
648 V_VT(&var) = VT_I4;
649 V_I4(&var) = i;
650 IPropertyBag_Write(prop_bag, L"MidiOutId", &var);
651
653 IPropertyBag_Release(prop_bag);
654 }
655}
656
657static void register_vfw_codecs(void)
658{
659#ifdef __REACTOS__ /* '{}' initializer is C23; MSVC before 19.32 rejects it */
660 REGFILTERPINS2 rgpins[2] = {0};
661#else
662 REGFILTERPINS2 rgpins[2] = {};
663#endif
664 IPropertyBag *prop_bag = NULL;
665 REGPINTYPES rgtypes[2];
666 REGFILTER2 rgf;
667 GUID typeguid;
668 ICINFO info;
669 VARIANT var;
670 HRESULT hr;
671 int i = 0;
672 HIC hic;
673
674 while (ICInfo(ICTYPE_VIDEO, i++, &info))
675 {
676 WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)),
677 LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))};
678
679 hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY);
680 ICGetInfo(hic, &info, sizeof(info));
681 ICClose(hic);
682
683 hr = register_codec(&CLSID_VideoCompressorCategory, name,
684 &CLSID_AVICo, info.szDescription, &prop_bag);
685 if (FAILED(hr))
686 continue;
687
688 /* write filter data */
689 rgf.dwVersion = 2;
691 rgf.cPins2 = 2;
692 rgf.rgPins2 = rgpins;
693 rgpins[0].dwFlags = 0;
694 rgpins[0].nMediaTypes = 1;
695 rgpins[0].lpMediaType = &rgtypes[0];
696 rgtypes[0].clsMajorType = &MEDIATYPE_Video;
697 typeguid = MEDIASUBTYPE_PCM;
698 typeguid.Data1 = info.fccHandler;
699 rgtypes[0].clsMinorType = &typeguid;
700 rgpins[1].dwFlags = REG_PINFLAG_B_OUTPUT;
701 rgpins[1].nMediaTypes = 1;
702 rgpins[1].lpMediaType = &rgtypes[1];
703 rgtypes[1].clsMajorType = &MEDIATYPE_Video;
704 rgtypes[1].clsMinorType = &GUID_NULL;
705
706 write_filter_data(prop_bag, &rgf);
707
708 /* write WaveInId */
709 V_VT(&var) = VT_BSTR;
711 IPropertyBag_Write(prop_bag, L"FccHandler", &var);
712
714 IPropertyBag_Release(prop_bag);
715 }
716}
717
718static void register_avicap_devices(void)
719{
720 WCHAR friendlyname[32], version[32];
721 IPropertyBag *prop_bag = NULL;
722 REGFILTERPINS2 rgpins = {0};
723 REGPINTYPES rgtypes;
724 REGFILTER2 rgf;
725 WCHAR name[7];
726 VARIANT var;
727 HRESULT hr;
728 int i = 0;
729
730 for (i = 0; i < 10; ++i)
731 {
732 if (!capGetDriverDescriptionW(i, friendlyname, ARRAY_SIZE(friendlyname),
734 continue;
735
736 swprintf(name, ARRAY_SIZE(name), L"video%d", i);
737
738 hr = register_codec(&CLSID_VideoInputDeviceCategory, name,
739 &CLSID_VfwCapture, friendlyname, &prop_bag);
740 if (FAILED(hr))
741 continue;
742
743 rgf.dwVersion = 2;
745 rgf.cPins2 = 1;
746 rgf.rgPins2 = &rgpins;
747 rgpins.dwFlags = 0;
748 rgpins.nMediaTypes = 1;
749 rgpins.lpMediaType = &rgtypes;
750 rgtypes.clsMajorType = &MEDIATYPE_Video;
751 rgtypes.clsMinorType = &MEDIASUBTYPE_None;
752
753 write_filter_data(prop_bag, &rgf);
754
755 /* write VFWIndex */
756 V_VT(&var) = VT_I4;
757 V_I4(&var) = i;
758 IPropertyBag_Write(prop_bag, L"VFWIndex", &var);
759
761 IPropertyBag_Release(prop_bag);
762 }
763}
764
767{
768 WCHAR guidstr[CHARS_IN_GUID];
769 HRESULT hr;
770 HKEY key;
771
772 TRACE("iface %p, class %s, out %p, flags %#lx.\n", iface, debugstr_guid(class), out, flags);
773
774 if (!out)
775 return E_POINTER;
776
777 *out = NULL;
778
779 if (!RegOpenKeyW(HKEY_CURRENT_USER, L"Software\\Microsoft\\ActiveMovie\\devenum", &key))
780 {
781 StringFromGUID2(class, guidstr, ARRAY_SIZE(guidstr));
782 RegDeleteTreeW(key, guidstr);
783 }
784
785 if (IsEqualGUID(class, &CLSID_LegacyAmFilterCategory))
787 else if (IsEqualGUID(class, &CLSID_AudioRendererCategory))
788 {
790 if (FAILED(hr)) return hr;
793 }
794 else if (IsEqualGUID(class, &CLSID_AudioInputDeviceCategory))
796 else if (IsEqualGUID(class, &CLSID_VideoCompressorCategory))
798 else if (IsEqualGUID(class, &CLSID_VideoInputDeviceCategory))
800
801 if (SUCCEEDED(hr = enum_moniker_create(class, out)))
802 {
803 IMoniker *mon;
804 hr = IEnumMoniker_Next(*out, 1, &mon, NULL);
805 if (hr == S_OK)
806 {
807 IMoniker_Release(mon);
808 IEnumMoniker_Reset(*out);
809 }
810 else
811 {
812 IEnumMoniker_Release(*out);
813 *out = NULL;
814 }
815 }
816
817 return hr;
818}
819
820/**********************************************************************
821 * ICreateDevEnum_Vtbl
822 */
823static const ICreateDevEnumVtbl ICreateDevEnum_Vtbl =
824{
829};
830
831/**********************************************************************
832 * static CreateDevEnum instance
833 */
Type
Definition: Type.h:7
BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName, INT cbName, LPWSTR lpszVer, INT cbVer)
Definition: avicap32.c:142
REGPINTYPES
Definition: axextend.idl:194
@ REG_PINFLAG_B_RENDERER
Definition: axextend.idl:219
@ REG_PINFLAG_B_OUTPUT
Definition: axextend.idl:221
@ REG_PINFLAG_B_ZERO
Definition: axextend.idl:218
const CLSID * clsMinorType
Definition: axextend.idl:193
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
const GUID IID_IUnknown
#define RegCloseKey(hKey)
Definition: registry.h:49
return
Definition: dirsup.c:529
#define CHARS_IN_GUID
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
static void register_vfw_codecs(void)
ICreateDevEnum devenum_factory
static ULONG WINAPI devenum_factory_AddRef(ICreateDevEnum *iface)
Definition: createdevenum.c:59
static HRESULT WINAPI devenum_factory_QueryInterface(ICreateDevEnum *iface, REFIID riid, void **ppv)
Definition: createdevenum.c:39
static HRESULT WINAPI devenum_factory_CreateClassEnumerator(ICreateDevEnum *iface, REFCLSID class, IEnumMoniker **out, DWORD flags)
static HRESULT register_codec(const GUID *class, const WCHAR *name, const GUID *clsid, const WCHAR *friendly_name, IPropertyBag **ret)
Definition: createdevenum.c:73
static void register_wavein_devices(void)
static void register_legacy_filters(void)
static void register_midiout_devices(void)
static void free_regfilter2(REGFILTER2 *rgf)
static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
HRESULT create_filter_data(VARIANT *var, REGFILTER2 *rgf)
static const ICreateDevEnumVtbl ICreateDevEnum_Vtbl
static void register_avicap_devices(void)
static void register_waveout_devices(void)
static ULONG WINAPI devenum_factory_Release(ICreateDevEnum *iface)
Definition: createdevenum.c:66
static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, const WCHAR *module, void *context)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT enum_moniker_create(REFCLSID class, IEnumMoniker **enum_mon)
#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 RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
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 CoTaskMemAlloc(SIZE_T size)
Definition: malloc.c:381
void *WINAPI CoTaskMemRealloc(void *ptr, SIZE_T size)
Definition: malloc.c:397
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
@ VT_BSTR
Definition: compat.h:2303
@ VT_ARRAY
Definition: compat.h:2341
@ VT_I4
Definition: compat.h:2298
@ VT_UI1
Definition: compat.h:2311
static const WCHAR version[]
Definition: asmname.c:66
GUID guid
Definition: version.c:147
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
#define swprintf
Definition: precomp.h:40
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define REG_PINFLAG_B_MANY
Definition: precomp.h:17
#define MERIT_DO_NOT_USE
Definition: precomp.h:18
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
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
unsigned int UINT
Definition: sysinfo.c:13
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ICTYPE_VIDEO
Definition: mmreg.h:531
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
const char * var
Definition: shader.c:5879
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)
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define KEY_READ
Definition: nt_native.h:1026
#define DWORD
Definition: nt_native.h:44
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
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define REG_DWORD
Definition: sdbapi.c:615
wcscat
wcscpy
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
Definition: vfw.h:280
DWORD dwVersion
Definition: axextend.idl:238
DWORD dwMerit
Definition: axextend.idl:239
const REGFILTERPINS2 * rgPins2
Definition: axextend.idl:253
ULONG cPins2
Definition: axextend.idl:252
const REGPINTYPES * lpMediaType
Definition: axextend.idl:230
Definition: http.c:7252
Definition: copy.c:22
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 ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
Definition: pdh_main.c:64
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:626
#define ICMODE_QUERY
Definition: vfw.h:271
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
_In_ ULONG iType
Definition: winddi.h:3748
#define WINAPI
Definition: msvc.h:6
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
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 waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2573
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
unsigned char BYTE
Definition: xxhash.c:193