ReactOS  0.4.14-dev-41-g31d7680
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 #define NONAMELESSSTRUCT
27 #define NONAMELESSUNION
28 
29 #include "devenum_private.h"
30 #include "vfw.h"
31 #include "aviriff.h"
32 #include "dsound.h"
33 
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36 #include "wine/heap.h"
37 #include "mmddk.h"
38 
39 #include "initguid.h"
40 #include "fil_data.h"
41 
43 
45 
46 static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0};
47 static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
48 static const WCHAR wszPins[] = {'P','i','n','s',0};
49 static const WCHAR wszAllowedMany[] = {'A','l','l','o','w','e','d','M','a','n','y',0};
50 static const WCHAR wszAllowedZero[] = {'A','l','l','o','w','e','d','Z','e','r','o',0};
51 static const WCHAR wszDirection[] = {'D','i','r','e','c','t','i','o','n',0};
52 static const WCHAR wszIsRendered[] = {'I','s','R','e','n','d','e','r','e','d',0};
53 static const WCHAR wszTypes[] = {'T','y','p','e','s',0};
54 static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
55 static const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0};
56 
58 static HRESULT register_codecs(void);
59 static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
60 
61 /**********************************************************************
62  * DEVENUM_ICreateDevEnum_QueryInterface (also IUnknown)
63  */
65  void **ppv)
66 {
67  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
68 
69  if (!ppv)
70  return E_POINTER;
71 
72  if (IsEqualGUID(riid, &IID_IUnknown) ||
73  IsEqualGUID(riid, &IID_ICreateDevEnum))
74  {
75  *ppv = iface;
77  return S_OK;
78  }
79 
80  FIXME("- no interface IID: %s\n", debugstr_guid(riid));
81  *ppv = NULL;
82  return E_NOINTERFACE;
83 }
84 
85 /**********************************************************************
86  * DEVENUM_ICreateDevEnum_AddRef (also IUnknown)
87  */
89 {
90  TRACE("\n");
91 
93 
94  return 2; /* non-heap based object */
95 }
96 
97 /**********************************************************************
98  * DEVENUM_ICreateDevEnum_Release (also IUnknown)
99  */
101 {
102  TRACE("\n");
103 
105 
106  return 1; /* non-heap based object */
107 }
108 
109 static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret)
110 {
111  static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0};
113  WCHAR *buffer;
114  ULONG eaten;
115  HRESULT hr;
116 
117  hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
118  if (FAILED(hr))
119  return hr;
120 
121  buffer = heap_alloc((strlenW(deviceW) + CHARS_IN_GUID + strlenW(name) + 1) * sizeof(WCHAR));
122  if (!buffer)
123  {
124  IParseDisplayName_Release(parser);
125  return E_OUTOFMEMORY;
126  }
127 
131  strcatW(buffer, name);
132 
133  hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, ret);
134  IParseDisplayName_Release(parser);
135  heap_free(buffer);
136  return hr;
137 }
138 
139 static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
140 {
141  HKEY hkeyTypes = NULL;
142  DWORD dwMajorTypes, i;
143  REGPINTYPES *lpMediaType = NULL;
144  DWORD dwMediaTypeSize = 0;
145 
146  if (RegOpenKeyExW(hkeyPinKey, wszTypes, 0, KEY_READ, &hkeyTypes) != ERROR_SUCCESS)
147  return ;
148 
149  if (RegQueryInfoKeyW(hkeyTypes, NULL, NULL, NULL, &dwMajorTypes, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
150  != ERROR_SUCCESS)
151  {
152  RegCloseKey(hkeyTypes);
153  return ;
154  }
155 
156  for (i = 0; i < dwMajorTypes; i++)
157  {
158  HKEY hkeyMajorType = NULL;
159  WCHAR wszMajorTypeName[64];
160  DWORD cName = sizeof(wszMajorTypeName) / sizeof(WCHAR);
161  DWORD dwMinorTypes, i1;
162 
163  if (RegEnumKeyExW(hkeyTypes, i, wszMajorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
164 
165  if (RegOpenKeyExW(hkeyTypes, wszMajorTypeName, 0, KEY_READ, &hkeyMajorType) != ERROR_SUCCESS) continue;
166 
167  if (RegQueryInfoKeyW(hkeyMajorType, NULL, NULL, NULL, &dwMinorTypes, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
168  != ERROR_SUCCESS)
169  {
170  RegCloseKey(hkeyMajorType);
171  continue;
172  }
173 
174  for (i1 = 0; i1 < dwMinorTypes; i1++)
175  {
176  WCHAR wszMinorTypeName[64];
177  CLSID *clsMajorType = NULL, *clsMinorType = NULL;
178  HRESULT hr;
179 
180  cName = sizeof(wszMinorTypeName) / sizeof(WCHAR);
181  if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
182 
183  clsMinorType = CoTaskMemAlloc(sizeof(CLSID));
184  if (!clsMinorType) continue;
185 
186  clsMajorType = CoTaskMemAlloc(sizeof(CLSID));
187  if (!clsMajorType) goto error_cleanup_types;
188 
189  hr = CLSIDFromString(wszMinorTypeName, clsMinorType);
190  if (FAILED(hr)) goto error_cleanup_types;
191 
192  hr = CLSIDFromString(wszMajorTypeName, clsMajorType);
193  if (FAILED(hr)) goto error_cleanup_types;
194 
195  if (rgPin->nMediaTypes == dwMediaTypeSize)
196  {
197  DWORD dwNewSize = dwMediaTypeSize + (dwMediaTypeSize < 2 ? 1 : dwMediaTypeSize / 2);
198  REGPINTYPES *lpNewMediaType;
199 
200  lpNewMediaType = CoTaskMemRealloc(lpMediaType, sizeof(REGPINTYPES) * dwNewSize);
201  if (!lpNewMediaType) goto error_cleanup_types;
202 
203  lpMediaType = lpNewMediaType;
204  dwMediaTypeSize = dwNewSize;
205  }
206 
207  lpMediaType[rgPin->nMediaTypes].clsMajorType = clsMajorType;
208  lpMediaType[rgPin->nMediaTypes].clsMinorType = clsMinorType;
209  rgPin->nMediaTypes++;
210  continue;
211 
212  error_cleanup_types:
213 
214  CoTaskMemFree(clsMajorType);
216  }
217 
218  RegCloseKey(hkeyMajorType);
219  }
220 
221  RegCloseKey(hkeyTypes);
222 
223  if (lpMediaType && !rgPin->nMediaTypes)
224  {
225  CoTaskMemFree(lpMediaType);
226  lpMediaType = NULL;
227  }
228 
229  rgPin->lpMediaType = lpMediaType;
230 }
231 
232 static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
233 {
234  HKEY hkeyPins = NULL;
235  DWORD dwPinsSubkeys, i;
236  REGFILTERPINS2 *rgPins = NULL;
237 
238  rgf2->dwVersion = 2;
239  rgf2->u.s2.cPins2 = 0;
240  rgf2->u.s2.rgPins2 = NULL;
241 
242  if (RegOpenKeyExW(hkeyFilterClass, wszPins, 0, KEY_READ, &hkeyPins) != ERROR_SUCCESS)
243  return ;
244 
245  if (RegQueryInfoKeyW(hkeyPins, NULL, NULL, NULL, &dwPinsSubkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
246  != ERROR_SUCCESS)
247  {
248  RegCloseKey(hkeyPins);
249  return ;
250  }
251 
252  if (dwPinsSubkeys)
253  {
254  rgPins = CoTaskMemAlloc(sizeof(REGFILTERPINS2) * dwPinsSubkeys);
255  if (!rgPins)
256  {
257  RegCloseKey(hkeyPins);
258  return ;
259  }
260  }
261 
262  for (i = 0; i < dwPinsSubkeys; i++)
263  {
264  HKEY hkeyPinKey = NULL;
265  WCHAR wszPinName[MAX_PATH];
266  DWORD cName = sizeof(wszPinName) / sizeof(WCHAR);
267  REGFILTERPINS2 *rgPin = &rgPins[rgf2->u.s2.cPins2];
268  DWORD value, size, Type;
269  LONG lRet;
270 
271  memset(rgPin, 0, sizeof(*rgPin));
272 
273  if (RegEnumKeyExW(hkeyPins, i, wszPinName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
274 
275  if (RegOpenKeyExW(hkeyPins, wszPinName, 0, KEY_READ, &hkeyPinKey) != ERROR_SUCCESS) continue;
276 
277  size = sizeof(DWORD);
278  lRet = RegQueryValueExW(hkeyPinKey, wszAllowedMany, 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_MANY;
283 
284  size = sizeof(DWORD);
285  lRet = RegQueryValueExW(hkeyPinKey, wszAllowedZero, NULL, &Type, (BYTE *)&value, &size);
286  if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
287  goto error_cleanup;
288  if (value)
289  rgPin->dwFlags |= REG_PINFLAG_B_ZERO;
290 
291  size = sizeof(DWORD);
292  lRet = RegQueryValueExW(hkeyPinKey, wszDirection, NULL, &Type, (BYTE *)&value, &size);
293  if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
294  goto error_cleanup;
295  if (value)
296  rgPin->dwFlags |= REG_PINFLAG_B_OUTPUT;
297 
298 
299  size = sizeof(DWORD);
300  lRet = RegQueryValueExW(hkeyPinKey, wszIsRendered, NULL, &Type, (BYTE *)&value, &size);
301  if (lRet != ERROR_SUCCESS || Type != REG_DWORD)
302  goto error_cleanup;
303  if (value)
305 
306  DEVENUM_ReadPinTypes(hkeyPinKey, rgPin);
307 
308  ++rgf2->u.s2.cPins2;
309  continue;
310 
311  error_cleanup:
312 
313  RegCloseKey(hkeyPinKey);
314  }
315 
316  RegCloseKey(hkeyPins);
317 
318  if (rgPins && !rgf2->u.s2.cPins2)
319  {
320  CoTaskMemFree(rgPins);
321  rgPins = NULL;
322  }
323 
324  rgf2->u.s2.rgPins2 = rgPins;
325 }
326 
327 static void free_regfilter2(REGFILTER2 *rgf)
328 {
329  if (rgf->u.s2.rgPins2)
330  {
331  UINT iPin;
332 
333  for (iPin = 0; iPin < rgf->u.s2.cPins2; iPin++)
334  {
335  if (rgf->u.s2.rgPins2[iPin].lpMediaType)
336  {
337  UINT iType;
338 
339  for (iType = 0; iType < rgf->u.s2.rgPins2[iPin].nMediaTypes; iType++)
340  {
341  CoTaskMemFree((void *)rgf->u.s2.rgPins2[iPin].lpMediaType[iType].clsMajorType);
342  CoTaskMemFree((void *)rgf->u.s2.rgPins2[iPin].lpMediaType[iType].clsMinorType);
343  }
344 
345  CoTaskMemFree((void *)rgf->u.s2.rgPins2[iPin].lpMediaType);
346  }
347  }
348 
349  CoTaskMemFree((void *)rgf->u.s2.rgPins2);
350  }
351 }
352 
353 static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
354 {
355  IAMFilterData *fildata;
356  SAFEARRAYBOUND sabound;
357  BYTE *data, *array;
358  VARIANT var;
359  ULONG size;
360  HRESULT hr;
361 
362  hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IAMFilterData, (void **)&fildata);
363  if (FAILED(hr)) goto cleanup;
364 
365  hr = IAMFilterData_CreateFilterData(fildata, rgf, &data, &size);
366  if (FAILED(hr)) goto cleanup;
367 
368  V_VT(&var) = VT_ARRAY | VT_UI1;
369  sabound.lLbound = 0;
370  sabound.cElements = size;
371  if (!(V_ARRAY(&var) = SafeArrayCreate(VT_UI1, 1, &sabound)))
372  goto cleanup;
373  hr = SafeArrayAccessData(V_ARRAY(&var), (void *)&array);
374  if (FAILED(hr)) goto cleanup;
375 
376  memcpy(array, data, size);
378  if (FAILED(hr)) goto cleanup;
379 
380  hr = IPropertyBag_Write(prop_bag, wszFilterData, &var);
381  if (FAILED(hr)) goto cleanup;
382 
383 cleanup:
384  VariantClear(&var);
386  IAMFilterData_Release(fildata);
387 }
388 
389 static void register_legacy_filters(void)
390 {
391  HKEY hkeyFilter = NULL;
392  DWORD dwFilterSubkeys, i;
393  LONG lRet;
394  HRESULT hr;
395 
396  lRet = RegOpenKeyExW(HKEY_CLASSES_ROOT, wszFilterKeyName, 0, KEY_READ, &hkeyFilter);
397  hr = HRESULT_FROM_WIN32(lRet);
398 
399  if (SUCCEEDED(hr))
400  {
401  lRet = RegQueryInfoKeyW(hkeyFilter, NULL, NULL, NULL, &dwFilterSubkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
402  hr = HRESULT_FROM_WIN32(lRet);
403  }
404 
405  if (SUCCEEDED(hr))
406  hr = DEVENUM_CreateAMCategoryKey(&CLSID_LegacyAmFilterCategory);
407 
408  if (SUCCEEDED(hr))
409  {
410  for (i = 0; i < dwFilterSubkeys; i++)
411  {
412  WCHAR wszFilterSubkeyName[64];
413  DWORD cName = sizeof(wszFilterSubkeyName) / sizeof(WCHAR);
414  IPropertyBag *prop_bag = NULL;
415  WCHAR wszRegKey[MAX_PATH];
416  HKEY classkey = NULL;
417  IMoniker *mon = NULL;
418  VARIANT var;
419  REGFILTER2 rgf2;
420  DWORD Type, len;
421 
422  if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue;
423 
424  TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
425 
426  strcpyW(wszRegKey, clsidW);
427  strcatW(wszRegKey, wszFilterSubkeyName);
428 
429  if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
430  continue;
431 
432  hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, &mon);
433  if (FAILED(hr)) goto cleanup;
434 
435  hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
436  if (FAILED(hr)) goto cleanup;
437 
438  /* write friendly name */
439  len = 0;
440  V_VT(&var) = VT_BSTR;
441  if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len))
442  {
443  WCHAR *friendlyname = heap_alloc(len);
444  if (!friendlyname)
445  goto cleanup;
446  RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len);
447  V_BSTR(&var) = SysAllocStringLen(friendlyname, len/sizeof(WCHAR));
448  heap_free(friendlyname);
449  }
450  else
451  V_BSTR(&var) = SysAllocString(wszFilterSubkeyName);
452 
453  if (!V_BSTR(&var))
454  goto cleanup;
455  hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
456  if (FAILED(hr)) goto cleanup;
457  VariantClear(&var);
458 
459  /* write clsid */
460  V_VT(&var) = VT_BSTR;
461  if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName)))
462  goto cleanup;
463  hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
464  if (FAILED(hr)) goto cleanup;
465  VariantClear(&var);
466 
467  /* write filter data */
468  rgf2.dwMerit = MERIT_NORMAL;
469 
470  len = sizeof(rgf2.dwMerit);
471  RegQueryValueExW(classkey, wszMeritName, NULL, &Type, (BYTE *)&rgf2.dwMerit, &len);
472 
473  DEVENUM_ReadPins(classkey, &rgf2);
474 
475  write_filter_data(prop_bag, &rgf2);
476 
477 cleanup:
478  if (prop_bag) IPropertyBag_Release(prop_bag);
479  if (mon) IMoniker_Release(mon);
480  RegCloseKey(classkey);
481  VariantClear(&var);
482  free_regfilter2(&rgf2);
483  }
484  }
485 
486  if (hkeyFilter) RegCloseKey(hkeyFilter);
487 }
488 
490 {
491  static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','D','i','r','e','c','t','S','o','u','n','d',' ','D','e','v','i','c','e',0};
492  static const WCHAR directsoundW[] = {'D','i','r','e','c','t','S','o','u','n','d',':',' ',0};
493  static const WCHAR dsguidW[] = {'D','S','G','u','i','d',0};
494  IPropertyBag *prop_bag = NULL;
495  REGFILTERPINS2 rgpins = {0};
496  REGPINTYPES rgtypes = {0};
497  REGFILTER2 rgf = {0};
499  IMoniker *mon = NULL;
500  VARIANT var;
501  HRESULT hr;
502 
503  hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
504  if (FAILED(hr)) goto cleanup;
505 
506  V_VT(&var) = VT_BSTR;
507  if (guid)
508  {
509  WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR));
510  if (!name)
511  goto cleanup;
512  strcpyW(name, directsoundW);
513  strcatW(name, desc);
514 
515  V_BSTR(&var) = SysAllocString(name);
516  heap_free(name);
517  }
518  else
519  V_BSTR(&var) = SysAllocString(defaultW);
520 
521  if (!V_BSTR(&var))
522  goto cleanup;
523 
524  hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon);
525  if (FAILED(hr)) goto cleanup;
526 
527  hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
528  if (FAILED(hr)) goto cleanup;
529 
530  /* write friendly name */
531  hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
532  if (FAILED(hr)) goto cleanup;
533  VariantClear(&var);
534 
535  /* write clsid */
536  V_VT(&var) = VT_BSTR;
537  StringFromGUID2(&CLSID_DSoundRender, clsid, CHARS_IN_GUID);
538  if (!(V_BSTR(&var) = SysAllocString(clsid)))
539  goto cleanup;
540  hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
541  if (FAILED(hr)) goto cleanup;
542  VariantClear(&var);
543 
544  /* write filter data */
545  rgf.dwVersion = 2;
546  rgf.dwMerit = guid ? MERIT_DO_NOT_USE : MERIT_PREFERRED;
547  rgf.u.s2.cPins2 = 1;
548  rgf.u.s2.rgPins2 = &rgpins;
550  /* FIXME: native registers many more formats */
551  rgpins.nMediaTypes = 1;
552  rgpins.lpMediaType = &rgtypes;
553  rgtypes.clsMajorType = &MEDIATYPE_Audio;
554  rgtypes.clsMinorType = &MEDIASUBTYPE_PCM;
555 
556  write_filter_data(prop_bag, &rgf);
557 
558  /* write DSound guid */
559  V_VT(&var) = VT_BSTR;
561  if (!(V_BSTR(&var) = SysAllocString(clsid)))
562  goto cleanup;
563  hr = IPropertyBag_Write(prop_bag, dsguidW, &var);
564  if (FAILED(hr)) goto cleanup;
565 
566 cleanup:
567  VariantClear(&var);
568  if (prop_bag) IPropertyBag_Release(prop_bag);
569  if (mon) IMoniker_Release(mon);
570 
571  return TRUE;
572 }
573 
574 static void register_waveout_devices(void)
575 {
576  static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','W','a','v','e','O','u','t',' ','D','e','v','i','c','e',0};
577  static const WCHAR waveoutidW[] = {'W','a','v','e','O','u','t','I','d',0};
578  IPropertyBag *prop_bag = NULL;
579  REGFILTERPINS2 rgpins = {0};
580  REGPINTYPES rgtypes = {0};
581  REGFILTER2 rgf = {0};
583  IMoniker *mon = NULL;
584  WAVEOUTCAPSW caps;
585  int i, count;
586  VARIANT var;
587  HRESULT hr;
588 
589  hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
590  if (FAILED(hr)) return;
591 
593 
594  for (i = -1; i < count; i++)
595  {
596  waveOutGetDevCapsW(i, &caps, sizeof(caps));
597 
598  V_VT(&var) = VT_BSTR;
599 
600  if (i == -1) /* WAVE_MAPPER */
601  V_BSTR(&var) = SysAllocString(defaultW);
602  else
603  V_BSTR(&var) = SysAllocString(caps.szPname);
604  if (!(V_BSTR(&var)))
605  goto cleanup;
606 
607  hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon);
608  if (FAILED(hr)) goto cleanup;
609 
610  hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
611  if (FAILED(hr)) goto cleanup;
612 
613  /* write friendly name */
614  hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
615  if (FAILED(hr)) goto cleanup;
616  VariantClear(&var);
617 
618  /* write clsid */
619  V_VT(&var) = VT_BSTR;
620  StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID);
621  if (!(V_BSTR(&var) = SysAllocString(clsid)))
622  goto cleanup;
623  hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
624  if (FAILED(hr)) goto cleanup;
625  VariantClear(&var);
626 
627  /* write filter data */
628  rgf.dwVersion = 2;
630  rgf.u.s2.cPins2 = 1;
631  rgf.u.s2.rgPins2 = &rgpins;
633  rgpins.nMediaTypes = 1;
634  rgpins.lpMediaType = &rgtypes;
635  rgtypes.clsMajorType = &MEDIATYPE_Audio;
636  rgtypes.clsMinorType = &MEDIASUBTYPE_NULL;
637 
638  write_filter_data(prop_bag, &rgf);
639 
640  /* write WaveOutId */
641  V_VT(&var) = VT_I4;
642  V_I4(&var) = i;
643  hr = IPropertyBag_Write(prop_bag, waveoutidW, &var);
644  if (FAILED(hr)) goto cleanup;
645 
646 cleanup:
647  VariantClear(&var);
648  if (prop_bag) IPropertyBag_Release(prop_bag);
649  if (mon) IMoniker_Release(mon);
650  }
651 }
652 
653 static void register_wavein_devices(void)
654 {
655  static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0};
656  IPropertyBag *prop_bag = NULL;
657  REGFILTER2 rgf = {0};
659  IMoniker *mon = NULL;
660  WAVEINCAPSW caps;
661  int i, count;
662  VARIANT var;
663  HRESULT hr;
664 
665  hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
666  if (FAILED(hr)) return;
667 
669 
670  for (i = 0; i < count; i++)
671  {
672  waveInGetDevCapsW(i, &caps, sizeof(caps));
673 
674  V_VT(&var) = VT_BSTR;
675 
676  V_BSTR(&var) = SysAllocString(caps.szPname);
677  if (!(V_BSTR(&var)))
678  goto cleanup;
679 
680  hr = register_codec(&CLSID_AudioInputDeviceCategory, V_BSTR(&var), &mon);
681  if (FAILED(hr)) goto cleanup;
682 
683  hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
684  if (FAILED(hr)) goto cleanup;
685 
686  /* write friendly name */
687  hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
688  if (FAILED(hr)) goto cleanup;
689  VariantClear(&var);
690 
691  /* write clsid */
692  V_VT(&var) = VT_BSTR;
693  StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID);
694  if (!(V_BSTR(&var) = SysAllocString(clsid)))
695  goto cleanup;
696  hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
697  if (FAILED(hr)) goto cleanup;
698  VariantClear(&var);
699 
700  /* write filter data */
701  rgf.dwVersion = 2;
703 
704  write_filter_data(prop_bag, &rgf);
705 
706  /* write WaveInId */
707  V_VT(&var) = VT_I4;
708  V_I4(&var) = i;
709  hr = IPropertyBag_Write(prop_bag, waveinidW, &var);
710  if (FAILED(hr)) goto cleanup;
711 
712 cleanup:
713  VariantClear(&var);
714  if (prop_bag) IPropertyBag_Release(prop_bag);
715  if (mon) IMoniker_Release(mon);
716  }
717 }
718 
719 static void register_midiout_devices(void)
720 {
721  static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','M','i','d','i','O','u','t',' ','D','e','v','i','c','e',0};
722  static const WCHAR midioutidW[] = {'M','i','d','i','O','u','t','I','d',0};
723  IPropertyBag *prop_bag = NULL;
724  REGFILTERPINS2 rgpins = {0};
725  REGPINTYPES rgtypes = {0};
726  REGFILTER2 rgf = {0};
728  IMoniker *mon = NULL;
729  MIDIOUTCAPSW caps;
730  int i, count;
731  VARIANT var;
732  HRESULT hr;
733 
734  hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
735  if (FAILED(hr)) return;
736 
738 
739  for (i = -1; i < count; i++)
740  {
741  midiOutGetDevCapsW(i, &caps, sizeof(caps));
742 
743  V_VT(&var) = VT_BSTR;
744 
745  if (i == -1) /* MIDI_MAPPER */
746  V_BSTR(&var) = SysAllocString(defaultW);
747  else
748  V_BSTR(&var) = SysAllocString(caps.szPname);
749  if (!(V_BSTR(&var)))
750  goto cleanup;
751 
752  hr = register_codec(&CLSID_MidiRendererCategory, V_BSTR(&var), &mon);
753  if (FAILED(hr)) goto cleanup;
754 
755  hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
756  if (FAILED(hr)) goto cleanup;
757 
758  /* write friendly name */
759  hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
760  if (FAILED(hr)) goto cleanup;
761  VariantClear(&var);
762 
763  /* write clsid */
764  V_VT(&var) = VT_BSTR;
765  StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID);
766  if (!(V_BSTR(&var) = SysAllocString(clsid)))
767  goto cleanup;
768  hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
769  if (FAILED(hr)) goto cleanup;
770  VariantClear(&var);
771 
772  /* write filter data */
773  rgf.dwVersion = 2;
774  rgf.dwMerit = (i == -1) ? MERIT_PREFERRED : MERIT_DO_NOT_USE;
775  rgf.u.s2.cPins2 = 1;
776  rgf.u.s2.rgPins2 = &rgpins;
778  rgpins.nMediaTypes = 1;
779  rgpins.lpMediaType = &rgtypes;
780  rgtypes.clsMajorType = &MEDIATYPE_Midi;
781  rgtypes.clsMinorType = &MEDIASUBTYPE_NULL;
782 
783  write_filter_data(prop_bag, &rgf);
784 
785  /* write MidiOutId */
786  V_VT(&var) = VT_I4;
787  V_I4(&var) = i;
788  hr = IPropertyBag_Write(prop_bag, midioutidW, &var);
789  if (FAILED(hr)) goto cleanup;
790 
791 cleanup:
792  VariantClear(&var);
793  if (prop_bag) IPropertyBag_Release(prop_bag);
794  if (mon) IMoniker_Release(mon);
795  }
796 }
797 
798 static void register_vfw_codecs(void)
799 {
800  static const WCHAR fcchandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0};
801  REGFILTERPINS2 rgpins[2] = {{0}};
802  IPropertyBag *prop_bag = NULL;
803  REGPINTYPES rgtypes[2];
804  REGFILTER2 rgf;
806  IMoniker *mon = NULL;
807  GUID typeguid;
808  ICINFO info;
809  VARIANT var;
810  HRESULT hr;
811  int i = 0;
812  HIC hic;
813 
814  hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
815  if (FAILED(hr)) return;
816 
817  while (ICInfo(ICTYPE_VIDEO, i++, &info))
818  {
819  WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)),
820  LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))};
821 
822  hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY);
823  ICGetInfo(hic, &info, sizeof(info));
824  ICClose(hic);
825 
826  V_VT(&var) = VT_BSTR;
827 
828  V_BSTR(&var) = SysAllocString(name);
829  if (!(V_BSTR(&var)))
830  goto cleanup;
831 
832  hr = register_codec(&CLSID_VideoCompressorCategory, V_BSTR(&var), &mon);
833  if (FAILED(hr)) goto cleanup;
834 
835  hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
836  if (FAILED(hr)) goto cleanup;
837 
838  /* write WaveInId */
839  hr = IPropertyBag_Write(prop_bag, fcchandlerW, &var);
840  if (FAILED(hr)) goto cleanup;
841  VariantClear(&var);
842 
843  /* write friendly name */
844  V_VT(&var) = VT_BSTR;
845  if (!(V_BSTR(&var) = SysAllocString(info.szDescription)))
846  goto cleanup;
847 
848  hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var);
849  if (FAILED(hr)) goto cleanup;
850  VariantClear(&var);
851 
852  /* write clsid */
853  V_VT(&var) = VT_BSTR;
854  StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID);
855  if (!(V_BSTR(&var) = SysAllocString(clsid)))
856  goto cleanup;
857  hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
858  if (FAILED(hr)) goto cleanup;
859  VariantClear(&var);
860 
861  /* write filter data */
862  rgf.dwVersion = 2;
864  rgf.u.s2.cPins2 = 2;
865  rgf.u.s2.rgPins2 = rgpins;
866  rgpins[0].dwFlags = 0;
867  rgpins[0].nMediaTypes = 1;
868  rgpins[0].lpMediaType = &rgtypes[0];
869  rgtypes[0].clsMajorType = &MEDIATYPE_Video;
870  typeguid = MEDIASUBTYPE_PCM;
871  typeguid.Data1 = info.fccHandler;
872  rgtypes[0].clsMinorType = &typeguid;
873  rgpins[1].dwFlags = REG_PINFLAG_B_OUTPUT;
874  rgpins[1].nMediaTypes = 1;
875  rgpins[1].lpMediaType = &rgtypes[1];
876  rgtypes[1].clsMajorType = &MEDIATYPE_Video;
877  rgtypes[1].clsMinorType = &GUID_NULL;
878 
879  write_filter_data(prop_bag, &rgf);
880 
881 cleanup:
882  VariantClear(&var);
883  if (prop_bag) IPropertyBag_Release(prop_bag);
884  if (mon) IMoniker_Release(mon);
885  }
886 }
887 
888 /**********************************************************************
889  * DEVENUM_ICreateDevEnum_CreateClassEnumerator
890  */
892  ICreateDevEnum * iface,
893  REFCLSID clsidDeviceClass,
894  IEnumMoniker **ppEnumMoniker,
895  DWORD dwFlags)
896 {
897  HRESULT hr;
898 
899  TRACE("(%p)->(%s, %p, %x)\n", iface, debugstr_guid(clsidDeviceClass), ppEnumMoniker, dwFlags);
900 
901  if (!ppEnumMoniker)
902  return E_POINTER;
903 
904  *ppEnumMoniker = NULL;
905 
906  register_codecs();
909  if (FAILED(hr)) return hr;
914 
915  return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
916 }
917 
918 /**********************************************************************
919  * ICreateDevEnum_Vtbl
920  */
921 static const ICreateDevEnumVtbl ICreateDevEnum_Vtbl =
922 {
927 };
928 
929 /**********************************************************************
930  * static CreateDevEnum instance
931  */
933 
934 /**********************************************************************
935  * DEVENUM_CreateAMCategoryKey (INTERNAL)
936  *
937  * Creates a registry key for a category at HKEY_CURRENT_USER\Software\
938  * Microsoft\ActiveMovie\devenum\{clsid}
939  */
940 static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
941 {
942  WCHAR wszRegKey[MAX_PATH];
943  HRESULT res = S_OK;
944  HKEY hkeyDummy = NULL;
945 
946  strcpyW(wszRegKey, wszActiveMovieKey);
947 
948  if (!StringFromGUID2(clsidCategory, wszRegKey + strlenW(wszRegKey), sizeof(wszRegKey)/sizeof(wszRegKey[0]) - strlenW(wszRegKey)))
949  res = E_INVALIDARG;
950 
951  if (SUCCEEDED(res))
952  {
953  LONG lRes = RegCreateKeyW(HKEY_CURRENT_USER, wszRegKey, &hkeyDummy);
954  res = HRESULT_FROM_WIN32(lRes);
955  }
956 
957  if (hkeyDummy)
958  RegCloseKey(hkeyDummy);
959 
960  if (FAILED(res))
961  ERR("Failed to create key HKEY_CURRENT_USER\\%s\n", debugstr_w(wszRegKey));
962 
963  return res;
964 }
965 
967 {
968  HRESULT res;
969  WCHAR class[CHARS_IN_GUID];
970  DWORD iDefaultDevice = -1;
971  IFilterMapper2 * pMapper = NULL;
972  REGFILTER2 rf2;
973  REGFILTERPINS2 rfp2;
974  HKEY basekey;
975 
976  /* Since devices can change between session, for example because you just plugged in a webcam
977  * or switched from pulseaudio to alsa, delete all old devices first
978  */
980  StringFromGUID2(&CLSID_LegacyAmFilterCategory, class, CHARS_IN_GUID);
981  RegDeleteTreeW(basekey, class);
982  StringFromGUID2(&CLSID_AudioRendererCategory, class, CHARS_IN_GUID);
983  RegDeleteTreeW(basekey, class);
984  StringFromGUID2(&CLSID_AudioInputDeviceCategory, class, CHARS_IN_GUID);
985  RegDeleteTreeW(basekey, class);
986  StringFromGUID2(&CLSID_VideoInputDeviceCategory, class, CHARS_IN_GUID);
987  RegDeleteTreeW(basekey, class);
988  StringFromGUID2(&CLSID_MidiRendererCategory, class, CHARS_IN_GUID);
989  RegDeleteTreeW(basekey, class);
990  StringFromGUID2(&CLSID_VideoCompressorCategory, class, CHARS_IN_GUID);
991  RegDeleteTreeW(basekey, class);
992  RegCloseKey(basekey);
993 
994  rf2.dwVersion = 2;
995  rf2.dwMerit = MERIT_PREFERRED;
996  rf2.u.s2.cPins2 = 1;
997  rf2.u.s2.rgPins2 = &rfp2;
998  rfp2.cInstances = 1;
999  rfp2.nMediums = 0;
1000  rfp2.lpMedium = NULL;
1001  rfp2.clsPinCategory = &IID_NULL;
1002 
1003  res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
1004  &IID_IFilterMapper2, (void **) &pMapper);
1005  /*
1006  * Fill in info for devices
1007  */
1008  if (SUCCEEDED(res))
1009  {
1010  UINT i;
1011  REGPINTYPES * pTypes;
1012  IPropertyBag * pPropBag = NULL;
1013 
1014  res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
1015  if (SUCCEEDED(res))
1016  for (i = 0; i < 10; i++)
1017  {
1018  WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10];
1019 
1021  szDeviceName, sizeof(szDeviceName)/sizeof(WCHAR),
1022  szDeviceVersion, sizeof(szDeviceVersion)/sizeof(WCHAR)))
1023  {
1024  IMoniker * pMoniker = NULL;
1025  WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 };
1026  snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf, i);
1027  /* The above code prevents 1 device with a different ID overwriting another */
1028 
1029  rfp2.nMediaTypes = 1;
1030  pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
1031  if (!pTypes) {
1032  IFilterMapper2_Release(pMapper);
1033  return E_OUTOFMEMORY;
1034  }
1035 
1036  pTypes[0].clsMajorType = &MEDIATYPE_Video;
1037  pTypes[0].clsMinorType = &MEDIASUBTYPE_None;
1038 
1039  rfp2.lpMediaType = pTypes;
1040 
1041  res = IFilterMapper2_RegisterFilter(pMapper,
1042  &CLSID_VfwCapture,
1043  szDeviceName,
1044  &pMoniker,
1045  &CLSID_VideoInputDeviceCategory,
1046  szDevicePath,
1047  &rf2);
1048 
1049  if (pMoniker) {
1050  OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 };
1051  VARIANT var;
1052  V_VT(&var) = VT_I4;
1053  V_I4(&var) = i;
1054  res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag);
1055  if (SUCCEEDED(res)) {
1056  res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var);
1057  IPropertyBag_Release(pPropBag);
1058  }
1059  IMoniker_Release(pMoniker);
1060  }
1061 
1062  if (i == iDefaultDevice) FIXME("Default device\n");
1063  CoTaskMemFree(pTypes);
1064  }
1065  }
1066  }
1067 
1068  if (pMapper)
1069  IFilterMapper2_Release(pMapper);
1070 
1071  return res;
1072 }
static void register_legacy_filters(void)
static const WCHAR wszDirection[]
Definition: createdevenum.c:51
WCHAR OLECHAR
Definition: compat.h:1933
return
Definition: dirsup.c:529
static void DEVENUM_UnlockModule(void)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)
Definition: msvideo_main.c:437
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:1939
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define snprintfW
Definition: unicode.h:60
static const WCHAR wszFriendlyName[]
Definition: createdevenum.c:54
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf)
Type
Definition: Type.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:342
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1060
#define LOBYTE(W)
Definition: jmemdos.c:487
Definition: http.c:6587
const WCHAR clsid_keyname[6]
Definition: devenum_main.c:45
#define KEY_READ
Definition: nt_native.h:1023
REFIID riid
Definition: precomp.h:44
_In_ ULONG iType
Definition: winddi.h:3748
#define REFCLSID
Definition: guiddef.h:117
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HKEY_CURRENT_USER
Definition: winreg.h:11
static const WCHAR defaultW[]
Definition: lex.c:47
#define V_ARRAY(A)
Definition: oleauto.h:222
#define CHARS_IN_GUID
const REGFILTERPINS2 * rgPins2
Definition: axextend.idl:246
#define CALLBACK
Definition: compat.h:27
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define HIBYTE(W)
Definition: jmemdos.c:486
static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret)
GLuint buffer
Definition: glext.h:5915
static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin)
static const ICreateDevEnumVtbl ICreateDevEnum_Vtbl
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) DECLSPEC_HIDDEN
Definition: mediacatenum.c:938
static const WCHAR wszAllowedMany[]
Definition: createdevenum.c:49
BOOL VFWAPI ICInfo(DWORD fccType, DWORD fccHandler, ICINFO *lpicinfo)
Definition: msvideo_main.c:337
#define DWORD
Definition: nt_native.h:44
static const WCHAR deviceW[]
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define V_I4(A)
Definition: oleauto.h:247
static void register_vfw_codecs(void)
#define ICMODE_QUERY
Definition: vfw.h:271
struct _test_info info[]
Definition: SetCursorPos.c:19
REGPINTYPES
Definition: axextend.idl:187
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID *clsidCategory)
DWORD dwMerit
Definition: axextend.idl:232
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2576
#define MERIT_DO_NOT_USE
Definition: precomp.h:18
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
const GUID * guid
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2176
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1139
unsigned int BOOL
Definition: ntddk_ex.h:94
LRESULT WINAPI ICClose(HIC hic)
long LONG
Definition: pedump.c:60
const CLSID * clsMinorType
Definition: axextend.idl:186
#define dprintf
Definition: regdump.c:33
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum *iface)
Definition: createdevenum.c:88
smooth NULL
Definition: ftsmooth.c:416
const GUID IID_IPropertyBag
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
const CLSID * clsPinCategory
Definition: axextend.idl:226
static void DEVENUM_LockModule(void)
const GUID IID_IParseDisplayName
static void free_regfilter2(REGFILTER2 *rgf)
static void register_midiout_devices(void)
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2140
static const WCHAR wszAllowedZero[]
Definition: createdevenum.c:50
#define debugstr_guid
Definition: kernel32.h:35
static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2)
WINE_DEFAULT_DEBUG_CHANNEL(devenum)
static void register_waveout_devices(void)
static const WCHAR backslashW[]
LRESULT VFWAPI ICGetInfo(HIC hic, ICINFO *picinfo, DWORD cb)
Definition: msvideo_main.c:601
ULONG cPins2
Definition: axextend.idl:245
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1126
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum *iface)
static const WCHAR clsidW[]
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
ICreateDevEnum DEVENUM_CreateDevEnum
const GUID IID_IUnknown
#define ICTYPE_VIDEO
Definition: mmreg.h:531
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2343
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR wszFilterKeyName[]
Definition: createdevenum.c:46
HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
Definition: enum.c:210
static const WCHAR wszActiveMovieKey[]
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
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:3686
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1039
int ret
REFCLSID clsid
Definition: msctf.c:84
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
#define IID_NULL
Definition: guiddef.h:98
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define V_VT(A)
Definition: oleauto.h:211
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
#define GUID_NULL
Definition: ks.h:106
static const WCHAR szDeviceName[]
Definition: provider.c:53
GLsizei const GLfloat * value
Definition: glext.h:6069
#define V_BSTR(A)
Definition: oleauto.h:226
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
Definition: reg.c:1746
#define ERR(fmt,...)
Definition: debug.h:109
Definition: vfw.h:280
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:602
static HRESULT register_codecs(void)
#define S_OK
Definition: intsafe.h:59
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
static const WCHAR wszPins[]
Definition: createdevenum.c:48
DWORD dwVersion
Definition: axextend.idl:231
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(ICreateDevEnum *iface, REFCLSID clsidDeviceClass, IEnumMoniker **ppEnumMoniker, DWORD dwFlags)
static const WCHAR wszTypes[]
Definition: createdevenum.c:53
UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:817
unsigned int UINT
Definition: ndis.h:50
const REGPINTYPES * lpMediaType
Definition: axextend.idl:223
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
const REGPINMEDIUM * lpMedium
Definition: axextend.idl:225
Definition: import.c:86
static const WCHAR wszFilterData[]
Definition: createdevenum.c:55
Definition: name.c:36
GLuint res
Definition: glext.h:9613
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2247
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
static void register_wavein_devices(void)
char * cleanup(char *str)
Definition: wpickclick.c:99
LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, SIZE_T size)
Definition: ifs.c:440
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2568
static HRESULT WINAPI DEVENUM_ICreateDevEnum_QueryInterface(ICreateDevEnum *iface, REFIID riid, void **ppv)
Definition: createdevenum.c:64
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
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:2527
static const WCHAR wszIsRendered[]
Definition: createdevenum.c:52
HINSTANCE DEVENUM_hInstance
Definition: devenum_main.c:29
#define E_POINTER
Definition: winerror.h:2365
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, const WCHAR *module, void *context)
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define LOWORD(l)
Definition: pedump.c:82
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:809
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1170
static const WCHAR wszMeritName[]
Definition: createdevenum.c:47
#define SUCCEEDED(hr)
Definition: intsafe.h:57
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 GLint GLint GLenum GLenum GLenum GLint GLuint GLenum GLenum GLfloat GLenum GLfloat GLenum GLint const GLfloat GLenum GLint const GLushort GLint GLint GLsizei GLsizei GLenum GLsizei GLsizei GLenum GLenum const GLvoid GLenum GLdouble GLenum GLint GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLenum GLfloat GLenum GLfloat GLenum GLushort const GLubyte GLenum GLenum GLenum GLint GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLvoid GLenum GLenum GLint GLenum GLint GLenum GLint GLuint GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble const GLfloat GLenum const GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble GLint GLint GLsizei GLsizei GLenum GLuint GLenum array
Definition: glfuncs.h:320
BOOL VFWAPI capGetDriverDescriptionW(WORD wDriverIndex, LPWSTR lpszName, INT cbName, LPWSTR lpszVer, INT cbVer)
Definition: avicap32.c:142
static BOOL heap_free(void *mem)
Definition: appwiz.h:75