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
);
33 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface
);
34 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface
);
35 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
);
39 IPropertyBag IPropertyBag_iface
;
45 static inline RegPropBagImpl
*impl_from_IPropertyBag(IPropertyBag
*iface
)
47 return CONTAINING_RECORD(iface
, RegPropBagImpl
, IPropertyBag_iface
);
50 static HRESULT WINAPI
DEVENUM_IPropertyBag_QueryInterface(
55 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
57 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppvObj
);
59 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
61 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
62 IsEqualGUID(riid
, &IID_IPropertyBag
))
65 DEVENUM_IPropertyBag_AddRef(iface
);
69 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
73 /**********************************************************************
74 * DEVENUM_IPropertyBag_AddRef (also IUnknown)
76 static ULONG WINAPI
DEVENUM_IPropertyBag_AddRef(LPPROPERTYBAG iface
)
78 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
80 TRACE("(%p)->() AddRef from %d\n", iface
, This
->ref
);
82 return InterlockedIncrement(&This
->ref
);
85 /**********************************************************************
86 * DEVENUM_IPropertyBag_Release (also IUnknown)
88 static ULONG WINAPI
DEVENUM_IPropertyBag_Release(LPPROPERTYBAG iface
)
90 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
93 TRACE("(%p)->() ReleaseThis->ref from %d\n", iface
, This
->ref
);
95 ref
= InterlockedDecrement(&This
->ref
);
97 RegCloseKey(This
->hkey
);
99 DEVENUM_UnlockModule();
104 static HRESULT WINAPI
DEVENUM_IPropertyBag_Read(
106 LPCOLESTR pszPropName
,
108 IErrorLog
* pErrorLog
)
113 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
117 TRACE("(%p)->(%s, %p, %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
119 if (!pszPropName
|| !pVar
)
122 reswin32
= RegQueryValueExW(This
->hkey
, pszPropName
, NULL
, NULL
, NULL
, &received
);
123 res
= HRESULT_FROM_WIN32(reswin32
);
127 pData
= HeapAlloc(GetProcessHeap(), 0, received
);
129 /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
130 reswin32
= RegQueryValueExW(This
->hkey
, pszPropName
, NULL
, &type
, pData
, &received
);
131 res
= HRESULT_FROM_WIN32(reswin32
);
136 res
= E_INVALIDARG
; /* assume we cannot coerce into right type */
138 TRACE("Read %d bytes (%s)\n", received
, type
== REG_SZ
? debugstr_w(pData
) : "binary data");
146 V_UNION(pVar
, bstrVal
) = CoTaskMemAlloc(received
);
147 memcpy(V_UNION(pVar
, bstrVal
), pData
, received
);
151 V_VT(pVar
) = VT_BSTR
;
154 V_UNION(pVar
, bstrVal
) = SysAllocStringLen(pData
, received
/sizeof(WCHAR
) - 1);
160 TRACE("REG_DWORD: %x\n", *(DWORD
*)pData
);
168 V_UNION(pVar
, ulVal
) = *(DWORD
*)pData
;
175 SAFEARRAYBOUND bound
;
176 void * pArrayElements
;
178 bound
.cElements
= received
;
179 TRACE("REG_BINARY: len = %d\n", received
);
183 V_VT(pVar
) = VT_ARRAY
| VT_UI1
;
185 case VT_ARRAY
| VT_UI1
:
186 if (!(V_UNION(pVar
, parray
) = SafeArrayCreate(VT_UI1
, 1, &bound
)))
193 if (res
== E_INVALIDARG
)
196 res
= SafeArrayAccessData(V_UNION(pVar
, parray
), &pArrayElements
);
200 CopyMemory(pArrayElements
, pData
, received
);
201 res
= SafeArrayUnaccessData(V_UNION(pVar
, parray
));
205 if (res
== E_INVALIDARG
)
206 FIXME("Variant type %x not supported for regtype %x\n", V_VT(pVar
), type
);
209 HeapFree(GetProcessHeap(), 0, pData
);
211 TRACE("<- %x\n", res
);
215 static HRESULT WINAPI
DEVENUM_IPropertyBag_Write(
217 LPCOLESTR pszPropName
,
220 RegPropBagImpl
*This
= impl_from_IPropertyBag(iface
);
221 LPVOID lpData
= NULL
;
226 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(pszPropName
), pVar
);
231 TRACE("writing %s\n", debugstr_w(V_UNION(pVar
, bstrVal
)));
232 lpData
= V_UNION(pVar
, bstrVal
);
234 cbData
= (lstrlenW(V_UNION(pVar
, bstrVal
)) + 1) * sizeof(WCHAR
);
238 TRACE("writing %u\n", V_UNION(pVar
, ulVal
));
239 lpData
= &V_UNION(pVar
, ulVal
);
241 cbData
= sizeof(DWORD
);
243 case VT_ARRAY
| VT_UI1
:
248 res
= SafeArrayGetLBound(V_UNION(pVar
, parray
), 1, &lLbound
);
249 res
= SafeArrayGetUBound(V_UNION(pVar
, parray
), 1, &lUbound
);
250 cbData
= (lUbound
- lLbound
+ 1) /* * sizeof(BYTE)*/;
251 TRACE("cbData: %d\n", cbData
);
252 res
= SafeArrayAccessData(V_UNION(pVar
, parray
), &lpData
);
256 FIXME("Variant type %d not handled\n", V_VT(pVar
));
260 if (RegSetValueExW(This
->hkey
,
262 dwType
, lpData
, cbData
) != ERROR_SUCCESS
)
265 if (V_VT(pVar
) & VT_ARRAY
)
266 res
= SafeArrayUnaccessData(V_UNION(pVar
, parray
));
271 static const IPropertyBagVtbl IPropertyBag_Vtbl
=
273 DEVENUM_IPropertyBag_QueryInterface
,
274 DEVENUM_IPropertyBag_AddRef
,
275 DEVENUM_IPropertyBag_Release
,
276 DEVENUM_IPropertyBag_Read
,
277 DEVENUM_IPropertyBag_Write
280 static HRESULT
DEVENUM_IPropertyBag_Construct(HANDLE hkey
, IPropertyBag
**ppBag
)
282 RegPropBagImpl
* rpb
= CoTaskMemAlloc(sizeof(RegPropBagImpl
));
284 return E_OUTOFMEMORY
;
285 rpb
->IPropertyBag_iface
.lpVtbl
= &IPropertyBag_Vtbl
;
288 *ppBag
= &rpb
->IPropertyBag_iface
;
289 DEVENUM_LockModule();
294 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_QueryInterface(
299 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
300 TRACE("\n\tIID:\t%s\n",debugstr_guid(riid
));
302 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
306 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
307 IsEqualGUID(riid
, &IID_IPersist
) ||
308 IsEqualGUID(riid
, &IID_IPersistStream
) ||
309 IsEqualGUID(riid
, &IID_IMoniker
))
312 DEVENUM_IMediaCatMoniker_AddRef(iface
);
316 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
317 return E_NOINTERFACE
;
320 /**********************************************************************
321 * DEVENUM_IMediaCatMoniker_AddRef (also IUnknown)
323 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_AddRef(LPMONIKER iface
)
325 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
328 return InterlockedIncrement(&This
->ref
);
331 /**********************************************************************
332 * DEVENUM_IMediaCatMoniker_Release (also IUnknown)
334 static ULONG WINAPI
DEVENUM_IMediaCatMoniker_Release(LPMONIKER iface
)
336 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
340 ref
= InterlockedDecrement(&This
->ref
);
342 RegCloseKey(This
->hkey
);
344 DEVENUM_UnlockModule();
349 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetClassID(
353 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
354 FIXME("(%p)->(%p): stub\n", This
, pClassID
);
356 if (pClassID
== NULL
)
362 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsDirty(LPMONIKER iface
)
364 FIXME("(%p)->(): stub\n", iface
);
369 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Load(LPMONIKER iface
, IStream
* pStm
)
371 FIXME("(%p)->(%p): stub\n", iface
, pStm
);
376 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Save(LPMONIKER iface
, IStream
* pStm
, BOOL fClearDirty
)
378 FIXME("(%p)->(%p, %s): stub\n", iface
, pStm
, fClearDirty
? "true" : "false");
380 return STG_E_CANTSAVE
;
383 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetSizeMax(
385 ULARGE_INTEGER
* pcbSize
)
387 FIXME("(%p)->(%p): stub\n", iface
, pcbSize
);
389 ZeroMemory(pcbSize
, sizeof(*pcbSize
));
394 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToObject(
401 IUnknown
* pObj
= NULL
;
402 IPropertyBag
* pProp
= NULL
;
405 HRESULT res
= E_FAIL
;
407 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
411 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riidResult
), ppvResult
);
417 /* first activation of this class */
419 res
=IMoniker_BindToStorage(iface
, NULL
, NULL
, &IID_IPropertyBag
, &pvptr
);
423 V_VT(&var
) = VT_LPWSTR
;
424 res
= IPropertyBag_Read(pProp
, clsid_keyname
, &var
, NULL
);
428 res
= CLSIDFromString(V_UNION(&var
,bstrVal
), &clsID
);
429 CoTaskMemFree(V_UNION(&var
, bstrVal
));
433 res
=CoCreateInstance(&clsID
,NULL
,CLSCTX_ALL
,&IID_IUnknown
,&pvptr
);
440 /* get the requested interface from the loaded class */
445 res2
= IUnknown_QueryInterface(pObj
, &IID_IPersistPropertyBag
, &ppv
);
446 if (SUCCEEDED(res2
)) {
447 res
= IPersistPropertyBag_Load((IPersistPropertyBag
*) ppv
, pProp
, NULL
);
448 IPersistPropertyBag_Release((IPersistPropertyBag
*) ppv
);
452 res
= IUnknown_QueryInterface(pObj
,riidResult
,ppvResult
);
453 IUnknown_Release(pObj
);
458 IPropertyBag_Release(pProp
);
461 TRACE("<- 0x%x\n", res
);
466 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_BindToStorage(
473 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
474 TRACE("(%p)->(%p, %p, %s, %p)\n", This
, pbc
, pmkToLeft
, debugstr_guid(riid
), ppvObj
);
478 if (pbc
|| pmkToLeft
)
479 return MK_E_NOSTORAGE
;
481 if (IsEqualGUID(riid
, &IID_IPropertyBag
))
484 DuplicateHandle(GetCurrentProcess(), This
->hkey
, GetCurrentProcess(), &hkey
, 0, 0, DUPLICATE_SAME_ACCESS
);
485 return DEVENUM_IPropertyBag_Construct(hkey
, (IPropertyBag
**)ppvObj
);
488 return MK_E_NOSTORAGE
;
491 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Reduce(
494 DWORD dwReduceHowFar
,
495 IMoniker
** ppmkToLeft
,
496 IMoniker
** ppmkReduced
)
498 TRACE("(%p)->(%p, %d, %p, %p)\n", iface
, pbc
, dwReduceHowFar
, ppmkToLeft
, ppmkReduced
);
502 *ppmkReduced
= iface
;
504 return MK_S_REDUCED_TO_SELF
;
507 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ComposeWith(
510 BOOL fOnlyIfNotGeneric
,
511 IMoniker
** ppmkComposite
)
513 FIXME("(%p)->(%p, %s, %p): stub\n", iface
, pmkRight
, fOnlyIfNotGeneric
? "true" : "false", ppmkComposite
);
515 /* FIXME: use CreateGenericComposite? */
516 *ppmkComposite
= NULL
;
521 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Enum(
524 IEnumMoniker
** ppenumMoniker
)
526 FIXME("(%p)->(%s, %p): stub\n", iface
, fForward
? "true" : "false", ppenumMoniker
);
528 *ppenumMoniker
= NULL
;
533 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsEqual(
535 IMoniker
* pmkOtherMoniker
)
537 FIXME("(%p)->(%p): stub\n", iface
, pmkOtherMoniker
);
542 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Hash(
546 TRACE("(%p)->(%p)\n", iface
, pdwHash
);
553 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsRunning(
557 IMoniker
* pmkNewlyRunning
)
559 FIXME("(%p)->(%p, %p, %p): stub\n", iface
, pbc
, pmkToLeft
, pmkNewlyRunning
);
564 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetTimeOfLastChange(
570 TRACE("(%p)->(%p, %p, %p)\n", iface
, pbc
, pmkToLeft
, pFileTime
);
572 pFileTime
->dwLowDateTime
= 0xFFFFFFFF;
573 pFileTime
->dwHighDateTime
= 0x7FFFFFFF;
575 return MK_E_UNAVAILABLE
;
578 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_Inverse(
582 TRACE("(%p)->(%p)\n", iface
, ppmk
);
586 return MK_E_NOINVERSE
;
589 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_CommonPrefixWith(
591 IMoniker
* pmkOtherMoniker
,
592 IMoniker
** ppmkPrefix
)
594 TRACE("(%p)->(%p, %p)\n", iface
, pmkOtherMoniker
, ppmkPrefix
);
598 return MK_E_NOPREFIX
;
601 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_RelativePathTo(
604 IMoniker
** ppmkRelPath
)
606 TRACE("(%p)->(%p, %p)\n", iface
, pmkOther
, ppmkRelPath
);
608 *ppmkRelPath
= pmkOther
;
613 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_GetDisplayName(
617 LPOLESTR
* ppszDisplayName
)
619 MediaCatMoniker
*This
= (MediaCatMoniker
*)iface
;
620 WCHAR wszBuffer
[MAX_PATH
];
621 static const WCHAR wszFriendlyName
[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
622 LONG received
= sizeof(wszFriendlyName
);
624 TRACE("(%p)->(%p, %p, %p)\n", iface
, pbc
, pmkToLeft
, ppszDisplayName
);
626 *ppszDisplayName
= NULL
;
628 /* FIXME: should this be the weird stuff we have to parse in IParseDisplayName? */
629 if (RegQueryValueW(This
->hkey
, wszFriendlyName
, wszBuffer
, &received
) == ERROR_SUCCESS
)
631 *ppszDisplayName
= CoTaskMemAlloc(received
);
632 strcpyW(*ppszDisplayName
, wszBuffer
);
639 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_ParseDisplayName(
643 LPOLESTR pszDisplayName
,
647 FIXME("(%p)->(%p, %p, %s, %p, %p)\n", iface
, pbc
, pmkToLeft
, debugstr_w(pszDisplayName
), pchEaten
, ppmkOut
);
655 static HRESULT WINAPI
DEVENUM_IMediaCatMoniker_IsSystemMoniker(
659 TRACE("(%p)->(%p)\n", iface
, pdwMksys
);
664 static const IMonikerVtbl IMoniker_Vtbl
=
666 DEVENUM_IMediaCatMoniker_QueryInterface
,
667 DEVENUM_IMediaCatMoniker_AddRef
,
668 DEVENUM_IMediaCatMoniker_Release
,
669 DEVENUM_IMediaCatMoniker_GetClassID
,
670 DEVENUM_IMediaCatMoniker_IsDirty
,
671 DEVENUM_IMediaCatMoniker_Load
,
672 DEVENUM_IMediaCatMoniker_Save
,
673 DEVENUM_IMediaCatMoniker_GetSizeMax
,
674 DEVENUM_IMediaCatMoniker_BindToObject
,
675 DEVENUM_IMediaCatMoniker_BindToStorage
,
676 DEVENUM_IMediaCatMoniker_Reduce
,
677 DEVENUM_IMediaCatMoniker_ComposeWith
,
678 DEVENUM_IMediaCatMoniker_Enum
,
679 DEVENUM_IMediaCatMoniker_IsEqual
,
680 DEVENUM_IMediaCatMoniker_Hash
,
681 DEVENUM_IMediaCatMoniker_IsRunning
,
682 DEVENUM_IMediaCatMoniker_GetTimeOfLastChange
,
683 DEVENUM_IMediaCatMoniker_Inverse
,
684 DEVENUM_IMediaCatMoniker_CommonPrefixWith
,
685 DEVENUM_IMediaCatMoniker_RelativePathTo
,
686 DEVENUM_IMediaCatMoniker_GetDisplayName
,
687 DEVENUM_IMediaCatMoniker_ParseDisplayName
,
688 DEVENUM_IMediaCatMoniker_IsSystemMoniker
691 MediaCatMoniker
* DEVENUM_IMediaCatMoniker_Construct(void)
693 MediaCatMoniker
* pMoniker
= NULL
;
694 pMoniker
= CoTaskMemAlloc(sizeof(MediaCatMoniker
));
698 pMoniker
->lpVtbl
= &IMoniker_Vtbl
;
700 pMoniker
->hkey
= NULL
;
702 DEVENUM_IMediaCatMoniker_AddRef((LPMONIKER
)pMoniker
);
704 DEVENUM_LockModule();
709 /**********************************************************************
710 * DEVENUM_IEnumMoniker_QueryInterface (also IUnknown)
712 static HRESULT WINAPI
DEVENUM_IEnumMoniker_QueryInterface(
717 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
719 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppvObj
);
721 if (This
== NULL
|| ppvObj
== NULL
) return E_POINTER
;
723 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
724 IsEqualGUID(riid
, &IID_IEnumMoniker
))
727 DEVENUM_IEnumMoniker_AddRef(iface
);
731 FIXME("- no interface IID: %s\n", debugstr_guid(riid
));
732 return E_NOINTERFACE
;
735 /**********************************************************************
736 * DEVENUM_IEnumMoniker_AddRef (also IUnknown)
738 static ULONG WINAPI
DEVENUM_IEnumMoniker_AddRef(LPENUMMONIKER iface
)
740 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
741 ULONG ref
= InterlockedIncrement(&This
->ref
);
743 TRACE("(%p)->() AddRef from %d\n", iface
, ref
- 1);
748 /**********************************************************************
749 * DEVENUM_IEnumMoniker_Release (also IUnknown)
751 static ULONG WINAPI
DEVENUM_IEnumMoniker_Release(LPENUMMONIKER iface
)
753 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
754 ULONG ref
= InterlockedDecrement(&This
->ref
);
756 TRACE("(%p)->() Release from %d\n", iface
, ref
+ 1);
760 RegCloseKey(This
->hkey
);
762 DEVENUM_UnlockModule();
768 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Next(LPENUMMONIKER iface
, ULONG celt
, IMoniker
** rgelt
, ULONG
* pceltFetched
)
770 WCHAR buffer
[MAX_PATH
+ 1];
773 MediaCatMoniker
* pMoniker
;
774 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
776 TRACE("(%p)->(%d, %p, %p)\n", iface
, celt
, rgelt
, pceltFetched
);
778 while (fetched
< celt
)
780 res
= RegEnumKeyW(This
->hkey
, This
->index
, buffer
, sizeof(buffer
) / sizeof(WCHAR
));
781 if (res
!= ERROR_SUCCESS
)
785 pMoniker
= DEVENUM_IMediaCatMoniker_Construct();
787 return E_OUTOFMEMORY
;
789 if (RegOpenKeyW(This
->hkey
, buffer
, &pMoniker
->hkey
) != ERROR_SUCCESS
)
791 DEVENUM_IMediaCatMoniker_Release((LPMONIKER
)pMoniker
);
794 rgelt
[fetched
] = (LPMONIKER
)pMoniker
;
798 This
->index
+= fetched
;
800 TRACE("-- fetched %d\n", fetched
);
803 *pceltFetched
= fetched
;
811 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Skip(LPENUMMONIKER iface
, ULONG celt
)
813 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
816 TRACE("(%p)->(%d)\n", iface
, celt
);
818 /* Before incrementing, check if there are any more values to run thru.
819 Some programs use the Skip() function to get the amount of devices */
820 if(RegQueryInfoKeyW(This
->hkey
, NULL
, NULL
, NULL
, &subKeys
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
824 if((This
->index
+ celt
) >= subKeys
)
834 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Reset(LPENUMMONIKER iface
)
836 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
838 TRACE("(%p)->()\n", iface
);
845 static HRESULT WINAPI
DEVENUM_IEnumMoniker_Clone(LPENUMMONIKER iface
, IEnumMoniker
** ppenum
)
847 FIXME("(%p)->(%p): stub\n", iface
, ppenum
);
852 /**********************************************************************
855 static const IEnumMonikerVtbl IEnumMoniker_Vtbl
=
857 DEVENUM_IEnumMoniker_QueryInterface
,
858 DEVENUM_IEnumMoniker_AddRef
,
859 DEVENUM_IEnumMoniker_Release
,
860 DEVENUM_IEnumMoniker_Next
,
861 DEVENUM_IEnumMoniker_Skip
,
862 DEVENUM_IEnumMoniker_Reset
,
863 DEVENUM_IEnumMoniker_Clone
866 HRESULT
DEVENUM_IEnumMoniker_Construct(HKEY hkey
, IEnumMoniker
** ppEnumMoniker
)
868 EnumMonikerImpl
* pEnumMoniker
= CoTaskMemAlloc(sizeof(EnumMonikerImpl
));
870 return E_OUTOFMEMORY
;
872 pEnumMoniker
->lpVtbl
= &IEnumMoniker_Vtbl
;
873 pEnumMoniker
->ref
= 1;
874 pEnumMoniker
->index
= 0;
875 pEnumMoniker
->hkey
= hkey
;
877 *ppEnumMoniker
= (IEnumMoniker
*)pEnumMoniker
;
879 DEVENUM_LockModule();