2 * Implementation of CLSID_SystemDeviceEnum.
3 * Implements IMoniker for CLSID_CDeviceMoniker.
4 * Implements IPropertyBag. (internal)
6 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
41 #include "quartz_private.h"
48 #define NUMELEMS(elem) (sizeof(elem)/sizeof(elem[0]))
51 /***************************************************************************
53 * new/delete for CLSID_SystemDeviceEnum
57 /* can I use offsetof safely? - FIXME? */
58 static QUARTZ_IFEntry CSysDevEnum_IFEntries[] =
60 { &IID_ICreateDevEnum, offsetof(CSysDevEnum,createdevenum)-offsetof(CSysDevEnum,unk) },
64 static void QUARTZ_DestroySystemDeviceEnum(IUnknown* punk)
66 CSysDevEnum_THIS(punk,unk);
68 CSysDevEnum_UninitICreateDevEnum( This );
71 HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj)
76 TRACE("(%p,%p)\n",punkOuter,ppobj);
78 psde = (CSysDevEnum*)QUARTZ_AllocObj( sizeof(CSysDevEnum) );
82 QUARTZ_IUnkInit( &psde->unk, punkOuter );
84 hr = CSysDevEnum_InitICreateDevEnum( psde );
87 QUARTZ_FreeObj( psde );
91 psde->unk.pEntries = CSysDevEnum_IFEntries;
92 psde->unk.dwEntries = sizeof(CSysDevEnum_IFEntries)/sizeof(CSysDevEnum_IFEntries[0]);
93 psde->unk.pOnFinalRelease = QUARTZ_DestroySystemDeviceEnum;
95 *ppobj = (void*)(&psde->unk);
101 /***************************************************************************
103 * CSysDevEnum::ICreateDevEnum
108 static HRESULT WINAPI
109 ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj)
111 CSysDevEnum_THIS(iface,createdevenum);
113 TRACE("(%p)->()\n",This);
115 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
119 ICreateDevEnum_fnAddRef(ICreateDevEnum* iface)
121 CSysDevEnum_THIS(iface,createdevenum);
123 TRACE("(%p)->()\n",This);
125 return IUnknown_AddRef(This->unk.punkControl);
129 ICreateDevEnum_fnRelease(ICreateDevEnum* iface)
131 CSysDevEnum_THIS(iface,createdevenum);
133 TRACE("(%p)->()\n",This);
135 return IUnknown_Release(This->unk.punkControl);
138 static HRESULT WINAPI
139 ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags)
141 CSysDevEnum_THIS(iface,createdevenum);
144 QUARTZ_CompList* pMonList;
148 WCHAR wszPath[ 1024 ];
152 FILETIME ftLastWrite;
154 TRACE("(%p)->(%s,%p,%08lx)\n",This,
155 debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
158 FIXME("unknown flags %08lx\n",dwFlags);
166 hr = QUARTZ_CreateCLSIDPath(
167 wszPath, sizeof(wszPath)/sizeof(wszPath[0]) - 16,
168 rclsidDeviceClass, QUARTZ_wszInstance );
172 lr = RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
173 0, KEY_READ, &hKey );
174 if ( lr != ERROR_SUCCESS )
176 TRACE("cannot open %s\n",debugstr_w(wszPath));
177 if ( lr == ERROR_FILE_NOT_FOUND ||
178 lr == ERROR_PATH_NOT_FOUND )
183 dwLen = lstrlenW(wszPath);
184 wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
185 dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
187 pMonList = QUARTZ_CompList_Alloc();
188 if ( pMonList == NULL )
194 /* enumerate all subkeys. */
200 hKey, dwIndex, &wszPath[dwLen], &cbName,
201 NULL, NULL, NULL, &ftLastWrite );
202 if ( lr == ERROR_NO_MORE_ITEMS )
204 if ( lr != ERROR_SUCCESS )
206 TRACE("RegEnumKeyEx returns %08lx\n",lr);
211 hr = QUARTZ_CreateDeviceMoniker(
212 HKEY_CLASSES_ROOT, wszPath, &pMon );
216 hr = QUARTZ_CompList_AddComp(
217 pMonList, (IUnknown*)pMon, NULL, 0 );
218 IMoniker_Release( pMon );
226 /* create an enumerator. */
227 hr = QUARTZ_CreateEnumUnknown(
228 &IID_IEnumMoniker, (void**)ppobj, pMonList );
234 if ( pMonList != NULL )
235 QUARTZ_CompList_Free( pMonList );
241 static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
243 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
244 /* IUnknown fields */
245 ICreateDevEnum_fnQueryInterface,
246 ICreateDevEnum_fnAddRef,
247 ICreateDevEnum_fnRelease,
248 /* ICreateDevEnum fields */
249 ICreateDevEnum_fnCreateClassEnumerator,
252 HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
254 TRACE("(%p)\n",psde);
255 ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
260 void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
262 TRACE("(%p)\n",psde);
266 /***************************************************************************
268 * CDeviceMoniker::IMoniker
272 static HRESULT WINAPI
273 IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj)
275 CDeviceMoniker_THIS(iface,moniker);
277 TRACE("(%p)->()\n",This);
279 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
283 IMoniker_fnAddRef(IMoniker* iface)
285 CDeviceMoniker_THIS(iface,moniker);
287 TRACE("(%p)->()\n",This);
289 return IUnknown_AddRef(This->unk.punkControl);
293 IMoniker_fnRelease(IMoniker* iface)
295 CDeviceMoniker_THIS(iface,moniker);
297 TRACE("(%p)->()\n",This);
299 return IUnknown_Release(This->unk.punkControl);
302 static HRESULT WINAPI IMoniker_fnGetClassID(IMoniker* iface, CLSID *pClassID)
304 CDeviceMoniker_THIS(iface,moniker);
306 TRACE("(%p)->()\n",This);
308 if ( pClassID == NULL )
310 memcpy( pClassID, &CLSID_CDeviceMoniker, sizeof(CLSID) );
315 static HRESULT WINAPI IMoniker_fnIsDirty(IMoniker* iface)
317 CDeviceMoniker_THIS(iface,moniker);
319 FIXME("(%p)->() stub!\n",This);
324 static HRESULT WINAPI IMoniker_fnLoad(IMoniker* iface, IStream* pStm)
326 CDeviceMoniker_THIS(iface,moniker);
328 FIXME("(%p)->() stub!\n",This);
333 static HRESULT WINAPI IMoniker_fnSave(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
335 CDeviceMoniker_THIS(iface,moniker);
337 FIXME("(%p)->() stub!\n",This);
342 static HRESULT WINAPI IMoniker_fnGetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
344 CDeviceMoniker_THIS(iface,moniker);
346 FIXME("(%p)->() stub!\n",This);
351 static HRESULT WINAPI IMoniker_fnBindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
353 CDeviceMoniker_THIS(iface,moniker);
355 IPropertyBag* pPropBag;
356 IPersistPropertyBag* pPersistPropBag;
360 TRACE("(%p)->(%p,%p,%s,%p)\n",This,
361 pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
364 FIXME("IBindCtx* pbc != NULL not implemented.\n");
367 if ( pmkToLeft != NULL )
369 FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
372 if ( ppvResult == NULL )
375 hr = QUARTZ_CreateRegPropertyBag(
376 This->m_hkRoot, This->m_pwszPath, &pPropBag );
380 vClsid.n1.n2.vt = VT_BSTR;
381 hr = IPropertyBag_Read(
382 pPropBag, QUARTZ_wszCLSID, &vClsid, NULL );
383 IPropertyBag_Release( pPropBag );
387 hr = CLSIDFromString( vClsid.n1.n2.n3.bstrVal, &clsid );
388 SysFreeString(vClsid.n1.n2.n3.bstrVal);
392 hr = CoCreateInstance(
393 &clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult );
397 hr = IUnknown_QueryInterface((IUnknown*)*ppvResult,&IID_IPersistPropertyBag,(void**)&pPersistPropBag);
398 if ( hr == E_NOINTERFACE )
405 hr = QUARTZ_CreateRegPropertyBag(
406 This->m_hkRoot, This->m_pwszPath, &pPropBag );
409 hr = IPersistPropertyBag_Load(pPersistPropBag,pPropBag,NULL);
410 IPropertyBag_Release( pPropBag );
412 IPersistPropertyBag_Release(pPersistPropBag);
417 IUnknown_Release((IUnknown*)*ppvResult);
421 TRACE( "hr = %08lx\n", hr );
426 static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
428 CDeviceMoniker_THIS(iface,moniker);
431 TRACE("(%p)->(%p,%p,%s,%p)\n",This,
432 pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
435 FIXME("IBindCtx* pbc != NULL not implemented.\n");
438 if ( pmkToLeft != NULL )
440 FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
443 if ( ppvResult == NULL )
447 if ( IsEqualGUID(riid,&IID_IUnknown) ||
448 IsEqualGUID(riid,&IID_IPropertyBag) )
450 hr = QUARTZ_CreateRegPropertyBag(
451 This->m_hkRoot, This->m_pwszPath,
452 (IPropertyBag**)ppvResult );
458 static HRESULT WINAPI IMoniker_fnReduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
460 CDeviceMoniker_THIS(iface,moniker);
462 TRACE("(%p)->()\n",This);
464 if ( ppmkReduced == NULL )
467 *ppmkReduced = iface; IMoniker_AddRef(iface);
469 return MK_S_REDUCED_TO_SELF;
472 static HRESULT WINAPI IMoniker_fnComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
474 CDeviceMoniker_THIS(iface,moniker);
476 FIXME("(%p)->() stub!\n",This);
481 static HRESULT WINAPI IMoniker_fnEnum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
483 CDeviceMoniker_THIS(iface,moniker);
485 TRACE("(%p)->()\n",This);
487 if ( ppenumMoniker == NULL )
490 *ppenumMoniker = NULL;
494 static HRESULT WINAPI IMoniker_fnIsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
496 CDeviceMoniker_THIS(iface,moniker);
498 FIXME("(%p)->() stub!\n",This);
503 static HRESULT WINAPI IMoniker_fnHash(IMoniker* iface,DWORD* pdwHash)
505 CDeviceMoniker_THIS(iface,moniker);
507 FIXME("(%p)->() stub!\n",This);
512 static HRESULT WINAPI IMoniker_fnIsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
514 CDeviceMoniker_THIS(iface,moniker);
516 FIXME("(%p)->() stub!\n",This);
521 static HRESULT WINAPI IMoniker_fnGetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime)
523 CDeviceMoniker_THIS(iface,moniker);
525 FIXME("(%p)->() stub!\n",This);
530 static HRESULT WINAPI IMoniker_fnInverse(IMoniker* iface,IMoniker** ppmk)
532 CDeviceMoniker_THIS(iface,moniker);
534 FIXME("(%p)->() stub!\n",This);
539 static HRESULT WINAPI IMoniker_fnCommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix)
541 CDeviceMoniker_THIS(iface,moniker);
543 FIXME("(%p)->() stub!\n",This);
548 static HRESULT WINAPI IMoniker_fnRelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
550 CDeviceMoniker_THIS(iface,moniker);
552 FIXME("(%p)->() stub!\n",This);
557 static HRESULT WINAPI IMoniker_fnGetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
559 CDeviceMoniker_THIS(iface,moniker);
561 FIXME("(%p)->() stub!\n",This);
566 static HRESULT WINAPI IMoniker_fnParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
568 CDeviceMoniker_THIS(iface,moniker);
570 FIXME("(%p)->() stub!\n",This);
575 static HRESULT WINAPI IMoniker_fnIsSystemMoniker(IMoniker* iface,DWORD* pdwMksys)
577 CDeviceMoniker_THIS(iface,moniker);
579 TRACE("(%p)->()\n",This);
580 if ( pdwMksys == NULL )
583 *pdwMksys = MKSYS_NONE;
588 static ICOM_VTABLE(IMoniker) imoniker =
590 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
591 /* IUnknown fields */
592 IMoniker_fnQueryInterface,
595 /* IPersist fields */
596 IMoniker_fnGetClassID,
597 /* IPersistStream fields */
601 IMoniker_fnGetSizeMax,
602 /* IMoniker fields */
603 IMoniker_fnBindToObject,
604 IMoniker_fnBindToStorage,
606 IMoniker_fnComposeWith,
610 IMoniker_fnIsRunning,
611 IMoniker_fnGetTimeOfLastChange,
613 IMoniker_fnCommonPrefixWith,
614 IMoniker_fnRelativePathTo,
615 IMoniker_fnGetDisplayName,
616 IMoniker_fnParseDisplayName,
617 IMoniker_fnIsSystemMoniker,
621 static HRESULT CDeviceMoniker_InitIMoniker(
622 CDeviceMoniker* pdm, HKEY hkRoot, LPCWSTR lpKeyPath )
626 ICOM_VTBL(&pdm->moniker) = &imoniker;
627 pdm->m_hkRoot = hkRoot;
628 pdm->m_pwszPath = NULL;
630 dwLen = sizeof(WCHAR)*(lstrlenW(lpKeyPath)+1);
631 pdm->m_pwszPath = (WCHAR*)QUARTZ_AllocMem( dwLen );
632 if ( pdm->m_pwszPath == NULL )
633 return E_OUTOFMEMORY;
634 memcpy( pdm->m_pwszPath, lpKeyPath, dwLen );
639 static void CDeviceMoniker_UninitIMoniker(
640 CDeviceMoniker* pdm )
642 if ( pdm->m_pwszPath != NULL )
643 QUARTZ_FreeMem( pdm->m_pwszPath );
646 /***************************************************************************
648 * new/delete for CDeviceMoniker
652 static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk)
654 CDeviceMoniker_THIS(punk,unk);
656 CDeviceMoniker_UninitIMoniker( This );
659 /* can I use offsetof safely? - FIXME? */
660 static QUARTZ_IFEntry CDeviceMoniker_IFEntries[] =
662 { &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
663 { &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
664 { &IID_IMoniker, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
667 HRESULT QUARTZ_CreateDeviceMoniker(
668 HKEY hkRoot, LPCWSTR lpKeyPath,
669 IMoniker** ppMoniker )
674 TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppMoniker );
676 pdm = (CDeviceMoniker*)QUARTZ_AllocObj( sizeof(CDeviceMoniker) );
678 return E_OUTOFMEMORY;
680 QUARTZ_IUnkInit( &pdm->unk, NULL );
681 hr = CDeviceMoniker_InitIMoniker( pdm, hkRoot, lpKeyPath );
684 QUARTZ_FreeObj( pdm );
688 pdm->unk.pEntries = CDeviceMoniker_IFEntries;
689 pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]);
690 pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker;
692 *ppMoniker = (IMoniker*)(&pdm->moniker);
698 /***************************************************************************
700 * CRegPropertyBag::IPropertyBag
704 static HRESULT WINAPI
705 IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj)
707 CRegPropertyBag_THIS(iface,propbag);
709 TRACE("(%p)->()\n",This);
711 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
715 IPropertyBag_fnAddRef(IPropertyBag* iface)
717 CRegPropertyBag_THIS(iface,propbag);
719 TRACE("(%p)->()\n",This);
721 return IUnknown_AddRef(This->unk.punkControl);
725 IPropertyBag_fnRelease(IPropertyBag* iface)
727 CRegPropertyBag_THIS(iface,propbag);
729 TRACE("(%p)->()\n",This);
731 return IUnknown_Release(This->unk.punkControl);
734 static HRESULT WINAPI
735 IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog)
737 CRegPropertyBag_THIS(iface,propbag);
746 TRACE("(%p)->(%s,%p,%p)\n",This,
747 debugstr_w(lpszPropName),pVar,pLog);
749 if ( lpszPropName == NULL || pVar == NULL )
753 lr = RegQueryValueExW(
754 This->m_hKey, lpszPropName, NULL,
755 &dwValueType, NULL, &dwSize );
756 if ( lr != ERROR_SUCCESS )
758 WARN( "RegQueryValueExW failed.\n" );
762 switch ( dwValueType )
765 TRACE( "REG_SZ / length = %lu\n", dwSize );
766 if ( pVar->n1.n2.vt == VT_EMPTY )
767 pVar->n1.n2.vt = VT_BSTR;
768 if ( pVar->n1.n2.vt != VT_BSTR )
770 FIXME( "type of VARIANT is not BSTR.\n" );
774 pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen(
776 if ( pVar->n1.n2.n3.bstrVal == NULL )
778 WARN( "out of memory.\n" );
779 return E_OUTOFMEMORY;
781 lr = RegQueryValueExW(
782 This->m_hKey, lpszPropName, NULL,
784 (BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize );
785 if ( lr != ERROR_SUCCESS )
787 WARN( "failed to query value\n" );
788 SysFreeString(pVar->n1.n2.n3.bstrVal);
791 TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) );
794 TRACE( "REG_BINARY / length = %lu\n", dwSize );
795 if ( pVar->n1.n2.vt == VT_EMPTY )
796 pVar->n1.n2.vt = VT_ARRAY|VT_UI1;
797 if ( pVar->n1.n2.vt != (VT_ARRAY|VT_UI1) )
799 FIXME( "type of VARIANT is not VT_ARRAY|VT_UI1.\n" );
803 sab.cElements = dwSize;
804 pArray = SafeArrayCreate( VT_UI1, 1, &sab );
805 if ( pArray == NULL )
806 return E_OUTOFMEMORY;
807 hr = SafeArrayLock( pArray );
810 WARN( "safe array can't be locked\n" );
811 SafeArrayDestroy( pArray );
814 lr = RegQueryValueExW(
815 This->m_hKey, lpszPropName, NULL,
817 (BYTE*)pArray->pvData, &dwSize );
818 SafeArrayUnlock( pArray );
819 if ( lr != ERROR_SUCCESS )
821 WARN( "failed to query value\n" );
822 SafeArrayDestroy( pArray );
825 pVar->n1.n2.n3.parray = pArray;
826 TRACE( "value is SAFEARRAY - array of BYTE; \n" );
829 TRACE( "REG_DWORD / length = %lu\n", dwSize );
830 if ( dwSize != sizeof(DWORD) )
832 WARN( "The length of REG_DWORD value is not sizeof(DWORD).\n" );
835 if ( pVar->n1.n2.vt == VT_EMPTY )
836 pVar->n1.n2.vt = VT_I4;
837 if ( pVar->n1.n2.vt != VT_I4 )
839 FIXME( "type of VARIANT is not VT_I4.\n" );
842 lr = RegQueryValueExW(
843 This->m_hKey, lpszPropName, NULL,
845 (BYTE*)(&dwDWordValue), &dwSize );
846 if ( lr != ERROR_SUCCESS )
848 WARN( "failed to query value\n" );
851 pVar->n1.n2.n3.lVal = dwDWordValue;
852 TRACE( "value is DWORD; %08lx\n", dwDWordValue );
855 FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This,
856 debugstr_w(lpszPropName),pVar,pLog);
860 TRACE( "returned successfully.\n" );
864 static HRESULT WINAPI
865 IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar)
867 CRegPropertyBag_THIS(iface,propbag);
873 TRACE("(%p)->(%s,%p)\n",This,
874 debugstr_w(lpszPropName),pVar);
876 if ( lpszPropName == NULL || pVar == NULL )
879 switch ( pVar->n1.n2.vt )
881 case VT_I4: /* REG_DWORD */
882 dwDWordValue = pVar->n1.n2.n3.lVal;
884 This->m_hKey, lpszPropName, 0,
886 (const BYTE*)(&dwDWordValue), sizeof(DWORD) );
887 if ( lr != ERROR_SUCCESS )
889 WARN( "failed to set value\n" );
893 case VT_BSTR: /* REG_SZ */
895 This->m_hKey, lpszPropName, 0,
897 (const BYTE*)(pVar->n1.n2.n3.bstrVal),
898 SysStringByteLen( pVar->n1.n2.n3.bstrVal ) );
899 if ( lr != ERROR_SUCCESS )
901 WARN( "failed to set value\n" );
905 case (VT_ARRAY|VT_UI1): /* REG_BINARY */
906 pArray = pVar->n1.n2.n3.parray;
907 if ( pArray->cDims != 1 || pArray->cbElements != 1 ||
908 pArray->rgsabound[0].lLbound != 0 )
910 WARN( "invalid array\n" );
913 hr = SafeArrayLock( pArray );
916 WARN( "safe array can't be locked\n" );
920 This->m_hKey, lpszPropName, 0,
922 (const BYTE*)pArray->pvData,
923 pArray->rgsabound[0].cElements );
924 SafeArrayUnlock( pArray );
925 if ( lr != ERROR_SUCCESS )
927 WARN( "failed to set value\n" );
932 FIXME("(%p)->(%s,%p) invalid/unsupported VARIANT type %04x\n",This,
933 debugstr_w(lpszPropName),pVar,pVar->n1.n2.vt);
937 TRACE( "returned successfully.\n" );
944 static ICOM_VTABLE(IPropertyBag) ipropbag =
946 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
947 /* IUnknown fields */
948 IPropertyBag_fnQueryInterface,
949 IPropertyBag_fnAddRef,
950 IPropertyBag_fnRelease,
951 /* IPropertyBag fields */
953 IPropertyBag_fnWrite,
956 static HRESULT CRegPropertyBag_InitIPropertyBag(
957 CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath )
959 WCHAR wszREG_SZ[ NUMELEMS(QUARTZ_wszREG_SZ) ];
962 ICOM_VTBL(&prpb->propbag) = &ipropbag;
964 memcpy(wszREG_SZ,QUARTZ_wszREG_SZ,sizeof(QUARTZ_wszREG_SZ) );
966 if ( RegCreateKeyExW(
967 hkRoot, lpKeyPath, 0, wszREG_SZ,
968 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
969 &prpb->m_hKey, &dwDisp ) != ERROR_SUCCESS )
975 static void CRegPropertyBag_UninitIPropertyBag(
976 CRegPropertyBag* prpb )
978 RegCloseKey( prpb->m_hKey );
982 /***************************************************************************
984 * new/delete for CRegPropertyBag
988 static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk)
990 CRegPropertyBag_THIS(punk,unk);
992 CRegPropertyBag_UninitIPropertyBag(This);
996 /* can I use offsetof safely? - FIXME? */
997 static QUARTZ_IFEntry CRegPropertyBag_IFEntries[] =
999 { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) },
1002 HRESULT QUARTZ_CreateRegPropertyBag(
1003 HKEY hkRoot, LPCWSTR lpKeyPath,
1004 IPropertyBag** ppPropBag )
1006 CRegPropertyBag* prpb;
1009 TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag );
1011 prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) );
1013 return E_OUTOFMEMORY;
1015 QUARTZ_IUnkInit( &prpb->unk, NULL );
1016 hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath );
1019 QUARTZ_FreeObj( prpb );
1023 prpb->unk.pEntries = CRegPropertyBag_IFEntries;
1024 prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]);
1025 prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag;
1027 *ppPropBag = (IPropertyBag*)(&prpb->propbag);
1032 /***************************************************************************
1034 * Helper for registering filters.
1038 HRESULT QUARTZ_GetFilterRegPath(
1039 WCHAR** ppwszPath, /* [OUT] path from HKEY_CLASSES_ROOT */
1040 const CLSID* pguidFilterCategory, /* [IN] Category */
1041 const CLSID* pclsid, /* [IN] CLSID of this filter */
1042 LPCWSTR lpInstance ) /* [IN] instance */
1045 WCHAR szKey[ 1024 ];
1046 WCHAR szFilterPath[ 512 ];
1047 WCHAR szCLSID[ 256 ];
1050 TRACE("(%p,%s,%s,%s)\n",ppwszPath,debugstr_guid(pguidFilterCategory),debugstr_guid(pclsid),debugstr_w(lpInstance) );
1054 QUARTZ_GUIDtoString( szCLSID, pclsid );
1055 lstrcpyW( szFilterPath, QUARTZ_wszInstance );
1056 QUARTZ_CatPathSepW( szFilterPath );
1057 if ( lpInstance != NULL )
1059 if ( lstrlenW(lpInstance) >= 256 )
1060 return E_INVALIDARG;
1061 lstrcatW( szFilterPath, lpInstance );
1065 lstrcatW( szFilterPath, szCLSID );
1068 hr = QUARTZ_CreateCLSIDPath(
1069 szKey, NUMELEMS(szKey),
1070 pguidFilterCategory, szFilterPath );
1074 buflen = sizeof(WCHAR)*(lstrlenW(szKey)+1);
1075 *ppwszPath = QUARTZ_AllocMem( buflen );
1076 if ( *ppwszPath == NULL )
1077 return E_OUTOFMEMORY;
1078 memcpy( *ppwszPath, szKey, buflen );
1082 HRESULT QUARTZ_RegisterFilterToMoniker(
1083 IMoniker* pMoniker, /* [IN] Moniker */
1084 const CLSID* pclsid, /* [IN] CLSID of this filter */
1085 LPCWSTR lpFriendlyName, /* [IN] friendly name */
1086 const BYTE* pbFilterData, /* [IN] filter data */
1087 DWORD cbFilterData ) /* [IN] size of the filter data */
1089 IPropertyBag* pPropBag = NULL;
1090 WCHAR wszClsid[128];
1094 SAFEARRAY* pArray = NULL;
1096 TRACE("(%p,%s,%s,%p,%08lu)\n",pMoniker,debugstr_guid(pclsid),debugstr_w(lpFriendlyName),pbFilterData,cbFilterData);
1098 hr = IMoniker_BindToStorage(pMoniker,NULL,NULL,&IID_IPropertyBag,(void**)&pPropBag);
1101 QUARTZ_GUIDtoString( wszClsid, pclsid );
1102 var.n1.n2.vt = VT_BSTR;
1103 var.n1.n2.n3.bstrVal = SysAllocString(wszClsid);
1104 if ( var.n1.n2.n3.bstrVal == NULL )
1109 hr = IPropertyBag_Write(pPropBag,QUARTZ_wszCLSID,&var);
1110 SysFreeString(var.n1.n2.n3.bstrVal);
1114 var.n1.n2.vt = VT_BSTR;
1115 var.n1.n2.n3.bstrVal = SysAllocString(lpFriendlyName);
1116 if ( var.n1.n2.n3.bstrVal == NULL )
1121 hr = IPropertyBag_Write(pPropBag,QUARTZ_wszFriendlyName,&var);
1122 SysFreeString(var.n1.n2.n3.bstrVal);
1126 if ( pbFilterData != NULL )
1128 var.n1.n2.vt = VT_ARRAY|VT_UI1;
1130 sab.cElements = cbFilterData;
1131 pArray = SafeArrayCreate( VT_UI1, 1, &sab );
1132 if ( pArray == NULL )
1137 hr = SafeArrayLock( pArray );
1140 var.n1.n2.n3.parray = pArray;
1141 memcpy( pArray->pvData, pbFilterData, cbFilterData );
1142 hr = IPropertyBag_Write(pPropBag,QUARTZ_wszFilterData,&var);
1143 SafeArrayUnlock( pArray );
1150 if ( pArray != NULL )
1151 SafeArrayDestroy( pArray );
1152 if ( pPropBag != NULL )
1153 IPropertyBag_Release(pPropBag);
1158 HRESULT QUARTZ_RegDeleteKey( HKEY hkRoot, LPCWSTR lpKeyPath )
1165 FILETIME ftLastWrite;
1167 WCHAR wszPath[ 512 ];
1169 TRACE("(%08x,%s)\n",hkRoot,debugstr_w(lpKeyPath));
1171 lr = RegOpenKeyExW( hkRoot, lpKeyPath, 0, KEY_ALL_ACCESS, &hKey );
1172 if ( lr == ERROR_SUCCESS )
1177 cbName = NUMELEMS(wszPath);
1179 hKey, dwIndex, wszPath, &cbName,
1180 NULL, NULL, NULL, &ftLastWrite );
1181 if ( lr != ERROR_SUCCESS )
1183 hr = QUARTZ_RegDeleteKey( hKey, wszPath );
1191 cbName = NUMELEMS(wszPath);
1193 hKey, 0, wszPath, &cbName, 0,
1195 if ( lr != ERROR_SUCCESS )
1197 lr = RegDeleteValueW( hKey, wszPath );
1198 if ( lr != ERROR_SUCCESS )
1200 WARN("RegDeleteValueW - %08lx\n",lr);
1205 RegCloseKey( hKey );
1207 lr = RegDeleteKeyW( hkRoot, lpKeyPath );
1208 WARN("RegDeleteKeyW - %08lx\n",lr);
1209 if ( lr != ERROR_SUCCESS && lr != ERROR_FILE_NOT_FOUND )
1215 HRESULT QUARTZ_GetPropertyFromMoniker(
1216 IMoniker* pMoniker, /* [IN] Moniker */
1217 LPCOLESTR lpszPropName, /* [IN] Property */
1218 VARIANT* pVar ) /* [OUT] */
1220 IPropertyBag* pPropBag = NULL;
1223 TRACE("(%p,%s,%p)\n",pMoniker,debugstr_w(lpszPropName),pVar);
1225 hr = IMoniker_BindToStorage(pMoniker,NULL,NULL,&IID_IPropertyBag,(void**)&pPropBag);
1228 hr = IPropertyBag_Read(pPropBag,lpszPropName,pVar,NULL);
1229 IPropertyBag_Release(pPropBag);
1234 HRESULT QUARTZ_GetCLSIDFromMoniker(
1235 IMoniker* pMoniker, /* [IN] Moniker */
1236 CLSID* pclsid ) /* [OUT] */
1241 var.n1.n2.vt = VT_BSTR;
1242 hr = QUARTZ_GetPropertyFromMoniker(
1243 pMoniker, QUARTZ_wszCLSID, &var );
1246 hr = CLSIDFromString(var.n1.n2.n3.bstrVal,pclsid);
1247 SysFreeString(var.n1.n2.n3.bstrVal);
1253 HRESULT QUARTZ_GetMeritFromMoniker(
1254 IMoniker* pMoniker, /* [IN] Moniker */
1255 DWORD* pdwMerit ) /* [OUT] */
1260 var.n1.n2.vt = VT_I4;
1261 hr = QUARTZ_GetPropertyFromMoniker(
1262 pMoniker, QUARTZ_wszMerit, &var );
1264 *pdwMerit = var.n1.n2.n3.lVal;
1269 HRESULT QUARTZ_GetFilterDataFromMoniker(
1270 IMoniker* pMoniker, /* [IN] Moniker */
1271 BYTE** ppbFilterData, /* [OUT] */
1272 DWORD* pcbFilterData ) /* [OUT] */
1278 var.n1.n2.vt = VT_ARRAY|VT_UI1;
1279 hr = QUARTZ_GetPropertyFromMoniker(
1280 pMoniker, QUARTZ_wszFilterData, &var );
1283 pArray = var.n1.n2.n3.parray;
1284 hr = SafeArrayLock( pArray );
1285 if ( SUCCEEDED(hr) )
1287 *pcbFilterData = pArray->rgsabound[0].cElements - pArray->rgsabound[0].lLbound;
1288 *ppbFilterData = (BYTE*)QUARTZ_AllocMem( *pcbFilterData );
1289 if ( *ppbFilterData == NULL )
1292 memcpy( *ppbFilterData, pArray->pvData, *pcbFilterData );
1294 SafeArrayUnlock( pArray );
1296 SafeArrayDestroy( pArray );