2 * Implementation of CLSID_SystemDeviceEnum.
3 * Implements IMoniker for CLSID_CDeviceMoniker.
4 * Implements IPropertyBag. (internal)
6 * hidenori@a2.ctktv.ne.jp
24 #include "debugtools.h"
25 DEFAULT_DEBUG_CHANNEL(quartz
);
27 #include "quartz_private.h"
34 #define NUMELEMS(elem) (sizeof(elem)/sizeof(elem[0]))
37 /***************************************************************************
39 * new/delete for CLSID_SystemDeviceEnum
43 /* can I use offsetof safely? - FIXME? */
44 static QUARTZ_IFEntry CSysDevEnum_IFEntries
[] =
46 { &IID_ICreateDevEnum
, offsetof(CSysDevEnum
,createdevenum
)-offsetof(CSysDevEnum
,unk
) },
50 static void QUARTZ_DestroySystemDeviceEnum(IUnknown
* punk
)
52 CSysDevEnum_THIS(punk
,unk
);
54 CSysDevEnum_UninitICreateDevEnum( This
);
57 HRESULT
QUARTZ_CreateSystemDeviceEnum(IUnknown
* punkOuter
,void** ppobj
)
62 TRACE("(%p,%p)\n",punkOuter
,ppobj
);
64 psde
= (CSysDevEnum
*)QUARTZ_AllocObj( sizeof(CSysDevEnum
) );
68 QUARTZ_IUnkInit( &psde
->unk
, punkOuter
);
70 hr
= CSysDevEnum_InitICreateDevEnum( psde
);
73 QUARTZ_FreeObj( psde
);
77 psde
->unk
.pEntries
= CSysDevEnum_IFEntries
;
78 psde
->unk
.dwEntries
= sizeof(CSysDevEnum_IFEntries
)/sizeof(CSysDevEnum_IFEntries
[0]);
79 psde
->unk
.pOnFinalRelease
= QUARTZ_DestroySystemDeviceEnum
;
81 *ppobj
= (void*)(&psde
->unk
);
87 /***************************************************************************
89 * CSysDevEnum::ICreateDevEnum
95 ICreateDevEnum_fnQueryInterface(ICreateDevEnum
* iface
,REFIID riid
,void** ppobj
)
97 CSysDevEnum_THIS(iface
,createdevenum
);
99 TRACE("(%p)->()\n",This
);
101 return IUnknown_QueryInterface(This
->unk
.punkControl
,riid
,ppobj
);
105 ICreateDevEnum_fnAddRef(ICreateDevEnum
* iface
)
107 CSysDevEnum_THIS(iface
,createdevenum
);
109 TRACE("(%p)->()\n",This
);
111 return IUnknown_AddRef(This
->unk
.punkControl
);
115 ICreateDevEnum_fnRelease(ICreateDevEnum
* iface
)
117 CSysDevEnum_THIS(iface
,createdevenum
);
119 TRACE("(%p)->()\n",This
);
121 return IUnknown_Release(This
->unk
.punkControl
);
124 static HRESULT WINAPI
125 ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum
* iface
,REFCLSID rclsidDeviceClass
,IEnumMoniker
** ppobj
, DWORD dwFlags
)
127 CSysDevEnum_THIS(iface
,createdevenum
);
130 QUARTZ_CompList
* pMonList
;
134 WCHAR wszPath
[ 1024 ];
138 FILETIME ftLastWrite
;
140 TRACE("(%p)->(%s,%p,%08lx)\n",This
,
141 debugstr_guid(rclsidDeviceClass
),ppobj
,dwFlags
);
144 FIXME("unknown flags %08lx\n",dwFlags
);
152 hr
= QUARTZ_CreateCLSIDPath(
153 wszPath
, sizeof(wszPath
)/sizeof(wszPath
[0]) - 16,
154 rclsidDeviceClass
, QUARTZ_wszInstance
);
158 lr
= RegOpenKeyExW( HKEY_CLASSES_ROOT
, wszPath
,
159 0, KEY_READ
, &hKey
);
160 if ( lr
!= ERROR_SUCCESS
)
162 TRACE("cannot open %s\n",debugstr_w(wszPath
));
163 if ( lr
== ERROR_FILE_NOT_FOUND
||
164 lr
== ERROR_PATH_NOT_FOUND
)
169 dwLen
= lstrlenW(wszPath
);
170 wszPath
[dwLen
++] = '\\'; wszPath
[dwLen
] = 0;
171 dwNameMax
= sizeof(wszPath
)/sizeof(wszPath
[0]) - dwLen
- 8;
173 pMonList
= QUARTZ_CompList_Alloc();
174 if ( pMonList
== NULL
)
180 /* enumerate all subkeys. */
186 hKey
, dwIndex
, &wszPath
[dwLen
], &cbName
,
187 NULL
, NULL
, NULL
, &ftLastWrite
);
188 if ( lr
== ERROR_NO_MORE_ITEMS
)
190 if ( lr
!= ERROR_SUCCESS
)
192 TRACE("RegEnumKeyEx returns %08lx\n",lr
);
197 hr
= QUARTZ_CreateDeviceMoniker(
198 HKEY_CLASSES_ROOT
, wszPath
, &pMon
);
202 hr
= QUARTZ_CompList_AddComp(
203 pMonList
, (IUnknown
*)pMon
, NULL
, 0 );
204 IMoniker_Release( pMon
);
212 /* create an enumerator. */
213 hr
= QUARTZ_CreateEnumUnknown(
214 &IID_IEnumMoniker
, (void**)ppobj
, pMonList
);
220 if ( pMonList
!= NULL
)
221 QUARTZ_CompList_Free( pMonList
);
227 static ICOM_VTABLE(ICreateDevEnum
) icreatedevenum
=
229 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
230 /* IUnknown fields */
231 ICreateDevEnum_fnQueryInterface
,
232 ICreateDevEnum_fnAddRef
,
233 ICreateDevEnum_fnRelease
,
234 /* ICreateDevEnum fields */
235 ICreateDevEnum_fnCreateClassEnumerator
,
238 HRESULT
CSysDevEnum_InitICreateDevEnum( CSysDevEnum
* psde
)
240 TRACE("(%p)\n",psde
);
241 ICOM_VTBL(&psde
->createdevenum
) = &icreatedevenum
;
246 void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum
* psde
)
248 TRACE("(%p)\n",psde
);
252 /***************************************************************************
254 * CDeviceMoniker::IMoniker
258 static HRESULT WINAPI
259 IMoniker_fnQueryInterface(IMoniker
* iface
,REFIID riid
,void** ppobj
)
261 CDeviceMoniker_THIS(iface
,moniker
);
263 TRACE("(%p)->()\n",This
);
265 return IUnknown_QueryInterface(This
->unk
.punkControl
,riid
,ppobj
);
269 IMoniker_fnAddRef(IMoniker
* iface
)
271 CDeviceMoniker_THIS(iface
,moniker
);
273 TRACE("(%p)->()\n",This
);
275 return IUnknown_AddRef(This
->unk
.punkControl
);
279 IMoniker_fnRelease(IMoniker
* iface
)
281 CDeviceMoniker_THIS(iface
,moniker
);
283 TRACE("(%p)->()\n",This
);
285 return IUnknown_Release(This
->unk
.punkControl
);
288 static HRESULT WINAPI
IMoniker_fnGetClassID(IMoniker
* iface
, CLSID
*pClassID
)
290 CDeviceMoniker_THIS(iface
,moniker
);
292 TRACE("(%p)->()\n",This
);
294 if ( pClassID
== NULL
)
296 memcpy( pClassID
, &CLSID_CDeviceMoniker
, sizeof(CLSID
) );
301 static HRESULT WINAPI
IMoniker_fnIsDirty(IMoniker
* iface
)
303 CDeviceMoniker_THIS(iface
,moniker
);
305 FIXME("(%p)->() stub!\n",This
);
310 static HRESULT WINAPI
IMoniker_fnLoad(IMoniker
* iface
, IStream
* pStm
)
312 CDeviceMoniker_THIS(iface
,moniker
);
314 FIXME("(%p)->() stub!\n",This
);
319 static HRESULT WINAPI
IMoniker_fnSave(IMoniker
* iface
, IStream
* pStm
, BOOL fClearDirty
)
321 CDeviceMoniker_THIS(iface
,moniker
);
323 FIXME("(%p)->() stub!\n",This
);
328 static HRESULT WINAPI
IMoniker_fnGetSizeMax(IMoniker
* iface
, ULARGE_INTEGER
* pcbSize
)
330 CDeviceMoniker_THIS(iface
,moniker
);
332 FIXME("(%p)->() stub!\n",This
);
337 static HRESULT WINAPI
IMoniker_fnBindToObject(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, REFIID riid
, VOID
** ppvResult
)
339 CDeviceMoniker_THIS(iface
,moniker
);
341 IPropertyBag
* pPropBag
;
342 IPersistPropertyBag
* pPersistPropBag
;
346 TRACE("(%p)->(%p,%p,%s,%p)\n",This
,
347 pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
350 FIXME("IBindCtx* pbc != NULL not implemented.\n");
353 if ( pmkToLeft
!= NULL
)
355 FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
358 if ( ppvResult
== NULL
)
361 hr
= QUARTZ_CreateRegPropertyBag(
362 This
->m_hkRoot
, This
->m_pwszPath
, &pPropBag
);
366 vClsid
.n1
.n2
.vt
= VT_BSTR
;
367 hr
= IPropertyBag_Read(
368 pPropBag
, QUARTZ_wszCLSID
, &vClsid
, NULL
);
369 IPropertyBag_Release( pPropBag
);
373 hr
= CLSIDFromString( vClsid
.n1
.n2
.n3
.bstrVal
, &clsid
);
374 SysFreeString(vClsid
.n1
.n2
.n3
.bstrVal
);
378 hr
= CoCreateInstance(
379 &clsid
, NULL
, CLSCTX_INPROC_SERVER
, riid
, ppvResult
);
383 hr
= IUnknown_QueryInterface((IUnknown
*)*ppvResult
,&IID_IPersistPropertyBag
,(void**)&pPersistPropBag
);
384 if ( hr
== E_NOINTERFACE
)
391 hr
= QUARTZ_CreateRegPropertyBag(
392 This
->m_hkRoot
, This
->m_pwszPath
, &pPropBag
);
395 hr
= IPersistPropertyBag_Load(pPersistPropBag
,pPropBag
,NULL
);
396 IPropertyBag_Release( pPropBag
);
398 IPersistPropertyBag_Release(pPersistPropBag
);
403 IUnknown_Release((IUnknown
*)*ppvResult
);
407 TRACE( "hr = %08lx\n", hr
);
412 static HRESULT WINAPI
IMoniker_fnBindToStorage(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, REFIID riid
, VOID
** ppvResult
)
414 CDeviceMoniker_THIS(iface
,moniker
);
417 TRACE("(%p)->(%p,%p,%s,%p)\n",This
,
418 pbc
,pmkToLeft
,debugstr_guid(riid
),ppvResult
);
421 FIXME("IBindCtx* pbc != NULL not implemented.\n");
424 if ( pmkToLeft
!= NULL
)
426 FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
429 if ( ppvResult
== NULL
)
433 if ( IsEqualGUID(riid
,&IID_IUnknown
) ||
434 IsEqualGUID(riid
,&IID_IPropertyBag
) )
436 hr
= QUARTZ_CreateRegPropertyBag(
437 This
->m_hkRoot
, This
->m_pwszPath
,
438 (IPropertyBag
**)ppvResult
);
444 static HRESULT WINAPI
IMoniker_fnReduce(IMoniker
* iface
,IBindCtx
* pbc
, DWORD dwReduceHowFar
,IMoniker
** ppmkToLeft
, IMoniker
** ppmkReduced
)
446 CDeviceMoniker_THIS(iface
,moniker
);
448 TRACE("(%p)->()\n",This
);
450 if ( ppmkReduced
== NULL
)
453 *ppmkReduced
= iface
; IMoniker_AddRef(iface
);
455 return MK_S_REDUCED_TO_SELF
;
458 static HRESULT WINAPI
IMoniker_fnComposeWith(IMoniker
* iface
,IMoniker
* pmkRight
,BOOL fOnlyIfNotGeneric
, IMoniker
** ppmkComposite
)
460 CDeviceMoniker_THIS(iface
,moniker
);
462 FIXME("(%p)->() stub!\n",This
);
467 static HRESULT WINAPI
IMoniker_fnEnum(IMoniker
* iface
,BOOL fForward
, IEnumMoniker
** ppenumMoniker
)
469 CDeviceMoniker_THIS(iface
,moniker
);
471 TRACE("(%p)->()\n",This
);
473 if ( ppenumMoniker
== NULL
)
476 *ppenumMoniker
= NULL
;
480 static HRESULT WINAPI
IMoniker_fnIsEqual(IMoniker
* iface
,IMoniker
* pmkOtherMoniker
)
482 CDeviceMoniker_THIS(iface
,moniker
);
484 FIXME("(%p)->() stub!\n",This
);
489 static HRESULT WINAPI
IMoniker_fnHash(IMoniker
* iface
,DWORD
* pdwHash
)
491 CDeviceMoniker_THIS(iface
,moniker
);
493 FIXME("(%p)->() stub!\n",This
);
498 static HRESULT WINAPI
IMoniker_fnIsRunning(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, IMoniker
* pmkNewlyRunning
)
500 CDeviceMoniker_THIS(iface
,moniker
);
502 FIXME("(%p)->() stub!\n",This
);
507 static HRESULT WINAPI
IMoniker_fnGetTimeOfLastChange(IMoniker
* iface
, IBindCtx
* pbc
, IMoniker
* pmkToLeft
, FILETIME
* pCompositeTime
)
509 CDeviceMoniker_THIS(iface
,moniker
);
511 FIXME("(%p)->() stub!\n",This
);
516 static HRESULT WINAPI
IMoniker_fnInverse(IMoniker
* iface
,IMoniker
** ppmk
)
518 CDeviceMoniker_THIS(iface
,moniker
);
520 FIXME("(%p)->() stub!\n",This
);
525 static HRESULT WINAPI
IMoniker_fnCommonPrefixWith(IMoniker
* iface
,IMoniker
* pmkOther
, IMoniker
** ppmkPrefix
)
527 CDeviceMoniker_THIS(iface
,moniker
);
529 FIXME("(%p)->() stub!\n",This
);
534 static HRESULT WINAPI
IMoniker_fnRelativePathTo(IMoniker
* iface
,IMoniker
* pmOther
, IMoniker
** ppmkRelPath
)
536 CDeviceMoniker_THIS(iface
,moniker
);
538 FIXME("(%p)->() stub!\n",This
);
543 static HRESULT WINAPI
IMoniker_fnGetDisplayName(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, LPOLESTR
*ppszDisplayName
)
545 CDeviceMoniker_THIS(iface
,moniker
);
547 FIXME("(%p)->() stub!\n",This
);
552 static HRESULT WINAPI
IMoniker_fnParseDisplayName(IMoniker
* iface
,IBindCtx
* pbc
, IMoniker
* pmkToLeft
, LPOLESTR pszDisplayName
, ULONG
* pchEaten
, IMoniker
** ppmkOut
)
554 CDeviceMoniker_THIS(iface
,moniker
);
556 FIXME("(%p)->() stub!\n",This
);
561 static HRESULT WINAPI
IMoniker_fnIsSystemMoniker(IMoniker
* iface
,DWORD
* pdwMksys
)
563 CDeviceMoniker_THIS(iface
,moniker
);
565 TRACE("(%p)->()\n",This
);
566 if ( pdwMksys
== NULL
)
569 *pdwMksys
= MKSYS_NONE
;
574 static ICOM_VTABLE(IMoniker
) imoniker
=
576 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
577 /* IUnknown fields */
578 IMoniker_fnQueryInterface
,
581 /* IPersist fields */
582 IMoniker_fnGetClassID
,
583 /* IPersistStream fields */
587 IMoniker_fnGetSizeMax
,
588 /* IMoniker fields */
589 IMoniker_fnBindToObject
,
590 IMoniker_fnBindToStorage
,
592 IMoniker_fnComposeWith
,
596 IMoniker_fnIsRunning
,
597 IMoniker_fnGetTimeOfLastChange
,
599 IMoniker_fnCommonPrefixWith
,
600 IMoniker_fnRelativePathTo
,
601 IMoniker_fnGetDisplayName
,
602 IMoniker_fnParseDisplayName
,
603 IMoniker_fnIsSystemMoniker
,
607 static HRESULT
CDeviceMoniker_InitIMoniker(
608 CDeviceMoniker
* pdm
, HKEY hkRoot
, LPCWSTR lpKeyPath
)
612 ICOM_VTBL(&pdm
->moniker
) = &imoniker
;
613 pdm
->m_hkRoot
= hkRoot
;
614 pdm
->m_pwszPath
= NULL
;
616 dwLen
= sizeof(WCHAR
)*(lstrlenW(lpKeyPath
)+1);
617 pdm
->m_pwszPath
= (WCHAR
*)QUARTZ_AllocMem( dwLen
);
618 if ( pdm
->m_pwszPath
== NULL
)
619 return E_OUTOFMEMORY
;
620 memcpy( pdm
->m_pwszPath
, lpKeyPath
, dwLen
);
625 static void CDeviceMoniker_UninitIMoniker(
626 CDeviceMoniker
* pdm
)
628 if ( pdm
->m_pwszPath
!= NULL
)
629 QUARTZ_FreeMem( pdm
->m_pwszPath
);
632 /***************************************************************************
634 * new/delete for CDeviceMoniker
638 static void QUARTZ_DestroyDeviceMoniker(IUnknown
* punk
)
640 CDeviceMoniker_THIS(punk
,unk
);
642 CDeviceMoniker_UninitIMoniker( This
);
645 /* can I use offsetof safely? - FIXME? */
646 static QUARTZ_IFEntry CDeviceMoniker_IFEntries
[] =
648 { &IID_IPersist
, offsetof(CDeviceMoniker
,moniker
)-offsetof(CDeviceMoniker
,unk
) },
649 { &IID_IPersistStream
, offsetof(CDeviceMoniker
,moniker
)-offsetof(CDeviceMoniker
,unk
) },
650 { &IID_IMoniker
, offsetof(CDeviceMoniker
,moniker
)-offsetof(CDeviceMoniker
,unk
) },
653 HRESULT
QUARTZ_CreateDeviceMoniker(
654 HKEY hkRoot
, LPCWSTR lpKeyPath
,
655 IMoniker
** ppMoniker
)
660 TRACE("(%08x,%s,%p)\n",hkRoot
,debugstr_w(lpKeyPath
),ppMoniker
);
662 pdm
= (CDeviceMoniker
*)QUARTZ_AllocObj( sizeof(CDeviceMoniker
) );
664 return E_OUTOFMEMORY
;
666 QUARTZ_IUnkInit( &pdm
->unk
, NULL
);
667 hr
= CDeviceMoniker_InitIMoniker( pdm
, hkRoot
, lpKeyPath
);
670 QUARTZ_FreeObj( pdm
);
674 pdm
->unk
.pEntries
= CDeviceMoniker_IFEntries
;
675 pdm
->unk
.dwEntries
= sizeof(CDeviceMoniker_IFEntries
)/sizeof(CDeviceMoniker_IFEntries
[0]);
676 pdm
->unk
.pOnFinalRelease
= &QUARTZ_DestroyDeviceMoniker
;
678 *ppMoniker
= (IMoniker
*)(&pdm
->moniker
);
684 /***************************************************************************
686 * CRegPropertyBag::IPropertyBag
690 static HRESULT WINAPI
691 IPropertyBag_fnQueryInterface(IPropertyBag
* iface
,REFIID riid
,void** ppobj
)
693 CRegPropertyBag_THIS(iface
,propbag
);
695 TRACE("(%p)->()\n",This
);
697 return IUnknown_QueryInterface(This
->unk
.punkControl
,riid
,ppobj
);
701 IPropertyBag_fnAddRef(IPropertyBag
* iface
)
703 CRegPropertyBag_THIS(iface
,propbag
);
705 TRACE("(%p)->()\n",This
);
707 return IUnknown_AddRef(This
->unk
.punkControl
);
711 IPropertyBag_fnRelease(IPropertyBag
* iface
)
713 CRegPropertyBag_THIS(iface
,propbag
);
715 TRACE("(%p)->()\n",This
);
717 return IUnknown_Release(This
->unk
.punkControl
);
720 static HRESULT WINAPI
721 IPropertyBag_fnRead(IPropertyBag
* iface
,LPCOLESTR lpszPropName
,VARIANT
* pVar
,IErrorLog
* pLog
)
723 CRegPropertyBag_THIS(iface
,propbag
);
732 TRACE("(%p)->(%s,%p,%p)\n",This
,
733 debugstr_w(lpszPropName
),pVar
,pLog
);
735 if ( lpszPropName
== NULL
|| pVar
== NULL
)
739 lr
= RegQueryValueExW(
740 This
->m_hKey
, lpszPropName
, NULL
,
741 &dwValueType
, NULL
, &dwSize
);
742 if ( lr
!= ERROR_SUCCESS
)
744 WARN( "RegQueryValueExW failed.\n" );
748 switch ( dwValueType
)
751 TRACE( "REG_SZ / length = %lu\n", dwSize
);
752 if ( pVar
->n1
.n2
.vt
== VT_EMPTY
)
753 pVar
->n1
.n2
.vt
= VT_BSTR
;
754 if ( pVar
->n1
.n2
.vt
!= VT_BSTR
)
756 FIXME( "type of VARIANT is not BSTR.\n" );
760 pVar
->n1
.n2
.n3
.bstrVal
= SysAllocStringByteLen(
762 if ( pVar
->n1
.n2
.n3
.bstrVal
== NULL
)
764 WARN( "out of memory.\n" );
765 return E_OUTOFMEMORY
;
767 lr
= RegQueryValueExW(
768 This
->m_hKey
, lpszPropName
, NULL
,
770 (BYTE
*)pVar
->n1
.n2
.n3
.bstrVal
, &dwSize
);
771 if ( lr
!= ERROR_SUCCESS
)
773 WARN( "failed to query value\n" );
774 SysFreeString(pVar
->n1
.n2
.n3
.bstrVal
);
777 TRACE( "value is BSTR; %s\n", debugstr_w(pVar
->n1
.n2
.n3
.bstrVal
) );
780 TRACE( "REG_BINARY / length = %lu\n", dwSize
);
781 if ( pVar
->n1
.n2
.vt
== VT_EMPTY
)
782 pVar
->n1
.n2
.vt
= VT_ARRAY
|VT_UI1
;
783 if ( pVar
->n1
.n2
.vt
!= (VT_ARRAY
|VT_UI1
) )
785 FIXME( "type of VARIANT is not VT_ARRAY|VT_UI1.\n" );
789 sab
.cElements
= dwSize
;
790 pArray
= SafeArrayCreate( VT_UI1
, 1, &sab
);
791 if ( pArray
== NULL
)
792 return E_OUTOFMEMORY
;
793 hr
= SafeArrayLock( pArray
);
796 WARN( "safe array can't be locked\n" );
797 SafeArrayDestroy( pArray
);
800 lr
= RegQueryValueExW(
801 This
->m_hKey
, lpszPropName
, NULL
,
803 (BYTE
*)pArray
->pvData
, &dwSize
);
804 SafeArrayUnlock( pArray
);
805 if ( lr
!= ERROR_SUCCESS
)
807 WARN( "failed to query value\n" );
808 SafeArrayDestroy( pArray
);
811 pVar
->n1
.n2
.n3
.parray
= pArray
;
812 TRACE( "value is SAFEARRAY - array of BYTE; \n" );
815 TRACE( "REG_DWORD / length = %lu\n", dwSize
);
816 if ( dwSize
!= sizeof(DWORD
) )
818 WARN( "The length of REG_DWORD value is not sizeof(DWORD).\n" );
821 if ( pVar
->n1
.n2
.vt
== VT_EMPTY
)
822 pVar
->n1
.n2
.vt
= VT_I4
;
823 if ( pVar
->n1
.n2
.vt
!= VT_I4
)
825 FIXME( "type of VARIANT is not VT_I4.\n" );
828 lr
= RegQueryValueExW(
829 This
->m_hKey
, lpszPropName
, NULL
,
831 (BYTE
*)(&dwDWordValue
), &dwSize
);
832 if ( lr
!= ERROR_SUCCESS
)
834 WARN( "failed to query value\n" );
837 pVar
->n1
.n2
.n3
.lVal
= dwDWordValue
;
838 TRACE( "value is DWORD; %08lx\n", dwDWordValue
);
841 FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This
,
842 debugstr_w(lpszPropName
),pVar
,pLog
);
846 TRACE( "returned successfully.\n" );
850 static HRESULT WINAPI
851 IPropertyBag_fnWrite(IPropertyBag
* iface
,LPCOLESTR lpszPropName
,VARIANT
* pVar
)
853 CRegPropertyBag_THIS(iface
,propbag
);
859 TRACE("(%p)->(%s,%p)\n",This
,
860 debugstr_w(lpszPropName
),pVar
);
862 if ( lpszPropName
== NULL
|| pVar
== NULL
)
865 switch ( pVar
->n1
.n2
.vt
)
867 case VT_I4
: /* REG_DWORD */
868 dwDWordValue
= pVar
->n1
.n2
.n3
.lVal
;
870 This
->m_hKey
, lpszPropName
, 0,
872 (const BYTE
*)(&dwDWordValue
), sizeof(DWORD
) );
873 if ( lr
!= ERROR_SUCCESS
)
875 WARN( "failed to set value\n" );
879 case VT_BSTR
: /* REG_SZ */
881 This
->m_hKey
, lpszPropName
, 0,
883 (const BYTE
*)(pVar
->n1
.n2
.n3
.bstrVal
),
884 SysStringByteLen( pVar
->n1
.n2
.n3
.bstrVal
) );
885 if ( lr
!= ERROR_SUCCESS
)
887 WARN( "failed to set value\n" );
891 case (VT_ARRAY
|VT_UI1
): /* REG_BINARY */
892 pArray
= pVar
->n1
.n2
.n3
.parray
;
893 if ( pArray
->cDims
!= 1 || pArray
->cbElements
!= 1 ||
894 pArray
->rgsabound
[0].lLbound
!= 0 )
896 WARN( "invalid array\n" );
899 hr
= SafeArrayLock( pArray
);
902 WARN( "safe array can't be locked\n" );
906 This
->m_hKey
, lpszPropName
, 0,
908 (const BYTE
*)pArray
->pvData
,
909 pArray
->rgsabound
[0].cElements
);
910 SafeArrayUnlock( pArray
);
911 if ( lr
!= ERROR_SUCCESS
)
913 WARN( "failed to set value\n" );
918 FIXME("(%p)->(%s,%p) invalid/unsupported VARIANT type %04x\n",This
,
919 debugstr_w(lpszPropName
),pVar
,pVar
->n1
.n2
.vt
);
923 TRACE( "returned successfully.\n" );
930 static ICOM_VTABLE(IPropertyBag
) ipropbag
=
932 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
933 /* IUnknown fields */
934 IPropertyBag_fnQueryInterface
,
935 IPropertyBag_fnAddRef
,
936 IPropertyBag_fnRelease
,
937 /* IPropertyBag fields */
939 IPropertyBag_fnWrite
,
942 static HRESULT
CRegPropertyBag_InitIPropertyBag(
943 CRegPropertyBag
* prpb
, HKEY hkRoot
, LPCWSTR lpKeyPath
)
945 WCHAR wszREG_SZ
[ NUMELEMS(QUARTZ_wszREG_SZ
) ];
948 ICOM_VTBL(&prpb
->propbag
) = &ipropbag
;
950 memcpy(wszREG_SZ
,QUARTZ_wszREG_SZ
,sizeof(QUARTZ_wszREG_SZ
) );
952 if ( RegCreateKeyExW(
953 hkRoot
, lpKeyPath
, 0, wszREG_SZ
,
954 REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
,
955 &prpb
->m_hKey
, &dwDisp
) != ERROR_SUCCESS
)
961 static void CRegPropertyBag_UninitIPropertyBag(
962 CRegPropertyBag
* prpb
)
964 RegCloseKey( prpb
->m_hKey
);
968 /***************************************************************************
970 * new/delete for CRegPropertyBag
974 static void QUARTZ_DestroyRegPropertyBag(IUnknown
* punk
)
976 CRegPropertyBag_THIS(punk
,unk
);
978 CRegPropertyBag_UninitIPropertyBag(This
);
982 /* can I use offsetof safely? - FIXME? */
983 static QUARTZ_IFEntry CRegPropertyBag_IFEntries
[] =
985 { &IID_IPropertyBag
, offsetof(CRegPropertyBag
,propbag
)-offsetof(CRegPropertyBag
,unk
) },
988 HRESULT
QUARTZ_CreateRegPropertyBag(
989 HKEY hkRoot
, LPCWSTR lpKeyPath
,
990 IPropertyBag
** ppPropBag
)
992 CRegPropertyBag
* prpb
;
995 TRACE("(%08x,%s,%p)\n",hkRoot
,debugstr_w(lpKeyPath
),ppPropBag
);
997 prpb
= (CRegPropertyBag
*)QUARTZ_AllocObj( sizeof(CRegPropertyBag
) );
999 return E_OUTOFMEMORY
;
1001 QUARTZ_IUnkInit( &prpb
->unk
, NULL
);
1002 hr
= CRegPropertyBag_InitIPropertyBag( prpb
, hkRoot
, lpKeyPath
);
1005 QUARTZ_FreeObj( prpb
);
1009 prpb
->unk
.pEntries
= CRegPropertyBag_IFEntries
;
1010 prpb
->unk
.dwEntries
= sizeof(CRegPropertyBag_IFEntries
)/sizeof(CRegPropertyBag_IFEntries
[0]);
1011 prpb
->unk
.pOnFinalRelease
= &QUARTZ_DestroyRegPropertyBag
;
1013 *ppPropBag
= (IPropertyBag
*)(&prpb
->propbag
);
1018 /***************************************************************************
1020 * Helper for registering filters.
1024 HRESULT
QUARTZ_GetFilterRegPath(
1025 WCHAR
** ppwszPath
, /* [OUT] path from HKEY_CLASSES_ROOT */
1026 const CLSID
* pguidFilterCategory
, /* [IN] Category */
1027 const CLSID
* pclsid
, /* [IN] CLSID of this filter */
1028 LPCWSTR lpInstance
) /* [IN] instance */
1031 WCHAR szKey
[ 1024 ];
1032 WCHAR szFilterPath
[ 512 ];
1033 WCHAR szCLSID
[ 256 ];
1036 TRACE("(%p,%s,%s,%s)\n",ppwszPath
,debugstr_guid(pguidFilterCategory
),debugstr_guid(pclsid
),debugstr_w(lpInstance
) );
1040 QUARTZ_GUIDtoString( szCLSID
, pclsid
);
1041 lstrcpyW( szFilterPath
, QUARTZ_wszInstance
);
1042 QUARTZ_CatPathSepW( szFilterPath
);
1043 if ( lpInstance
!= NULL
)
1045 if ( lstrlenW(lpInstance
) >= 256 )
1046 return E_INVALIDARG
;
1047 lstrcatW( szFilterPath
, lpInstance
);
1051 lstrcatW( szFilterPath
, szCLSID
);
1054 hr
= QUARTZ_CreateCLSIDPath(
1055 szKey
, NUMELEMS(szKey
),
1056 pguidFilterCategory
, szFilterPath
);
1060 buflen
= sizeof(WCHAR
)*(lstrlenW(szKey
)+1);
1061 *ppwszPath
= QUARTZ_AllocMem( buflen
);
1062 if ( *ppwszPath
== NULL
)
1063 return E_OUTOFMEMORY
;
1064 memcpy( *ppwszPath
, szKey
, buflen
);
1068 HRESULT
QUARTZ_RegisterFilterToMoniker(
1069 IMoniker
* pMoniker
, /* [IN] Moniker */
1070 const CLSID
* pclsid
, /* [IN] CLSID of this filter */
1071 LPCWSTR lpFriendlyName
, /* [IN] friendly name */
1072 const BYTE
* pbFilterData
, /* [IN] filter data */
1073 DWORD cbFilterData
) /* [IN] size of the filter data */
1075 IPropertyBag
* pPropBag
= NULL
;
1076 WCHAR wszClsid
[128];
1080 SAFEARRAY
* pArray
= NULL
;
1082 TRACE("(%p,%s,%s,%p,%08lu)\n",pMoniker
,debugstr_guid(pclsid
),debugstr_w(lpFriendlyName
),pbFilterData
,cbFilterData
);
1084 hr
= IMoniker_BindToStorage(pMoniker
,NULL
,NULL
,&IID_IPropertyBag
,(void**)&pPropBag
);
1087 QUARTZ_GUIDtoString( wszClsid
, pclsid
);
1088 var
.n1
.n2
.vt
= VT_BSTR
;
1089 var
.n1
.n2
.n3
.bstrVal
= SysAllocString(wszClsid
);
1090 if ( var
.n1
.n2
.n3
.bstrVal
== NULL
)
1095 hr
= IPropertyBag_Write(pPropBag
,QUARTZ_wszCLSID
,&var
);
1096 SysFreeString(var
.n1
.n2
.n3
.bstrVal
);
1100 var
.n1
.n2
.vt
= VT_BSTR
;
1101 var
.n1
.n2
.n3
.bstrVal
= SysAllocString(lpFriendlyName
);
1102 if ( var
.n1
.n2
.n3
.bstrVal
== NULL
)
1107 hr
= IPropertyBag_Write(pPropBag
,QUARTZ_wszFriendlyName
,&var
);
1108 SysFreeString(var
.n1
.n2
.n3
.bstrVal
);
1112 if ( pbFilterData
!= NULL
)
1114 var
.n1
.n2
.vt
= VT_ARRAY
|VT_UI1
;
1116 sab
.cElements
= cbFilterData
;
1117 pArray
= SafeArrayCreate( VT_UI1
, 1, &sab
);
1118 if ( pArray
== NULL
)
1123 hr
= SafeArrayLock( pArray
);
1126 var
.n1
.n2
.n3
.parray
= pArray
;
1127 memcpy( pArray
->pvData
, pbFilterData
, cbFilterData
);
1128 hr
= IPropertyBag_Write(pPropBag
,QUARTZ_wszFilterData
,&var
);
1129 SafeArrayUnlock( pArray
);
1136 if ( pArray
!= NULL
)
1137 SafeArrayDestroy( pArray
);
1138 if ( pPropBag
!= NULL
)
1139 IPropertyBag_Release(pPropBag
);
1144 HRESULT
QUARTZ_RegDeleteKey( HKEY hkRoot
, LPCWSTR lpKeyPath
)
1151 FILETIME ftLastWrite
;
1153 WCHAR wszPath
[ 512 ];
1155 TRACE("(%08x,%s)\n",hkRoot
,debugstr_w(lpKeyPath
));
1157 lr
= RegOpenKeyExW( hkRoot
, lpKeyPath
, 0, KEY_ALL_ACCESS
, &hKey
);
1158 if ( lr
== ERROR_SUCCESS
)
1163 cbName
= NUMELEMS(wszPath
);
1165 hKey
, dwIndex
, wszPath
, &cbName
,
1166 NULL
, NULL
, NULL
, &ftLastWrite
);
1167 if ( lr
!= ERROR_SUCCESS
)
1169 hr
= QUARTZ_RegDeleteKey( hKey
, wszPath
);
1177 cbName
= NUMELEMS(wszPath
);
1179 hKey
, 0, wszPath
, &cbName
, 0,
1181 if ( lr
!= ERROR_SUCCESS
)
1183 lr
= RegDeleteValueW( hKey
, wszPath
);
1184 if ( lr
!= ERROR_SUCCESS
)
1186 WARN("RegDeleteValueW - %08lx\n",lr
);
1191 RegCloseKey( hKey
);
1193 lr
= RegDeleteKeyW( hkRoot
, lpKeyPath
);
1194 WARN("RegDeleteKeyW - %08lx\n",lr
);
1195 if ( lr
!= ERROR_SUCCESS
&& lr
!= ERROR_FILE_NOT_FOUND
)
1201 HRESULT
QUARTZ_GetPropertyFromMoniker(
1202 IMoniker
* pMoniker
, /* [IN] Moniker */
1203 LPCOLESTR lpszPropName
, /* [IN] Property */
1204 VARIANT
* pVar
) /* [OUT] */
1206 IPropertyBag
* pPropBag
= NULL
;
1209 TRACE("(%p,%s,%p)\n",pMoniker
,debugstr_w(lpszPropName
),pVar
);
1211 hr
= IMoniker_BindToStorage(pMoniker
,NULL
,NULL
,&IID_IPropertyBag
,(void**)&pPropBag
);
1214 hr
= IPropertyBag_Read(pPropBag
,lpszPropName
,pVar
,NULL
);
1215 IPropertyBag_Release(pPropBag
);
1220 HRESULT
QUARTZ_GetCLSIDFromMoniker(
1221 IMoniker
* pMoniker
, /* [IN] Moniker */
1222 CLSID
* pclsid
) /* [OUT] */
1227 var
.n1
.n2
.vt
= VT_BSTR
;
1228 hr
= QUARTZ_GetPropertyFromMoniker(
1229 pMoniker
, QUARTZ_wszCLSID
, &var
);
1232 hr
= CLSIDFromString(var
.n1
.n2
.n3
.bstrVal
,pclsid
);
1233 SysFreeString(var
.n1
.n2
.n3
.bstrVal
);
1239 HRESULT
QUARTZ_GetMeritFromMoniker(
1240 IMoniker
* pMoniker
, /* [IN] Moniker */
1241 DWORD
* pdwMerit
) /* [OUT] */
1246 var
.n1
.n2
.vt
= VT_I4
;
1247 hr
= QUARTZ_GetPropertyFromMoniker(
1248 pMoniker
, QUARTZ_wszMerit
, &var
);
1250 *pdwMerit
= var
.n1
.n2
.n3
.lVal
;
1255 HRESULT
QUARTZ_GetFilterDataFromMoniker(
1256 IMoniker
* pMoniker
, /* [IN] Moniker */
1257 BYTE
** ppbFilterData
, /* [OUT] */
1258 DWORD
* pcbFilterData
) /* [OUT] */
1264 var
.n1
.n2
.vt
= VT_ARRAY
|VT_UI1
;
1265 hr
= QUARTZ_GetPropertyFromMoniker(
1266 pMoniker
, QUARTZ_wszFilterData
, &var
);
1269 pArray
= var
.n1
.n2
.n3
.parray
;
1270 hr
= SafeArrayLock( pArray
);
1271 if ( SUCCEEDED(hr
) )
1273 *pcbFilterData
= pArray
->rgsabound
[0].cElements
- pArray
->rgsabound
[0].lLbound
;
1274 *ppbFilterData
= (BYTE
*)QUARTZ_AllocMem( *pcbFilterData
);
1275 if ( *ppbFilterData
== NULL
)
1278 memcpy( *ppbFilterData
, pArray
->pvData
, *pcbFilterData
);
1280 SafeArrayUnlock( pArray
);
1282 SafeArrayDestroy( pArray
);