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 );