Started implementing AVI splitter.
[wine.git] / dlls / quartz / devmon.c
blobcef8eb7090c858901bbcfe0d2547424f8d70a4e6
1 /*
2 * Implements IMoniker for CLSID_CDeviceMoniker.
3 * Implements IPropertyBag. (internal)
5 * hidenori@a2.ctktv.ne.jp
6 */
8 #include "config.h"
10 #include "windef.h"
11 #include "winbase.h"
12 #include "wingdi.h"
13 #include "winuser.h"
14 #include "winreg.h"
15 #include "winerror.h"
16 #include "objidl.h"
17 #include "oleidl.h"
18 #include "ocidl.h"
19 #include "oleauto.h"
20 #include "strmif.h"
21 #include "uuids.h"
23 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(quartz);
26 #include "quartz_private.h"
27 #include "devmon.h"
28 #include "regsvr.h"
31 /***************************************************************************
33 * CDeviceMoniker::IMoniker
37 static HRESULT WINAPI
38 IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj)
40 CDeviceMoniker_THIS(iface,moniker);
42 TRACE("(%p)->()\n",This);
44 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
47 static ULONG WINAPI
48 IMoniker_fnAddRef(IMoniker* iface)
50 CDeviceMoniker_THIS(iface,moniker);
52 TRACE("(%p)->()\n",This);
54 return IUnknown_AddRef(This->unk.punkControl);
57 static ULONG WINAPI
58 IMoniker_fnRelease(IMoniker* iface)
60 CDeviceMoniker_THIS(iface,moniker);
62 TRACE("(%p)->()\n",This);
64 return IUnknown_Release(This->unk.punkControl);
67 static HRESULT WINAPI IMoniker_fnGetClassID(IMoniker* iface, CLSID *pClassID)
69 CDeviceMoniker_THIS(iface,moniker);
71 TRACE("(%p)->()\n",This);
73 if ( pClassID == NULL )
74 return E_POINTER;
75 memcpy( pClassID, &CLSID_CDeviceMoniker, sizeof(CLSID) );
77 return NOERROR;
80 static HRESULT WINAPI IMoniker_fnIsDirty(IMoniker* iface)
82 CDeviceMoniker_THIS(iface,moniker);
84 FIXME("(%p)->() stub!\n",This);
86 return E_NOTIMPL;
89 static HRESULT WINAPI IMoniker_fnLoad(IMoniker* iface, IStream* pStm)
91 CDeviceMoniker_THIS(iface,moniker);
93 FIXME("(%p)->() stub!\n",This);
95 return E_NOTIMPL;
98 static HRESULT WINAPI IMoniker_fnSave(IMoniker* iface, IStream* pStm, BOOL fClearDirty)
100 CDeviceMoniker_THIS(iface,moniker);
102 FIXME("(%p)->() stub!\n",This);
104 return E_NOTIMPL;
107 static HRESULT WINAPI IMoniker_fnGetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
109 CDeviceMoniker_THIS(iface,moniker);
111 FIXME("(%p)->() stub!\n",This);
113 return E_NOTIMPL;
116 static HRESULT WINAPI IMoniker_fnBindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
118 CDeviceMoniker_THIS(iface,moniker);
119 HRESULT hr;
120 IPropertyBag* pPropBag;
121 VARIANT vClsid;
122 CLSID clsid;
124 TRACE("(%p)->(%p,%p,%s,%p)\n",This,
125 pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
126 if ( pbc != NULL )
128 FIXME("IBindCtx* pbc != NULL not implemented.\n");
129 return E_FAIL;
131 if ( pmkToLeft != NULL )
133 FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
134 return E_FAIL;
136 if ( ppvResult == NULL )
137 return E_POINTER;
139 hr = QUARTZ_CreateRegPropertyBag(
140 This->m_hkRoot, This->m_pwszPath, &pPropBag );
141 if ( FAILED(hr) )
142 return hr;
144 vClsid.n1.n2.vt = VT_BSTR;
145 hr = IPropertyBag_Read(
146 pPropBag, QUARTZ_wszCLSID, &vClsid, NULL );
147 IPropertyBag_Release( pPropBag );
148 if ( FAILED(hr) )
149 return hr;
151 hr = CLSIDFromString( vClsid.n1.n2.n3.bstrVal, &clsid );
152 SysFreeString(vClsid.n1.n2.n3.bstrVal);
153 if ( FAILED(hr) )
154 return hr;
156 hr = CoCreateInstance(
157 &clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult );
158 TRACE( "hr = %08lx\n", hr );
160 return hr;
163 static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
165 CDeviceMoniker_THIS(iface,moniker);
166 HRESULT hr;
168 TRACE("(%p)->(%p,%p,%s,%p)\n",This,
169 pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
170 if ( pbc != NULL )
172 FIXME("IBindCtx* pbc != NULL not implemented.\n");
173 return E_FAIL;
175 if ( pmkToLeft != NULL )
177 FIXME("IMoniker* pmkToLeft != NULL not implemented.\n");
178 return E_FAIL;
180 if ( ppvResult == NULL )
181 return E_POINTER;
183 hr = E_NOINTERFACE;
184 if ( IsEqualGUID(riid,&IID_IUnknown) ||
185 IsEqualGUID(riid,&IID_IPropertyBag) )
187 hr = QUARTZ_CreateRegPropertyBag(
188 This->m_hkRoot, This->m_pwszPath,
189 (IPropertyBag**)ppvResult );
192 return hr;
195 static HRESULT WINAPI IMoniker_fnReduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
197 CDeviceMoniker_THIS(iface,moniker);
199 TRACE("(%p)->()\n",This);
201 if ( ppmkReduced == NULL )
202 return E_POINTER;
204 *ppmkReduced = iface; IMoniker_AddRef(iface);
206 return MK_S_REDUCED_TO_SELF;
209 static HRESULT WINAPI IMoniker_fnComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
211 CDeviceMoniker_THIS(iface,moniker);
213 FIXME("(%p)->() stub!\n",This);
215 return E_NOTIMPL;
218 static HRESULT WINAPI IMoniker_fnEnum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
220 CDeviceMoniker_THIS(iface,moniker);
222 TRACE("(%p)->()\n",This);
224 if ( ppenumMoniker == NULL )
225 return E_POINTER;
227 *ppenumMoniker = NULL;
228 return NOERROR;
231 static HRESULT WINAPI IMoniker_fnIsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
233 CDeviceMoniker_THIS(iface,moniker);
235 FIXME("(%p)->() stub!\n",This);
237 return E_NOTIMPL;
240 static HRESULT WINAPI IMoniker_fnHash(IMoniker* iface,DWORD* pdwHash)
242 CDeviceMoniker_THIS(iface,moniker);
244 FIXME("(%p)->() stub!\n",This);
246 return E_NOTIMPL;
249 static HRESULT WINAPI IMoniker_fnIsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning)
251 CDeviceMoniker_THIS(iface,moniker);
253 FIXME("(%p)->() stub!\n",This);
255 return E_NOTIMPL;
258 static HRESULT WINAPI IMoniker_fnGetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime)
260 CDeviceMoniker_THIS(iface,moniker);
262 FIXME("(%p)->() stub!\n",This);
264 return E_NOTIMPL;
267 static HRESULT WINAPI IMoniker_fnInverse(IMoniker* iface,IMoniker** ppmk)
269 CDeviceMoniker_THIS(iface,moniker);
271 FIXME("(%p)->() stub!\n",This);
273 return E_NOTIMPL;
276 static HRESULT WINAPI IMoniker_fnCommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix)
278 CDeviceMoniker_THIS(iface,moniker);
280 FIXME("(%p)->() stub!\n",This);
282 return E_NOTIMPL;
285 static HRESULT WINAPI IMoniker_fnRelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
287 CDeviceMoniker_THIS(iface,moniker);
289 FIXME("(%p)->() stub!\n",This);
291 return E_NOTIMPL;
294 static HRESULT WINAPI IMoniker_fnGetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
296 CDeviceMoniker_THIS(iface,moniker);
298 FIXME("(%p)->() stub!\n",This);
300 return E_NOTIMPL;
303 static HRESULT WINAPI IMoniker_fnParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
305 CDeviceMoniker_THIS(iface,moniker);
307 FIXME("(%p)->() stub!\n",This);
309 return E_NOTIMPL;
312 static HRESULT WINAPI IMoniker_fnIsSystemMoniker(IMoniker* iface,DWORD* pdwMksys)
314 CDeviceMoniker_THIS(iface,moniker);
316 TRACE("(%p)->()\n",This);
317 if ( pdwMksys == NULL )
318 return E_POINTER;
320 *pdwMksys = MKSYS_NONE;
321 return S_FALSE;
325 static ICOM_VTABLE(IMoniker) imoniker =
327 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
328 /* IUnknown fields */
329 IMoniker_fnQueryInterface,
330 IMoniker_fnAddRef,
331 IMoniker_fnRelease,
332 /* IPersist fields */
333 IMoniker_fnGetClassID,
334 /* IPersistStream fields */
335 IMoniker_fnIsDirty,
336 IMoniker_fnLoad,
337 IMoniker_fnSave,
338 IMoniker_fnGetSizeMax,
339 /* IMoniker fields */
340 IMoniker_fnBindToObject,
341 IMoniker_fnBindToStorage,
342 IMoniker_fnReduce,
343 IMoniker_fnComposeWith,
344 IMoniker_fnEnum,
345 IMoniker_fnIsEqual,
346 IMoniker_fnHash,
347 IMoniker_fnIsRunning,
348 IMoniker_fnGetTimeOfLastChange,
349 IMoniker_fnInverse,
350 IMoniker_fnCommonPrefixWith,
351 IMoniker_fnRelativePathTo,
352 IMoniker_fnGetDisplayName,
353 IMoniker_fnParseDisplayName,
354 IMoniker_fnIsSystemMoniker,
358 static HRESULT CDeviceMoniker_InitIMoniker(
359 CDeviceMoniker* pdm, HKEY hkRoot, LPCWSTR lpKeyPath )
361 DWORD dwLen;
363 ICOM_VTBL(&pdm->moniker) = &imoniker;
364 pdm->m_hkRoot = hkRoot;
365 pdm->m_pwszPath = NULL;
367 dwLen = sizeof(WCHAR)*(lstrlenW(lpKeyPath)+1);
368 pdm->m_pwszPath = (WCHAR*)QUARTZ_AllocMem( dwLen );
369 if ( pdm->m_pwszPath == NULL )
370 return E_OUTOFMEMORY;
371 memcpy( pdm->m_pwszPath, lpKeyPath, dwLen );
373 return NOERROR;
376 static void CDeviceMoniker_UninitIMoniker(
377 CDeviceMoniker* pdm )
379 if ( pdm->m_pwszPath != NULL )
380 QUARTZ_FreeMem( pdm->m_pwszPath );
383 /***************************************************************************
385 * new/delete for CDeviceMoniker
389 static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk)
391 CDeviceMoniker_THIS(punk,unk);
393 CDeviceMoniker_UninitIMoniker( This );
396 /* can I use offsetof safely? - FIXME? */
397 static QUARTZ_IFEntry CDeviceMoniker_IFEntries[] =
399 { &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
400 { &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
401 { &IID_IMoniker, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
404 HRESULT QUARTZ_CreateDeviceMoniker(
405 HKEY hkRoot, LPCWSTR lpKeyPath,
406 IMoniker** ppMoniker )
408 CDeviceMoniker* pdm;
409 HRESULT hr;
411 TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppMoniker );
413 pdm = (CDeviceMoniker*)QUARTZ_AllocObj( sizeof(CDeviceMoniker) );
414 if ( pdm == NULL )
415 return E_OUTOFMEMORY;
417 QUARTZ_IUnkInit( &pdm->unk, NULL );
418 hr = CDeviceMoniker_InitIMoniker( pdm, hkRoot, lpKeyPath );
419 if ( FAILED(hr) )
421 QUARTZ_FreeObj( pdm );
422 return hr;
425 pdm->unk.pEntries = CDeviceMoniker_IFEntries;
426 pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]);
427 pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker;
429 *ppMoniker = (IMoniker*)(&pdm->moniker);
431 return S_OK;
435 /***************************************************************************
437 * CRegPropertyBag::IPropertyBag
441 static HRESULT WINAPI
442 IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj)
444 CRegPropertyBag_THIS(iface,propbag);
446 TRACE("(%p)->()\n",This);
448 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
451 static ULONG WINAPI
452 IPropertyBag_fnAddRef(IPropertyBag* iface)
454 CRegPropertyBag_THIS(iface,propbag);
456 TRACE("(%p)->()\n",This);
458 return IUnknown_AddRef(This->unk.punkControl);
461 static ULONG WINAPI
462 IPropertyBag_fnRelease(IPropertyBag* iface)
464 CRegPropertyBag_THIS(iface,propbag);
466 TRACE("(%p)->()\n",This);
468 return IUnknown_Release(This->unk.punkControl);
471 static HRESULT WINAPI
472 IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog)
474 CRegPropertyBag_THIS(iface,propbag);
475 LONG lr;
476 DWORD dwSize;
477 DWORD dwValueType;
479 TRACE("(%p)->(%s,%p,%p)\n",This,
480 debugstr_w(lpszPropName),pVar,pLog);
482 if ( lpszPropName == NULL || pVar == NULL )
483 return E_POINTER;
485 dwSize = 0;
486 lr = RegQueryValueExW(
487 This->m_hKey, lpszPropName, NULL,
488 &dwValueType, NULL, &dwSize );
489 if ( lr != ERROR_SUCCESS )
491 TRACE( "RegQueryValueExW failed.\n" );
492 return E_INVALIDARG;
495 switch ( dwValueType )
497 case REG_SZ:
498 TRACE( "REG_SZ / length = %lu\n", dwSize );
499 if ( pVar->n1.n2.vt == VT_EMPTY )
500 pVar->n1.n2.vt = VT_BSTR;
501 if ( pVar->n1.n2.vt != VT_BSTR )
503 TRACE( "type of VARIANT is not BSTR\n" );
504 return E_FAIL;
507 pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen(
508 NULL, dwSize );
509 if ( pVar->n1.n2.n3.bstrVal == NULL )
511 TRACE( "out of memory.\n" );
512 return E_OUTOFMEMORY;
514 lr = RegQueryValueExW(
515 This->m_hKey, lpszPropName, NULL,
516 &dwValueType,
517 (BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize );
518 if ( lr != ERROR_SUCCESS )
520 TRACE( "failed to query value\n" );
521 SysFreeString(pVar->n1.n2.n3.bstrVal);
522 return E_FAIL;
524 TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) );
525 break;
526 default:
527 FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This,
528 debugstr_w(lpszPropName),pVar,pLog);
529 return E_FAIL;
532 TRACE( "returned successfully.\n" );
533 return NOERROR;
536 static HRESULT WINAPI
537 IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar)
539 CRegPropertyBag_THIS(iface,propbag);
541 FIXME("(%p)->(%s,%p) stub!\n",This,
542 debugstr_w(lpszPropName),pVar);
544 if ( lpszPropName == NULL || pVar == NULL )
545 return E_POINTER;
547 return E_NOTIMPL;
553 static ICOM_VTABLE(IPropertyBag) ipropbag =
555 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
556 /* IUnknown fields */
557 IPropertyBag_fnQueryInterface,
558 IPropertyBag_fnAddRef,
559 IPropertyBag_fnRelease,
560 /* IPropertyBag fields */
561 IPropertyBag_fnRead,
562 IPropertyBag_fnWrite,
565 static HRESULT CRegPropertyBag_InitIPropertyBag(
566 CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath )
568 ICOM_VTBL(&prpb->propbag) = &ipropbag;
570 if ( RegOpenKeyExW(
571 hkRoot, lpKeyPath, 0,
572 KEY_ALL_ACCESS, &prpb->m_hKey ) != ERROR_SUCCESS )
573 return E_FAIL;
575 return NOERROR;
578 static void CRegPropertyBag_UninitIPropertyBag(
579 CRegPropertyBag* prpb )
581 RegCloseKey( prpb->m_hKey );
585 /***************************************************************************
587 * new/delete for CRegPropertyBag
591 static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk)
593 CRegPropertyBag_THIS(punk,unk);
595 CRegPropertyBag_UninitIPropertyBag(This);
599 /* can I use offsetof safely? - FIXME? */
600 static QUARTZ_IFEntry CRegPropertyBag_IFEntries[] =
602 { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) },
605 HRESULT QUARTZ_CreateRegPropertyBag(
606 HKEY hkRoot, LPCWSTR lpKeyPath,
607 IPropertyBag** ppPropBag )
609 CRegPropertyBag* prpb;
610 HRESULT hr;
612 TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag );
614 prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) );
615 if ( prpb == NULL )
616 return E_OUTOFMEMORY;
618 QUARTZ_IUnkInit( &prpb->unk, NULL );
619 hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath );
620 if ( FAILED(hr) )
622 QUARTZ_FreeObj( prpb );
623 return hr;
626 prpb->unk.pEntries = CRegPropertyBag_IFEntries;
627 prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]);
628 prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag;
630 *ppPropBag = (IPropertyBag*)(&prpb->propbag);
632 return S_OK;