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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
32 /* #define ICOM_THIS_From_IROTData(class, name) class* This = (class*)(((char*)name)-sizeof(void*)) */
34 WINE_DEFAULT_DEBUG_CHANNEL(devenum
);
36 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface
);
37 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface
);
38 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
);
42 IPropertyBagVtbl
*lpVtbl
;
48 static HRESULT WINAPI
DEVENUM_IPropertyBag_QueryInterface(
53 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
54 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
56 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
58 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
59 IsEqualGUID(riid
, &IID_IPropertyBag
))
61 *ppvObj
= (LPVOID
)iface
;
62 DEVENUM_IPropertyBag_AddRef(iface
);
66 FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid
));
70 /**********************************************************************
71 * DEVENUM_IPropertyBag_AddRef (also IUnknown)
73 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
)
75 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
78 return InterlockedIncrement(&This
->ref
);
81 /**********************************************************************
82 * DEVENUM_IPropertyBag_Release (also IUnknown)
84 static ULONG WINAPI
DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface
)
86 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
91 ref
= InterlockedDecrement(&This
->ref
);
93 RegCloseKey(This
->hkey
);
95 DEVENUM_UnlockModule();
100 static HRESULT WINAPI
DEVENUM_IPropertyBag_Read(
102 LPCOLESTR pszPropName
,
104 IErrorLog
* pErrorLog
)
109 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
113 TRACE("(%p)->(%s, %p, %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
115 if (!pszPropName
|| !pVar
)
118 reswin32
= RegQueryValueExW(This
->hkey
, pszPropName
, NULL
, NULL
, NULL
, &received
);
119 res
= HRESULT_FROM_WIN32(reswin32
);
123 pData
= HeapAlloc(GetProcessHeap(), 0, received
);
125 /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
126 reswin32
= RegQueryValueExW(This
->hkey
, pszPropName
, NULL
, &type
, pData
, &received
);
127 res
= HRESULT_FROM_WIN32(reswin32
);
132 res
= E_INVALIDARG
; /* assume we cannot coerce into right type */
134 TRACE("Read %ld bytes (%s)\n", received
, type
== REG_SZ
? debugstr_w((LPWSTR
)pData
) : "binary data");
142 V_UNION(pVar
, bstrVal
) = CoTaskMemAlloc(received
);
143 memcpy(V_UNION(pVar
, bstrVal
), (LPWSTR
)pData
, received
);
147 V_VT(pVar
) = VT_BSTR
;
150 V_UNION(pVar
, bstrVal
) = SysAllocStringLen((LPWSTR
)pData
, received
/sizeof(WCHAR
) - 1);
156 TRACE("REG_DWORD: %lx\n", *(DWORD
*)pData
);
164 V_UNION(pVar
, ulVal
) = *(DWORD
*)pData
;
171 SAFEARRAYBOUND bound
;
172 void * pArrayElements
;
174 bound
.cElements
= received
;
175 TRACE("REG_BINARY: len = %ld\n", received
);
179 case VT_ARRAY
| VT_UI1
:
180 if (!(V_UNION(pVar
, parray
) = SafeArrayCreate(VT_UI1
, 1, &bound
)))
186 if (res
== E_INVALIDARG
)
189 res
= SafeArrayAccessData(V_UNION(pVar
, parray
), &pArrayElements
);
193 CopyMemory(pArrayElements
, pData
, received
);
194 res
= SafeArrayUnaccessData(V_UNION(pVar
, parray
));
198 if (res
== E_INVALIDARG
)
199 FIXME("Variant type %x not supported for regtype %lx\n", V_VT(pVar
), type
);
202 HeapFree(GetProcessHeap(), 0, pData
);
204 TRACE("<- %lx\n", res
);
208 static HRESULT WINAPI
DEVENUM_IPropertyBag_Write(
210 LPCOLESTR pszPropName
,
213 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
214 LPVOID lpData
= NULL
;
219 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(pszPropName
), pVar
);
224 TRACE("writing %s\n", debugstr_w(V_UNION(pVar
, bstrVal
)));
225 lpData
= (LPVOID
)V_UNION(pVar
, bstrVal
);
227 cbData
= (lstrlenW(V_UNION(pVar
, bstrVal
)) + 1) * sizeof(WCHAR
);
231 TRACE("writing %lu\n", V_UNION(pVar
, ulVal
));
232 lpData
= (LPVOID
)&V_UNION(pVar
, ulVal
);
234 cbData
= sizeof(DWORD
);
236 case VT_ARRAY
| VT_UI1
:
241 res
= SafeArrayGetLBound(V_UNION(pVar
, parray
), 1, &lLbound
);
242 res
= SafeArrayGetUBound(V_UNION(pVar
, parray
), 1, &lUbound
);
243 cbData
= (lUbound
- lLbound
+ 1) /* * sizeof(BYTE)*/;
244 TRACE("cbData: %ld\n", cbData
);
245 res
= SafeArrayAccessData(V_UNION(pVar
, parray
), &lpData
);
249 FIXME("Variant type %d not handled\n", V_VT(pVar
));
253 if (RegSetValueExW(This
->hkey
,
255 dwType
, lpData
, cbData
) != ERROR_SUCCESS
)
258 if (V_VT(pVar
) & VT_ARRAY
)
259 res
= SafeArrayUnaccessData(V_UNION(pVar
, parray
));
264 static IPropertyBagVtbl IPropertyBag_Vtbl
=
266 DEVENUM_IPropertyBag_QueryInterface
,
267 DEVENUM_IPropertyBag_AddRef
,
268 DEVENUM_IPropertyBag_Release
,
269 DEVENUM_IPropertyBag_Read
,
270 DEVENUM_IPropertyBag_Write
273 static HRESULT
DEVENUM_IPropertyBag_Construct(HANDLE hkey
, IPropertyBag
**ppBag
)
275 RegPropBagImpl
* rpb
= CoTaskMemAlloc(sizeof(RegPropBagImpl
));
277 return E_OUTOFMEMORY
;
278 rpb
->lpVtbl
= &IPropertyBag_Vtbl
;
281 *ppBag
= (IPropertyBag
*)rpb
;
282 DEVENUM_LockModule();
287 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_QueryInterface(
292 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
293 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
295 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
299 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
300 IsEqualGUID(riid
, &IID_IPersist
) ||
301 IsEqualGUID(riid
, &IID_IPersistStream
) ||
302 IsEqualGUID(riid
, &IID_IMoniker
))
304 *ppvObj
= (LPVOID
)iface
;
305 DEVENUM_IMediaCatMoniker_AddRef(iface
);
309 FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid
));
310 return E_NOINTERFACE
;
313 /**********************************************************************
314 * DEVENUM_IMediaCatMoniker_AddRef (also IUnknown)
316 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface
)
318 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
321 return InterlockedIncrement(&This
->ref
);
324 /**********************************************************************
325 * DEVENUM_IMediaCatMoniker_Release (also IUnknown)
327 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_Release(LPMONIKER iface
)
329 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
333 ref
= InterlockedDecrement(&This
->ref
);
335 RegCloseKey(This
->hkey
);
337 DEVENUM_UnlockModule();
342 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetClassID(
346 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
347 FIXME("(%p)->(%p)\n", This
, pClassID
);
349 if (pClassID
== NULL
)
355 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsDirty(LPMONIKER iface
)
362 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Load(LPMONIKER iface
, IStream
* pStm
)
364 FIXME("(%p)\n", pStm
);
369 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Save(LPMONIKER iface
, IStream
* pStm
, BOOL fClearDirty
)
371 FIXME("(%p, %s)\n", pStm
, fClearDirty
? "true" : "false");
373 return STG_E_CANTSAVE
;
376 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetSizeMax(
378 ULARGE_INTEGER
* pcbSize
)
380 FIXME("(%p)\n", pcbSize
);
382 ZeroMemory(pcbSize
, sizeof(*pcbSize
));
387 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToObject(
394 IUnknown
* pObj
= NULL
;
395 IPropertyBag
* pProp
= NULL
;
398 HRESULT res
= E_FAIL
;
400 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
404 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riidResult
), ppvResult
);
410 /* first activation of this class */
412 res
=IMoniker_BindToStorage(iface
, NULL
, NULL
, &IID_IPropertyBag
, &pvptr
);
413 pProp
= (IPropertyBag
*)pvptr
;
416 V_VT(&var
) = VT_LPWSTR
;
417 res
= IPropertyBag_Read(pProp
, clsid_keyname
, &var
, NULL
);
421 res
= CLSIDFromString(V_UNION(&var
,bstrVal
), &clsID
);
422 CoTaskMemFree(V_UNION(&var
, bstrVal
));
426 res
=CoCreateInstance(&clsID
,NULL
,CLSCTX_ALL
,&IID_IUnknown
,&pvptr
);
427 pObj
= (IUnknown
*)pvptr
;
433 /* get the requested interface from the loaded class */
434 res
= IUnknown_QueryInterface(pObj
,riidResult
,ppvResult
);
435 IUnknown_Release(pObj
);
440 IPropertyBag_Release(pProp
);
443 TRACE("<- 0x%lx\n", res
);
448 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToStorage(
455 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
456 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riid
), ppvObj
);
460 if (pbc
|| pmkToLeft
)
461 return MK_E_NOSTORAGE
;
463 if (IsEqualGUID(riid
, &IID_IPropertyBag
))
466 DuplicateHandle(GetCurrentProcess(), This
->hkey
, GetCurrentProcess(), &hkey
, 0, 0, DUPLICATE_SAME_ACCESS
);
467 return DEVENUM_IPropertyBag_Construct(hkey
, (IPropertyBag
**)ppvObj
);
470 return MK_E_NOSTORAGE
;
473 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Reduce(
476 DWORD dwReduceHowFar
,
477 IMoniker
** ppmkToLeft
,
478 IMoniker
** ppmkReduced
)
480 TRACE("(%p, %ld, %p, %p)\n", pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
484 *ppmkReduced
= iface
;
486 return MK_S_REDUCED_TO_SELF
;
489 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ComposeWith(
492 BOOL fOnlyIfNotGeneric
,
493 IMoniker
** ppmkComposite
)
495 FIXME("(%p, %s, %p): stub\n", pmkRight
, fOnlyIfNotGeneric
? "true" : "false", ppmkComposite
);
497 /* FIXME: use CreateGenericComposite? */
498 *ppmkComposite
= NULL
;
503 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Enum(
506 IEnumMoniker
** ppenumMoniker
)
508 FIXME("(%s, %p): stub\n", fForward
? "true" : "false", ppenumMoniker
);
510 *ppenumMoniker
= NULL
;
515 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsEqual(
517 IMoniker
* pmkOtherMoniker
)
519 FIXME("(%p)\n", pmkOtherMoniker
);
524 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Hash(
528 TRACE("(%p)\n", pdwHash
);
535 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsRunning(
539 IMoniker
* pmkNewlyRunning
)
541 FIXME("(%p, %p, %p)\n", pbc
, pmkToLeft
, pmkNewlyRunning
);
546 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetTimeOfLastChange(
552 TRACE("(%p, %p, %p)\n", pbc
, pmkToLeft
, pFileTime
);
554 pFileTime
->dwLowDateTime
= 0xFFFFFFFF;
555 pFileTime
->dwHighDateTime
= 0x7FFFFFFF;
557 return MK_E_UNAVAILABLE
;
560 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Inverse(
564 TRACE("(%p)\n", ppmk
);
568 return MK_E_NOINVERSE
;
571 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_CommonPrefixWith(
573 IMoniker
* pmkOtherMoniker
,
574 IMoniker
** ppmkPrefix
)
576 TRACE("(%p, %p)\n", pmkOtherMoniker
, ppmkPrefix
);
580 return MK_E_NOPREFIX
;
583 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_RelativePathTo(
586 IMoniker
** ppmkRelPath
)
588 TRACE("(%p, %p)\n", pmkOther
, ppmkRelPath
);
590 *ppmkRelPath
= pmkOther
;
595 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetDisplayName(
599 LPOLESTR
* ppszDisplayName
)
601 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
602 WCHAR wszBuffer
[MAX_PATH
];
603 static const WCHAR wszFriendlyName
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
604 LONG received
= sizeof(wszFriendlyName
);
606 TRACE("(%p, %p, %p)\n", pbc
, pmkToLeft
, ppszDisplayName
);
608 *ppszDisplayName
= NULL
;
610 /* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */
611 if (RegQueryValueW(This
->hkey
, wszFriendlyName
, wszBuffer
, &received
) == ERROR_SUCCESS
)
613 *ppszDisplayName
= CoTaskMemAlloc(received
);
614 strcpyW(*ppszDisplayName
, wszBuffer
);
621 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ParseDisplayName(
625 LPOLESTR pszDisplayName
,
629 FIXME("(%p, %p, %s, %p, %p)\n", pbc
, pmkToLeft
, debugstr_w(pszDisplayName
), pchEaten
, ppmkOut
);
637 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsSystemMoniker(
641 TRACE("(%p)\n", pdwMksys
);
646 static IMonikerVtbl IMoniker_Vtbl
=
648 DEVENUM_IMediaCatMoniker_QueryInterface
,
649 DEVENUM_IMediaCatMoniker_AddRef
,
650 DEVENUM_IMediaCatMoniker_Release
,
651 DEVENUM_IMediaCatMoniker_GetClassID
,
652 DEVENUM_IMediaCatMoniker_IsDirty
,
653 DEVENUM_IMediaCatMoniker_Load
,
654 DEVENUM_IMediaCatMoniker_Save
,
655 DEVENUM_IMediaCatMoniker_GetSizeMax
,
656 DEVENUM_IMediaCatMoniker_BindToObject
,
657 DEVENUM_IMediaCatMoniker_BindToStorage
,
658 DEVENUM_IMediaCatMoniker_Reduce
,
659 DEVENUM_IMediaCatMoniker_ComposeWith
,
660 DEVENUM_IMediaCatMoniker_Enum
,
661 DEVENUM_IMediaCatMoniker_IsEqual
,
662 DEVENUM_IMediaCatMoniker_Hash
,
663 DEVENUM_IMediaCatMoniker_IsRunning
,
664 DEVENUM_IMediaCatMoniker_GetTimeOfLastChange
,
665 DEVENUM_IMediaCatMoniker_Inverse
,
666 DEVENUM_IMediaCatMoniker_CommonPrefixWith
,
667 DEVENUM_IMediaCatMoniker_RelativePathTo
,
668 DEVENUM_IMediaCatMoniker_GetDisplayName
,
669 DEVENUM_IMediaCatMoniker_ParseDisplayName
,
670 DEVENUM_IMediaCatMoniker_IsSystemMoniker
673 MediaCatMoniker
* DEVENUM_IMediaCatMoniker_Construct()
675 MediaCatMoniker
* pMoniker
= NULL
;
676 pMoniker
= CoTaskMemAlloc(sizeof(MediaCatMoniker
));
680 pMoniker
->lpVtbl
= &IMoniker_Vtbl
;
682 pMoniker
->hkey
= NULL
;
684 DEVENUM_IMediaCatMoniker_AddRef((LPMONIKER
)pMoniker
);
686 DEVENUM_LockModule();
691 /**********************************************************************
692 * DEVENUM_IEnumMoniker_QueryInterface (also IUnknown)
694 static HRESULT WINAPI
DEVENUM_IEnumMoniker_QueryInterface(
699 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
700 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
702 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
704 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
705 IsEqualGUID(riid
, &IID_IEnumMoniker
))
707 *ppvObj
= (LPVOID
)iface
;
708 DEVENUM_IEnumMoniker_AddRef(iface
);
712 FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid
));
713 return E_NOINTERFACE
;
716 /**********************************************************************
717 * DEVENUM_IEnumMoniker_AddRef (also IUnknown)
719 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface
)
721 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
722 ULONG ref
= InterlockedIncrement(&This
->ref
);
724 TRACE("(%p)->() AddRef from %ld\n", iface
, ref
- 1);
729 /**********************************************************************
730 * DEVENUM_IEnumMoniker_Release (also IUnknown)
732 static ULONG WINAPI
DEVENUM_IEnumMoniker_Release(LPENUMMONIKER iface
)
734 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
735 ULONG ref
= InterlockedDecrement(&This
->ref
);
737 TRACE("(%p)->() Release from %ld\n", iface
, ref
+ 1);
741 RegCloseKey(This
->hkey
);
743 DEVENUM_UnlockModule();
749 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Next(LPENUMMONIKER iface
, ULONG celt
, IMoniker
** rgelt
, ULONG
* pceltFetched
)
751 WCHAR buffer
[MAX_PATH
+ 1];
754 MediaCatMoniker
* pMoniker
;
755 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
757 TRACE("(%p)->(%ld, %p, %p)\n", iface
, celt
, rgelt
, pceltFetched
);
759 while (fetched
< celt
)
761 res
= RegEnumKeyW(This
->hkey
, This
->index
, buffer
, sizeof(buffer
) / sizeof(WCHAR
));
762 if (res
!= ERROR_SUCCESS
)
766 pMoniker
= DEVENUM_IMediaCatMoniker_Construct();
768 return E_OUTOFMEMORY
;
770 if (RegOpenKeyW(This
->hkey
, buffer
, &pMoniker
->hkey
) != ERROR_SUCCESS
)
772 DEVENUM_IMediaCatMoniker_Release((LPMONIKER
)pMoniker
);
775 rgelt
[fetched
] = (LPMONIKER
)pMoniker
;
779 This
->index
+= fetched
;
781 TRACE("-- fetched %ld\n", fetched
);
784 *pceltFetched
= fetched
;
792 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Skip(LPENUMMONIKER iface
, ULONG celt
)
794 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
796 TRACE("(%p)->(%ld)\n", iface
, celt
);
803 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Reset(LPENUMMONIKER iface
)
805 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
807 TRACE("(%p)->()\n", iface
);
814 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Clone(LPENUMMONIKER iface
, IEnumMoniker
** ppenum
)
816 FIXME("(%p)->(%p): stub\n", iface
, ppenum
);
821 /**********************************************************************
824 static IEnumMonikerVtbl IEnumMoniker_Vtbl
=
826 DEVENUM_IEnumMoniker_QueryInterface
,
827 DEVENUM_IEnumMoniker_AddRef
,
828 DEVENUM_IEnumMoniker_Release
,
829 DEVENUM_IEnumMoniker_Next
,
830 DEVENUM_IEnumMoniker_Skip
,
831 DEVENUM_IEnumMoniker_Reset
,
832 DEVENUM_IEnumMoniker_Clone
835 HRESULT
DEVENUM_IEnumMoniker_Construct(HKEY hkey
, IEnumMoniker
** ppEnumMoniker
)
837 EnumMonikerImpl
* pEnumMoniker
= CoTaskMemAlloc(sizeof(EnumMonikerImpl
));
839 return E_OUTOFMEMORY
;
841 pEnumMoniker
->lpVtbl
= &IEnumMoniker_Vtbl
;
842 pEnumMoniker
->ref
= 1;
843 pEnumMoniker
->index
= 0;
844 pEnumMoniker
->hkey
= hkey
;
846 *ppEnumMoniker
= (IEnumMoniker
*)pEnumMoniker
;
848 DEVENUM_LockModule();