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
;
49 static HRESULT WINAPI
DEVENUM_IPropertyBag_QueryInterface(
54 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
55 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
57 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
59 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
60 IsEqualGUID(riid
, &IID_IPropertyBag
))
62 *ppvObj
= (LPVOID
)iface
;
63 DEVENUM_IPropertyBag_AddRef(iface
);
67 FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid
));
71 /**********************************************************************
72 * DEVENUM_IPropertyBag_AddRef (also IUnknown)
74 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
)
76 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
79 return InterlockedIncrement(&This
->ref
);
82 /**********************************************************************
83 * DEVENUM_IPropertyBag_Release (also IUnknown)
85 static ULONG WINAPI
DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface
)
87 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
91 if (InterlockedDecrement(&This
->ref
) == 0) {
92 RegCloseKey(This
->hkey
);
94 DEVENUM_UnlockModule();
100 static HRESULT WINAPI
DEVENUM_IPropertyBag_Read(
102 LPCOLESTR pszPropName
,
104 IErrorLog
* pErrorLog
)
109 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
112 WCHAR buffer
[MAX_PATH
];
116 TRACE("(%p)->(%s, %p, %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
118 if (!pszPropName
|| !pVar
)
122 pszName
= pszPropName
;
123 if (This
->bInterface
)
126 received
= sizeof(buffer
)/sizeof(WCHAR
);
127 reswin32
= RegEnumKeyEx(This
->hkey
, 0, buffer
, &received
, NULL
, NULL
, NULL
, NULL
);
129 reswin32
= RegOpenKeyExW(This
->hkey
, buffer
, 0, KEY_READ
, &hkey
);
131 if (!wcsicmp(pszPropName
, L
"DevicePath"))
132 pszName
= L
"SymbolicLink";
136 reswin32
= RegQueryValueExW(hkey
, pszName
, NULL
, NULL
, NULL
, &received
);
137 res
= HRESULT_FROM_WIN32(reswin32
);
141 pData
= HeapAlloc(GetProcessHeap(), 0, received
);
143 /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
144 reswin32
= RegQueryValueExW(hkey
, pszName
, NULL
, &type
, pData
, &received
);
145 res
= HRESULT_FROM_WIN32(reswin32
);
150 res
= E_INVALIDARG
; /* assume we cannot coerce into right type */
152 TRACE("Read %ld bytes (%s)\n", received
, type
== REG_SZ
? debugstr_w((LPWSTR
)pData
) : "binary data");
160 V_UNION(pVar
, bstrVal
) = CoTaskMemAlloc(received
);
161 memcpy(V_UNION(pVar
, bstrVal
), (LPWSTR
)pData
, received
);
165 V_VT(pVar
) = VT_BSTR
;
168 V_UNION(pVar
, bstrVal
) = SysAllocStringLen((LPWSTR
)pData
, received
/sizeof(WCHAR
) - 1);
174 TRACE("REG_DWORD: %lx\n", *(DWORD
*)pData
);
182 V_UNION(pVar
, ulVal
) = *(DWORD
*)pData
;
189 SAFEARRAYBOUND bound
;
190 void * pArrayElements
;
192 bound
.cElements
= received
;
193 TRACE("REG_BINARY: len = %ld\n", received
);
197 case VT_ARRAY
| VT_UI1
:
198 if (!(V_UNION(pVar
, parray
) = SafeArrayCreate(VT_UI1
, 1, &bound
)))
204 if (res
== E_INVALIDARG
)
207 res
= SafeArrayAccessData(V_UNION(pVar
, parray
), &pArrayElements
);
211 CopyMemory(pArrayElements
, pData
, received
);
212 res
= SafeArrayUnaccessData(V_UNION(pVar
, parray
));
216 if (res
== E_INVALIDARG
)
217 FIXME("Variant type %x not supported for regtype %lx\n", V_VT(pVar
), type
);
221 HeapFree(GetProcessHeap(), 0, pData
);
223 if (This
->bInterface
)
226 TRACE("<- %lx\n", res
);
230 static HRESULT WINAPI
DEVENUM_IPropertyBag_Write(
232 LPCOLESTR pszPropName
,
235 RegPropBagImpl
*This
= (RegPropBagImpl
*)iface
;
236 LPVOID lpData
= NULL
;
241 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(pszPropName
), pVar
);
246 TRACE("writing %s\n", debugstr_w(V_UNION(pVar
, bstrVal
)));
247 lpData
= (LPVOID
)V_UNION(pVar
, bstrVal
);
249 cbData
= (lstrlenW(V_UNION(pVar
, bstrVal
)) + 1) * sizeof(WCHAR
);
253 TRACE("writing %lu\n", V_UNION(pVar
, ulVal
));
254 lpData
= (LPVOID
)&V_UNION(pVar
, ulVal
);
256 cbData
= sizeof(DWORD
);
258 case VT_ARRAY
| VT_UI1
:
263 res
= SafeArrayGetLBound(V_UNION(pVar
, parray
), 1, &lLbound
);
264 res
= SafeArrayGetUBound(V_UNION(pVar
, parray
), 1, &lUbound
);
265 cbData
= (lUbound
- lLbound
+ 1) /* * sizeof(BYTE)*/;
266 TRACE("cbData: %ld\n", cbData
);
267 res
= SafeArrayAccessData(V_UNION(pVar
, parray
), &lpData
);
271 FIXME("Variant type %d not handled\n", V_VT(pVar
));
275 if (RegSetValueExW(This
->hkey
,
277 dwType
, lpData
, cbData
) != ERROR_SUCCESS
)
280 if (V_VT(pVar
) & VT_ARRAY
)
281 res
= SafeArrayUnaccessData(V_UNION(pVar
, parray
));
286 static IPropertyBagVtbl IPropertyBag_Vtbl
=
288 DEVENUM_IPropertyBag_QueryInterface
,
289 DEVENUM_IPropertyBag_AddRef
,
290 DEVENUM_IPropertyBag_Release
,
291 DEVENUM_IPropertyBag_Read
,
292 DEVENUM_IPropertyBag_Write
295 static HRESULT
DEVENUM_IPropertyBag_Construct(HANDLE hkey
, IPropertyBag
**ppBag
, BOOL bInterface
)
297 RegPropBagImpl
* rpb
= CoTaskMemAlloc(sizeof(RegPropBagImpl
));
299 return E_OUTOFMEMORY
;
300 rpb
->lpVtbl
= &IPropertyBag_Vtbl
;
303 rpb
->bInterface
= bInterface
;
305 *ppBag
= (IPropertyBag
*)rpb
;
306 DEVENUM_LockModule();
311 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_QueryInterface(
316 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
317 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
319 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
323 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
324 IsEqualGUID(riid
, &IID_IPersist
) ||
325 IsEqualGUID(riid
, &IID_IPersistStream
) ||
326 IsEqualGUID(riid
, &IID_IMoniker
))
328 *ppvObj
= (LPVOID
)iface
;
329 DEVENUM_IMediaCatMoniker_AddRef(iface
);
333 FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid
));
334 return E_NOINTERFACE
;
337 /**********************************************************************
338 * DEVENUM_IMediaCatMoniker_AddRef (also IUnknown)
340 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface
)
342 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
345 return InterlockedIncrement(&This
->ref
);
348 /**********************************************************************
349 * DEVENUM_IMediaCatMoniker_Release (also IUnknown)
351 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_Release(LPMONIKER iface
)
353 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
357 ref
= InterlockedDecrement(&This
->ref
);
359 RegCloseKey(This
->hkey
);
361 DEVENUM_UnlockModule();
366 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetClassID(
370 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
371 FIXME("(%p)->(%p)\n", This
, pClassID
);
373 if (pClassID
== NULL
)
379 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsDirty(LPMONIKER iface
)
386 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Load(LPMONIKER iface
, IStream
* pStm
)
388 FIXME("(%p)\n", pStm
);
393 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Save(LPMONIKER iface
, IStream
* pStm
, BOOL fClearDirty
)
395 FIXME("(%p, %s)\n", pStm
, fClearDirty
? "true" : "false");
397 return STG_E_CANTSAVE
;
400 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetSizeMax(
402 ULARGE_INTEGER
* pcbSize
)
404 FIXME("(%p)\n", pcbSize
);
406 ZeroMemory(pcbSize
, sizeof(*pcbSize
));
411 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToObject(
418 IUnknown
* pObj
= NULL
;
419 IPropertyBag
* pProp
= NULL
;
420 IPersistPropertyBag
* pBag
;
423 HRESULT res
= E_FAIL
;
425 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
429 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riidResult
), ppvResult
);
435 /* first activation of this class */
437 res
=IMoniker_BindToStorage(iface
, NULL
, NULL
, &IID_IPropertyBag
, &pvptr
);
438 pProp
= (IPropertyBag
*)pvptr
;
441 V_VT(&var
) = VT_LPWSTR
;
442 res
= IPropertyBag_Read(pProp
, clsid_keyname
, &var
, NULL
);
446 res
= CLSIDFromString(V_UNION(&var
,bstrVal
), &clsID
);
447 CoTaskMemFree(V_UNION(&var
, bstrVal
));
451 res
=CoCreateInstance(&clsID
,NULL
,CLSCTX_ALL
,&IID_IUnknown
,&pvptr
);
452 pObj
= (IUnknown
*)pvptr
;
458 if (This
->bInterface
)
460 res
= IUnknown_QueryInterface(pObj
, &IID_IPersistPropertyBag
, (void**)&pBag
);
463 res
= IPersistPropertyBag_Load(pBag
, pProp
, NULL
); /* FIXME */
464 IPersistPropertyBag_Release(pBag
);
467 /* get the requested interface from the loaded class */
468 res
= IUnknown_QueryInterface(pObj
,riidResult
,ppvResult
);
473 IPropertyBag_Release(pProp
);
476 TRACE("<- 0x%lx\n", res
);
481 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToStorage(
488 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
489 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riid
), ppvObj
);
493 if (pbc
|| pmkToLeft
)
494 return MK_E_NOSTORAGE
;
496 if (IsEqualGUID(riid
, &IID_IPropertyBag
))
499 DuplicateHandle(GetCurrentProcess(), This
->hkey
, GetCurrentProcess(), &hkey
, 0, 0, DUPLICATE_SAME_ACCESS
);
500 return DEVENUM_IPropertyBag_Construct(hkey
, (IPropertyBag
**)ppvObj
, This
->bInterface
);
503 return MK_E_NOSTORAGE
;
506 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Reduce(
509 DWORD dwReduceHowFar
,
510 IMoniker
** ppmkToLeft
,
511 IMoniker
** ppmkReduced
)
513 TRACE("(%p, %ld, %p, %p)\n", pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
517 *ppmkReduced
= iface
;
519 return MK_S_REDUCED_TO_SELF
;
522 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ComposeWith(
525 BOOL fOnlyIfNotGeneric
,
526 IMoniker
** ppmkComposite
)
528 FIXME("(%p, %s, %p): stub\n", pmkRight
, fOnlyIfNotGeneric
? "true" : "false", ppmkComposite
);
530 /* FIXME: use CreateGenericComposite? */
531 *ppmkComposite
= NULL
;
536 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Enum(
539 IEnumMoniker
** ppenumMoniker
)
541 FIXME("(%s, %p): stub\n", fForward
? "true" : "false", ppenumMoniker
);
543 *ppenumMoniker
= NULL
;
548 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsEqual(
550 IMoniker
* pmkOtherMoniker
)
552 FIXME("(%p)\n", pmkOtherMoniker
);
557 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Hash(
561 TRACE("(%p)\n", pdwHash
);
568 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsRunning(
572 IMoniker
* pmkNewlyRunning
)
574 FIXME("(%p, %p, %p)\n", pbc
, pmkToLeft
, pmkNewlyRunning
);
579 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetTimeOfLastChange(
585 TRACE("(%p, %p, %p)\n", pbc
, pmkToLeft
, pFileTime
);
587 pFileTime
->dwLowDateTime
= 0xFFFFFFFF;
588 pFileTime
->dwHighDateTime
= 0x7FFFFFFF;
590 return MK_E_UNAVAILABLE
;
593 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Inverse(
597 TRACE("(%p)\n", ppmk
);
601 return MK_E_NOINVERSE
;
604 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_CommonPrefixWith(
606 IMoniker
* pmkOtherMoniker
,
607 IMoniker
** ppmkPrefix
)
609 TRACE("(%p, %p)\n", pmkOtherMoniker
, ppmkPrefix
);
613 return MK_E_NOPREFIX
;
616 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_RelativePathTo(
619 IMoniker
** ppmkRelPath
)
621 TRACE("(%p, %p)\n", pmkOther
, ppmkRelPath
);
623 *ppmkRelPath
= pmkOther
;
628 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetDisplayName(
632 LPOLESTR
* ppszDisplayName
)
634 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
635 WCHAR wszBuffer
[MAX_PATH
];
636 static const WCHAR wszFriendlyName
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
637 LONG received
= sizeof(wszFriendlyName
);
639 TRACE("(%p, %p, %p)\n", pbc
, pmkToLeft
, ppszDisplayName
);
641 *ppszDisplayName
= NULL
;
643 /* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */
644 if (RegQueryValueW(This
->hkey
, wszFriendlyName
, wszBuffer
, &received
) == ERROR_SUCCESS
)
646 *ppszDisplayName
= CoTaskMemAlloc(received
);
647 strcpyW(*ppszDisplayName
, wszBuffer
);
654 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ParseDisplayName(
658 LPOLESTR pszDisplayName
,
662 FIXME("(%p, %p, %s, %p, %p)\n", pbc
, pmkToLeft
, debugstr_w(pszDisplayName
), pchEaten
, ppmkOut
);
670 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsSystemMoniker(
674 TRACE("(%p)\n", pdwMksys
);
679 static IMonikerVtbl IMoniker_Vtbl
=
681 DEVENUM_IMediaCatMoniker_QueryInterface
,
682 DEVENUM_IMediaCatMoniker_AddRef
,
683 DEVENUM_IMediaCatMoniker_Release
,
684 DEVENUM_IMediaCatMoniker_GetClassID
,
685 DEVENUM_IMediaCatMoniker_IsDirty
,
686 DEVENUM_IMediaCatMoniker_Load
,
687 DEVENUM_IMediaCatMoniker_Save
,
688 DEVENUM_IMediaCatMoniker_GetSizeMax
,
689 DEVENUM_IMediaCatMoniker_BindToObject
,
690 DEVENUM_IMediaCatMoniker_BindToStorage
,
691 DEVENUM_IMediaCatMoniker_Reduce
,
692 DEVENUM_IMediaCatMoniker_ComposeWith
,
693 DEVENUM_IMediaCatMoniker_Enum
,
694 DEVENUM_IMediaCatMoniker_IsEqual
,
695 DEVENUM_IMediaCatMoniker_Hash
,
696 DEVENUM_IMediaCatMoniker_IsRunning
,
697 DEVENUM_IMediaCatMoniker_GetTimeOfLastChange
,
698 DEVENUM_IMediaCatMoniker_Inverse
,
699 DEVENUM_IMediaCatMoniker_CommonPrefixWith
,
700 DEVENUM_IMediaCatMoniker_RelativePathTo
,
701 DEVENUM_IMediaCatMoniker_GetDisplayName
,
702 DEVENUM_IMediaCatMoniker_ParseDisplayName
,
703 DEVENUM_IMediaCatMoniker_IsSystemMoniker
706 MediaCatMoniker
* DEVENUM_IMediaCatMoniker_Construct()
708 MediaCatMoniker
* pMoniker
= NULL
;
709 pMoniker
= CoTaskMemAlloc(sizeof(MediaCatMoniker
));
713 pMoniker
->lpVtbl
= &IMoniker_Vtbl
;
715 pMoniker
->hkey
= NULL
;
716 pMoniker
->bInterface
= FALSE
;
718 DEVENUM_IMediaCatMoniker_AddRef((LPMONIKER
)pMoniker
);
720 DEVENUM_LockModule();
725 /**********************************************************************
726 * DEVENUM_IEnumMoniker_QueryInterface (also IUnknown)
728 static HRESULT WINAPI
DEVENUM_IEnumMoniker_QueryInterface(
733 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
734 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
736 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
738 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
739 IsEqualGUID(riid
, &IID_IEnumMoniker
))
741 *ppvObj
= (LPVOID
)iface
;
742 DEVENUM_IEnumMoniker_AddRef(iface
);
746 FIXME("- no interface\n\tIID:\t%s\n", debugstr_guid(riid
));
747 return E_NOINTERFACE
;
750 /**********************************************************************
751 * DEVENUM_IEnumMoniker_AddRef (also IUnknown)
753 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface
)
755 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
759 return InterlockedIncrement(&This
->ref
);
762 /**********************************************************************
763 * DEVENUM_IEnumMoniker_Release (also IUnknown)
765 static ULONG WINAPI
DEVENUM_IEnumMoniker_Release(LPENUMMONIKER iface
)
767 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
771 if (!InterlockedDecrement(&This
->ref
))
773 RegCloseKey(This
->hkey
);
775 DEVENUM_UnlockModule();
781 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Next(LPENUMMONIKER iface
, ULONG celt
, IMoniker
** rgelt
, ULONG
* pceltFetched
)
783 WCHAR buffer
[MAX_PATH
+ 1];
786 MediaCatMoniker
* pMoniker
;
787 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
789 TRACE("(%ld, %p, %p)\n", celt
, rgelt
, pceltFetched
);
791 while (fetched
< celt
)
793 res
= RegEnumKeyW(This
->hkey
, This
->index
, buffer
, sizeof(buffer
) / sizeof(WCHAR
));
794 if (res
!= ERROR_SUCCESS
)
798 pMoniker
= DEVENUM_IMediaCatMoniker_Construct();
800 return E_OUTOFMEMORY
;
802 pMoniker
->bInterface
= This
->bInterface
;
803 if (RegOpenKeyW(This
->hkey
, buffer
, &pMoniker
->hkey
) != ERROR_SUCCESS
)
805 DEVENUM_IMediaCatMoniker_Release((LPMONIKER
)pMoniker
);
808 rgelt
[fetched
] = (LPMONIKER
)pMoniker
;
812 This
->index
+= fetched
;
814 TRACE("-- fetched %ld\n", fetched
);
817 *pceltFetched
= fetched
;
825 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Skip(LPENUMMONIKER iface
, ULONG celt
)
827 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
829 TRACE("(%ld)\n", celt
);
836 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Reset(LPENUMMONIKER iface
)
838 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
847 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Clone(LPENUMMONIKER iface
, IEnumMoniker
** ppenum
)
849 FIXME("(%p): stub\n", ppenum
);
854 /**********************************************************************
857 static IEnumMonikerVtbl IEnumMoniker_Vtbl
=
859 DEVENUM_IEnumMoniker_QueryInterface
,
860 DEVENUM_IEnumMoniker_AddRef
,
861 DEVENUM_IEnumMoniker_Release
,
862 DEVENUM_IEnumMoniker_Next
,
863 DEVENUM_IEnumMoniker_Skip
,
864 DEVENUM_IEnumMoniker_Reset
,
865 DEVENUM_IEnumMoniker_Clone
868 HRESULT
DEVENUM_IEnumMoniker_Construct(HKEY hkey
, IEnumMoniker
** ppEnumMoniker
, BOOL bInterface
)
870 EnumMonikerImpl
* pEnumMoniker
= CoTaskMemAlloc(sizeof(EnumMonikerImpl
));
872 return E_OUTOFMEMORY
;
874 pEnumMoniker
->lpVtbl
= &IEnumMoniker_Vtbl
;
875 pEnumMoniker
->ref
= 1;
876 pEnumMoniker
->index
= 0;
877 pEnumMoniker
->hkey
= hkey
;
878 pEnumMoniker
->bInterface
= bInterface
;
880 *ppEnumMoniker
= (IEnumMoniker
*)pEnumMoniker
;
882 DEVENUM_LockModule();