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"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(devenum
);
36 IEnumMoniker IEnumMoniker_iface
;
48 IPropertyBag IPropertyBag_iface
;
50 enum device_type type
;
53 WCHAR path
[MAX_PATH
]; /* for filters and codecs */
54 CLSID clsid
; /* for DMOs */
59 static inline RegPropBagImpl
*impl_from_IPropertyBag(IPropertyBag
*iface
)
61 return CONTAINING_RECORD(iface
, RegPropBagImpl
, IPropertyBag_iface
);
64 static HRESULT WINAPI
DEVENUM_IPropertyBag_QueryInterface(
69 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
71 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppvObj
);
73 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
75 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
76 IsEqualGUID(riid
, &IID_IPropertyBag
))
79 IPropertyBag_AddRef(iface
);
83 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
87 /**********************************************************************
88 * DEVENUM_IPropertyBag_AddRef (also IUnknown)
90 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
)
92 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
94 TRACE("(%p)->() AddRef from %d\n", iface
, This
->ref
);
96 return InterlockedIncrement(&This
->ref
);
99 /**********************************************************************
100 * DEVENUM_IPropertyBag_Release (also IUnknown)
102 static ULONG WINAPI
DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface
)
104 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
107 TRACE("(%p)->() ReleaseThis->ref from %d\n", iface
, This
->ref
);
109 ref
= InterlockedDecrement(&This
->ref
);
112 DEVENUM_UnlockModule();
117 static HRESULT WINAPI
DEVENUM_IPropertyBag_Read(
119 LPCOLESTR pszPropName
,
121 IErrorLog
* pErrorLog
)
123 static const WCHAR FriendlyNameW
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
127 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
129 LONG reswin32
= ERROR_SUCCESS
;
133 TRACE("(%p)->(%s, %p, %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
135 if (!pszPropName
|| !pVar
)
138 if (This
->type
== DEVICE_DMO
)
140 if (!strcmpW(pszPropName
, FriendlyNameW
))
142 res
= DMOGetName(&This
->clsid
, name
);
145 V_VT(pVar
) = VT_BSTR
;
146 V_BSTR(pVar
) = SysAllocString(name
);
150 return HRESULT_FROM_WIN32(ERROR_NOT_FOUND
);
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
);
161 reswin32
= RegQueryValueExW(hkey
, pszPropName
, NULL
, NULL
, NULL
, &received
);
162 res
= HRESULT_FROM_WIN32(reswin32
);
167 pData
= HeapAlloc(GetProcessHeap(), 0, received
);
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
);
176 res
= E_INVALIDARG
; /* assume we cannot coerce into right type */
178 TRACE("Read %d bytes (%s)\n", received
, type
== REG_SZ
? debugstr_w(pData
) : "binary data");
186 V_BSTR(pVar
) = CoTaskMemAlloc(received
);
187 memcpy(V_BSTR(pVar
), pData
, received
);
191 V_VT(pVar
) = VT_BSTR
;
194 V_BSTR(pVar
) = SysAllocStringLen(pData
, received
/sizeof(WCHAR
) - 1);
200 TRACE("REG_DWORD: %x\n", *(DWORD
*)pData
);
208 V_I4(pVar
) = *(DWORD
*)pData
;
215 SAFEARRAYBOUND bound
;
216 void * pArrayElements
;
218 bound
.cElements
= received
;
219 TRACE("REG_BINARY: len = %d\n", received
);
223 V_VT(pVar
) = VT_ARRAY
| VT_UI1
;
225 case VT_ARRAY
| VT_UI1
:
226 if (!(V_ARRAY(pVar
) = SafeArrayCreate(VT_UI1
, 1, &bound
)))
233 if (res
== E_INVALIDARG
)
236 res
= SafeArrayAccessData(V_ARRAY(pVar
), &pArrayElements
);
240 CopyMemory(pArrayElements
, pData
, received
);
241 res
= SafeArrayUnaccessData(V_ARRAY(pVar
));
245 if (res
== E_INVALIDARG
)
246 FIXME("Variant type %x not supported for regtype %x\n", V_VT(pVar
), type
);
249 HeapFree(GetProcessHeap(), 0, pData
);
253 TRACE("<- %x\n", res
);
257 static HRESULT WINAPI
DEVENUM_IPropertyBag_Write(
259 LPCOLESTR pszPropName
,
262 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
263 LPVOID lpData
= NULL
;
267 LONG lres
= ERROR_SUCCESS
;
270 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(pszPropName
), pVar
);
272 if (This
->type
== DEVICE_DMO
)
273 return E_ACCESSDENIED
;
279 TRACE("writing %s\n", debugstr_w(V_BSTR(pVar
)));
280 lpData
= V_BSTR(pVar
);
282 cbData
= (lstrlenW(V_BSTR(pVar
)) + 1) * sizeof(WCHAR
);
286 TRACE("writing %u\n", V_UI4(pVar
));
287 lpData
= &V_UI4(pVar
);
289 cbData
= sizeof(DWORD
);
291 case VT_ARRAY
| VT_UI1
:
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
);
304 FIXME("Variant type %d not handled\n", V_VT(pVar
));
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
);
316 lres
= RegSetValueExW(hkey
, pszPropName
, 0, dwType
, lpData
, cbData
);
317 res
= HRESULT_FROM_WIN32(lres
);
321 if (V_VT(pVar
) & VT_ARRAY
)
322 res
= SafeArrayUnaccessData(V_ARRAY(pVar
));
327 static const IPropertyBagVtbl IPropertyBag_Vtbl
=
329 DEVENUM_IPropertyBag_QueryInterface
,
330 DEVENUM_IPropertyBag_AddRef
,
331 DEVENUM_IPropertyBag_Release
,
332 DEVENUM_IPropertyBag_Read
,
333 DEVENUM_IPropertyBag_Write
336 static HRESULT
create_PropertyBag(MediaCatMoniker
*mon
, IPropertyBag
**ppBag
)
338 RegPropBagImpl
* rpb
= CoTaskMemAlloc(sizeof(RegPropBagImpl
));
340 return E_OUTOFMEMORY
;
341 rpb
->IPropertyBag_iface
.lpVtbl
= &IPropertyBag_Vtbl
;
343 rpb
->type
= mon
->type
;
345 if (rpb
->type
== DEVICE_DMO
)
346 rpb
->clsid
= mon
->clsid
;
347 else if (rpb
->type
== DEVICE_FILTER
)
349 strcpyW(rpb
->path
, clsidW
);
350 strcatW(rpb
->path
, backslashW
);
353 StringFromGUID2(&mon
->class, rpb
->path
+ strlenW(rpb
->path
), CHARS_IN_GUID
);
354 strcatW(rpb
->path
, instanceW
);
355 strcatW(rpb
->path
, backslashW
);
357 strcatW(rpb
->path
, mon
->name
);
359 else if (rpb
->type
== DEVICE_CODEC
)
361 strcpyW(rpb
->path
, wszActiveMovieKey
);
364 StringFromGUID2(&mon
->class, rpb
->path
+ strlenW(rpb
->path
), CHARS_IN_GUID
);
365 strcatW(rpb
->path
, backslashW
);
367 strcatW(rpb
->path
, mon
->name
);
370 *ppBag
= &rpb
->IPropertyBag_iface
;
371 DEVENUM_LockModule();
376 static inline MediaCatMoniker
*impl_from_IMoniker(IMoniker
*iface
)
378 return CONTAINING_RECORD(iface
, MediaCatMoniker
, IMoniker_iface
);
381 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_QueryInterface(IMoniker
*iface
, REFIID riid
,
384 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
389 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
390 IsEqualGUID(riid
, &IID_IPersist
) ||
391 IsEqualGUID(riid
, &IID_IPersistStream
) ||
392 IsEqualGUID(riid
, &IID_IMoniker
))
395 IMoniker_AddRef(iface
);
399 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
401 return E_NOINTERFACE
;
404 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(IMoniker
*iface
)
406 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
407 ULONG ref
= InterlockedIncrement(&This
->ref
);
409 TRACE("(%p) ref=%d\n", This
, ref
);
414 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_Release(IMoniker
*iface
)
416 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
417 ULONG ref
= InterlockedDecrement(&This
->ref
);
419 TRACE("(%p) ref=%d\n", This
, ref
);
422 CoTaskMemFree(This
->name
);
424 DEVENUM_UnlockModule();
429 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetClassID(IMoniker
*iface
, CLSID
*pClassID
)
431 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
433 TRACE("(%p)->(%p)\n", This
, pClassID
);
435 if (pClassID
== NULL
)
438 *pClassID
= CLSID_CDeviceMoniker
;
443 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsDirty(IMoniker
*iface
)
445 FIXME("(%p)->(): stub\n", iface
);
450 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Load(IMoniker
*iface
, IStream
*pStm
)
452 FIXME("(%p)->(%p): stub\n", iface
, pStm
);
457 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Save(IMoniker
*iface
, IStream
*pStm
, BOOL fClearDirty
)
459 FIXME("(%p)->(%p, %s): stub\n", iface
, pStm
, fClearDirty
? "true" : "false");
461 return STG_E_CANTSAVE
;
464 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetSizeMax(IMoniker
*iface
, ULARGE_INTEGER
*pcbSize
)
466 FIXME("(%p)->(%p): stub\n", iface
, pcbSize
);
468 ZeroMemory(pcbSize
, sizeof(*pcbSize
));
473 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToObject(IMoniker
*iface
, IBindCtx
*pbc
,
474 IMoniker
*pmkToLeft
, REFIID riidResult
, void **ppvResult
)
476 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
477 IUnknown
* pObj
= NULL
;
478 IPropertyBag
* pProp
= NULL
;
481 HRESULT res
= E_FAIL
;
483 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riidResult
), ppvResult
);
493 /* first activation of this class */
495 res
=IMoniker_BindToStorage(iface
, NULL
, NULL
, &IID_IPropertyBag
, &pvptr
);
499 V_VT(&var
) = VT_LPWSTR
;
500 res
= IPropertyBag_Read(pProp
, clsidW
, &var
, NULL
);
504 res
= CLSIDFromString(V_BSTR(&var
), &clsID
);
505 CoTaskMemFree(V_BSTR(&var
));
509 res
=CoCreateInstance(&clsID
,NULL
,CLSCTX_ALL
,&IID_IUnknown
,&pvptr
);
516 /* get the requested interface from the loaded class */
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
);
528 res
= IUnknown_QueryInterface(pObj
,riidResult
,ppvResult
);
529 IUnknown_Release(pObj
);
534 IPropertyBag_Release(pProp
);
537 TRACE("<- 0x%x\n", res
);
542 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToStorage(IMoniker
*iface
, IBindCtx
*pbc
,
543 IMoniker
*pmkToLeft
, REFIID riid
, void **ppvObj
)
545 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
547 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riid
), ppvObj
);
552 return MK_E_NOSTORAGE
;
556 static DWORD reported
;
559 FIXME("ignoring IBindCtx %p\n", pbc
);
564 if (IsEqualGUID(riid
, &IID_IPropertyBag
))
566 return create_PropertyBag(This
, (IPropertyBag
**)ppvObj
);
569 return MK_E_NOSTORAGE
;
572 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Reduce(IMoniker
*iface
, IBindCtx
*pbc
,
573 DWORD dwReduceHowFar
, IMoniker
**ppmkToLeft
, IMoniker
**ppmkReduced
)
575 TRACE("(%p)->(%p, %d, %p, %p)\n", iface
, pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
579 *ppmkReduced
= iface
;
581 return MK_S_REDUCED_TO_SELF
;
584 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ComposeWith(IMoniker
*iface
, IMoniker
*pmkRight
,
585 BOOL fOnlyIfNotGeneric
, IMoniker
**ppmkComposite
)
587 FIXME("(%p)->(%p, %s, %p): stub\n", iface
, pmkRight
, fOnlyIfNotGeneric
? "true" : "false", ppmkComposite
);
589 /* FIXME: use CreateGenericComposite? */
590 *ppmkComposite
= NULL
;
595 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Enum(IMoniker
*iface
, BOOL fForward
,
596 IEnumMoniker
**ppenumMoniker
)
598 FIXME("(%p)->(%s, %p): stub\n", iface
, fForward
? "true" : "false", ppenumMoniker
);
600 *ppenumMoniker
= NULL
;
605 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsEqual(IMoniker
*iface
, IMoniker
*pmkOtherMoniker
)
608 LPOLESTR this_name
, other_name
;
612 TRACE("(%p)->(%p)\n", iface
, pmkOtherMoniker
);
614 if (!pmkOtherMoniker
)
617 IMoniker_GetClassID(pmkOtherMoniker
, &clsid
);
618 if (!IsEqualCLSID(&clsid
, &CLSID_CDeviceMoniker
))
621 res
= CreateBindCtx(0, &bind
);
626 if (SUCCEEDED(IMoniker_GetDisplayName(iface
, bind
, NULL
, &this_name
)) &&
627 SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker
, bind
, NULL
, &other_name
)))
629 int result
= lstrcmpiW(this_name
, other_name
);
630 CoTaskMemFree(this_name
);
631 CoTaskMemFree(other_name
);
635 IBindCtx_Release(bind
);
639 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Hash(IMoniker
*iface
, DWORD
*pdwHash
)
641 TRACE("(%p)->(%p)\n", iface
, pdwHash
);
648 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsRunning(IMoniker
*iface
, IBindCtx
*pbc
,
649 IMoniker
*pmkToLeft
, IMoniker
*pmkNewlyRunning
)
651 FIXME("(%p)->(%p, %p, %p): stub\n", iface
, pbc
, pmkToLeft
, pmkNewlyRunning
);
656 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetTimeOfLastChange(IMoniker
*iface
, IBindCtx
*pbc
,
657 IMoniker
*pmkToLeft
, FILETIME
*pFileTime
)
659 TRACE("(%p)->(%p, %p, %p)\n", iface
, pbc
, pmkToLeft
, pFileTime
);
661 pFileTime
->dwLowDateTime
= 0xFFFFFFFF;
662 pFileTime
->dwHighDateTime
= 0x7FFFFFFF;
664 return MK_E_UNAVAILABLE
;
667 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Inverse(IMoniker
*iface
, IMoniker
**ppmk
)
669 TRACE("(%p)->(%p)\n", iface
, ppmk
);
673 return MK_E_NOINVERSE
;
676 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_CommonPrefixWith(IMoniker
*iface
,
677 IMoniker
*pmkOtherMoniker
, IMoniker
**ppmkPrefix
)
679 TRACE("(%p)->(%p, %p)\n", iface
, pmkOtherMoniker
, ppmkPrefix
);
683 return MK_E_NOPREFIX
;
686 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker
*iface
, IMoniker
*pmkOther
,
687 IMoniker
**ppmkRelPath
)
689 TRACE("(%p)->(%p, %p)\n", iface
, pmkOther
, ppmkRelPath
);
691 *ppmkRelPath
= pmkOther
;
696 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker
*iface
, IBindCtx
*pbc
,
697 IMoniker
*pmkToLeft
, LPOLESTR
*ppszDisplayName
)
699 MediaCatMoniker
*This
= impl_from_IMoniker(iface
);
702 TRACE("(%p)->(%p, %p, %p)\n", iface
, pbc
, pmkToLeft
, ppszDisplayName
);
704 *ppszDisplayName
= NULL
;
706 if (This
->type
== DEVICE_DMO
)
708 buffer
= CoTaskMemAlloc((strlenW(deviceW
) + strlenW(dmoW
)
709 + 2 * CHARS_IN_GUID
+ 1) * sizeof(WCHAR
));
710 if (!buffer
) return E_OUTOFMEMORY
;
712 strcpyW(buffer
, deviceW
);
713 strcatW(buffer
, dmoW
);
714 StringFromGUID2(&This
->clsid
, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
715 StringFromGUID2(&This
->class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
719 buffer
= CoTaskMemAlloc((strlenW(deviceW
) + 3 + (This
->has_class
? CHARS_IN_GUID
: 0)
720 + strlenW(This
->name
) + 1) * sizeof(WCHAR
));
721 if (!buffer
) return E_OUTOFMEMORY
;
723 strcpyW(buffer
, deviceW
);
724 if (This
->type
== DEVICE_FILTER
)
725 strcatW(buffer
, swW
);
726 else if (This
->type
== DEVICE_CODEC
)
727 strcatW(buffer
, cmW
);
731 StringFromGUID2(&This
->class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
732 strcatW(buffer
, backslashW
);
734 strcatW(buffer
, This
->name
);
737 *ppszDisplayName
= buffer
;
741 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ParseDisplayName(IMoniker
*iface
, IBindCtx
*pbc
,
742 IMoniker
*pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
*pchEaten
, IMoniker
**ppmkOut
)
744 FIXME("(%p)->(%p, %p, %s, %p, %p)\n", iface
, pbc
, pmkToLeft
, debugstr_w(pszDisplayName
), pchEaten
, ppmkOut
);
752 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsSystemMoniker(IMoniker
*iface
, DWORD
*pdwMksys
)
754 TRACE("(%p)->(%p)\n", iface
, pdwMksys
);
759 static const IMonikerVtbl IMoniker_Vtbl
=
761 DEVENUM_IMediaCatMoniker_QueryInterface
,
762 DEVENUM_IMediaCatMoniker_AddRef
,
763 DEVENUM_IMediaCatMoniker_Release
,
764 DEVENUM_IMediaCatMoniker_GetClassID
,
765 DEVENUM_IMediaCatMoniker_IsDirty
,
766 DEVENUM_IMediaCatMoniker_Load
,
767 DEVENUM_IMediaCatMoniker_Save
,
768 DEVENUM_IMediaCatMoniker_GetSizeMax
,
769 DEVENUM_IMediaCatMoniker_BindToObject
,
770 DEVENUM_IMediaCatMoniker_BindToStorage
,
771 DEVENUM_IMediaCatMoniker_Reduce
,
772 DEVENUM_IMediaCatMoniker_ComposeWith
,
773 DEVENUM_IMediaCatMoniker_Enum
,
774 DEVENUM_IMediaCatMoniker_IsEqual
,
775 DEVENUM_IMediaCatMoniker_Hash
,
776 DEVENUM_IMediaCatMoniker_IsRunning
,
777 DEVENUM_IMediaCatMoniker_GetTimeOfLastChange
,
778 DEVENUM_IMediaCatMoniker_Inverse
,
779 DEVENUM_IMediaCatMoniker_CommonPrefixWith
,
780 DEVENUM_IMediaCatMoniker_RelativePathTo
,
781 DEVENUM_IMediaCatMoniker_GetDisplayName
,
782 DEVENUM_IMediaCatMoniker_ParseDisplayName
,
783 DEVENUM_IMediaCatMoniker_IsSystemMoniker
786 MediaCatMoniker
* DEVENUM_IMediaCatMoniker_Construct(void)
788 MediaCatMoniker
* pMoniker
= NULL
;
789 pMoniker
= CoTaskMemAlloc(sizeof(MediaCatMoniker
));
793 pMoniker
->IMoniker_iface
.lpVtbl
= &IMoniker_Vtbl
;
795 pMoniker
->has_class
= FALSE
;
796 pMoniker
->name
= NULL
;
798 DEVENUM_IMediaCatMoniker_AddRef(&pMoniker
->IMoniker_iface
);
800 DEVENUM_LockModule();
805 static inline EnumMonikerImpl
*impl_from_IEnumMoniker(IEnumMoniker
*iface
)
807 return CONTAINING_RECORD(iface
, EnumMonikerImpl
, IEnumMoniker_iface
);
810 static HRESULT WINAPI
DEVENUM_IEnumMoniker_QueryInterface(IEnumMoniker
*iface
, REFIID riid
,
813 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppv
);
818 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
819 IsEqualGUID(riid
, &IID_IEnumMoniker
))
822 IEnumMoniker_AddRef(iface
);
826 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
828 return E_NOINTERFACE
;
831 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(IEnumMoniker
*iface
)
833 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
834 ULONG ref
= InterlockedIncrement(&This
->ref
);
836 TRACE("(%p) ref=%d\n", This
, ref
);
841 static ULONG WINAPI
DEVENUM_IEnumMoniker_Release(IEnumMoniker
*iface
)
843 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
844 ULONG ref
= InterlockedDecrement(&This
->ref
);
846 TRACE("(%p) ref=%d\n", This
, ref
);
850 IEnumDMO_Release(This
->dmo_enum
);
851 RegCloseKey(This
->sw_key
);
852 RegCloseKey(This
->cm_key
);
854 DEVENUM_UnlockModule();
860 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Next(IEnumMoniker
*iface
, ULONG celt
, IMoniker
**rgelt
,
863 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
864 WCHAR buffer
[MAX_PATH
+ 1];
867 MediaCatMoniker
* pMoniker
;
873 TRACE("(%p)->(%d, %p, %p)\n", iface
, celt
, rgelt
, pceltFetched
);
875 while (fetched
< celt
)
877 /* FIXME: try PNP devices first */
880 if ((hr
= IEnumDMO_Next(This
->dmo_enum
, 1, &clsid
, &name
, NULL
)) == S_OK
)
882 if (!(pMoniker
= DEVENUM_IMediaCatMoniker_Construct()))
883 return E_OUTOFMEMORY
;
885 pMoniker
->type
= DEVICE_DMO
;
886 pMoniker
->clsid
= clsid
;
888 StringFromGUID2(&clsid
, buffer
, CHARS_IN_GUID
);
889 StringFromGUID2(&This
->class, buffer
+ CHARS_IN_GUID
- 1, CHARS_IN_GUID
);
891 /* try DirectShow filters */
892 else if (!(res
= RegEnumKeyW(This
->sw_key
, This
->sw_index
, buffer
, ARRAY_SIZE(buffer
))))
895 if ((res
= RegOpenKeyExW(This
->sw_key
, buffer
, 0, KEY_QUERY_VALUE
, &hkey
)))
898 if (!(pMoniker
= DEVENUM_IMediaCatMoniker_Construct()))
899 return E_OUTOFMEMORY
;
901 pMoniker
->type
= DEVICE_FILTER
;
903 if (!(pMoniker
->name
= CoTaskMemAlloc((strlenW(buffer
) + 1) * sizeof(WCHAR
))))
905 IMoniker_Release(&pMoniker
->IMoniker_iface
);
906 return E_OUTOFMEMORY
;
908 strcpyW(pMoniker
->name
, buffer
);
910 /* then try codecs */
911 else if (!(res
= RegEnumKeyW(This
->cm_key
, This
->cm_index
, buffer
, ARRAY_SIZE(buffer
))))
915 if ((res
= RegOpenKeyExW(This
->cm_key
, buffer
, 0, KEY_QUERY_VALUE
, &hkey
)))
918 if (!(pMoniker
= DEVENUM_IMediaCatMoniker_Construct()))
919 return E_OUTOFMEMORY
;
921 pMoniker
->type
= DEVICE_CODEC
;
923 if (!(pMoniker
->name
= CoTaskMemAlloc((strlenW(buffer
) + 1) * sizeof(WCHAR
))))
925 IMoniker_Release(&pMoniker
->IMoniker_iface
);
926 return E_OUTOFMEMORY
;
928 strcpyW(pMoniker
->name
, buffer
);
933 pMoniker
->has_class
= TRUE
;
934 pMoniker
->class = This
->class;
936 rgelt
[fetched
] = &pMoniker
->IMoniker_iface
;
940 TRACE("-- fetched %d\n", fetched
);
943 *pceltFetched
= fetched
;
951 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Skip(IEnumMoniker
*iface
, ULONG celt
)
953 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
955 TRACE("(%p)->(%d)\n", iface
, celt
);
959 /* FIXME: try PNP devices first */
962 if (IEnumDMO_Skip(This
->dmo_enum
, 1) == S_OK
)
964 /* try DirectShow filters */
965 else if (RegEnumKeyW(This
->sw_key
, This
->sw_index
, NULL
, 0) != ERROR_NO_MORE_ITEMS
)
969 /* then try codecs */
970 else if (RegEnumKeyW(This
->cm_key
, This
->cm_index
, NULL
, 0) != ERROR_NO_MORE_ITEMS
)
981 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Reset(IEnumMoniker
*iface
)
983 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
985 TRACE("(%p)->()\n", iface
);
987 IEnumDMO_Reset(This
->dmo_enum
);
994 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Clone(IEnumMoniker
*iface
, IEnumMoniker
**ppenum
)
996 FIXME("(%p)->(%p): stub\n", iface
, ppenum
);
1001 /**********************************************************************
1004 static const IEnumMonikerVtbl IEnumMoniker_Vtbl
=
1006 DEVENUM_IEnumMoniker_QueryInterface
,
1007 DEVENUM_IEnumMoniker_AddRef
,
1008 DEVENUM_IEnumMoniker_Release
,
1009 DEVENUM_IEnumMoniker_Next
,
1010 DEVENUM_IEnumMoniker_Skip
,
1011 DEVENUM_IEnumMoniker_Reset
,
1012 DEVENUM_IEnumMoniker_Clone
1015 HRESULT
create_EnumMoniker(REFCLSID
class, IEnumMoniker
**ppEnumMoniker
)
1017 EnumMonikerImpl
* pEnumMoniker
= CoTaskMemAlloc(sizeof(EnumMonikerImpl
));
1022 return E_OUTOFMEMORY
;
1024 pEnumMoniker
->IEnumMoniker_iface
.lpVtbl
= &IEnumMoniker_Vtbl
;
1025 pEnumMoniker
->ref
= 1;
1026 pEnumMoniker
->sw_index
= 0;
1027 pEnumMoniker
->cm_index
= 0;
1028 pEnumMoniker
->class = *class;
1030 strcpyW(buffer
, clsidW
);
1031 strcatW(buffer
, backslashW
);
1032 StringFromGUID2(class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
1033 strcatW(buffer
, instanceW
);
1034 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, buffer
, 0, KEY_ENUMERATE_SUB_KEYS
, &pEnumMoniker
->sw_key
))
1035 pEnumMoniker
->sw_key
= NULL
;
1037 strcpyW(buffer
, wszActiveMovieKey
);
1038 StringFromGUID2(class, buffer
+ strlenW(buffer
), CHARS_IN_GUID
);
1039 if (RegOpenKeyExW(HKEY_CURRENT_USER
, buffer
, 0, KEY_ENUMERATE_SUB_KEYS
, &pEnumMoniker
->cm_key
))
1040 pEnumMoniker
->cm_key
= NULL
;
1042 hr
= DMOEnum(class, 0, 0, NULL
, 0, NULL
, &pEnumMoniker
->dmo_enum
);
1045 IEnumMoniker_Release(&pEnumMoniker
->IEnumMoniker_iface
);
1049 *ppEnumMoniker
= &pEnumMoniker
->IEnumMoniker_iface
;
1051 DEVENUM_LockModule();