ReactOS  0.4.14-dev-583-g2a1ba2c
mediacatenum.c
Go to the documentation of this file.
1 /*
2  * IEnumMoniker 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 IEnumMoniker interface which enumerates through moniker
22  * objects created from HKEY_CLASSES/CLSID/{DEVICE_CLSID}/Instance
23  */
24 
25 #include "devenum_private.h"
26 #include "oleauto.h"
27 #include "ocidl.h"
28 #include "dmoreg.h"
29 
30 #include "wine/debug.h"
31 
33 
34 typedef struct
35 {
37  CLSID class;
45 
46 typedef struct
47 {
51  union
52  {
53  WCHAR path[MAX_PATH]; /* for filters and codecs */
54  CLSID clsid; /* for DMOs */
55  };
57 
58 
60 {
61  return CONTAINING_RECORD(iface, RegPropBagImpl, IPropertyBag_iface);
62 }
63 
65  LPPROPERTYBAG iface,
66  REFIID riid,
67  LPVOID *ppvObj)
68 {
70 
71  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj);
72 
73  if (This == NULL || ppvObj == NULL) return E_POINTER;
74 
75  if (IsEqualGUID(riid, &IID_IUnknown) ||
77  {
78  *ppvObj = iface;
79  IPropertyBag_AddRef(iface);
80  return S_OK;
81  }
82 
83  FIXME("- no interface IID: %s\n", debugstr_guid(riid));
84  return E_NOINTERFACE;
85 }
86 
87 /**********************************************************************
88  * DEVENUM_IPropertyBag_AddRef (also IUnknown)
89  */
90 static ULONG WINAPI DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface)
91 {
93 
94  TRACE("(%p)->() AddRef from %d\n", iface, This->ref);
95 
96  return InterlockedIncrement(&This->ref);
97 }
98 
99 /**********************************************************************
100  * DEVENUM_IPropertyBag_Release (also IUnknown)
101  */
102 static ULONG WINAPI DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface)
103 {
105  ULONG ref;
106 
107  TRACE("(%p)->() ReleaseThis->ref from %d\n", iface, This->ref);
108 
109  ref = InterlockedDecrement(&This->ref);
110  if (ref == 0) {
113  }
114  return ref;
115 }
116 
118  LPPROPERTYBAG iface,
119  LPCOLESTR pszPropName,
120  VARIANT* pVar,
121  IErrorLog* pErrorLog)
122 {
123  static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
124  LPVOID pData = NULL;
125  DWORD received;
126  DWORD type = 0;
128  HRESULT res = S_OK;
129  LONG reswin32 = ERROR_SUCCESS;
130  WCHAR name[80];
131  HKEY hkey;
132 
133  TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
134 
135  if (!pszPropName || !pVar)
136  return E_POINTER;
137 
138  if (This->type == DEVICE_DMO)
139  {
140  if (!lstrcmpW(pszPropName, FriendlyNameW))
141  {
142  res = DMOGetName(&This->clsid, name);
143  if (SUCCEEDED(res))
144  {
145  V_VT(pVar) = VT_BSTR;
146  V_BSTR(pVar) = SysAllocString(name);
147  }
148  return res;
149  }
151  }
152 
153  if (This->type == DEVICE_FILTER)
154  reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
155  else if (This->type == DEVICE_CODEC)
156  reswin32 = RegOpenKeyW(HKEY_CURRENT_USER, This->path, &hkey);
157  res = HRESULT_FROM_WIN32(reswin32);
158 
159  if (SUCCEEDED(res))
160  {
161  reswin32 = RegQueryValueExW(hkey, pszPropName, NULL, NULL, NULL, &received);
162  res = HRESULT_FROM_WIN32(reswin32);
163  }
164 
165  if (SUCCEEDED(res))
166  {
168 
169  /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
170  reswin32 = RegQueryValueExW(hkey, pszPropName, NULL, &type, pData, &received);
171  res = HRESULT_FROM_WIN32(reswin32);
172  }
173 
174  if (SUCCEEDED(res))
175  {
176  res = E_INVALIDARG; /* assume we cannot coerce into right type */
177 
178  TRACE("Read %d bytes (%s)\n", received, type == REG_SZ ? debugstr_w(pData) : "binary data");
179 
180  switch (type)
181  {
182  case REG_SZ:
183  switch (V_VT(pVar))
184  {
185  case VT_LPWSTR:
186  V_BSTR(pVar) = CoTaskMemAlloc(received);
187  memcpy(V_BSTR(pVar), pData, received);
188  res = S_OK;
189  break;
190  case VT_EMPTY:
191  V_VT(pVar) = VT_BSTR;
192  /* fall through */
193  case VT_BSTR:
194  V_BSTR(pVar) = SysAllocStringLen(pData, received/sizeof(WCHAR) - 1);
195  res = S_OK;
196  break;
197  }
198  break;
199  case REG_DWORD:
200  TRACE("REG_DWORD: %x\n", *(DWORD *)pData);
201  switch (V_VT(pVar))
202  {
203  case VT_EMPTY:
204  V_VT(pVar) = VT_I4;
205  /* fall through */
206  case VT_I4:
207  case VT_UI4:
208  V_I4(pVar) = *(DWORD *)pData;
209  res = S_OK;
210  break;
211  }
212  break;
213  case REG_BINARY:
214  {
215  SAFEARRAYBOUND bound;
216  void * pArrayElements;
217  bound.lLbound = 0;
218  bound.cElements = received;
219  TRACE("REG_BINARY: len = %d\n", received);
220  switch (V_VT(pVar))
221  {
222  case VT_EMPTY:
223  V_VT(pVar) = VT_ARRAY | VT_UI1;
224  /* fall through */
225  case VT_ARRAY | VT_UI1:
226  if (!(V_ARRAY(pVar) = SafeArrayCreate(VT_UI1, 1, &bound)))
227  res = E_OUTOFMEMORY;
228  else
229  res = S_OK;
230  break;
231  }
232 
233  if (res == E_INVALIDARG)
234  break;
235 
236  res = SafeArrayAccessData(V_ARRAY(pVar), &pArrayElements);
237  if (FAILED(res))
238  break;
239 
240  CopyMemory(pArrayElements, pData, received);
242  break;
243  }
244  }
245  if (res == E_INVALIDARG)
246  FIXME("Variant type %x not supported for regtype %x\n", V_VT(pVar), type);
247  }
248 
250 
251  RegCloseKey(hkey);
252 
253  TRACE("<- %x\n", res);
254  return res;
255 }
256 
258  LPPROPERTYBAG iface,
259  LPCOLESTR pszPropName,
260  VARIANT* pVar)
261 {
263  LPVOID lpData = NULL;
264  DWORD cbData = 0;
265  DWORD dwType = 0;
266  HRESULT res = S_OK;
267  LONG lres = ERROR_SUCCESS;
268  HKEY hkey;
269 
270  TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
271 
272  if (This->type == DEVICE_DMO)
273  return E_ACCESSDENIED;
274 
275  switch (V_VT(pVar))
276  {
277  case VT_BSTR:
278  case VT_LPWSTR:
279  TRACE("writing %s\n", debugstr_w(V_BSTR(pVar)));
280  lpData = V_BSTR(pVar);
281  dwType = REG_SZ;
282  cbData = (lstrlenW(V_BSTR(pVar)) + 1) * sizeof(WCHAR);
283  break;
284  case VT_I4:
285  case VT_UI4:
286  TRACE("writing %u\n", V_UI4(pVar));
287  lpData = &V_UI4(pVar);
288  dwType = REG_DWORD;
289  cbData = sizeof(DWORD);
290  break;
291  case VT_ARRAY | VT_UI1:
292  {
293  LONG lUbound = 0;
294  LONG lLbound = 0;
295  dwType = REG_BINARY;
296  res = SafeArrayGetLBound(V_ARRAY(pVar), 1, &lLbound);
297  res = SafeArrayGetUBound(V_ARRAY(pVar), 1, &lUbound);
298  cbData = (lUbound - lLbound + 1) /* * sizeof(BYTE)*/;
299  TRACE("cbData: %d\n", cbData);
300  res = SafeArrayAccessData(V_ARRAY(pVar), &lpData);
301  break;
302  }
303  default:
304  FIXME("Variant type %d not handled\n", V_VT(pVar));
305  return E_FAIL;
306  }
307 
308  if (This->type == DEVICE_FILTER)
309  lres = RegCreateKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
310  else if (This->type == DEVICE_CODEC)
311  lres = RegCreateKeyW(HKEY_CURRENT_USER, This->path, &hkey);
312  res = HRESULT_FROM_WIN32(lres);
313 
314  if (SUCCEEDED(res))
315  {
316  lres = RegSetValueExW(hkey, pszPropName, 0, dwType, lpData, cbData);
317  res = HRESULT_FROM_WIN32(lres);
318  RegCloseKey(hkey);
319  }
320 
321  if (V_VT(pVar) & VT_ARRAY)
323 
324  return res;
325 }
326 
327 static const IPropertyBagVtbl IPropertyBag_Vtbl =
328 {
334 };
335 
337 {
339  if (!rpb)
340  return E_OUTOFMEMORY;
341  rpb->IPropertyBag_iface.lpVtbl = &IPropertyBag_Vtbl;
342  rpb->ref = 1;
343  rpb->type = mon->type;
344 
345  if (rpb->type == DEVICE_DMO)
346  rpb->clsid = mon->clsid;
347  else if (rpb->type == DEVICE_FILTER)
348  {
349  lstrcpyW(rpb->path, clsidW);
350  lstrcatW(rpb->path, backslashW);
351  if (mon->has_class)
352  {
353  StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID);
354  lstrcatW(rpb->path, instanceW);
355  lstrcatW(rpb->path, backslashW);
356  }
357  lstrcatW(rpb->path, mon->name);
358  }
359  else if (rpb->type == DEVICE_CODEC)
360  {
362  if (mon->has_class)
363  {
364  StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID);
365  lstrcatW(rpb->path, backslashW);
366  }
367  lstrcatW(rpb->path, mon->name);
368  }
369 
370  *ppBag = &rpb->IPropertyBag_iface;
372  return S_OK;
373 }
374 
375 
377 {
378  return CONTAINING_RECORD(iface, MediaCatMoniker, IMoniker_iface);
379 }
380 
382  void **ppv)
383 {
384  TRACE("\n\tIID:\t%s\n",debugstr_guid(riid));
385 
386  if (!ppv)
387  return E_POINTER;
388 
389  if (IsEqualGUID(riid, &IID_IUnknown) ||
392  IsEqualGUID(riid, &IID_IMoniker))
393  {
394  *ppv = iface;
395  IMoniker_AddRef(iface);
396  return S_OK;
397  }
398 
399  FIXME("- no interface IID: %s\n", debugstr_guid(riid));
400  *ppv = NULL;
401  return E_NOINTERFACE;
402 }
403 
405 {
408 
409  TRACE("(%p) ref=%d\n", This, ref);
410 
411  return ref;
412 }
413 
415 {
418 
419  TRACE("(%p) ref=%d\n", This, ref);
420 
421  if (ref == 0) {
422  CoTaskMemFree(This->name);
425  }
426  return ref;
427 }
428 
430 {
432 
433  TRACE("(%p)->(%p)\n", This, pClassID);
434 
435  if (pClassID == NULL)
436  return E_INVALIDARG;
437 
438  *pClassID = CLSID_CDeviceMoniker;
439 
440  return S_OK;
441 }
442 
444 {
445  FIXME("(%p)->(): stub\n", iface);
446 
447  return S_FALSE;
448 }
449 
451 {
452  FIXME("(%p)->(%p): stub\n", iface, pStm);
453 
454  return E_NOTIMPL;
455 }
456 
458 {
459  FIXME("(%p)->(%p, %s): stub\n", iface, pStm, fClearDirty ? "true" : "false");
460 
461  return STG_E_CANTSAVE;
462 }
463 
465 {
466  FIXME("(%p)->(%p): stub\n", iface, pcbSize);
467 
468  ZeroMemory(pcbSize, sizeof(*pcbSize));
469 
470  return S_OK;
471 }
472 
474  IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult)
475 {
477  IUnknown * pObj = NULL;
478  IPropertyBag * pProp = NULL;
479  CLSID clsID;
480  VARIANT var;
481  HRESULT res = E_FAIL;
482 
483  TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult);
484 
485  if (!ppvResult)
486  return E_POINTER;
487 
488  VariantInit(&var);
489  *ppvResult = NULL;
490 
491  if(pmkToLeft==NULL)
492  {
493  /* first activation of this class */
494  LPVOID pvptr;
495  res=IMoniker_BindToStorage(iface, NULL, NULL, &IID_IPropertyBag, &pvptr);
496  pProp = pvptr;
497  if (SUCCEEDED(res))
498  {
499  V_VT(&var) = VT_LPWSTR;
500  res = IPropertyBag_Read(pProp, clsidW, &var, NULL);
501  }
502  if (SUCCEEDED(res))
503  {
504  res = CLSIDFromString(V_BSTR(&var), &clsID);
505  CoTaskMemFree(V_BSTR(&var));
506  }
507  if (SUCCEEDED(res))
508  {
509  res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IUnknown,&pvptr);
510  pObj = pvptr;
511  }
512  }
513 
514  if (pObj!=NULL)
515  {
516  /* get the requested interface from the loaded class */
517  res = S_OK;
518  if (pProp) {
519  HRESULT res2;
520  LPVOID ppv = NULL;
521  res2 = IUnknown_QueryInterface(pObj, &IID_IPersistPropertyBag, &ppv);
522  if (SUCCEEDED(res2)) {
523  res = IPersistPropertyBag_Load((IPersistPropertyBag *) ppv, pProp, NULL);
524  IPersistPropertyBag_Release((IPersistPropertyBag *) ppv);
525  }
526  }
527  if (SUCCEEDED(res))
528  res= IUnknown_QueryInterface(pObj,riidResult,ppvResult);
529  IUnknown_Release(pObj);
530  }
531 
532  if (pProp)
533  {
534  IPropertyBag_Release(pProp);
535  }
536 
537  TRACE("<- 0x%x\n", res);
538 
539  return res;
540 }
541 
543  IMoniker *pmkToLeft, REFIID riid, void **ppvObj)
544 {
546 
547  TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
548 
549  *ppvObj = NULL;
550 
551  if (pmkToLeft)
552  return MK_E_NOSTORAGE;
553 
554  if (pbc != NULL)
555  {
556  static DWORD reported;
557  if (!reported)
558  {
559  FIXME("ignoring IBindCtx %p\n", pbc);
560  reported++;
561  }
562  }
563 
565  {
566  return create_PropertyBag(This, (IPropertyBag**)ppvObj);
567  }
568 
569  return MK_E_NOSTORAGE;
570 }
571 
573  DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
574 {
575  TRACE("(%p)->(%p, %d, %p, %p)\n", iface, pbc, dwReduceHowFar, ppmkToLeft, ppmkReduced);
576 
577  if (ppmkToLeft)
578  *ppmkToLeft = NULL;
579  *ppmkReduced = iface;
580 
581  return MK_S_REDUCED_TO_SELF;
582 }
583 
585  BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
586 {
587  FIXME("(%p)->(%p, %s, %p): stub\n", iface, pmkRight, fOnlyIfNotGeneric ? "true" : "false", ppmkComposite);
588 
589  /* FIXME: use CreateGenericComposite? */
590  *ppmkComposite = NULL;
591 
592  return E_NOTIMPL;
593 }
594 
596  IEnumMoniker **ppenumMoniker)
597 {
598  FIXME("(%p)->(%s, %p): stub\n", iface, fForward ? "true" : "false", ppenumMoniker);
599 
600  *ppenumMoniker = NULL;
601 
602  return S_OK;
603 }
604 
606 {
607  CLSID clsid;
608  LPOLESTR this_name, other_name;
609  IBindCtx *bind;
610  HRESULT res;
611 
612  TRACE("(%p)->(%p)\n", iface, pmkOtherMoniker);
613 
614  if (!pmkOtherMoniker)
615  return E_INVALIDARG;
616 
617  IMoniker_GetClassID(pmkOtherMoniker, &clsid);
618  if (!IsEqualCLSID(&clsid, &CLSID_CDeviceMoniker))
619  return S_FALSE;
620 
621  res = CreateBindCtx(0, &bind);
622  if (FAILED(res))
623  return res;
624 
625  res = S_FALSE;
626  if (SUCCEEDED(IMoniker_GetDisplayName(iface, bind, NULL, &this_name)) &&
627  SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker, bind, NULL, &other_name)))
628  {
629  int result = lstrcmpiW(this_name, other_name);
630  CoTaskMemFree(this_name);
631  CoTaskMemFree(other_name);
632  if (!result)
633  res = S_OK;
634  }
635  IBindCtx_Release(bind);
636  return res;
637 }
638 
640 {
641  TRACE("(%p)->(%p)\n", iface, pdwHash);
642 
643  *pdwHash = 0;
644 
645  return S_OK;
646 }
647 
649  IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
650 {
651  FIXME("(%p)->(%p, %p, %p): stub\n", iface, pbc, pmkToLeft, pmkNewlyRunning);
652 
653  return S_FALSE;
654 }
655 
657  IMoniker *pmkToLeft, FILETIME *pFileTime)
658 {
659  TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, pFileTime);
660 
661  pFileTime->dwLowDateTime = 0xFFFFFFFF;
662  pFileTime->dwHighDateTime = 0x7FFFFFFF;
663 
664  return MK_E_UNAVAILABLE;
665 }
666 
668 {
669  TRACE("(%p)->(%p)\n", iface, ppmk);
670 
671  *ppmk = NULL;
672 
673  return MK_E_NOINVERSE;
674 }
675 
677  IMoniker *pmkOtherMoniker, IMoniker **ppmkPrefix)
678 {
679  TRACE("(%p)->(%p, %p)\n", iface, pmkOtherMoniker, ppmkPrefix);
680 
681  *ppmkPrefix = NULL;
682 
683  return MK_E_NOPREFIX;
684 }
685 
687  IMoniker **ppmkRelPath)
688 {
689  TRACE("(%p)->(%p, %p)\n", iface, pmkOther, ppmkRelPath);
690 
691  *ppmkRelPath = pmkOther;
692 
693  return MK_S_HIM;
694 }
695 
697  IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
698 {
700  WCHAR *buffer;
701 
702  TRACE("(%p)->(%p, %p, %p)\n", iface, pbc, pmkToLeft, ppszDisplayName);
703 
704  *ppszDisplayName = NULL;
705 
706  if (This->type == DEVICE_DMO)
707  {
709  + 2 * CHARS_IN_GUID + 1) * sizeof(WCHAR));
710  if (!buffer) return E_OUTOFMEMORY;
711 
713  lstrcatW(buffer, dmoW);
716  }
717  else
718  {
719  buffer = CoTaskMemAlloc((lstrlenW(deviceW) + 3 + (This->has_class ? CHARS_IN_GUID : 0)
720  + lstrlenW(This->name) + 1) * sizeof(WCHAR));
721  if (!buffer) return E_OUTOFMEMORY;
722 
724  if (This->type == DEVICE_FILTER)
725  lstrcatW(buffer, swW);
726  else if (This->type == DEVICE_CODEC)
727  lstrcatW(buffer, cmW);
728 
729  if (This->has_class)
730  {
733  }
734  lstrcatW(buffer, This->name);
735  }
736 
737  *ppszDisplayName = buffer;
738  return S_OK;
739 }
740 
742  IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
743 {
744  FIXME("(%p)->(%p, %p, %s, %p, %p)\n", iface, pbc, pmkToLeft, debugstr_w(pszDisplayName), pchEaten, ppmkOut);
745 
746  *pchEaten = 0;
747  *ppmkOut = NULL;
748 
749  return MK_E_SYNTAX;
750 }
751 
753 {
754  TRACE("(%p)->(%p)\n", iface, pdwMksys);
755 
756  return S_FALSE;
757 }
758 
759 static const IMonikerVtbl IMoniker_Vtbl =
760 {
784 };
785 
787 {
788  MediaCatMoniker * pMoniker = NULL;
789  pMoniker = CoTaskMemAlloc(sizeof(MediaCatMoniker));
790  if (!pMoniker)
791  return NULL;
792 
793  pMoniker->IMoniker_iface.lpVtbl = &IMoniker_Vtbl;
794  pMoniker->ref = 0;
795  pMoniker->has_class = FALSE;
796  pMoniker->name = NULL;
797 
799 
801 
802  return pMoniker;
803 }
804 
806 {
807  return CONTAINING_RECORD(iface, EnumMonikerImpl, IEnumMoniker_iface);
808 }
809 
811  void **ppv)
812 {
813  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
814 
815  if (!ppv)
816  return E_POINTER;
817 
818  if (IsEqualGUID(riid, &IID_IUnknown) ||
820  {
821  *ppv = iface;
822  IEnumMoniker_AddRef(iface);
823  return S_OK;
824  }
825 
826  FIXME("- no interface IID: %s\n", debugstr_guid(riid));
827  *ppv = NULL;
828  return E_NOINTERFACE;
829 }
830 
832 {
835 
836  TRACE("(%p) ref=%d\n", This, ref);
837 
838  return ref;
839 }
840 
842 {
845 
846  TRACE("(%p) ref=%d\n", This, ref);
847 
848  if (!ref)
849  {
850  IEnumDMO_Release(This->dmo_enum);
851  RegCloseKey(This->sw_key);
852  RegCloseKey(This->cm_key);
855  return 0;
856  }
857  return ref;
858 }
859 
861  ULONG *pceltFetched)
862 {
864  WCHAR buffer[MAX_PATH + 1];
865  LONG res;
866  ULONG fetched = 0;
867  MediaCatMoniker * pMoniker;
868  CLSID clsid;
869  HRESULT hr;
870  HKEY hkey;
871 
872  TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
873 
874  while (fetched < celt)
875  {
876  /* FIXME: try PNP devices first */
877 
878  /* try DMOs */
879  if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, NULL, NULL)) == S_OK)
880  {
881  if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
882  return E_OUTOFMEMORY;
883 
884  pMoniker->type = DEVICE_DMO;
885  pMoniker->clsid = clsid;
886 
889  }
890  /* try DirectShow filters */
891  else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, ARRAY_SIZE(buffer))))
892  {
893  This->sw_index++;
894  if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
895  break;
896 
897  if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
898  return E_OUTOFMEMORY;
899 
900  pMoniker->type = DEVICE_FILTER;
901 
902  if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR))))
903  {
904  IMoniker_Release(&pMoniker->IMoniker_iface);
905  return E_OUTOFMEMORY;
906  }
907  lstrcpyW(pMoniker->name, buffer);
908  }
909  /* then try codecs */
910  else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, ARRAY_SIZE(buffer))))
911  {
912  This->cm_index++;
913 
914  if ((res = RegOpenKeyExW(This->cm_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
915  break;
916 
917  if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
918  return E_OUTOFMEMORY;
919 
920  pMoniker->type = DEVICE_CODEC;
921 
922  if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR))))
923  {
924  IMoniker_Release(&pMoniker->IMoniker_iface);
925  return E_OUTOFMEMORY;
926  }
927  lstrcpyW(pMoniker->name, buffer);
928  }
929  else
930  break;
931 
932  pMoniker->has_class = TRUE;
933  pMoniker->class = This->class;
934 
935  rgelt[fetched] = &pMoniker->IMoniker_iface;
936  fetched++;
937  }
938 
939  TRACE("-- fetched %d\n", fetched);
940 
941  if (pceltFetched)
942  *pceltFetched = fetched;
943 
944  if (fetched != celt)
945  return S_FALSE;
946  else
947  return S_OK;
948 }
949 
951 {
953 
954  TRACE("(%p)->(%d)\n", iface, celt);
955 
956  while (celt--)
957  {
958  /* FIXME: try PNP devices first */
959 
960  /* try DMOs */
961  if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK)
962  ;
963  /* try DirectShow filters */
964  else if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
965  {
966  This->sw_index++;
967  }
968  /* then try codecs */
969  else if (RegEnumKeyW(This->cm_key, This->cm_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
970  {
971  This->cm_index++;
972  }
973  else
974  return S_FALSE;
975  }
976 
977  return S_OK;
978 }
979 
981 {
983 
984  TRACE("(%p)->()\n", iface);
985 
986  IEnumDMO_Reset(This->dmo_enum);
987  This->sw_index = 0;
988  This->cm_index = 0;
989 
990  return S_OK;
991 }
992 
994 {
995  FIXME("(%p)->(%p): stub\n", iface, ppenum);
996 
997  return E_NOTIMPL;
998 }
999 
1000 /**********************************************************************
1001  * IEnumMoniker_Vtbl
1002  */
1003 static const IEnumMonikerVtbl IEnumMoniker_Vtbl =
1004 {
1012 };
1013 
1015 {
1016  EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
1017  WCHAR buffer[78];
1018  HRESULT hr;
1019 
1020  if (!pEnumMoniker)
1021  return E_OUTOFMEMORY;
1022 
1023  pEnumMoniker->IEnumMoniker_iface.lpVtbl = &IEnumMoniker_Vtbl;
1024  pEnumMoniker->ref = 1;
1025  pEnumMoniker->sw_index = 0;
1026  pEnumMoniker->cm_index = 0;
1027  pEnumMoniker->class = *class;
1028 
1034  pEnumMoniker->sw_key = NULL;
1035 
1039  pEnumMoniker->cm_key = NULL;
1040 
1041  hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &pEnumMoniker->dmo_enum);
1042  if (FAILED(hr))
1043  {
1044  IEnumMoniker_Release(&pEnumMoniker->IEnumMoniker_iface);
1045  return hr;
1046  }
1047 
1048  *ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
1049 
1051 
1052  return S_OK;
1053 }
static const WCHAR dmoW[]
static const IPropertyBagVtbl IPropertyBag_Vtbl
Definition: mediacatenum.c:327
#define E_ACCESSDENIED
Definition: winerror.h:2849
static void DEVENUM_UnlockModule(void)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define MK_S_REDUCED_TO_SELF
Definition: winerror.h:2773
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_ParseDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR pszDisplayName, ULONG *pchEaten, IMoniker **ppmkOut)
Definition: mediacatenum.c:741
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:1947
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsRunning(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, IMoniker *pmkNewlyRunning)
Definition: mediacatenum.c:648
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsDirty(IMoniker *iface)
Definition: mediacatenum.c:443
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
static const WCHAR instanceW[]
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
WCHAR path[MAX_PATH]
Definition: mediacatenum.c:53
#define REG_BINARY
Definition: nt_native.h:1496
enum device_type type
#define MK_E_NOINVERSE
Definition: winerror.h:2793
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
REFIID riid
Definition: precomp.h:44
#define REFCLSID
Definition: guiddef.h:117
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define HKEY_CURRENT_USER
Definition: winreg.h:11
const GUID IID_IPersist
Definition: proxy.cpp:14
#define V_ARRAY(A)
Definition: oleauto.h:222
device_type
#define CHARS_IN_GUID
const GUID IID_IEnumMoniker
r received
Definition: btrfs.c:2864
REFIID LPVOID * ppv
Definition: atlbase.h:39
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
Definition: mediacatenum.c:696
static ULONG WINAPI DEVENUM_IEnumMoniker_AddRef(IEnumMoniker *iface)
Definition: mediacatenum.c:831
#define ZeroMemory
Definition: winbase.h:1642
GLuint buffer
Definition: glext.h:5915
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetTimeOfLastChange(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, FILETIME *pFileTime)
Definition: mediacatenum.c:656
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
static const WCHAR swW[]
static LPOLESTR
Definition: stg_prop.c:27
#define lstrlenW
Definition: compat.h:415
#define E_FAIL
Definition: ddrawi.h:102
#define DWORD
Definition: nt_native.h:44
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Inverse(IMoniker *iface, IMoniker **ppmk)
Definition: mediacatenum.c:667
Definition: send.c:47
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_ComposeWith(IMoniker *iface, IMoniker *pmkRight, BOOL fOnlyIfNotGeneric, IMoniker **ppmkComposite)
Definition: mediacatenum.c:584
IEnumMoniker IEnumMoniker_iface
Definition: mediacatenum.c:36
static const WCHAR deviceW[]
#define V_I4(A)
Definition: oleauto.h:247
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsEqual(IMoniker *iface, IMoniker *pmkOtherMoniker)
Definition: mediacatenum.c:605
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static ULONG WINAPI DEVENUM_IMediaCatMoniker_Release(IMoniker *iface)
Definition: mediacatenum.c:414
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void)
Definition: mediacatenum.c:786
static HRESULT WINAPI DEVENUM_IEnumMoniker_QueryInterface(IEnumMoniker *iface, REFIID riid, void **ppv)
Definition: mediacatenum.c:810
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_QueryInterface(IMoniker *iface, REFIID riid, void **ppv)
Definition: mediacatenum.c:381
DWORD dwHighDateTime
Definition: mapidefs.h:66
static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
Definition: mediacatenum.c:336
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
const GUID IID_IPersistPropertyBag
Definition: proxy.cpp:11
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Load(IMoniker *iface, IStream *pStm)
Definition: mediacatenum.c:450
#define S_FALSE
Definition: winerror.h:2357
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
const GUID IID_IPropertyBag
HRESULT WINAPI DMOGetName(REFCLSID clsidDMO, WCHAR name[])
Definition: dmoreg.c:342
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
static void DEVENUM_LockModule(void)
IPropertyBag IPropertyBag_iface
Definition: mediacatenum.c:48
#define debugstr_guid
Definition: kernel32.h:35
static const WCHAR cmW[]
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
static const WCHAR backslashW[]
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
struct EnumMonikerImpl EnumMonikerImpl
static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
Definition: mediacatenum.c:841
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt)
Definition: mediacatenum.c:950
#define GetProcessHeap()
Definition: compat.h:403
static const WCHAR clsidW[]
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
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
const GUID IID_IUnknown
static ULONG WINAPI DEVENUM_IMediaCatMoniker_AddRef(IMoniker *iface)
Definition: mediacatenum.c:404
#define MAX_PATH
Definition: compat.h:26
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_CommonPrefixWith(IMoniker *iface, IMoniker *pmkOtherMoniker, IMoniker **ppmkPrefix)
Definition: mediacatenum.c:676
#define WINAPI
Definition: msvc.h:6
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riid, void **ppvObj)
Definition: mediacatenum.c:542
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
static ULONG WINAPI DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface)
Definition: mediacatenum.c:102
#define CopyMemory
Definition: winbase.h:1640
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Enum(IMoniker *iface, BOOL fForward, IEnumMoniker **ppenumMoniker)
Definition: mediacatenum.c:595
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_IsSystemMoniker(IMoniker *iface, DWORD *pdwMksys)
Definition: mediacatenum.c:752
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
Definition: safearray.c:1066
unsigned long DWORD
Definition: ntddk_ex.h:95
WINE_DEFAULT_DEBUG_CHANNEL(devenum)
static const WCHAR wszActiveMovieKey[]
const GUID IID_IPersistStream
Definition: proxy.cpp:13
static HRESULT WINAPI DEVENUM_IPropertyBag_Read(LPPROPERTYBAG iface, LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog)
Definition: mediacatenum.c:117
#define V_UI4(A)
Definition: oleauto.h:270
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Save(IMoniker *iface, IStream *pStm, BOOL fClearDirty)
Definition: mediacatenum.c:457
static ULONG WINAPI DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface)
Definition: mediacatenum.c:90
static RegPropBagImpl * impl_from_IPropertyBag(IPropertyBag *iface)
Definition: mediacatenum.c:59
IMoniker IMoniker_iface
REFCLSID clsid
Definition: msctf.c:82
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult)
Definition: mediacatenum.c:473
#define InterlockedDecrement
Definition: armddk.h:52
#define V_VT(A)
Definition: oleauto.h:211
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, IMoniker **rgelt, ULONG *pceltFetched)
Definition: mediacatenum.c:860
#define V_BSTR(A)
Definition: oleauto.h:226
#define MK_E_NOPREFIX
Definition: winerror.h:2795
IEnumDMO * dmo_enum
Definition: mediacatenum.c:39
static MediaCatMoniker * impl_from_IMoniker(IMoniker *iface)
Definition: mediacatenum.c:376
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2416
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
#define S_OK
Definition: intsafe.h:59
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
#define InterlockedIncrement
Definition: armddk.h:53
#define lstrcpyW
Definition: compat.h:414
#define ARRAY_SIZE(a)
Definition: main.h:24
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSize)
Definition: mediacatenum.c:464
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:732
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker *iface, IMoniker *pmkOther, IMoniker **ppmkRelPath)
Definition: mediacatenum.c:686
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetClassID(IMoniker *iface, CLSID *pClassID)
Definition: mediacatenum.c:429
static EnumMonikerImpl * impl_from_IEnumMoniker(IEnumMoniker *iface)
Definition: mediacatenum.c:805
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
#define ERROR_NOT_FOUND
Definition: winerror.h:690
#define MK_E_UNAVAILABLE
Definition: winerror.h:2784
Definition: name.c:38
GLuint res
Definition: glext.h:9613
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define MK_E_NOSTORAGE
Definition: winerror.h:2794
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define MK_E_SYNTAX
Definition: winerror.h:2785
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD dwReduceHowFar, IMoniker **ppmkToLeft, IMoniker **ppmkReduced)
Definition: mediacatenum.c:572
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
#define E_POINTER
Definition: winerror.h:2365
#define STG_E_CANTSAVE
Definition: winerror.h:2591
GLuint64EXT * result
Definition: glext.h:11304
#define REG_DWORD
Definition: sdbapi.c:596
#define IsEqualCLSID(rclsid1, rclsid2)
Definition: guiddef.h:96
static HRESULT WINAPI DEVENUM_IPropertyBag_Write(LPPROPERTYBAG iface, LPCOLESTR pszPropName, VARIANT *pVar)
Definition: mediacatenum.c:257
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:404
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_Hash(IMoniker *iface, DWORD *pdwHash)
Definition: mediacatenum.c:639
static const IEnumMonikerVtbl IEnumMoniker_Vtbl
#define HeapFree(x, y, z)
Definition: compat.h:402
DWORD dwLowDateTime
Definition: mapidefs.h:65
static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
Definition: mediacatenum.c:980
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
#define SUCCEEDED(hr)
Definition: intsafe.h:57
enum device_type type
Definition: mediacatenum.c:50
static HRESULT WINAPI DEVENUM_IPropertyBag_QueryInterface(LPPROPERTYBAG iface, REFIID riid, LPVOID *ppvObj)
Definition: mediacatenum.c:64
static HRESULT WINAPI DEVENUM_IEnumMoniker_Clone(IEnumMoniker *iface, IEnumMoniker **ppenum)
Definition: mediacatenum.c:993
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
static const IMonikerVtbl IMoniker_Vtbl
Definition: mediacatenum.c:759
#define REG_SZ
Definition: layer.c:22
#define MK_S_HIM
Definition: winerror.h:2775