2 * IEnumMoniker implementation for DEVENUM.dll
4 * Copyright (C) 2002 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * - Implements IEnumMoniker interface which enumerates through moniker
22 * objects created from HKEY_CLASSES/CLSID/{DEVICE_CLSID}/Instance
25 #include "devenum_private.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(devenum
);
35 IEnumMoniker IEnumMoniker_iface
;
46 IPropertyBag IPropertyBag_iface
;
48 enum device_type type
;
53 static inline RegPropBagImpl
*impl_from_IPropertyBag(IPropertyBag
*iface
)
55 return CONTAINING_RECORD(iface
, RegPropBagImpl
, IPropertyBag_iface
);
58 static HRESULT WINAPI
DEVENUM_IPropertyBag_QueryInterface(
63 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
65 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppvObj
);
67 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
69 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
70 IsEqualGUID(riid
, &IID_IPropertyBag
))
73 IPropertyBag_AddRef(iface
);
77 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
81 /**********************************************************************
82 * DEVENUM_IPropertyBag_AddRef (also IUnknown)
84 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
)
86 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
88 TRACE("(%p)->() AddRef from %d\n", iface
, This
->ref
);
90 return InterlockedIncrement(&This
->ref
);
93 /**********************************************************************
94 * DEVENUM_IPropertyBag_Release (also IUnknown)
96 static ULONG WINAPI
DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface
)
98 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
101 TRACE("(%p)->() ReleaseThis->ref from %d\n", iface
, This
->ref
);
103 ref
= InterlockedDecrement(&This
->ref
);
106 DEVENUM_UnlockModule();
111 static HRESULT WINAPI
DEVENUM_IPropertyBag_Read(
113 LPCOLESTR pszPropName
,
115 IErrorLog
* pErrorLog
)
120 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
122 LONG reswin32
= ERROR_SUCCESS
;
125 TRACE("(%p)->(%s, %p, %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
127 if (!pszPropName
|| !pVar
)
130 if (This
->type
== DEVICE_FILTER
)
131 reswin32
= RegOpenKeyW(HKEY_CLASSES_ROOT
, This
->path
, &hkey
);
132 else if (This
->type
== DEVICE_CODEC
)
133 reswin32
= RegOpenKeyW(HKEY_CURRENT_USER
, This
->path
, &hkey
);
134 res
= HRESULT_FROM_WIN32(reswin32
);
138 reswin32
= RegQueryValueExW(hkey
, pszPropName
, NULL
, NULL
, NULL
, &received
);
139 res
= HRESULT_FROM_WIN32(reswin32
);
144 pData
= HeapAlloc(GetProcessHeap(), 0, received
);
146 /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
147 reswin32
= RegQueryValueExW(hkey
, pszPropName
, NULL
, &type
, pData
, &received
);
148 res
= HRESULT_FROM_WIN32(reswin32
);
153 res
= E_INVALIDARG
; /* assume we cannot coerce into right type */
155 TRACE("Read %d bytes (%s)\n", received
, type
== REG_SZ
? debugstr_w(pData
) : "binary data");
163 V_BSTR(pVar
) = CoTaskMemAlloc(received
);
164 memcpy(V_BSTR(pVar
), pData
, received
);
168 V_VT(pVar
) = VT_BSTR
;
171 V_BSTR(pVar
) = SysAllocStringLen(pData
, received
/sizeof(WCHAR
) - 1);
177 TRACE("REG_DWORD: %x\n", *(DWORD
*)pData
);
185 V_I4(pVar
) = *(DWORD
*)pData
;
192 SAFEARRAYBOUND bound
;
193 void * pArrayElements
;
195 bound
.cElements
= received
;
196 TRACE("REG_BINARY: len = %d\n", received
);
200 V_VT(pVar
) = VT_ARRAY
| VT_UI1
;
202 case VT_ARRAY
| VT_UI1
:
203 if (!(V_ARRAY(pVar
) = SafeArrayCreate(VT_UI1
, 1, &bound
)))
210 if (res
== E_INVALIDARG
)
213 res
= SafeArrayAccessData(V_ARRAY(pVar
), &pArrayElements
);
217 CopyMemory(pArrayElements
, pData
, received
);
218 res
= SafeArrayUnaccessData(V_ARRAY(pVar
));
222 if (res
== E_INVALIDARG
)
223 FIXME("Variant type %x not supported for regtype %x\n", V_VT(pVar
), type
);
226 HeapFree(GetProcessHeap(), 0, pData
);
230 TRACE("<- %x\n", res
);
234 static HRESULT WINAPI
DEVENUM_IPropertyBag_Write(
236 LPCOLESTR pszPropName
,
239 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
240 LPVOID lpData
= NULL
;
244 LONG lres
= ERROR_SUCCESS
;
247 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(pszPropName
), pVar
);
253 TRACE("writing %s\n", debugstr_w(V_BSTR(pVar
)));
254 lpData
= V_BSTR(pVar
);
256 cbData
= (lstrlenW(V_BSTR(pVar
)) + 1) * sizeof(WCHAR
);
260 TRACE("writing %u\n", V_UI4(pVar
));
261 lpData
= &V_UI4(pVar
);
263 cbData
= sizeof(DWORD
);
265 case VT_ARRAY
| VT_UI1
:
270 res
= SafeArrayGetLBound(V_ARRAY(pVar
), 1, &lLbound
);
271 res
= SafeArrayGetUBound(V_ARRAY(pVar
), 1, &lUbound
);
272 cbData
= (lUbound
- lLbound
+ 1) /* * sizeof(BYTE)*/;
273 TRACE("cbData: %d\n", cbData
);
274 res
= SafeArrayAccessData(V_ARRAY(pVar
), &lpData
);
278 FIXME("Variant type %d not handled\n", V_VT(pVar
));
282 if (This
->type
== DEVICE_FILTER
)
283 lres
= RegCreateKeyW(HKEY_CLASSES_ROOT
, This
->path
, &hkey
);
284 else if (This
->type
== DEVICE_CODEC
)
285 lres
= RegCreateKeyW(HKEY_CURRENT_USER
, This
->path
, &hkey
);
286 res
= HRESULT_FROM_WIN32(lres
);
290 lres
= RegSetValueExW(hkey
, pszPropName
, 0, dwType
, lpData
, cbData
);
291 res
= HRESULT_FROM_WIN32(lres
);
295 if (V_VT(pVar
) & VT_ARRAY
)
296 res
= SafeArrayUnaccessData(V_ARRAY(pVar
));
301 static const IPropertyBagVtbl IPropertyBag_Vtbl
=
303 DEVENUM_IPropertyBag_QueryInterface
,
304 DEVENUM_IPropertyBag_AddRef
,
305 DEVENUM_IPropertyBag_Release
,
306 DEVENUM_IPropertyBag_Read
,
307 DEVENUM_IPropertyBag_Write
310 static HRESULT
create_PropertyBag(MediaCatMoniker
*mon
, IPropertyBag
**ppBag
)
312 RegPropBagImpl
* rpb
= CoTaskMemAlloc(sizeof(RegPropBagImpl
));
314 return E_OUTOFMEMORY
;
315 rpb
->IPropertyBag_iface
.lpVtbl
= &IPropertyBag_Vtbl
;
317 rpb
->type
= mon
->type
;
319 if (rpb
->type
== DEVICE_FILTER
)
320 strcpyW(rpb
->path
, clsidW
);
321 else if (rpb
->type
== DEVICE_CODEC
)
322 strcpyW(rpb
->path
, wszActiveMovieKey
);
325 StringFromGUID2(&mon
->class, rpb
->path
+ strlenW(rpb
->path
), CHARS_IN_GUID
);
326 if (rpb
->type
== DEVICE_FILTER
)
327 strcatW(rpb
->path
, instanceW
);
328 strcatW(rpb
->path
, backslashW
);
330 strcatW(rpb
->path
, mon
->name
);
332 *ppBag
= &rpb
->IPropertyBag_iface
;
333 DEVENUM_LockModule();
338 static inline MediaCatMoniker
*impl_from_IMoniker(IMoniker
*iface
)
340 return CONTAINING_RECORD(iface
, MediaCatMoniker
, IMoniker_iface
);
343 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_QueryInterface(IMoniker
*iface
, REFIID riid
,
346 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
351 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
352 IsEqualGUID(riid
, &IID_IPersist
) ||
353 IsEqualGUID(riid
, &IID_IPersistStream
) ||
354 IsEqualGUID(riid
, &IID_IMoniker
))
357 IMoniker_AddRef(iface
);
361 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
363 return E_NOINTERFACE
;
366 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(IMoniker
*iface
)
368 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
369 ULONG ref
= InterlockedIncrement(&This
->ref
);
371 TRACE("(%p) ref=%d\n", This
, ref
);
376 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_Release(IMoniker
*iface
)
378 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
379 ULONG ref
= InterlockedDecrement(&This
->ref
);
381 TRACE("(%p) ref=%d\n", This
, ref
);
384 CoTaskMemFree(This
->name
);
386 DEVENUM_UnlockModule();
391 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetClassID(IMoniker
*iface
, CLSID
*pClassID
)
393 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
395 TRACE("(%p)->(%p)\n", This
, pClassID
);
397 if (pClassID
== NULL
)
400 *pClassID
= CLSID_CDeviceMoniker
;
405 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsDirty(IMoniker
*iface
)
407 FIXME("(%p)->(): stub\n", iface
);
412 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Load(IMoniker
*iface
, IStream
*pStm
)
414 FIXME("(%p)->(%p): stub\n", iface
, pStm
);
419 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Save(IMoniker
*iface
, IStream
*pStm
, BOOL fClearDirty
)
421 FIXME("(%p)->(%p, %s): stub\n", iface
, pStm
, fClearDirty
? "true" : "false");
423 return STG_E_CANTSAVE
;
426 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetSizeMax(IMoniker
*iface
, ULARGE_INTEGER
*pcbSize
)
428 FIXME("(%p)->(%p): stub\n", iface
, pcbSize
);
430 ZeroMemory(pcbSize
, sizeof(*pcbSize
));
435 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToObject(IMoniker
*iface
, IBindCtx
*pbc
,
436 IMoniker
*pmkToLeft
, REFIID riidResult
, void **ppvResult
)
438 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
439 IUnknown
* pObj
= NULL
;
440 IPropertyBag
* pProp
= NULL
;
443 HRESULT res
= E_FAIL
;
445 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riidResult
), ppvResult
);
452 /* first activation of this class */
454 res
=IMoniker_BindToStorage(iface
, NULL
, NULL
, &IID_IPropertyBag
, &pvptr
);
458 V_VT(&var
) = VT_LPWSTR
;
459 res
= IPropertyBag_Read(pProp
, clsid_keyname
, &var
, NULL
);
463 res
= CLSIDFromString(V_BSTR(&var
), &clsID
);
464 CoTaskMemFree(V_BSTR(&var
));
468 res
=CoCreateInstance(&clsID
,NULL
,CLSCTX_ALL
,&IID_IUnknown
,&pvptr
);
475 /* get the requested interface from the loaded class */
480 res2
= IUnknown_QueryInterface(pObj
, &IID_IPersistPropertyBag
, &ppv
);
481 if (SUCCEEDED(res2
)) {
482 res
= IPersistPropertyBag_Load((IPersistPropertyBag
*) ppv
, pProp
, NULL
);
483 IPersistPropertyBag_Release((IPersistPropertyBag
*) ppv
);
487 res
= IUnknown_QueryInterface(pObj
,riidResult
,ppvResult
);
488 IUnknown_Release(pObj
);
493 IPropertyBag_Release(pProp
);
496 TRACE("<- 0x%x\n", res
);
501 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToStorage(IMoniker
*iface
, IBindCtx
*pbc
,
502 IMoniker
*pmkToLeft
, REFIID riid
, void **ppvObj
)
504 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
506 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riid
), ppvObj
);
511 return MK_E_NOSTORAGE
;
515 static DWORD reported
;
518 FIXME("ignoring IBindCtx %p\n", pbc
);
523 if (IsEqualGUID(riid
, &IID_IPropertyBag
))
525 return create_PropertyBag(This
, (IPropertyBag
**)ppvObj
);
528 return MK_E_NOSTORAGE
;
531 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Reduce(IMoniker
*iface
, IBindCtx
*pbc
,
532 DWORD dwReduceHowFar
, IMoniker
**ppmkToLeft
, IMoniker
**ppmkReduced
)
534 TRACE("(%p)->(%p, %d, %p, %p)\n", iface
, pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
538 *ppmkReduced
= iface
;
540 return MK_S_REDUCED_TO_SELF
;
543 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ComposeWith(IMoniker
*iface
, IMoniker
*pmkRight
,
544 BOOL fOnlyIfNotGeneric
, IMoniker
**ppmkComposite
)
546 FIXME("(%p)->(%p, %s, %p): stub\n", iface
, pmkRight
, fOnlyIfNotGeneric
? "true" : "false", ppmkComposite
);
548 /* FIXME: use CreateGenericComposite? */
549 *ppmkComposite
= NULL
;
554 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Enum(IMoniker
*iface
, BOOL fForward
,
555 IEnumMoniker
**ppenumMoniker
)
557 FIXME("(%p)->(%s, %p): stub\n", iface
, fForward
? "true" : "false", ppenumMoniker
);
559 *ppenumMoniker
= NULL
;
564 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsEqual(IMoniker
*iface
, IMoniker
*pmkOtherMoniker
)
567 LPOLESTR this_name
, other_name
;
571 TRACE("(%p)->(%p)\n", iface
, pmkOtherMoniker
);
573 if (!pmkOtherMoniker
)
576 IMoniker_GetClassID(pmkOtherMoniker
, &clsid
);
577 if (!IsEqualCLSID(&clsid
, &CLSID_CDeviceMoniker
))
580 res
= CreateBindCtx(0, &bind
);
585 if (SUCCEEDED(IMoniker_GetDisplayName(iface
, bind
, NULL
, &this_name
)) &&
586 SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker
, bind
, NULL
, &other_name
)))
588 int result
= lstrcmpiW(this_name
, other_name
);
589 CoTaskMemFree(this_name
);
590 CoTaskMemFree(other_name
);
594 IBindCtx_Release(bind
);
598 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Hash(IMoniker
*iface
, DWORD
*pdwHash
)
600 TRACE("(%p)->(%p)\n", iface
, pdwHash
);
607 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsRunning(IMoniker
*iface
, IBindCtx
*pbc
,
608 IMoniker
*pmkToLeft
, IMoniker
*pmkNewlyRunning
)
610 FIXME("(%p)->(%p, %p, %p): stub\n", iface
, pbc
, pmkToLeft
, pmkNewlyRunning
);
615 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetTimeOfLastChange(IMoniker
*iface
, IBindCtx
*pbc
,
616 IMoniker
*pmkToLeft
, FILETIME
*pFileTime
)
618 TRACE("(%p)->(%p, %p, %p)\n", iface
, pbc
, pmkToLeft
, pFileTime
);
620 pFileTime
->dwLowDateTime
= 0xFFFFFFFF;
621 pFileTime
->dwHighDateTime
= 0x7FFFFFFF;
623 return MK_E_UNAVAILABLE
;
626 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Inverse(IMoniker
*iface
, IMoniker
**ppmk
)
628 TRACE("(%p)->(%p)\n", iface
, ppmk
);
632 return MK_E_NOINVERSE
;
635 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_CommonPrefixWith(IMoniker
*iface
,
636 IMoniker
*pmkOtherMoniker
, IMoniker
**ppmkPrefix
)
638 TRACE("(%p)->(%p, %p)\n", iface
, pmkOtherMoniker
, ppmkPrefix
);
642 return MK_E_NOPREFIX
;
645 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker
*iface
, IMoniker
*pmkOther
,
646 IMoniker
**ppmkRelPath
)
648 TRACE("(%p)->(%p, %p)\n", iface
, pmkOther
, ppmkRelPath
);
650 *ppmkRelPath
= pmkOther
;
655 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
,
656 IMoniker
*pmkToLeft
, LPOLESTR
*ppszDisplayName
)
658 static const WCHAR swW
[] = {'s','w',':',0};
659 static const WCHAR cmW
[] = {'c','m',':',0};
660 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
663 TRACE("(%p)->(%p, %p, %p)\n", iface
, pbc
, pmkToLeft
, ppszDisplayName
);
665 *ppszDisplayName
= NULL
;
667 buffer
= CoTaskMemAlloc((strlenW(deviceW
) + 4 + (This
->has_class
? CHARS_IN_GUID
: 0)
668 + strlenW(This
->name
) + 1) * sizeof(WCHAR
));
670 return E_OUTOFMEMORY
;
672 strcpyW(buffer
, deviceW
);
673 if (This
->type
== DEVICE_FILTER
)
674 strcatW(buffer
, swW
);
675 else if (This
->type
== DEVICE_CODEC
)
676 strcatW(buffer
, cmW
);
680 StringFromGUID2(&This
->class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
681 strcatW(buffer
, backslashW
);
683 strcatW(buffer
, This
->name
);
685 *ppszDisplayName
= buffer
;
689 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ParseDisplayName(IMoniker
*iface
, IBindCtx
*pbc
,
690 IMoniker
*pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
*pchEaten
, IMoniker
**ppmkOut
)
692 FIXME("(%p)->(%p, %p, %s, %p, %p)\n", iface
, pbc
, pmkToLeft
, debugstr_w(pszDisplayName
), pchEaten
, ppmkOut
);
700 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsSystemMoniker(IMoniker
*iface
, DWORD
*pdwMksys
)
702 TRACE("(%p)->(%p)\n", iface
, pdwMksys
);
707 static const IMonikerVtbl IMoniker_Vtbl
=
709 DEVENUM_IMediaCatMoniker_QueryInterface
,
710 DEVENUM_IMediaCatMoniker_AddRef
,
711 DEVENUM_IMediaCatMoniker_Release
,
712 DEVENUM_IMediaCatMoniker_GetClassID
,
713 DEVENUM_IMediaCatMoniker_IsDirty
,
714 DEVENUM_IMediaCatMoniker_Load
,
715 DEVENUM_IMediaCatMoniker_Save
,
716 DEVENUM_IMediaCatMoniker_GetSizeMax
,
717 DEVENUM_IMediaCatMoniker_BindToObject
,
718 DEVENUM_IMediaCatMoniker_BindToStorage
,
719 DEVENUM_IMediaCatMoniker_Reduce
,
720 DEVENUM_IMediaCatMoniker_ComposeWith
,
721 DEVENUM_IMediaCatMoniker_Enum
,
722 DEVENUM_IMediaCatMoniker_IsEqual
,
723 DEVENUM_IMediaCatMoniker_Hash
,
724 DEVENUM_IMediaCatMoniker_IsRunning
,
725 DEVENUM_IMediaCatMoniker_GetTimeOfLastChange
,
726 DEVENUM_IMediaCatMoniker_Inverse
,
727 DEVENUM_IMediaCatMoniker_CommonPrefixWith
,
728 DEVENUM_IMediaCatMoniker_RelativePathTo
,
729 DEVENUM_IMediaCatMoniker_GetDisplayName
,
730 DEVENUM_IMediaCatMoniker_ParseDisplayName
,
731 DEVENUM_IMediaCatMoniker_IsSystemMoniker
734 MediaCatMoniker
* DEVENUM_IMediaCatMoniker_Construct(void)
736 MediaCatMoniker
* pMoniker
= NULL
;
737 pMoniker
= CoTaskMemAlloc(sizeof(MediaCatMoniker
));
741 pMoniker
->IMoniker_iface
.lpVtbl
= &IMoniker_Vtbl
;
743 pMoniker
->has_class
= FALSE
;
744 pMoniker
->name
= NULL
;
746 DEVENUM_IMediaCatMoniker_AddRef(&pMoniker
->IMoniker_iface
);
748 DEVENUM_LockModule();
753 static inline EnumMonikerImpl
*impl_from_IEnumMoniker(IEnumMoniker
*iface
)
755 return CONTAINING_RECORD(iface
, EnumMonikerImpl
, IEnumMoniker_iface
);
758 static HRESULT WINAPI
DEVENUM_IEnumMoniker_QueryInterface(IEnumMoniker
*iface
, REFIID riid
,
761 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppv
);
766 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
767 IsEqualGUID(riid
, &IID_IEnumMoniker
))
770 IEnumMoniker_AddRef(iface
);
774 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
776 return E_NOINTERFACE
;
779 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(IEnumMoniker
*iface
)
781 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
782 ULONG ref
= InterlockedIncrement(&This
->ref
);
784 TRACE("(%p) ref=%d\n", This
, ref
);
789 static ULONG WINAPI
DEVENUM_IEnumMoniker_Release(IEnumMoniker
*iface
)
791 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
792 ULONG ref
= InterlockedDecrement(&This
->ref
);
794 TRACE("(%p) ref=%d\n", This
, ref
);
798 RegCloseKey(This
->sw_key
);
799 RegCloseKey(This
->cm_key
);
801 DEVENUM_UnlockModule();
807 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Next(IEnumMoniker
*iface
, ULONG celt
, IMoniker
**rgelt
,
810 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
811 WCHAR buffer
[MAX_PATH
+ 1];
814 MediaCatMoniker
* pMoniker
;
817 TRACE("(%p)->(%d, %p, %p)\n", iface
, celt
, rgelt
, pceltFetched
);
819 while (fetched
< celt
)
821 /* FIXME: try PNP devices and DMOs first */
823 /* try DirectShow filters */
824 if (!(res
= RegEnumKeyW(This
->sw_key
, This
->sw_index
, buffer
, sizeof(buffer
)/sizeof(WCHAR
))))
827 if ((res
= RegOpenKeyExW(This
->sw_key
, buffer
, 0, KEY_QUERY_VALUE
, &hkey
)))
830 if (!(pMoniker
= DEVENUM_IMediaCatMoniker_Construct()))
831 return E_OUTOFMEMORY
;
833 pMoniker
->type
= DEVICE_FILTER
;
835 /* then try codecs */
836 else if (!(res
= RegEnumKeyW(This
->cm_key
, This
->cm_index
, buffer
, sizeof(buffer
)/sizeof(WCHAR
))))
840 if ((res
= RegOpenKeyExW(This
->cm_key
, buffer
, 0, KEY_QUERY_VALUE
, &hkey
)))
843 if (!(pMoniker
= DEVENUM_IMediaCatMoniker_Construct()))
844 return E_OUTOFMEMORY
;
846 pMoniker
->type
= DEVICE_CODEC
;
851 if (!(pMoniker
->name
= CoTaskMemAlloc((strlenW(buffer
) + 1) * sizeof(WCHAR
))))
853 IMoniker_Release(&pMoniker
->IMoniker_iface
);
854 return E_OUTOFMEMORY
;
856 strcpyW(pMoniker
->name
, buffer
);
857 pMoniker
->has_class
= TRUE
;
858 pMoniker
->class = This
->class;
860 rgelt
[fetched
] = &pMoniker
->IMoniker_iface
;
864 TRACE("-- fetched %d\n", fetched
);
867 *pceltFetched
= fetched
;
875 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Skip(IEnumMoniker
*iface
, ULONG celt
)
877 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
879 TRACE("(%p)->(%d)\n", iface
, celt
);
883 /* FIXME: try PNP devices and DMOs first */
885 /* try DirectShow filters */
886 if (RegEnumKeyW(This
->sw_key
, This
->sw_index
, NULL
, 0) != ERROR_NO_MORE_ITEMS
)
890 /* then try codecs */
891 else if (RegEnumKeyW(This
->cm_key
, This
->cm_index
, NULL
, 0) != ERROR_NO_MORE_ITEMS
)
902 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Reset(IEnumMoniker
*iface
)
904 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
906 TRACE("(%p)->()\n", iface
);
914 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Clone(IEnumMoniker
*iface
, IEnumMoniker
**ppenum
)
916 FIXME("(%p)->(%p): stub\n", iface
, ppenum
);
921 /**********************************************************************
924 static const IEnumMonikerVtbl IEnumMoniker_Vtbl
=
926 DEVENUM_IEnumMoniker_QueryInterface
,
927 DEVENUM_IEnumMoniker_AddRef
,
928 DEVENUM_IEnumMoniker_Release
,
929 DEVENUM_IEnumMoniker_Next
,
930 DEVENUM_IEnumMoniker_Skip
,
931 DEVENUM_IEnumMoniker_Reset
,
932 DEVENUM_IEnumMoniker_Clone
935 HRESULT
create_EnumMoniker(REFCLSID
class, IEnumMoniker
**ppEnumMoniker
)
937 EnumMonikerImpl
* pEnumMoniker
= CoTaskMemAlloc(sizeof(EnumMonikerImpl
));
941 return E_OUTOFMEMORY
;
943 pEnumMoniker
->IEnumMoniker_iface
.lpVtbl
= &IEnumMoniker_Vtbl
;
944 pEnumMoniker
->ref
= 1;
945 pEnumMoniker
->sw_index
= 0;
946 pEnumMoniker
->cm_index
= 0;
947 pEnumMoniker
->class = *class;
949 strcpyW(buffer
, clsidW
);
950 StringFromGUID2(class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
951 strcatW(buffer
, instanceW
);
952 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, buffer
, 0, KEY_ENUMERATE_SUB_KEYS
, &pEnumMoniker
->sw_key
))
953 pEnumMoniker
->sw_key
= NULL
;
955 strcpyW(buffer
, wszActiveMovieKey
);
956 StringFromGUID2(class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
957 if (RegOpenKeyExW(HKEY_CURRENT_USER
, buffer
, 0, KEY_ENUMERATE_SUB_KEYS
, &pEnumMoniker
->cm_key
))
958 pEnumMoniker
->cm_key
= NULL
;
960 *ppEnumMoniker
= &pEnumMoniker
->IEnumMoniker_iface
;
962 DEVENUM_LockModule();