From 96e9615701afa29a76f4d81427443bf5d219c007 Mon Sep 17 00:00:00 2001 From: Hidenori Takeshima <hidenori@a2.ctktv.ne.jp> Date: Fri, 7 Sep 2001 19:46:49 +0000 Subject: [PATCH] Added some stubs. Started implementing some interfaces in FilterGraph. --- dlls/quartz/Makefile.in | 8 + dlls/quartz/complist.c | 83 +++++++- dlls/quartz/complist.h | 14 +- dlls/quartz/devenum.c | 8 +- dlls/quartz/devenum.h | 2 +- dlls/quartz/devmon.c | 422 ++++++++++++++++++++++++++++++++++++++ dlls/quartz/devmon.h | 36 ++++ dlls/quartz/enumunk.c | 244 ++++++++++++++++++++++ dlls/quartz/enumunk.h | 16 ++ dlls/quartz/fgclsid.c | 97 +++++++++ dlls/quartz/fgidisp.c | 128 ++++++++++++ dlls/quartz/fgraph.c | 81 ++++++-- dlls/quartz/fgraph.h | 80 ++++++-- dlls/quartz/fmap.c | 8 +- dlls/quartz/fmap.h | 2 +- dlls/quartz/fmap2.c | 8 +- dlls/quartz/fmap2.h | 3 +- dlls/quartz/ibasaud.c | 4 +- dlls/quartz/ibasvid.c | 4 +- dlls/quartz/idevenum.c | 109 +++++++++- dlls/quartz/ifgraph.c | 444 +++++++++++++++++++++++++++++++++++++--- dlls/quartz/ifmap.c | 52 +++-- dlls/quartz/ifmap3.c | 20 +- dlls/quartz/igrver.c | 108 ++++++++++ dlls/quartz/imcntl.c | 4 +- dlls/quartz/imem.c | 9 +- dlls/quartz/imesink.c | 95 +++++++++ dlls/quartz/imevent.c | 16 +- dlls/quartz/imfilter.c | 162 +++++++++++++++ dlls/quartz/impos.c | 25 ++- dlls/quartz/imseek.c | 4 +- dlls/quartz/irclock.c | 9 +- dlls/quartz/iunk.h | 2 +- dlls/quartz/ividwin.c | 4 +- dlls/quartz/main.c | 10 +- dlls/quartz/memalloc.c | 16 +- dlls/quartz/memalloc.h | 3 +- dlls/quartz/monprop.c | 205 +++++++++++++++++++ dlls/quartz/monprop.h | 34 +++ dlls/quartz/quartz.spec | 9 +- dlls/quartz/regsvr.c | 359 +++++++++++++++++++++++++++++--- dlls/quartz/regsvr.h | 54 +++-- dlls/quartz/sysclock.c | 17 +- dlls/quartz/sysclock.h | 3 +- 44 files changed, 2865 insertions(+), 156 deletions(-) create mode 100644 dlls/quartz/devmon.c create mode 100644 dlls/quartz/devmon.h create mode 100644 dlls/quartz/enumunk.c create mode 100644 dlls/quartz/enumunk.h create mode 100644 dlls/quartz/fgclsid.c create mode 100644 dlls/quartz/fgidisp.c create mode 100644 dlls/quartz/igrver.c create mode 100644 dlls/quartz/imesink.c create mode 100644 dlls/quartz/imfilter.c create mode 100644 dlls/quartz/monprop.c create mode 100644 dlls/quartz/monprop.h diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index ef6264d41b9..6ce20a3b1f8 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -12,6 +12,10 @@ C_SRCS = \ amerror.c \ complist.c \ devenum.c \ + devmon.c \ + enumunk.c \ + fgclsid.c \ + fgidisp.c \ fgraph.c \ fmap.c \ fmap2.c \ @@ -21,9 +25,12 @@ C_SRCS = \ ifgraph.c \ ifmap.c \ ifmap3.c \ + igrver.c \ imcntl.c \ imem.c \ + imesink.c \ imevent.c \ + imfilter.c \ impos.c \ imseek.c \ irclock.c \ @@ -31,6 +38,7 @@ C_SRCS = \ ividwin.c \ main.c \ memalloc.c \ + monprop.c \ regsvr.c \ sysclock.c diff --git a/dlls/quartz/complist.c b/dlls/quartz/complist.c index 305a2509a74..5bf07f876e7 100644 --- a/dlls/quartz/complist.c +++ b/dlls/quartz/complist.c @@ -25,6 +25,7 @@ struct QUARTZ_CompList { QUARTZ_CompListItem* pFirst; QUARTZ_CompListItem* pLast; + CRITICAL_SECTION csList; }; struct QUARTZ_CompListItem @@ -32,6 +33,8 @@ struct QUARTZ_CompListItem IUnknown* punk; QUARTZ_CompListItem* pNext; QUARTZ_CompListItem* pPrev; + void* pvData; + DWORD dwDataLen; }; @@ -45,6 +48,8 @@ QUARTZ_CompList* QUARTZ_CompList_Alloc( void ) /* construct. */ pList->pFirst = NULL; pList->pLast = NULL; + + InitializeCriticalSection( &pList->csList ); } return pList; @@ -63,17 +68,33 @@ void QUARTZ_CompList_Free( QUARTZ_CompList* pList ) pNext = pCur->pNext; if ( pCur->punk != NULL ) IUnknown_Release( pCur->punk ); + if ( pCur->pvData != NULL ) + QUARTZ_FreeMem( pCur->pvData ); QUARTZ_FreeMem( pCur ); pCur = pNext; } + + DeleteCriticalSection( &pList->csList ); + QUARTZ_FreeMem( pList ); } } -QUARTZ_CompList* QUARTZ_CompList_Dup( QUARTZ_CompList* pList ) +void QUARTZ_CompList_Lock( QUARTZ_CompList* pList ) +{ + EnterCriticalSection( &pList->csList ); +} + +void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList ) +{ + LeaveCriticalSection( &pList->csList ); +} + +QUARTZ_CompList* QUARTZ_CompList_Dup( + const QUARTZ_CompList* pList, BOOL fDupData ) { QUARTZ_CompList* pNewList; - QUARTZ_CompListItem* pCur; + const QUARTZ_CompListItem* pCur; HRESULT hr; pNewList = QUARTZ_CompList_Alloc(); @@ -85,7 +106,13 @@ QUARTZ_CompList* QUARTZ_CompList_Dup( QUARTZ_CompList* pList ) { if ( pCur->punk != NULL ) { - hr = QUARTZ_CompList_AddComp( pNewList, pCur->punk ); + if ( fDupData ) + hr = QUARTZ_CompList_AddComp( + pNewList, pCur->punk, + pCur->pvData, pCur->dwDataLen ); + else + hr = QUARTZ_CompList_AddComp( + pNewList, pCur->punk, NULL, 0 ); if ( FAILED(hr) ) { QUARTZ_CompList_Free( pNewList ); @@ -98,21 +125,38 @@ QUARTZ_CompList* QUARTZ_CompList_Dup( QUARTZ_CompList* pList ) return pNewList; } -HRESULT QUARTZ_CompList_AddComp( QUARTZ_CompList* pList, IUnknown* punk ) +HRESULT QUARTZ_CompList_AddComp( + QUARTZ_CompList* pList, IUnknown* punk, + const void* pvData, DWORD dwDataLen ) { QUARTZ_CompListItem* pItem; pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) ); if ( pItem == NULL ) return E_OUTOFMEMORY; /* out of memory. */ + + pItem->pvData = NULL; + pItem->dwDataLen = 0; + if ( pvData != NULL ) + { + pItem->pvData = (void*)QUARTZ_AllocMem( dwDataLen ); + if ( pItem->pvData == NULL ) + { + QUARTZ_FreeMem( pItem ); + return E_OUTOFMEMORY; + } + memcpy( pItem->pvData, pvData, dwDataLen ); + pItem->dwDataLen = dwDataLen; + } + pItem->punk = punk; IUnknown_AddRef(punk); if ( pList->pFirst != NULL ) pList->pFirst->pPrev = pItem; else pList->pLast = pItem; - pList->pFirst = pItem; pItem->pNext = pList->pFirst; + pList->pFirst = pItem; pItem->pPrev = NULL; return S_OK; @@ -139,6 +183,8 @@ HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk ) /* release this item. */ if ( pCur->punk != NULL ) IUnknown_Release( pCur->punk ); + if ( pCur->pvData != NULL ) + QUARTZ_FreeMem( pCur->pvData ); QUARTZ_FreeMem( pCur ); return S_OK; @@ -160,6 +206,23 @@ QUARTZ_CompListItem* QUARTZ_CompList_SearchComp( return NULL; } +QUARTZ_CompListItem* QUARTZ_CompList_SearchData( + QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen ) +{ + QUARTZ_CompListItem* pCur; + + pCur = pList->pFirst; + while ( pCur != NULL ) + { + if ( pCur->dwDataLen == dwDataLen && + !memcmp( pCur->pvData, pvData, dwDataLen ) ) + return pCur; + pCur = pCur->pNext; + } + + return NULL; +} + QUARTZ_CompListItem* QUARTZ_CompList_GetFirst( QUARTZ_CompList* pList ) { @@ -176,3 +239,13 @@ IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem ) { return pItem->punk; } + +const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem ) +{ + return pItem->pvData; +} + +DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem ) +{ + return pItem->dwDataLen; +} diff --git a/dlls/quartz/complist.h b/dlls/quartz/complist.h index c5b1c45abe1..9f02dc2e1df 100644 --- a/dlls/quartz/complist.h +++ b/dlls/quartz/complist.h @@ -12,16 +12,26 @@ typedef struct QUARTZ_CompListItem QUARTZ_CompListItem; QUARTZ_CompList* QUARTZ_CompList_Alloc( void ); void QUARTZ_CompList_Free( QUARTZ_CompList* pList ); -QUARTZ_CompList* QUARTZ_CompList_Dup( QUARTZ_CompList* pList ); -HRESULT QUARTZ_CompList_AddComp( QUARTZ_CompList* pList, IUnknown* punk ); +void QUARTZ_CompList_Lock( QUARTZ_CompList* pList ); +void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList ); + +QUARTZ_CompList* QUARTZ_CompList_Dup( + const QUARTZ_CompList* pList, BOOL fDupData ); +HRESULT QUARTZ_CompList_AddComp( + QUARTZ_CompList* pList, IUnknown* punk, + const void* pvData, DWORD dwDataLen ); HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk ); QUARTZ_CompListItem* QUARTZ_CompList_SearchComp( QUARTZ_CompList* pList, IUnknown* punk ); +QUARTZ_CompListItem* QUARTZ_CompList_SearchData( + QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen ); QUARTZ_CompListItem* QUARTZ_CompList_GetFirst( QUARTZ_CompList* pList ); QUARTZ_CompListItem* QUARTZ_CompList_GetNext( QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev ); IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem ); +const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem ); +DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem ); #endif /* QUARTZ_COMPLIST_H */ diff --git a/dlls/quartz/devenum.c b/dlls/quartz/devenum.c index 390409bc67e..6d94bca142f 100644 --- a/dlls/quartz/devenum.c +++ b/dlls/quartz/devenum.c @@ -41,6 +41,7 @@ static void QUARTZ_DestroySystemDeviceEnum(IUnknown* punk) HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj) { CSysDevEnum* psde; + HRESULT hr; TRACE("(%p,%p)\n",punkOuter,ppobj); @@ -50,7 +51,12 @@ HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj) QUARTZ_IUnkInit( &psde->unk, punkOuter ); - CSysDevEnum_InitICreateDevEnum( psde ); + hr = CSysDevEnum_InitICreateDevEnum( psde ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( psde ); + return hr; + } psde->unk.pEntries = IFEntries; psde->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); diff --git a/dlls/quartz/devenum.h b/dlls/quartz/devenum.h index 10ce46fc756..59ff85d2e4a 100644 --- a/dlls/quartz/devenum.h +++ b/dlls/quartz/devenum.h @@ -28,7 +28,7 @@ typedef struct CSysDevEnum HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj); -void CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde ); +HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde ); void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde ); diff --git a/dlls/quartz/devmon.c b/dlls/quartz/devmon.c new file mode 100644 index 00000000000..317d5c771c6 --- /dev/null +++ b/dlls/quartz/devmon.c @@ -0,0 +1,422 @@ +/* + * Implements IMoniker for CLSID_CDeviceMoniker. + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "objidl.h" +#include "oleidl.h" +#include "ocidl.h" +#include "oleauto.h" +#include "strmif.h" +#include "uuids.h" +#include "wine/unicode.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "devmon.h" +#include "monprop.h" +#include "regsvr.h" + + +static HRESULT WINAPI +IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IMoniker_fnAddRef(IMoniker* iface) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IMoniker_fnRelease(IMoniker* iface) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI IMoniker_fnGetClassID(IMoniker* iface, CLSID *pClassID) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + + if ( pClassID == NULL ) + return E_POINTER; + memcpy( pClassID, &CLSID_CDeviceMoniker, sizeof(CLSID) ); + + return NOERROR; +} + +static HRESULT WINAPI IMoniker_fnIsDirty(IMoniker* iface) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnLoad(IMoniker* iface, IStream* pStm) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnSave(IMoniker* iface, IStream* pStm, BOOL fClearDirty) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnGetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnBindToObject(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) +{ + CDeviceMoniker_THIS(iface,moniker); + HRESULT hr; + IPropertyBag* pPropBag; + VARIANT vClsid; + CLSID clsid; + + TRACE("(%p)->(%p,%p,%s,%p)\n",This, + pbc,pmkToLeft,debugstr_guid(riid),ppvResult); + if ( pbc != NULL ) + { + FIXME("IBindCtx* pbc != NULL not implemented.\n"); + return E_FAIL; + } + if ( pmkToLeft != NULL ) + { + FIXME("IMoniker* pmkToLeft != NULL not implemented.\n"); + return E_FAIL; + } + if ( ppvResult == NULL ) + return E_POINTER; + + hr = QUARTZ_CreateRegPropertyBag( + This->m_hkRoot, This->m_pwszPath, &pPropBag ); + if ( FAILED(hr) ) + return hr; + + vClsid.n1.n2.vt = VT_BSTR; + hr = IPropertyBag_Read( + pPropBag, QUARTZ_wszCLSID, &vClsid, NULL ); + IPropertyBag_Release( pPropBag ); + if ( FAILED(hr) ) + return hr; + + hr = CLSIDFromString( vClsid.n1.n2.n3.bstrVal, &clsid ); + SysFreeString(vClsid.n1.n2.n3.bstrVal); + if ( FAILED(hr) ) + return hr; + + return CoCreateInstance( + &clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult ); +} + +static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) +{ + CDeviceMoniker_THIS(iface,moniker); + HRESULT hr; + + TRACE("(%p)->(%p,%p,%s,%p)\n",This, + pbc,pmkToLeft,debugstr_guid(riid),ppvResult); + if ( pbc != NULL ) + { + FIXME("IBindCtx* pbc != NULL not implemented.\n"); + return E_FAIL; + } + if ( pmkToLeft != NULL ) + { + FIXME("IMoniker* pmkToLeft != NULL not implemented.\n"); + return E_FAIL; + } + if ( ppvResult == NULL ) + return E_POINTER; + + hr = E_NOINTERFACE; + if ( IsEqualGUID(riid,&IID_IUnknown) || + IsEqualGUID(riid,&IID_IPropertyBag) ) + { + hr = QUARTZ_CreateRegPropertyBag( + This->m_hkRoot, This->m_pwszPath, + (IPropertyBag**)ppvResult ); + } + + return hr; +} + +static HRESULT WINAPI IMoniker_fnReduce(IMoniker* iface,IBindCtx* pbc, DWORD dwReduceHowFar,IMoniker** ppmkToLeft, IMoniker** ppmkReduced) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + + if ( ppmkReduced == NULL ) + return E_POINTER; + + *ppmkReduced = iface; IMoniker_AddRef(iface); + + return MK_S_REDUCED_TO_SELF; +} + +static HRESULT WINAPI IMoniker_fnComposeWith(IMoniker* iface,IMoniker* pmkRight,BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnEnum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + + if ( ppenumMoniker == NULL ) + return E_POINTER; + + *ppenumMoniker = NULL; + return NOERROR; +} + +static HRESULT WINAPI IMoniker_fnIsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnHash(IMoniker* iface,DWORD* pdwHash) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnIsRunning(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnGetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pCompositeTime) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnInverse(IMoniker* iface,IMoniker** ppmk) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnCommonPrefixWith(IMoniker* iface,IMoniker* pmkOther, IMoniker** ppmkPrefix) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnRelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnGetDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnParseDisplayName(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut) +{ + CDeviceMoniker_THIS(iface,moniker); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IMoniker_fnIsSystemMoniker(IMoniker* iface,DWORD* pdwMksys) +{ + CDeviceMoniker_THIS(iface,moniker); + + TRACE("(%p)->()\n",This); + if ( pdwMksys == NULL ) + return E_POINTER; + + *pdwMksys = MKSYS_NONE; + return S_FALSE; +} + + +static ICOM_VTABLE(IMoniker) imoniker = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IMoniker_fnQueryInterface, + IMoniker_fnAddRef, + IMoniker_fnRelease, + /* IPersist fields */ + IMoniker_fnGetClassID, + /* IPersistStream fields */ + IMoniker_fnIsDirty, + IMoniker_fnLoad, + IMoniker_fnSave, + IMoniker_fnGetSizeMax, + /* IMoniker fields */ + IMoniker_fnBindToObject, + IMoniker_fnBindToStorage, + IMoniker_fnReduce, + IMoniker_fnComposeWith, + IMoniker_fnEnum, + IMoniker_fnIsEqual, + IMoniker_fnHash, + IMoniker_fnIsRunning, + IMoniker_fnGetTimeOfLastChange, + IMoniker_fnInverse, + IMoniker_fnCommonPrefixWith, + IMoniker_fnRelativePathTo, + IMoniker_fnGetDisplayName, + IMoniker_fnParseDisplayName, + IMoniker_fnIsSystemMoniker, +}; + + +static HRESULT CDeviceMoniker_InitIMoniker( + CDeviceMoniker* pdm, HKEY hkRoot, LPCWSTR lpKeyPath ) +{ + DWORD dwLen; + + ICOM_VTBL(&pdm->moniker) = &imoniker; + pdm->m_hkRoot = hkRoot; + pdm->m_pwszPath = NULL; + + dwLen = sizeof(WCHAR)*(strlenW(lpKeyPath)+1); + pdm->m_pwszPath = (WCHAR*)QUARTZ_AllocMem( dwLen ); + if ( pdm->m_pwszPath == NULL ) + return E_OUTOFMEMORY; + memcpy( pdm->m_pwszPath, lpKeyPath, dwLen ); + + return NOERROR; +} + +static void CDeviceMoniker_UninitIMoniker( + CDeviceMoniker* pdm ) +{ + if ( pdm->m_pwszPath != NULL ) + QUARTZ_FreeMem( pdm->m_pwszPath ); +} + + +static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk) +{ + CDeviceMoniker_THIS(punk,unk); + + CDeviceMoniker_UninitIMoniker( This ); +} + +/* can I use offsetof safely? - FIXME? */ +static QUARTZ_IFEntry IFEntries[] = +{ + { &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) }, + { &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) }, + { &IID_IMoniker, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) }, +}; + +HRESULT QUARTZ_CreateDeviceMoniker( + HKEY hkRoot, LPCWSTR lpKeyPath, + IMoniker** ppMoniker ) +{ + CDeviceMoniker* pdm; + HRESULT hr; + + TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppMoniker ); + + pdm = (CDeviceMoniker*)QUARTZ_AllocObj( sizeof(CDeviceMoniker) ); + if ( pdm == NULL ) + return E_OUTOFMEMORY; + + QUARTZ_IUnkInit( &pdm->unk, NULL ); + hr = CDeviceMoniker_InitIMoniker( pdm, hkRoot, lpKeyPath ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( pdm ); + return hr; + } + + pdm->unk.pEntries = IFEntries; + pdm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); + pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker; + + *ppMoniker = (IMoniker*)(&pdm->moniker); + + return S_OK; +} + + diff --git a/dlls/quartz/devmon.h b/dlls/quartz/devmon.h new file mode 100644 index 00000000000..7791a52d24f --- /dev/null +++ b/dlls/quartz/devmon.h @@ -0,0 +1,36 @@ +#ifndef WINE_DSHOW_DEVMON_H +#define WINE_DSHOW_DEVMON_H + +/* + implements CLSID_CDeviceMoniker. + + - At least, the following interfaces should be implemented: + + IUnknown + + IPersist - IPersistStream - IMoniker + */ + +#include "iunk.h" + +typedef struct DMON_IMonikerImpl +{ + ICOM_VFIELD(IMoniker); +} DMON_IMonikerImpl; + +typedef struct CDeviceMoniker +{ + QUARTZ_IUnkImpl unk; + DMON_IMonikerImpl moniker; + /* IMoniker fields */ + HKEY m_hkRoot; + WCHAR* m_pwszPath; +} CDeviceMoniker; + +#define CDeviceMoniker_THIS(iface,member) CDeviceMoniker* This = (CDeviceMoniker*)(((char*)iface)-offsetof(CDeviceMoniker,member)) + +HRESULT QUARTZ_CreateDeviceMoniker( + HKEY hkRoot, LPCWSTR lpKeyPath, + IMoniker** ppMoniker ); + + +#endif /* WINE_DSHOW_DEVMON_H */ diff --git a/dlls/quartz/enumunk.c b/dlls/quartz/enumunk.c new file mode 100644 index 00000000000..eeb887734ca --- /dev/null +++ b/dlls/quartz/enumunk.c @@ -0,0 +1,244 @@ +/* + * Implementation of IEnumUnknown (for internal use). + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "wine/obj_oleaut.h" +#include "strmif.h" +#include "control.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "enumunk.h" +#include "iunk.h" + + + +typedef struct IEnumUnknownImpl +{ + ICOM_VFIELD(IEnumUnknown); +} IEnumUnknownImpl; + +typedef struct +{ + QUARTZ_IUnkImpl unk; + IEnumUnknownImpl enumunk; + struct QUARTZ_IFEntry IFEntries[1]; + QUARTZ_CompList* pCompList; + QUARTZ_CompListItem* pItemCur; +} CEnumUnknown; + +#define CEnumUnknown_THIS(iface,member) CEnumUnknown* This = ((CEnumUnknown*)(((char*)iface)-offsetof(CEnumUnknown,member))) + + + + +static HRESULT WINAPI +IEnumUnknown_fnQueryInterface(IEnumUnknown* iface,REFIID riid,void** ppobj) +{ + CEnumUnknown_THIS(iface,enumunk); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IEnumUnknown_fnAddRef(IEnumUnknown* iface) +{ + CEnumUnknown_THIS(iface,enumunk); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IEnumUnknown_fnRelease(IEnumUnknown* iface) +{ + CEnumUnknown_THIS(iface,enumunk); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI +IEnumUnknown_fnNext(IEnumUnknown* iface,ULONG cReq,IUnknown** ppunk,ULONG* pcFetched) +{ + CEnumUnknown_THIS(iface,enumunk); + HRESULT hr; + ULONG cFetched; + + TRACE("(%p)->(%lu,%p,%p)\n",This,cReq,ppunk,pcFetched); + + if ( pcFetched == NULL && cReq > 1 ) + return E_INVALIDARG; + if ( ppunk == NULL ) + return E_POINTER; + + QUARTZ_CompList_Lock( This->pCompList ); + + hr = NOERROR; + cFetched = 0; + while ( cReq > 0 ) + { + if ( This->pItemCur == NULL ) + { + hr = S_FALSE; + break; + } + ppunk[ cFetched ++ ] = QUARTZ_CompList_GetItemPtr( This->pItemCur ); + IUnknown_AddRef( *ppunk ); + + This->pItemCur = + QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur ); + cReq --; + } + + QUARTZ_CompList_Unlock( This->pCompList ); + + if ( pcFetched != NULL ) + *pcFetched = cFetched; + + return hr; +} + +static HRESULT WINAPI +IEnumUnknown_fnSkip(IEnumUnknown* iface,ULONG cSkip) +{ + CEnumUnknown_THIS(iface,enumunk); + HRESULT hr; + + TRACE("(%p)->()\n",This); + + QUARTZ_CompList_Lock( This->pCompList ); + + hr = NOERROR; + while ( cSkip > 0 ) + { + if ( This->pItemCur == NULL ) + { + hr = S_FALSE; + break; + } + This->pItemCur = + QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur ); + cSkip --; + } + + QUARTZ_CompList_Unlock( This->pCompList ); + + return hr; +} + +static HRESULT WINAPI +IEnumUnknown_fnReset(IEnumUnknown* iface) +{ + CEnumUnknown_THIS(iface,enumunk); + + TRACE("(%p)->()\n",This); + + QUARTZ_CompList_Lock( This->pCompList ); + + This->pItemCur = QUARTZ_CompList_GetFirst( This->pCompList ); + + QUARTZ_CompList_Unlock( This->pCompList ); + + return NOERROR; +} + +static HRESULT WINAPI +IEnumUnknown_fnClone(IEnumUnknown* iface,IEnumUnknown** ppunk) +{ + CEnumUnknown_THIS(iface,enumunk); + HRESULT hr; + + TRACE("(%p)->()\n",This); + + if ( ppunk == NULL ) + return E_POINTER; + + QUARTZ_CompList_Lock( This->pCompList ); + + hr = QUARTZ_CreateEnumUnknown( + This->IFEntries[0].piid, + (void**)ppunk, + This->pCompList ); + + QUARTZ_CompList_Unlock( This->pCompList ); + + return hr; +} + + +static ICOM_VTABLE(IEnumUnknown) ienumunk = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IEnumUnknown_fnQueryInterface, + IEnumUnknown_fnAddRef, + IEnumUnknown_fnRelease, + /* IEnumUnknown fields */ + IEnumUnknown_fnNext, + IEnumUnknown_fnSkip, + IEnumUnknown_fnReset, + IEnumUnknown_fnClone, +}; + +void QUARTZ_DestroyEnumUnknown(IUnknown* punk) +{ + CEnumUnknown_THIS(punk,unk); + + if ( This->pCompList != NULL ) + QUARTZ_CompList_Free( This->pCompList ); +} + +HRESULT QUARTZ_CreateEnumUnknown( + REFIID riidEnum, void** ppobj, const QUARTZ_CompList* pCompList ) +{ + CEnumUnknown* penum; + QUARTZ_CompList* pCompListDup; + + TRACE("(%s,%p,%p)\n",debugstr_guid(riidEnum),ppobj,pCompList); + + pCompListDup = QUARTZ_CompList_Dup( pCompList, FALSE ); + if ( pCompListDup == NULL ) + return E_OUTOFMEMORY; + + penum = (CEnumUnknown*)QUARTZ_AllocObj( sizeof(CEnumUnknown) ); + if ( penum == NULL ) + { + QUARTZ_CompList_Free( pCompListDup ); + return E_OUTOFMEMORY; + } + + QUARTZ_IUnkInit( &penum->unk, NULL ); + ICOM_VTBL(&penum->enumunk) = &ienumunk; + + penum->IFEntries[0].piid = riidEnum; + penum->IFEntries[0].ofsVTPtr = + offsetof(CEnumUnknown,enumunk)-offsetof(CEnumUnknown,unk); + penum->pCompList = pCompListDup; + penum->pItemCur = QUARTZ_CompList_GetFirst( pCompListDup ); + + penum->unk.pEntries = penum->IFEntries; + penum->unk.dwEntries = 1; + penum->unk.pOnFinalRelease = QUARTZ_DestroyEnumUnknown; + + *ppobj = (void*)(&penum->enumunk); + + return S_OK; +} + diff --git a/dlls/quartz/enumunk.h b/dlls/quartz/enumunk.h new file mode 100644 index 00000000000..ca7dbf10b32 --- /dev/null +++ b/dlls/quartz/enumunk.h @@ -0,0 +1,16 @@ +/* + * Implementation of IEnumUnknown (for internal use). + * + * hidenori@a2.ctktv.ne.jp + */ + +#ifndef QUARTZ_ENUMUNK_H +#define QUARTZ_ENUMUNK_H + +#include "complist.h" + +HRESULT QUARTZ_CreateEnumUnknown( + REFIID riidEnum, void** ppobj, const QUARTZ_CompList* pCompList ); + + +#endif /* QUARTZ_ENUMUNK_H */ diff --git a/dlls/quartz/fgclsid.c b/dlls/quartz/fgclsid.c new file mode 100644 index 00000000000..b66609c8158 --- /dev/null +++ b/dlls/quartz/fgclsid.c @@ -0,0 +1,97 @@ +/* + * Implementation of IPersist for FilterGraph. + * + * FIXME - stub. + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "wine/obj_oleaut.h" +#include "strmif.h" +#include "control.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "fgraph.h" + + + +static HRESULT WINAPI +IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,persist); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IPersist_fnAddRef(IPersist* iface) +{ + CFilterGraph_THIS(iface,persist); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IPersist_fnRelease(IPersist* iface) +{ + CFilterGraph_THIS(iface,persist); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + + +static HRESULT WINAPI +IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid) +{ + CFilterGraph_THIS(iface,persist); + + TRACE("(%p)->()\n",This); + + if ( pclsid == NULL ) + return E_POINTER; + memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) ); + + return E_NOTIMPL; +} + + +static ICOM_VTABLE(IPersist) ipersist = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IPersist_fnQueryInterface, + IPersist_fnAddRef, + IPersist_fnRelease, + /* IPersist fields */ + IPersist_fnGetClassID, +}; + +HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->persist) = &ipersist; + + return NOERROR; +} + +void CFilterGraph_UninitIPersist( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} diff --git a/dlls/quartz/fgidisp.c b/dlls/quartz/fgidisp.c new file mode 100644 index 00000000000..cebaa82a17f --- /dev/null +++ b/dlls/quartz/fgidisp.c @@ -0,0 +1,128 @@ +/* + * Implementation of IDispatch for FilterGraph. + * + * FIXME - stub. + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "wine/obj_oleaut.h" +#include "strmif.h" +#include "control.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "fgraph.h" + + + +static HRESULT WINAPI +IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,disp); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IDispatch_fnAddRef(IDispatch* iface) +{ + CFilterGraph_THIS(iface,disp); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IDispatch_fnRelease(IDispatch* iface) +{ + CFilterGraph_THIS(iface,disp); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI +IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr) +{ + CFilterGraph_THIS(iface,disp); + + FIXME("(%p)->()\n",This); + + return E_NOTIMPL; +} + + + +static ICOM_VTABLE(IDispatch) idispatch = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IDispatch_fnQueryInterface, + IDispatch_fnAddRef, + IDispatch_fnRelease, + /* IDispatch fields */ + IDispatch_fnGetTypeInfoCount, + IDispatch_fnGetTypeInfo, + IDispatch_fnGetIDsOfNames, + IDispatch_fnInvoke, +}; + + +HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->disp) = &idispatch; + + return NOERROR; +} + +void CFilterGraph_UninitIDispatch( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} + diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c index 3889fa87f89..29ff724ca97 100644 --- a/dlls/quartz/fgraph.c +++ b/dlls/quartz/fgraph.c @@ -1,8 +1,6 @@ /* * Implementation of CLSID_FilterGraph. * - * FIXME - stub. - * * hidenori@a2.ctktv.ne.jp */ @@ -27,12 +25,17 @@ DEFAULT_DEBUG_CHANNEL(quartz); /* can I use offsetof safely? - FIXME? */ static QUARTZ_IFEntry IFEntries[] = { + { &IID_IPersist, offsetof(CFilterGraph,persist)-offsetof(CFilterGraph,unk) }, + { &IID_IDispatch, offsetof(CFilterGraph,disp)-offsetof(CFilterGraph,unk) }, { &IID_IFilterGraph, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) }, { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) }, { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) }, + { &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) }, { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) }, + { &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) }, { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) }, { &IID_IMediaEventEx, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) }, + { &IID_IMediaEventSink, offsetof(CFilterGraph,mediaeventsink)-offsetof(CFilterGraph,unk) }, { &IID_IMediaPosition, offsetof(CFilterGraph,mediaposition)-offsetof(CFilterGraph,unk) }, { &IID_IMediaSeeking, offsetof(CFilterGraph,mediaseeking)-offsetof(CFilterGraph,unk) }, { &IID_IBasicVideo, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) }, @@ -42,23 +45,55 @@ static QUARTZ_IFEntry IFEntries[] = }; +struct FGInitEntry +{ + HRESULT (*pInit)(CFilterGraph*); + void (*pUninit)(CFilterGraph*); +}; + +static const struct FGInitEntry FGRAPH_Init[] = +{ + #define FGENT(a) {&CFilterGraph_Init##a,&CFilterGraph_Uninit##a}, + + FGENT(IPersist) + FGENT(IDispatch) + FGENT(IFilterGraph2) + FGENT(IGraphVersion) + FGENT(IMediaControl) + FGENT(IMediaFilter) + FGENT(IMediaEventEx) + FGENT(IMediaEventSink) + FGENT(IMediaPosition) + FGENT(IMediaSeeking) + FGENT(IBasicVideo2) + FGENT(IBasicAudio) + FGENT(IVideoWindow) + + #undef FGENT + { NULL, NULL }, +}; + + static void QUARTZ_DestroyFilterGraph(IUnknown* punk) { CFilterGraph_THIS(punk,unk); + int i; - CFilterGraph_UninitIFilterGraph2( This ); - CFilterGraph_UninitIMediaControl( This ); - CFilterGraph_UninitIMediaEventEx( This ); - CFilterGraph_UninitIMediaPosition( This ); - CFilterGraph_UninitIMediaSeeking( This ); - CFilterGraph_UninitIBasicVideo2( This ); - CFilterGraph_UninitIBasicAudio( This ); - CFilterGraph_UninitIVideoWindow( This ); + i = 0; + while ( FGRAPH_Init[i].pInit != NULL ) + { + FGRAPH_Init[i].pUninit( This ); + i++; + } + + TRACE( "succeeded.\n" ); } HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj) { CFilterGraph* pfg; + HRESULT hr; + int i; TRACE("(%p,%p)\n",punkOuter,ppobj); @@ -67,14 +102,24 @@ HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj) return E_OUTOFMEMORY; QUARTZ_IUnkInit( &pfg->unk, punkOuter ); - CFilterGraph_InitIFilterGraph2( pfg ); - CFilterGraph_InitIMediaControl( pfg ); - CFilterGraph_InitIMediaEventEx( pfg ); - CFilterGraph_InitIMediaPosition( pfg ); - CFilterGraph_InitIMediaSeeking( pfg ); - CFilterGraph_InitIBasicVideo2( pfg ); - CFilterGraph_InitIBasicAudio( pfg ); - CFilterGraph_InitIVideoWindow( pfg ); + + i = 0; + hr = NOERROR; + while ( FGRAPH_Init[i].pInit != NULL ) + { + hr = FGRAPH_Init[i].pInit( pfg ); + if ( FAILED(hr) ) + break; + i++; + } + + if ( FAILED(hr) ) + { + while ( --i >= 0 ) + FGRAPH_Init[i].pUninit( pfg ); + QUARTZ_FreeObj( pfg ); + return hr; + } pfg->unk.pEntries = IFEntries; pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h index d606c11ea0e..e06551c2439 100644 --- a/dlls/quartz/fgraph.h +++ b/dlls/quartz/fgraph.h @@ -7,37 +7,69 @@ - At least, the following interfaces should be implemented: IUnknown + + IPersist + + IDispatch + IFilterGraph - IGraphBuilder - IFilterGraph2 + + IGraphVersion + IDispatch - IMediaControl + + IPersist - IMediaFilter + IDispatch - IMediaEvent - IMediaEventEx + + IMediaEventSink + IDispatch - IMediaPosition + IMediaSeeking - + IDispatch - IBasicVideo (pass to a renderer) + + IDispatch - IBasicVideo[2] (pass to a renderer) + IDispatch - IBasicAudio (pass to a renderer) + IDispatch - IVideoWindow (pass to a renderer) (following interfaces are not implemented) - + IDispatch - + IMediaEventSink - + IGraphVerson + + IMarshal + + IFilterMapper2 - IFilterMapper3 + FIXME - Are there any missing interfaces??? */ #include "iunk.h" +#include "complist.h" + + +typedef struct FG_IPersistImpl +{ + ICOM_VFIELD(IPersist); +} FG_IPersistImpl; + +typedef struct FG_IDispatchImpl +{ + ICOM_VFIELD(IDispatch); +} FG_IDispatchImpl; typedef struct FG_IFilterGraph2Impl { ICOM_VFIELD(IFilterGraph2); } FG_IFilterGraph2Impl; +typedef struct FG_IGraphVersionImpl +{ + ICOM_VFIELD(IGraphVersion); +} FG_IGraphVersionImpl; + typedef struct FG_IMediaControlImpl { ICOM_VFIELD(IMediaControl); } FG_IMediaControlImpl; +typedef struct FG_IMediaFilterImpl +{ + ICOM_VFIELD(IMediaFilter); +} FG_IMediaFilterImpl; + typedef struct FG_IMediaEventImpl { ICOM_VFIELD(IMediaEventEx); } FG_IMediaEventImpl; +typedef struct FG_IMediaEventSinkImpl +{ + ICOM_VFIELD(IMediaEventSink); +} FG_IMediaEventSinkImpl; + typedef struct FG_IMediaPositionImpl { ICOM_VFIELD(IMediaPosition); @@ -67,18 +99,30 @@ typedef struct FG_IVideoWindowImpl typedef struct CFilterGraph { QUARTZ_IUnkImpl unk; + FG_IPersistImpl persist; + FG_IDispatchImpl disp; FG_IFilterGraph2Impl fgraph; + FG_IGraphVersionImpl graphversion; FG_IMediaControlImpl mediacontrol; + FG_IMediaFilterImpl mediafilter; FG_IMediaEventImpl mediaevent; + FG_IMediaEventSinkImpl mediaeventsink; FG_IMediaPositionImpl mediaposition; FG_IMediaSeekingImpl mediaseeking; FG_IBasicVideoImpl basvid; FG_IBasicAudioImpl basaud; FG_IVideoWindowImpl vidwin; + /* IDispatch fields. */ /* IFilterGraph2 fields. */ + QUARTZ_CompList* m_pFilterList; + /* IGraphVersion fields. */ + CRITICAL_SECTION m_csGraphVersion; + LONG m_lGraphVersion; /* IMediaControl fields. */ /* IMediaEvent fields. */ + HANDLE m_hMediaEvent; + /* IMediaEventSink fields. */ /* IMediaPosition fields. */ /* IMediaSeeking fields. */ /* IBasicVideo2 fields. */ @@ -87,24 +131,36 @@ typedef struct CFilterGraph } CFilterGraph; #define CFilterGraph_THIS(iface,member) CFilterGraph* This = ((CFilterGraph*)(((char*)iface)-offsetof(CFilterGraph,member))) +#define CFilterGraph_IPersist(th) ((IPersist*)&((th)->persist)) +#define CFilterGraph_IDispatch(th) ((IDispatch*)&((th)->disp)) HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj); -void CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg ); +void CFilterGraph_UninitIPersist( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg ); +void CFilterGraph_UninitIDispatch( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg ); void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg ); -void CFilterGraph_InitIMediaControl( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg ); +void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIMediaControl( CFilterGraph* pfg ); void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg ); -void CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg ); +void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg ); void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg ); -void CFilterGraph_InitIMediaPosition( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg ); +void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIMediaPosition( CFilterGraph* pfg ); void CFilterGraph_UninitIMediaPosition( CFilterGraph* pfg ); -void CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg ); void CFilterGraph_UninitIMediaSeeking( CFilterGraph* pfg ); -void CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg ); void CFilterGraph_UninitIBasicVideo2( CFilterGraph* pfg ); -void CFilterGraph_InitIBasicAudio( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIBasicAudio( CFilterGraph* pfg ); void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg ); -void CFilterGraph_InitIVideoWindow( CFilterGraph* pfg ); +HRESULT CFilterGraph_InitIVideoWindow( CFilterGraph* pfg ); void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg ); diff --git a/dlls/quartz/fmap.c b/dlls/quartz/fmap.c index e588f7c0d45..2853b25e50a 100644 --- a/dlls/quartz/fmap.c +++ b/dlls/quartz/fmap.c @@ -41,6 +41,7 @@ static void QUARTZ_DestroyFilterMapper(IUnknown* punk) HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj) { CFilterMapper* pfm; + HRESULT hr; TRACE("(%p,%p)\n",punkOuter,ppobj); @@ -49,7 +50,12 @@ HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj) return E_OUTOFMEMORY; QUARTZ_IUnkInit( &pfm->unk, punkOuter ); - CFilterMapper_InitIFilterMapper( pfm ); + hr = CFilterMapper_InitIFilterMapper( pfm ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( pfm ); + return hr; + } pfm->unk.pEntries = IFEntries; pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); diff --git a/dlls/quartz/fmap.h b/dlls/quartz/fmap.h index 353898153f7..c21cc2e8076 100644 --- a/dlls/quartz/fmap.h +++ b/dlls/quartz/fmap.h @@ -29,7 +29,7 @@ typedef struct CFilterMapper HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj); -void CFilterMapper_InitIFilterMapper( CFilterMapper* pfm ); +HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm ); void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm ); diff --git a/dlls/quartz/fmap2.c b/dlls/quartz/fmap2.c index ff3271792b2..96c6a9b985c 100644 --- a/dlls/quartz/fmap2.c +++ b/dlls/quartz/fmap2.c @@ -42,6 +42,7 @@ static void QUARTZ_DestroyFilterMapper2(IUnknown* punk) HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj) { CFilterMapper2* pfm; + HRESULT hr; TRACE("(%p,%p)\n",punkOuter,ppobj); @@ -50,7 +51,12 @@ HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj) return E_OUTOFMEMORY; QUARTZ_IUnkInit( &pfm->unk, punkOuter ); - CFilterMapper2_InitIFilterMapper3( pfm ); + hr = CFilterMapper2_InitIFilterMapper3( pfm ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( pfm ); + return hr; + } pfm->unk.pEntries = IFEntries; pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); diff --git a/dlls/quartz/fmap2.h b/dlls/quartz/fmap2.h index 0ee05a1e5b4..6cf7718c577 100644 --- a/dlls/quartz/fmap2.h +++ b/dlls/quartz/fmap2.h @@ -22,6 +22,7 @@ typedef struct CFilterMapper2 { QUARTZ_IUnkImpl unk; FM2_IFilterMapper3Impl fmap3; + /* IFilterMapper3 fields */ } CFilterMapper2; #define CFilterMapper2_THIS(iface,member) CFilterMapper2* This = ((CFilterMapper2*)(((char*)iface)-offsetof(CFilterMapper2,member))) @@ -29,7 +30,7 @@ typedef struct CFilterMapper2 HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj); -void CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde ); +HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde ); void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* psde ); diff --git a/dlls/quartz/ibasaud.c b/dlls/quartz/ibasaud.c index fbfe7828626..643a75a5c59 100644 --- a/dlls/quartz/ibasaud.c +++ b/dlls/quartz/ibasaud.c @@ -158,10 +158,12 @@ static ICOM_VTABLE(IBasicAudio) ibasicaudio = }; -void CFilterGraph_InitIBasicAudio( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIBasicAudio( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->basaud) = &ibasicaudio; + + return NOERROR; } void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg ) diff --git a/dlls/quartz/ibasvid.c b/dlls/quartz/ibasvid.c index 3915b1be69c..44843c34d38 100644 --- a/dlls/quartz/ibasvid.c +++ b/dlls/quartz/ibasvid.c @@ -479,10 +479,12 @@ static ICOM_VTABLE(IBasicVideo2) ibasicvideo = }; -void CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIBasicVideo2( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->basvid) = &ibasicvideo; + + return NOERROR; } void CFilterGraph_UninitIBasicVideo2( CFilterGraph* pfg ) diff --git a/dlls/quartz/idevenum.c b/dlls/quartz/idevenum.c index cf62c15a082..5c644bebb14 100644 --- a/dlls/quartz/idevenum.c +++ b/dlls/quartz/idevenum.c @@ -11,18 +11,28 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winuser.h" +#include "winreg.h" #include "winerror.h" #include "wine/obj_base.h" -#include "wine/obj_oleaut.h" +#include "objidl.h" +#include "oleidl.h" +#include "ocidl.h" #include "strmif.h" #include "control.h" #include "uuids.h" +#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "devenum.h" +#include "regsvr.h" +#include "enumunk.h" +#include "complist.h" +#include "devmon.h" + static HRESULT WINAPI ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj) @@ -58,10 +68,95 @@ static HRESULT WINAPI ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags) { CSysDevEnum_THIS(iface,createdevenum); - - FIXME("(%p)->() stub!\n",This); - - return E_NOTIMPL; + HRESULT hr; + HKEY hKey; + QUARTZ_CompList* pMonList; + IMoniker* pMon; + DWORD dwIndex; + LONG lr; + WCHAR wszPath[ 1024 ]; + DWORD dwLen; + DWORD dwNameMax; + DWORD cbName; + FILETIME ftLastWrite; + + TRACE("(%p)->(%s,%p,%08lx)\n",This, + debugstr_guid(rclsidDeviceClass),ppobj,dwFlags); + if ( dwFlags != 0 ) + { + FIXME("unknown flags %08lx\n",dwFlags); + return E_NOTIMPL; + } + + if ( ppobj == NULL ) + return E_POINTER; + *ppobj = NULL; + + hr = QUARTZ_CreateCLSIDPath( + wszPath, sizeof(wszPath)/sizeof(wszPath[0]), + rclsidDeviceClass, QUARTZ_wszInstance ); + if ( FAILED(hr) ) + return hr; + + if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath, + 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) + return E_FAIL; + + dwLen = strlenW(wszPath); + wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0; + dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8; + + pMonList = QUARTZ_CompList_Alloc(); + if ( pMonList == NULL ) + { + hr = E_OUTOFMEMORY; + goto err; + } + + /* enumerate all subkeys. */ + dwIndex = 0; + while ( 1 ) + { + cbName = dwNameMax; + lr = RegEnumKeyExW( + hKey, dwIndex, &wszPath[dwLen], &cbName, + NULL, NULL, NULL, &ftLastWrite ); + if ( lr == ERROR_NO_MORE_ITEMS ) + break; + if ( lr != ERROR_SUCCESS ) + { + hr = E_FAIL; + goto err; + } + + hr = QUARTZ_CreateDeviceMoniker( + HKEY_CLASSES_ROOT, wszPath, &pMon ); + if ( FAILED(hr) ) + goto err; + + hr = QUARTZ_CompList_AddComp( + pMonList, (IUnknown*)pMon, NULL, 0 ); + IMoniker_Release( pMon ); + + if ( FAILED(hr) ) + goto err; + + dwIndex ++; + } + + /* create an enumerator. */ + hr = QUARTZ_CreateEnumUnknown( + &IID_IEnumMoniker, (void**)ppobj, pMonList ); + if ( FAILED(hr) ) + goto err; + + hr = S_OK; +err: + if ( pMonList != NULL ) + QUARTZ_CompList_Free( pMonList ); + RegCloseKey( hKey ); + + return hr; } static ICOM_VTABLE(ICreateDevEnum) icreatedevenum = @@ -75,10 +170,12 @@ static ICOM_VTABLE(ICreateDevEnum) icreatedevenum = ICreateDevEnum_fnCreateClassEnumerator, }; -void CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde ) +HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde ) { TRACE("(%p)\n",psde); ICOM_VTBL(&psde->createdevenum) = &icreatedevenum; + + return NOERROR; } void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde ) diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c index a6ef7d7f7a6..43565d02064 100644 --- a/dlls/quartz/ifgraph.c +++ b/dlls/quartz/ifgraph.c @@ -18,12 +18,63 @@ #include "strmif.h" #include "control.h" #include "uuids.h" +#include "vfwmsgs.h" +#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "fgraph.h" +#include "enumunk.h" + + +static HRESULT CFilterGraph_DisconnectAllPins( IBaseFilter* pFilter ) +{ + IEnumPins* pEnum = NULL; + IPin* pPin; + IPin* pConnTo; + ULONG cFetched; + HRESULT hr; + + hr = IBaseFilter_EnumPins( pFilter, &pEnum ); + if ( FAILED(hr) ) + return hr; + if ( pEnum == NULL ) + return E_FAIL; + + while ( 1 ) + { + pPin = NULL; + cFetched = 0; + hr = IEnumPins_Next( pEnum, 1, &pPin, &cFetched ); + if ( FAILED(hr) ) + break; + if ( hr != NOERROR || pPin == NULL || cFetched != 1 ) + { + hr = NOERROR; + break; + } + + pConnTo = NULL; + hr = IPin_ConnectedTo(pPin,&pConnTo); + if ( hr == NOERROR && pConnTo != NULL ) + { + IPin_Disconnect(pPin); + IPin_Disconnect(pConnTo); + IPin_Release(pConnTo); + } + + IPin_Release( pPin ); + } + + IEnumPins_Release( pEnum ); + + return hr; +} + + +/****************************************************************************/ static HRESULT WINAPI IFilterGraph2_fnQueryInterface(IFilterGraph2* iface,REFIID riid,void** ppobj) @@ -59,45 +110,272 @@ static HRESULT WINAPI IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pName) { CFilterGraph_THIS(iface,fgraph); - - FIXME( "(%p)->() stub!\n", This ); - return E_NOTIMPL; + FILTER_INFO info; + HRESULT hr; + HRESULT hrSucceeded = S_OK; + QUARTZ_CompListItem* pItem; + int i,iLen; + + TRACE( "(%p)->(%p,%s)\n",This,pFilter,debugstr_w(pName) ); + + QUARTZ_CompList_Lock( This->m_pFilterList ); + + if ( pName != NULL ) + { + pItem = QUARTZ_CompList_SearchData( + This->m_pFilterList, + pName, sizeof(WCHAR)*(strlenW(pName)+1) ); + if ( pItem == NULL ) + goto name_ok; + + hrSucceeded = VFW_S_DUPLICATE_NAME; + + iLen = strlenW(pName); + if ( iLen > 32 ) + iLen = 32; + memcpy( info.achName, pName, sizeof(WCHAR)*iLen ); + info.achName[iLen] = 0; + } + else + { + ZeroMemory( &info, sizeof(info) ); + hr = IBaseFilter_QueryFilterInfo( pFilter, &info ); + if ( FAILED(hr) ) + goto end; + + iLen = strlenW(info.achName); + pItem = QUARTZ_CompList_SearchData( + This->m_pFilterList, + info.achName, sizeof(WCHAR)*(iLen+1) ); + if ( pItem == NULL ) + { + pName = info.achName; + goto name_ok; + } + } + + /* generate modified names for this filter.. */ + iLen = strlenW(info.achName); + if ( iLen > 32 ) + iLen = 32; + info.achName[iLen++] = ' '; + + for ( i = 0; i <= 99; i++ ) + { + info.achName[iLen+0] = (i%10) + '0'; + info.achName[iLen+1] = ((i/10)%10) + '0'; + info.achName[iLen+2] = 0; + pItem = QUARTZ_CompList_SearchData( + This->m_pFilterList, + info.achName, sizeof(WCHAR)*(iLen+3) ); + if ( pItem == NULL ) + { + pName = info.achName; + goto name_ok; + } + } + + hr = ( pName == NULL ) ? E_FAIL : VFW_E_DUPLICATE_NAME; + goto end; + +name_ok: + /* register this filter. */ + hr = QUARTZ_CompList_AddComp( + This->m_pFilterList, (IUnknown*)pFilter, + pName, sizeof(WCHAR)*(strlenW(pName)+1) ); + if ( FAILED(hr) ) + goto end; + + hr = IBaseFilter_JoinFilterGraph(pFilter,(IFilterGraph*)iface,pName); + if ( FAILED(hr) ) + { + QUARTZ_CompList_RemoveComp( + This->m_pFilterList,(IUnknown*)pFilter); + goto end; + } + + EnterCriticalSection( &This->m_csGraphVersion ); + This->m_lGraphVersion ++; + LeaveCriticalSection( &This->m_csGraphVersion ); + + hr = hrSucceeded; +end: + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + return hr; } static HRESULT WINAPI IFilterGraph2_fnRemoveFilter(IFilterGraph2* iface,IBaseFilter* pFilter) { CFilterGraph_THIS(iface,fgraph); + QUARTZ_CompListItem* pItem; + HRESULT hr = NOERROR; - FIXME( "(%p)->() stub!\n", This ); - return E_NOTIMPL; + TRACE( "(%p)->(%p)\n",This,pFilter ); + + QUARTZ_CompList_Lock( This->m_pFilterList ); + + pItem = QUARTZ_CompList_SearchComp( + This->m_pFilterList, (IUnknown*)pFilter ); + if ( pItem != NULL ) + { + CFilterGraph_DisconnectAllPins(pFilter); + hr = IBaseFilter_JoinFilterGraph( + pFilter, NULL, QUARTZ_CompList_GetDataPtr(pItem) ); + QUARTZ_CompList_RemoveComp( + This->m_pFilterList, (IUnknown*)pFilter ); + } + + EnterCriticalSection( &This->m_csGraphVersion ); + This->m_lGraphVersion ++; + LeaveCriticalSection( &This->m_csGraphVersion ); + + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + return hr; } static HRESULT WINAPI IFilterGraph2_fnEnumFilters(IFilterGraph2* iface,IEnumFilters** ppEnum) { CFilterGraph_THIS(iface,fgraph); + HRESULT hr; - FIXME( "(%p)->() stub!\n", This ); - return E_NOTIMPL; + TRACE( "(%p)->(%p)\n",This,ppEnum ); + + QUARTZ_CompList_Lock( This->m_pFilterList ); + + hr = QUARTZ_CreateEnumUnknown( + &IID_IEnumFilters, (void**)ppEnum, This->m_pFilterList ); + + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + return hr; } static HRESULT WINAPI IFilterGraph2_fnFindFilterByName(IFilterGraph2* iface,LPCWSTR pName,IBaseFilter** ppFilter) { CFilterGraph_THIS(iface,fgraph); + QUARTZ_CompListItem* pItem; + HRESULT hr = E_FAIL; - FIXME( "(%p)->() stub!\n", This ); - return E_NOTIMPL; + TRACE( "(%p)->(%s,%p)\n",This,debugstr_w(pName),ppFilter ); + + if ( ppFilter == NULL ) + return E_POINTER; + *ppFilter = NULL; + + QUARTZ_CompList_Lock( This->m_pFilterList ); + + pItem = QUARTZ_CompList_SearchData( + This->m_pFilterList, + pName, sizeof(WCHAR)*(strlenW(pName)+1) ); + if ( pItem != NULL ) + { + *ppFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem); + hr = NOERROR; + } + + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + return hr; } static HRESULT WINAPI IFilterGraph2_fnConnectDirect(IFilterGraph2* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt) { CFilterGraph_THIS(iface,fgraph); - - FIXME( "(%p)->() stub!\n", This ); - return E_NOTIMPL; + IPin* pConnTo; + PIN_INFO infoIn; + PIN_INFO infoOut; + FILTER_INFO finfoIn; + FILTER_INFO finfoOut; + HRESULT hr; + + TRACE( "(%p)->(%p,%p,%p)\n",This,pOut,pIn,pmt ); + + infoIn.pFilter = NULL; + infoOut.pFilter = NULL; + finfoIn.pGraph = NULL; + finfoOut.pGraph = NULL; + + QUARTZ_CompList_Lock( This->m_pFilterList ); + + hr = IPin_QueryPinInfo(pIn,&infoIn); + if ( FAILED(hr) ) + goto end; + hr = IPin_QueryPinInfo(pOut,&infoOut); + if ( FAILED(hr) ) + goto end; + if ( infoIn.pFilter == NULL || infoOut.pFilter == NULL || + infoIn.dir != PINDIR_INPUT || infoOut.dir != PINDIR_OUTPUT ) + { + hr = E_FAIL; + goto end; + } + + hr = IBaseFilter_QueryFilterInfo(infoIn.pFilter,&finfoIn); + if ( FAILED(hr) ) + goto end; + hr = IBaseFilter_QueryFilterInfo(infoOut.pFilter,&finfoOut); + if ( FAILED(hr) ) + goto end; + if ( finfoIn.pGraph != ((IFilterGraph*)iface) || + finfoOut.pGraph != ((IFilterGraph*)iface) ) + { + hr = E_FAIL; + goto end; + } + + pConnTo = NULL; + hr = IPin_ConnectedTo(pIn,&pConnTo); + if ( FAILED(hr) ) + goto end; + if ( pConnTo != NULL ) + { + IPin_Release(pConnTo); + goto end; + } + + pConnTo = NULL; + hr = IPin_ConnectedTo(pOut,&pConnTo); + if ( FAILED(hr) ) + goto end; + if ( pConnTo != NULL ) + { + IPin_Release(pConnTo); + goto end; + } + + hr = IPin_Connect(pIn,pOut,pmt); + if ( FAILED(hr) ) + goto end; + hr = IPin_Connect(pOut,pIn,pmt); + if ( FAILED(hr) ) + { + IPin_Disconnect(pIn); + goto end; + } + + EnterCriticalSection( &This->m_csGraphVersion ); + This->m_lGraphVersion ++; + LeaveCriticalSection( &This->m_csGraphVersion ); + +end: + QUARTZ_CompList_Unlock( This->m_pFilterList ); + + if ( infoIn.pFilter != NULL ) + IBaseFilter_Release(infoIn.pFilter); + if ( infoOut.pFilter != NULL ) + IBaseFilter_Release(infoOut.pFilter); + if ( finfoIn.pGraph != NULL ) + IFilterGraph_Release(finfoIn.pGraph); + if ( finfoOut.pGraph != NULL ) + IFilterGraph_Release(finfoOut.pGraph); + + return hr; } static HRESULT WINAPI @@ -105,7 +383,12 @@ IFilterGraph2_fnReconnect(IFilterGraph2* iface,IPin* pPin) { CFilterGraph_THIS(iface,fgraph); - FIXME( "(%p)->() stub!\n", This ); + FIXME( "(%p)->(%p) stub!\n",This,pPin ); + + EnterCriticalSection( &This->m_csGraphVersion ); + This->m_lGraphVersion ++; + LeaveCriticalSection( &This->m_csGraphVersion ); + return E_NOTIMPL; } @@ -114,7 +397,12 @@ IFilterGraph2_fnDisconnect(IFilterGraph2* iface,IPin* pPin) { CFilterGraph_THIS(iface,fgraph); - FIXME( "(%p)->() stub!\n", This ); + FIXME( "(%p)->(%p) stub!\n",This,pPin ); + + EnterCriticalSection( &This->m_csGraphVersion ); + This->m_lGraphVersion ++; + LeaveCriticalSection( &This->m_csGraphVersion ); + return E_NOTIMPL; } @@ -131,8 +419,19 @@ static HRESULT WINAPI IFilterGraph2_fnConnect(IFilterGraph2* iface,IPin* pOut,IPin* pIn) { CFilterGraph_THIS(iface,fgraph); + HRESULT hr; + + TRACE( "(%p)->(%p,%p)\n",This,pOut,pIn ); + + /* At first, try to connect directly. */ + hr = IFilterGraph_ConnectDirect(iface,pOut,pIn,NULL); + if ( hr == NOERROR ) + return NOERROR; + + /* FIXME - try to connect indirectly. */ + FIXME( "(%p)->(%p,%p) stub!\n",This,pOut,pIn ); + - FIXME( "(%p)->() stub!\n", This ); return E_NOTIMPL; } @@ -141,7 +440,7 @@ IFilterGraph2_fnRender(IFilterGraph2* iface,IPin* pOut) { CFilterGraph_THIS(iface,fgraph); - FIXME( "(%p)->() stub!\n", This ); + FIXME( "(%p)->(%p) stub!\n",This,pOut ); return E_NOTIMPL; } @@ -149,9 +448,81 @@ static HRESULT WINAPI IFilterGraph2_fnRenderFile(IFilterGraph2* iface,LPCWSTR lpFileName,LPCWSTR lpPlayList) { CFilterGraph_THIS(iface,fgraph); - - FIXME( "(%p)->() stub!\n", This ); - return E_NOTIMPL; + HRESULT hr; + IBaseFilter* pFilter = NULL; + IEnumPins* pEnum = NULL; + IPin* pPin; + ULONG cFetched; + PIN_DIRECTION dir; + ULONG cTryToRender; + ULONG cActRender; + + TRACE( "(%p)->(%s,%s)\n",This, + debugstr_w(lpFileName),debugstr_w(lpPlayList) ); + + if ( lpPlayList != NULL ) + return E_INVALIDARG; + + pFilter = NULL; + hr = IFilterGraph2_AddSourceFilter(iface,lpFileName,NULL,&pFilter); + if ( FAILED(hr) ) + goto end; + if ( pFilter == NULL ) + { + hr = E_FAIL; + goto end; + } + pEnum = NULL; + hr = IBaseFilter_EnumPins( pFilter, &pEnum ); + if ( FAILED(hr) ) + goto end; + if ( pEnum == NULL ) + { + hr = E_FAIL; + goto end; + } + + cTryToRender = 0; + cActRender = 0; + + while ( 1 ) + { + pPin = NULL; + cFetched = 0; + hr = IEnumPins_Next( pEnum, 1, &pPin, &cFetched ); + if ( FAILED(hr) ) + goto end; + if ( hr != NOERROR || pPin == NULL || cFetched != 1 ) + { + hr = NOERROR; + break; + } + hr = IPin_QueryDirection( pPin, &dir ); + if ( hr == NOERROR && dir == PINDIR_OUTPUT ) + { + cTryToRender ++; + hr = IFilterGraph2_Render( iface, pPin ); + if ( hr == NOERROR ) + cActRender ++; + } + IPin_Release( pPin ); + } + + if ( hr == NOERROR ) + { + if ( cTryToRender > cActRender ) + hr = VFW_S_PARTIAL_RENDER; + if ( cActRender == 0 ) + hr = E_FAIL; + } + +end: + if ( pEnum != NULL ) + IEnumPins_Release( pEnum ); + if ( pFilter != NULL ) + IBaseFilter_Release( pFilter ); + + return hr; } static HRESULT WINAPI @@ -159,7 +530,8 @@ IFilterGraph2_fnAddSourceFilter(IFilterGraph2* iface,LPCWSTR lpFileName,LPCWSTR { CFilterGraph_THIS(iface,fgraph); - FIXME( "(%p)->() stub!\n", This ); + FIXME( "(%p)->(%s,%s,%p) stub!\n",This, + debugstr_w(lpFileName),debugstr_w(lpFilterName),ppBaseFilter ); return E_NOTIMPL; } @@ -208,7 +580,12 @@ IFilterGraph2_fnReconnectEx(IFilterGraph2* iface,IPin* pPin,const AM_MEDIA_TYPE* { CFilterGraph_THIS(iface,fgraph); - FIXME( "(%p)->() stub!\n", This ); + FIXME( "(%p)->(%p,%p) stub!\n",This,pPin,pmt ); + + EnterCriticalSection( &This->m_csGraphVersion ); + This->m_lGraphVersion ++; + LeaveCriticalSection( &This->m_csGraphVersion ); + return E_NOTIMPL; } @@ -218,7 +595,7 @@ IFilterGraph2_fnRenderEx(IFilterGraph2* iface,IPin* pPin,DWORD dwParam1,DWORD* p CFilterGraph_THIS(iface,fgraph); /* undoc. */ - FIXME( "(%p)->() stub!\n", This ); + FIXME( "(%p)->(%p,%08lx,%p) stub!\n",This,pPin,dwParam1,pdwParam2); return E_NOTIMPL; } @@ -255,13 +632,34 @@ static ICOM_VTABLE(IFilterGraph2) ifgraph = IFilterGraph2_fnRenderEx, }; -void CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->fgraph) = &ifgraph; + + pfg->m_pFilterList = QUARTZ_CompList_Alloc(); + if ( pfg->m_pFilterList == NULL ) + return E_OUTOFMEMORY; + + return NOERROR; } void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg ) { + QUARTZ_CompListItem* pItem; + TRACE("(%p)\n",pfg); + + /* remove all filters... */ + while ( 1 ) + { + pItem = QUARTZ_CompList_GetFirst( pfg->m_pFilterList ); + if ( pItem == NULL ) + break; + IFilterGraph2_fnRemoveFilter( + (IFilterGraph2*)(&pfg->fgraph), + (IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem) ); + } + + QUARTZ_CompList_Free( pfg->m_pFilterList ); } diff --git a/dlls/quartz/ifmap.c b/dlls/quartz/ifmap.c index 9927e16c725..8d420d0dcd9 100644 --- a/dlls/quartz/ifmap.c +++ b/dlls/quartz/ifmap.c @@ -11,6 +11,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winreg.h" #include "winerror.h" #include "wine/obj_base.h" #include "wine/obj_oleaut.h" @@ -23,6 +24,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "fmap.h" +#include "regsvr.h" static HRESULT WINAPI @@ -61,19 +63,35 @@ IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszNam { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->(%s,%s,%08lx)\n",This, + debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit); - return E_NOTIMPL; + /* FIXME */ + /* FIXME - handle dwMerit! */ + return QUARTZ_RegisterAMovieFilter( + &CLSID_LegacyAmFilterCategory, + &clsid, + NULL, 0, + lpwszName, NULL, TRUE ); } static HRESULT WINAPI IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia) { CFilterMapper_THIS(iface,fmap); + HRESULT hr; - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->()\n",This); - return E_NOTIMPL; + if ( pclsidMedia == NULL ) + return E_POINTER; + hr = CoCreateGuid(pclsidMedia); + if ( FAILED(hr) ) + return hr; + + /* FIXME */ + return IFilterMapper_RegisterFilter(iface, + *pclsidMedia,lpwszName,0x60000000); } static HRESULT WINAPI @@ -81,7 +99,7 @@ IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwsz { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->() stub!\n",This); return E_NOTIMPL; } @@ -91,7 +109,7 @@ IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR l { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->() stub!\n",This); return E_NOTIMPL; } @@ -101,9 +119,13 @@ IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter) { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter)); - return E_NOTIMPL; + /* FIXME */ + return QUARTZ_RegisterAMovieFilter( + &CLSID_LegacyAmFilterCategory, + &clsidFilter, + NULL, 0, NULL, NULL, FALSE ); } static HRESULT WINAPI @@ -111,9 +133,10 @@ IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia) { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia)); - return E_NOTIMPL; + /* FIXME */ + return IFilterMapper_UnregisterFilter(iface,clsidMedia); } static HRESULT WINAPI @@ -121,7 +144,8 @@ IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszN { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->(%s,%s) stub!\n",This, + debugstr_guid(&clsidPin),debugstr_w(lpwszName)); return E_NOTIMPL; } @@ -131,7 +155,7 @@ IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj { CFilterMapper_THIS(iface,fmap); - TRACE("(%p)->() stub!\n",This); + FIXME("(%p)->() stub!\n",This); return E_NOTIMPL; } @@ -157,10 +181,12 @@ static ICOM_VTABLE(IFilterMapper) ifmap = }; -void CFilterMapper_InitIFilterMapper( CFilterMapper* pfm ) +HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm ) { TRACE("(%p)\n",pfm); ICOM_VTBL(&pfm->fmap) = &ifmap; + + return NOERROR; } void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm ) diff --git a/dlls/quartz/ifmap3.c b/dlls/quartz/ifmap3.c index d8b51c3978b..b706ab43804 100644 --- a/dlls/quartz/ifmap3.c +++ b/dlls/quartz/ifmap3.c @@ -11,6 +11,7 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winreg.h" #include "winerror.h" #include "wine/obj_base.h" #include "wine/obj_oleaut.h" @@ -23,6 +24,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "fmap2.h" +#include "regsvr.h" static HRESULT WINAPI @@ -60,7 +62,9 @@ IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DW { CFilterMapper2_THIS(iface,fmap3); - FIXME("(%p)->() stub!\n",This); + FIXME("(%p)->(%s,%lu,%s) stub!\n",This, + debugstr_guid(rclsidCategory), + (unsigned long)dwMerit,debugstr_w(lpwszDesc)); return E_NOTIMPL; } @@ -71,7 +75,10 @@ IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCateg { CFilterMapper2_THIS(iface,fmap3); - FIXME("(%p)->() stub!\n",This); + FIXME("(%p)->(%s,%s,%s) stub!\n",This, + debugstr_guid(pclsidCategory), + debugstr_w(lpwszInst), + debugstr_guid(rclsidFilter)); return E_NOTIMPL; } @@ -82,7 +89,10 @@ IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCW { CFilterMapper2_THIS(iface,fmap3); - FIXME("(%p)->() stub!\n",This); + FIXME( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This, + debugstr_guid(rclsidFilter),debugstr_w(lpName), + ppMoniker,debugstr_guid(pclsidCategory), + debugstr_w(lpwszInst),pRF2 ); return E_NOTIMPL; } @@ -129,10 +139,12 @@ static ICOM_VTABLE(IFilterMapper3) ifmap3 = }; -void CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm ) +HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm ) { TRACE("(%p)\n",pfm); ICOM_VTBL(&pfm->fmap3) = &ifmap3; + + return NOERROR; } void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm ) diff --git a/dlls/quartz/igrver.c b/dlls/quartz/igrver.c new file mode 100644 index 00000000000..a7e157961c8 --- /dev/null +++ b/dlls/quartz/igrver.c @@ -0,0 +1,108 @@ +/* + * Implementation of IGraphVersion for FilterGraph. + * + * FIXME - stub. + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "wine/obj_oleaut.h" +#include "strmif.h" +#include "control.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "fgraph.h" + + + +static HRESULT WINAPI +IGraphVersion_fnQueryInterface(IGraphVersion* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IGraphVersion_fnAddRef(IGraphVersion* iface) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IGraphVersion_fnRelease(IGraphVersion* iface) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + + +static HRESULT WINAPI +IGraphVersion_fnQueryVersion(IGraphVersion* iface,LONG* plVersion) +{ + CFilterGraph_THIS(iface,graphversion); + + TRACE("(%p)->(%p)\n",This,plVersion); + + if ( plVersion == NULL ) + return E_POINTER; + + EnterCriticalSection( &This->m_csGraphVersion ); + *plVersion = This->m_lGraphVersion; + LeaveCriticalSection( &This->m_csGraphVersion ); + + return NOERROR; +} + + +static ICOM_VTABLE(IGraphVersion) igraphversion = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IGraphVersion_fnQueryInterface, + IGraphVersion_fnAddRef, + IGraphVersion_fnRelease, + /* IGraphVersion fields */ + IGraphVersion_fnQueryVersion, +}; + + + +HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->graphversion) = &igraphversion; + + InitializeCriticalSection( &pfg->m_csGraphVersion ); + pfg->m_lGraphVersion = 1; + + return NOERROR; +} + +void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + + DeleteCriticalSection( &pfg->m_csGraphVersion ); +} + diff --git a/dlls/quartz/imcntl.c b/dlls/quartz/imcntl.c index 0e91bee1424..67bb2fa368f 100644 --- a/dlls/quartz/imcntl.c +++ b/dlls/quartz/imcntl.c @@ -213,10 +213,12 @@ static ICOM_VTABLE(IMediaControl) imediacontrol = }; -void CFilterGraph_InitIMediaControl( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIMediaControl( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->mediacontrol) = &imediacontrol; + + return NOERROR; } void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg ) diff --git a/dlls/quartz/imem.c b/dlls/quartz/imem.c index 5d7b1d67937..7053fea3f52 100644 --- a/dlls/quartz/imem.c +++ b/dlls/quartz/imem.c @@ -126,8 +126,15 @@ static ICOM_VTABLE(IMemAllocator) imemalloc = }; -void CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma ) +HRESULT CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma ) { TRACE("(%p)\n",pma); ICOM_VTBL(&pma->memalloc) = &imemalloc; + + return NOERROR; +} + +void CMemoryAllocator_UninitIMemAllocator( CMemoryAllocator* pma ) +{ + TRACE("(%p)\n",pma); } diff --git a/dlls/quartz/imesink.c b/dlls/quartz/imesink.c new file mode 100644 index 00000000000..5e2e7bfce42 --- /dev/null +++ b/dlls/quartz/imesink.c @@ -0,0 +1,95 @@ +/* + * Implementation of IMediaEventSink for FilterGraph. + * + * FIXME - stub. + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "wine/obj_oleaut.h" +#include "strmif.h" +#include "control.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "fgraph.h" + + + +static HRESULT WINAPI +IMediaEventSink_fnQueryInterface(IMediaEventSink* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,mediaeventsink); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IMediaEventSink_fnAddRef(IMediaEventSink* iface) +{ + CFilterGraph_THIS(iface,mediaeventsink); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IMediaEventSink_fnRelease(IMediaEventSink* iface) +{ + CFilterGraph_THIS(iface,mediaeventsink); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI +IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2) +{ + CFilterGraph_THIS(iface,mediaeventsink); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + + +static ICOM_VTABLE(IMediaEventSink) imediaeventsink = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IMediaEventSink_fnQueryInterface, + IMediaEventSink_fnAddRef, + IMediaEventSink_fnRelease, + /* IMediaEventSink fields */ + IMediaEventSink_fnNotify, +}; + + + +HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->mediaeventsink) = &imediaeventsink; + + return NOERROR; +} + +void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} + diff --git a/dlls/quartz/imevent.c b/dlls/quartz/imevent.c index 12a3078b20b..eaf44382599 100644 --- a/dlls/quartz/imevent.c +++ b/dlls/quartz/imevent.c @@ -102,9 +102,11 @@ IMediaEventEx_fnGetEventHandle(IMediaEventEx* iface,OAEVENT* hEvent) { CFilterGraph_THIS(iface,mediaevent); - FIXME("(%p)->() stub!\n",This); + TRACE("(%p)->()\n",This); - return E_NOTIMPL; + *hEvent = (OAEVENT)This->m_hMediaEvent; + + return NOERROR; } static HRESULT WINAPI @@ -215,13 +217,21 @@ static ICOM_VTABLE(IMediaEventEx) imediaevent = }; -void CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->mediaevent) = &imediaevent; + + pfg->m_hMediaEvent = CreateEventA( NULL, TRUE, FALSE, NULL ); + if ( pfg->m_hMediaEvent == (HANDLE)NULL ) + return E_OUTOFMEMORY; + + return NOERROR; } void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); + + CloseHandle( pfg->m_hMediaEvent ); } diff --git a/dlls/quartz/imfilter.c b/dlls/quartz/imfilter.c new file mode 100644 index 00000000000..2c7e94a233a --- /dev/null +++ b/dlls/quartz/imfilter.c @@ -0,0 +1,162 @@ +/* + * Implementation of IMediaFilter for FilterGraph. + * + * FIXME - stub. + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "wine/obj_oleaut.h" +#include "strmif.h" +#include "control.h" +#include "uuids.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "fgraph.h" + + + +static HRESULT WINAPI +IMediaFilter_fnQueryInterface(IMediaFilter* iface,REFIID riid,void** ppobj) +{ + CFilterGraph_THIS(iface,mediafilter); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IMediaFilter_fnAddRef(IMediaFilter* iface) +{ + CFilterGraph_THIS(iface,mediafilter); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IMediaFilter_fnRelease(IMediaFilter* iface) +{ + CFilterGraph_THIS(iface,mediafilter); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + + +static HRESULT WINAPI +IMediaFilter_fnGetClassID(IMediaFilter* iface,CLSID* pclsid) +{ + CFilterGraph_THIS(iface,mediafilter); + + TRACE("(%p)->()\n",This); + + return IPersist_GetClassID( + CFilterGraph_IPersist(This),pclsid); +} + +static HRESULT WINAPI +IMediaFilter_fnStop(IMediaFilter* iface) +{ + CFilterGraph_THIS(iface,mediafilter); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IMediaFilter_fnPause(IMediaFilter* iface) +{ + CFilterGraph_THIS(iface,mediafilter); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart) +{ + CFilterGraph_THIS(iface,mediafilter); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dw,FILTER_STATE* pState) +{ + CFilterGraph_THIS(iface,mediafilter); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock) +{ + CFilterGraph_THIS(iface,mediafilter); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +IMediaFilter_fnGetSyncSource(IMediaFilter* iface,IReferenceClock** ppobjClock) +{ + CFilterGraph_THIS(iface,mediafilter); + + FIXME("(%p)->() stub!\n",This); + + return E_NOTIMPL; +} + + + +static ICOM_VTABLE(IMediaFilter) imediafilter = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IMediaFilter_fnQueryInterface, + IMediaFilter_fnAddRef, + IMediaFilter_fnRelease, + /* IPersist fields */ + IMediaFilter_fnGetClassID, + /* IMediaFilter fields */ + IMediaFilter_fnStop, + IMediaFilter_fnPause, + IMediaFilter_fnRun, + IMediaFilter_fnGetState, + IMediaFilter_fnSetSyncSource, + IMediaFilter_fnGetSyncSource, +}; + +HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); + ICOM_VTBL(&pfg->mediafilter) = &imediafilter; + + return NOERROR; +} + +void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg ) +{ + TRACE("(%p)\n",pfg); +} diff --git a/dlls/quartz/impos.c b/dlls/quartz/impos.c index caf6e3f0073..2036d509ca0 100644 --- a/dlls/quartz/impos.c +++ b/dlls/quartz/impos.c @@ -60,9 +60,10 @@ IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo) { CFilterGraph_THIS(iface,mediaposition); - FIXME("(%p)->()\n",This); + TRACE("(%p)->()\n",This); - return E_NOTIMPL; + return IDispatch_GetTypeInfoCount( + CFilterGraph_IDispatch(This),pcTypeInfo); } static HRESULT WINAPI @@ -70,9 +71,10 @@ IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, IT { CFilterGraph_THIS(iface,mediaposition); - FIXME("(%p)->()\n",This); + TRACE("(%p)->()\n",This); - return E_NOTIMPL; + return IDispatch_GetTypeInfo( + CFilterGraph_IDispatch(This),iTypeInfo,lcid,ppobj); } static HRESULT WINAPI @@ -80,9 +82,10 @@ IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppws { CFilterGraph_THIS(iface,mediaposition); - FIXME("(%p)->()\n",This); + TRACE("(%p)->()\n",This); - return E_NOTIMPL; + return IDispatch_GetIDsOfNames( + CFilterGraph_IDispatch(This),riid,ppwszName,cNames,lcid,pDispId); } static HRESULT WINAPI @@ -90,9 +93,11 @@ IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID l { CFilterGraph_THIS(iface,mediaposition); - FIXME("(%p)->()\n",This); + TRACE("(%p)->()\n",This); - return E_NOTIMPL; + return IDispatch_Invoke( + CFilterGraph_IDispatch(This), + DispId,riid,lcid,wFlags,pDispParams,pVarRes,pExcepInfo,puArgErr); } @@ -234,10 +239,12 @@ static ICOM_VTABLE(IMediaPosition) imediaposition = }; -void CFilterGraph_InitIMediaPosition( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIMediaPosition( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->mediaposition) = &imediaposition; + + return NOERROR; } void CFilterGraph_UninitIMediaPosition( CFilterGraph* pfg ) diff --git a/dlls/quartz/imseek.c b/dlls/quartz/imseek.c index 2dbc5000297..cf67ff76f5a 100644 --- a/dlls/quartz/imseek.c +++ b/dlls/quartz/imseek.c @@ -257,10 +257,12 @@ static ICOM_VTABLE(IMediaSeeking) imediaseeking = IMediaSeeking_fnGetPreroll, }; -void CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->mediaseeking) = &imediaseeking; + + return NOERROR; } void CFilterGraph_UninitIMediaSeeking( CFilterGraph* pfg ) diff --git a/dlls/quartz/irclock.c b/dlls/quartz/irclock.c index a780774b730..910f3103848 100644 --- a/dlls/quartz/irclock.c +++ b/dlls/quartz/irclock.c @@ -104,8 +104,15 @@ static ICOM_VTABLE(IReferenceClock) irefclk = }; -void CSystemClock_InitIReferenceClock( CSystemClock* psc ) +HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc ) { TRACE("(%p)\n",psc); ICOM_VTBL(&psc->refclk) = &irefclk; + + return NOERROR; +} + +void CSystemClock_UninitIReferenceClock( CSystemClock* psc ) +{ + TRACE("(%p)\n",psc); } diff --git a/dlls/quartz/iunk.h b/dlls/quartz/iunk.h index 0555f3b82d7..338d1136e9a 100644 --- a/dlls/quartz/iunk.h +++ b/dlls/quartz/iunk.h @@ -29,7 +29,7 @@ typedef struct QUARTZ_IFEntry { - REFIID piid; /* interface ID. */ + const IID* piid; /* interface ID. */ size_t ofsVTPtr; /* offset from IUnknown. */ } QUARTZ_IFEntry; diff --git a/dlls/quartz/ividwin.c b/dlls/quartz/ividwin.c index 5feb73f04e5..a81fa751926 100644 --- a/dlls/quartz/ividwin.c +++ b/dlls/quartz/ividwin.c @@ -547,10 +547,12 @@ static ICOM_VTABLE(IVideoWindow) ivideowindow = }; -void CFilterGraph_InitIVideoWindow( CFilterGraph* pfg ) +HRESULT CFilterGraph_InitIVideoWindow( CFilterGraph* pfg ) { TRACE("(%p)\n",pfg); ICOM_VTBL(&pfg->vidwin) = &ivideowindow; + + return NOERROR; } void CFilterGraph_UninitIVideoWindow( CFilterGraph* pfg ) diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c index b1479584d18..90cc02d7932 100644 --- a/dlls/quartz/main.c +++ b/dlls/quartz/main.c @@ -50,7 +50,7 @@ typedef struct { /* IUnknown fields */ ICOM_VFIELD(IClassFactory); - DWORD ref; + LONG ref; /* IClassFactory fields */ const QUARTZ_CLASSENTRY* pEntry; } IClassFactoryImpl; @@ -128,16 +128,18 @@ static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface) TRACE("(%p)->()\n",This); - return ++(This->ref); + return InterlockedExchangeAdd(&(This->ref),1) + 1; } static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface) { ICOM_THIS(IClassFactoryImpl,iface); + LONG ref; TRACE("(%p)->()\n",This); - if ( (--(This->ref)) > 0 ) - return This->ref; + ref = InterlockedExchangeAdd(&(This->ref),-1) - 1; + if ( ref > 0 ) + return (ULONG)ref; QUARTZ_FreeObj(This); return 0; diff --git a/dlls/quartz/memalloc.c b/dlls/quartz/memalloc.c index 16410bf5e2c..7bde1491308 100644 --- a/dlls/quartz/memalloc.c +++ b/dlls/quartz/memalloc.c @@ -29,9 +29,17 @@ static QUARTZ_IFEntry IFEntries[] = { &IID_IMemAllocator, offsetof(CMemoryAllocator,memalloc)-offsetof(CMemoryAllocator,unk) }, }; +static void QUARTZ_DestroyMemoryAllocator(IUnknown* punk) +{ + CMemoryAllocator_THIS(punk,unk); + + CMemoryAllocator_UninitIMemAllocator( This ); +} + HRESULT QUARTZ_CreateMemoryAllocator(IUnknown* punkOuter,void** ppobj) { CMemoryAllocator* pma; + HRESULT hr; TRACE("(%p,%p)\n",punkOuter,ppobj); @@ -40,10 +48,16 @@ HRESULT QUARTZ_CreateMemoryAllocator(IUnknown* punkOuter,void** ppobj) return E_OUTOFMEMORY; QUARTZ_IUnkInit( &pma->unk, punkOuter ); - CMemoryAllocator_InitIMemAllocator( pma ); + hr = CMemoryAllocator_InitIMemAllocator( pma ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( pma ); + return hr; + } pma->unk.pEntries = IFEntries; pma->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); + pma->unk.pOnFinalRelease = QUARTZ_DestroyMemoryAllocator; *ppobj = (void*)(&pma->unk); diff --git a/dlls/quartz/memalloc.h b/dlls/quartz/memalloc.h index 408e9dbc2ee..4b6ae4ac8a9 100644 --- a/dlls/quartz/memalloc.h +++ b/dlls/quartz/memalloc.h @@ -30,7 +30,8 @@ typedef struct CMemoryAllocator HRESULT QUARTZ_CreateMemoryAllocator(IUnknown* punkOuter,void** ppobj); -void CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma ); +HRESULT CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma ); +void CMemoryAllocator_UninitIMemAllocator( CMemoryAllocator* pma ); #endif /* WINE_DSHOW_MEMALLOC_H */ diff --git a/dlls/quartz/monprop.c b/dlls/quartz/monprop.c new file mode 100644 index 00000000000..81a029c08ec --- /dev/null +++ b/dlls/quartz/monprop.c @@ -0,0 +1,205 @@ +/* + * Implements IPropertyBag. (internal) + * + * hidenori@a2.ctktv.ne.jp + */ + +#include "config.h" + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" +#include "wine/obj_base.h" +#include "objidl.h" +#include "oleidl.h" +#include "ocidl.h" +#include "oleauto.h" +#include "strmif.h" +#include "wine/unicode.h" + +#include "debugtools.h" +DEFAULT_DEBUG_CHANNEL(quartz); + +#include "quartz_private.h" +#include "monprop.h" + + +static HRESULT WINAPI +IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj) +{ + CRegPropertyBag_THIS(iface,propbag); + + TRACE("(%p)->()\n",This); + + return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj); +} + +static ULONG WINAPI +IPropertyBag_fnAddRef(IPropertyBag* iface) +{ + CRegPropertyBag_THIS(iface,propbag); + + TRACE("(%p)->()\n",This); + + return IUnknown_AddRef(This->unk.punkControl); +} + +static ULONG WINAPI +IPropertyBag_fnRelease(IPropertyBag* iface) +{ + CRegPropertyBag_THIS(iface,propbag); + + TRACE("(%p)->()\n",This); + + return IUnknown_Release(This->unk.punkControl); +} + +static HRESULT WINAPI +IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog) +{ + CRegPropertyBag_THIS(iface,propbag); + LONG lr; + DWORD dwSize; + DWORD dwValueType; + + TRACE("(%p)->(%s,%p,%p)\n",This, + debugstr_w(lpszPropName),pVar,pLog); + + if ( lpszPropName == NULL || pVar == NULL ) + return E_POINTER; + + dwSize = 0; + lr = RegQueryValueExW( + This->m_hKey, lpszPropName, NULL, + &dwValueType, NULL, &dwSize ); + if ( lr != ERROR_SUCCESS ) + return E_INVALIDARG; + + switch ( dwValueType ) + { + case REG_SZ: + if ( pVar->n1.n2.vt == VT_EMPTY ) + pVar->n1.n2.vt = VT_BSTR; + if ( pVar->n1.n2.vt != VT_BSTR ) + return E_FAIL; + + pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen( + NULL, dwSize ); + if ( pVar->n1.n2.n3.bstrVal == NULL ) + return E_OUTOFMEMORY; + lr = RegQueryValueExW( + This->m_hKey, lpszPropName, NULL, + &dwValueType, + (BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize ); + if ( lr != ERROR_SUCCESS ) + { + SysFreeString(pVar->n1.n2.n3.bstrVal); + return E_FAIL; + } + break; + default: + FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This, + debugstr_w(lpszPropName),pVar,pLog); + return E_FAIL; + } + + return NOERROR; +} + +static HRESULT WINAPI +IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar) +{ + CRegPropertyBag_THIS(iface,propbag); + + FIXME("(%p)->(%s,%p) stub!\n",This, + debugstr_w(lpszPropName),pVar); + + if ( lpszPropName == NULL || pVar == NULL ) + return E_POINTER; + + return E_NOTIMPL; +} + + + + +static ICOM_VTABLE(IPropertyBag) ipropbag = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + /* IUnknown fields */ + IPropertyBag_fnQueryInterface, + IPropertyBag_fnAddRef, + IPropertyBag_fnRelease, + /* IPropertyBag fields */ + IPropertyBag_fnRead, + IPropertyBag_fnWrite, +}; + +static HRESULT CRegPropertyBag_InitIPropertyBag( + CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath ) +{ + ICOM_VTBL(&prpb->propbag) = &ipropbag; + + if ( RegOpenKeyExW( + hkRoot, lpKeyPath, 0, + KEY_ALL_ACCESS, &prpb->m_hKey ) != ERROR_SUCCESS ) + return E_FAIL; + + return NOERROR; +} + +static void CRegPropertyBag_UninitIPropertyBag( + CRegPropertyBag* prpb ) +{ + RegCloseKey( prpb->m_hKey ); +} + + +static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk) +{ + CRegPropertyBag_THIS(punk,unk); + + CRegPropertyBag_UninitIPropertyBag(This); +} + + +/* can I use offsetof safely? - FIXME? */ +static QUARTZ_IFEntry IFEntries[] = +{ + { &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) }, +}; + +HRESULT QUARTZ_CreateRegPropertyBag( + HKEY hkRoot, LPCWSTR lpKeyPath, + IPropertyBag** ppPropBag ) +{ + CRegPropertyBag* prpb; + HRESULT hr; + + TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag ); + + prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) ); + if ( prpb == NULL ) + return E_OUTOFMEMORY; + + QUARTZ_IUnkInit( &prpb->unk, NULL ); + hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( prpb ); + return hr; + } + + prpb->unk.pEntries = IFEntries; + prpb->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); + prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag; + + *ppPropBag = (IPropertyBag*)(&prpb->propbag); + + return S_OK; +} + + diff --git a/dlls/quartz/monprop.h b/dlls/quartz/monprop.h new file mode 100644 index 00000000000..25c4946b97e --- /dev/null +++ b/dlls/quartz/monprop.h @@ -0,0 +1,34 @@ +#ifndef WINE_DSHOW_MONPROP_H +#define WINE_DSHOW_MONPROP_H + +/* + implements IPropertyBag for accessing registry. + + - At least, the following interfaces should be implemented: + + IUnknown + + IPropertyBag + */ + +#include "iunk.h" + +typedef struct DMON_IPropertyBagImpl +{ + ICOM_VFIELD(IPropertyBag); +} DMON_IPropertyBagImpl; + +typedef struct CRegPropertyBag +{ + QUARTZ_IUnkImpl unk; + DMON_IPropertyBagImpl propbag; + /* IPropertyBag fields */ + HKEY m_hKey; +} CRegPropertyBag; + +#define CRegPropertyBag_THIS(iface,member) CRegPropertyBag* This = (CRegPropertyBag*)(((char*)iface)-offsetof(CRegPropertyBag,member)) + +HRESULT QUARTZ_CreateRegPropertyBag( + HKEY hkRoot, LPCWSTR lpKeyPath, + IPropertyBag** ppPropBag ); + +#endif /* WINE_DSHOW_MONPROP_H */ diff --git a/dlls/quartz/quartz.spec b/dlls/quartz/quartz.spec index b32471f703c..809f83ba449 100644 --- a/dlls/quartz/quartz.spec +++ b/dlls/quartz/quartz.spec @@ -2,9 +2,14 @@ name quartz type win32 init QUARTZ_DllMain -#import ole2.dll -import kernel32.dll import ntdll.dll +import kernel32.dll +import user32.dll +#import gdi32.dll +import advapi32.dll +#import winmm.dll +import ole32.dll +import oleaut32.dll debug_channels (quartz) diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c index 3def2762364..f979137f46d 100644 --- a/dlls/quartz/regsvr.c +++ b/dlls/quartz/regsvr.c @@ -9,49 +9,362 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winuser.h" #include "winerror.h" #include "winreg.h" +#include "uuids.h" +#include "wine/unicode.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); #include "regsvr.h" +#ifndef NUMELEMS +#define NUMELEMS(elem) (sizeof(elem)/sizeof((elem)[0])) +#endif /* NUMELEMS */ -HRESULT QUARTZ_RegisterDLLServer( - const CLSID* pclsid, - LPCSTR lpFriendlyName, - LPCSTR lpNameOfDLL ) +const WCHAR QUARTZ_wszREG_SZ[] = + {'R','E','G','_','S','Z',0}; +const WCHAR QUARTZ_wszInprocServer32[] = + {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0}; +const WCHAR QUARTZ_wszThreadingModel[] = + {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; +const WCHAR QUARTZ_wszBoth[] = + {'B','o','t','h',0}; +const WCHAR QUARTZ_wszCLSID[] = + {'C','L','S','I','D',0}; +const WCHAR QUARTZ_wszFilterData[] = + {'F','i','l','t','e','r',' ','D','a','t','a',0}; +const WCHAR QUARTZ_wszFriendlyName[] = + {'F','r','i','e','n','d','l','y','N','a','m','e',0}; +const WCHAR QUARTZ_wszInstance[] = + {'I','n','s','t','a','n','c','e',0}; +const WCHAR QUARTZ_wszMerit[] = + {'M','e','r','i','t',0}; + +static +void QUARTZ_CatPathSepW( WCHAR* pBuf ) +{ + int len = strlenW(pBuf); + pBuf[len] = '\\'; + pBuf[len+1] = 0; +} + +static +void QUARTZ_GUIDtoString( WCHAR* pBuf, const GUID* pguid ) +{ + /* W"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}" */ + static const WCHAR wszFmt[] = + {'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X', + '-','%','0','2','X','%','0','2','X','-','%','0','2','X','%', + '0','2','X','%','0','2','X','%','0','2','X','%','0','2','X', + '%','0','2','X','}',0}; + + wsprintfW( pBuf, wszFmt, + pguid->Data1, pguid->Data2, pguid->Data3, + pguid->Data4[0], pguid->Data4[1], + pguid->Data4[2], pguid->Data4[3], + pguid->Data4[4], pguid->Data4[5], + pguid->Data4[6], pguid->Data4[7] ); +} + +static +LONG QUARTZ_RegOpenKeyW( + HKEY hkRoot, LPCWSTR lpszPath, + REGSAM rsAccess, HKEY* phKey, + BOOL fCreateKey ) +{ + DWORD dwDisp; + WCHAR wszREG_SZ[ NUMELEMS(QUARTZ_wszREG_SZ) ]; + + memcpy(wszREG_SZ,QUARTZ_wszREG_SZ,sizeof(QUARTZ_wszREG_SZ) ); + + if ( fCreateKey ) + return RegCreateKeyExW( + hkRoot, lpszPath, 0, wszREG_SZ, + REG_OPTION_NON_VOLATILE, rsAccess, NULL, phKey, &dwDisp ); + else + return RegOpenKeyExW( + hkRoot, lpszPath, 0, rsAccess, phKey ); +} + +static +LONG QUARTZ_RegSetValueString( + HKEY hKey, LPCWSTR lpszName, LPCWSTR lpValue ) +{ + return RegSetValueExW( + hKey, lpszName, 0, REG_SZ, + (const BYTE*)lpValue, + sizeof(lpValue[0]) * (strlenW(lpValue)+1) ); +} + +static +LONG QUARTZ_RegSetValueDWord( + HKEY hKey, LPCWSTR lpszName, DWORD dwValue ) { - FIXME( "stub!\n" ); - return E_FAIL; + return RegSetValueExW( + hKey, lpszName, 0, REG_DWORD, + (const BYTE*)(&dwValue), sizeof(DWORD) ); } -HRESULT QUARTZ_UnregisterDLLServer( - const CLSID* pclsid ) +static +LONG QUARTZ_RegSetValueBinary( + HKEY hKey, LPCWSTR lpszName, + const BYTE* pData, int iLenOfData ) { - FIXME( "stub!\n" ); - return E_FAIL; + return RegSetValueExW( + hKey, lpszName, 0, REG_BINARY, pData, iLenOfData ); } +HRESULT QUARTZ_CreateCLSIDPath( + WCHAR* pwszBuf, DWORD dwBufLen, + const CLSID* pclsid, + LPCWSTR lpszPathFromCLSID ) +{ + int avail; + + strcpyW( pwszBuf, QUARTZ_wszCLSID ); + QUARTZ_CatPathSepW( pwszBuf+5 ); + QUARTZ_GUIDtoString( pwszBuf+6, pclsid ); + if ( lpszPathFromCLSID != NULL ) + { + avail = (int)dwBufLen - strlenW(pwszBuf) - 8; + if ( avail <= strlenW(lpszPathFromCLSID) ) + return E_FAIL; + QUARTZ_CatPathSepW( pwszBuf ); + strcatW( pwszBuf, lpszPathFromCLSID ); + } + + return NOERROR; +} -HRESULT QUARTZ_RegisterFilter( - const CLSID* pguidFilterCategory, - const CLSID* pclsid, - const BYTE* pbFilterData, - DWORD cbFilterData, - LPCSTR lpFriendlyName ) +HRESULT QUARTZ_OpenCLSIDKey( + HKEY* phKey, /* [OUT] hKey */ + REGSAM rsAccess, /* [IN] access */ + BOOL fCreate, /* TRUE = RegCreateKey, FALSE = RegOpenKey */ + const CLSID* pclsid, /* CLSID */ + LPCWSTR lpszPathFromCLSID ) /* related path from CLSID */ { - FIXME( "stub!\n" ); - return E_FAIL; + WCHAR szKey[ 1024 ]; + HRESULT hr; + LONG lr; + + hr = QUARTZ_CreateCLSIDPath( + szKey, NUMELEMS(szKey), + pclsid, lpszPathFromCLSID ); + if ( FAILED(hr) ) + return hr; + + lr = QUARTZ_RegOpenKeyW( + HKEY_CLASSES_ROOT, szKey, rsAccess, phKey, fCreate ); + if ( lr != ERROR_SUCCESS ) + return E_FAIL; + + return S_OK; } -HRESULT QUARTZ_UnregisterFilter( - const CLSID* pguidFilterCategory, - const CLSID* pclsid ) + + +HRESULT QUARTZ_RegisterAMovieDLLServer( + const CLSID* pclsid, /* [IN] CLSID */ + LPCWSTR lpFriendlyName, /* [IN] Friendly name */ + LPCWSTR lpNameOfDLL, /* [IN] name of the registered DLL */ + BOOL fRegister ) /* [IN] TRUE = register, FALSE = unregister */ { - FIXME( "stub!\n" ); - return E_FAIL; + HRESULT hr; + HKEY hKey; + + if ( fRegister ) + { + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, TRUE, + pclsid, NULL ); + if ( FAILED(hr) ) + return hr; + + if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString( + hKey, NULL, lpFriendlyName ) != ERROR_SUCCESS ) + hr = E_FAIL; + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, TRUE, + pclsid, QUARTZ_wszInprocServer32 ); + if ( FAILED(hr) ) + return hr; + + if ( QUARTZ_RegSetValueString( + hKey, NULL, lpNameOfDLL ) != ERROR_SUCCESS ) + hr = E_FAIL; + if ( QUARTZ_RegSetValueString( + hKey, QUARTZ_wszThreadingModel, + QUARTZ_wszBoth ) != ERROR_SUCCESS ) + hr = E_FAIL; + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + } + else + { + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, FALSE, + pclsid, NULL ); + if ( FAILED(hr) ) + return NOERROR; + + RegDeleteValueW( hKey, NULL ); + RegDeleteValueW( hKey, QUARTZ_wszThreadingModel ); + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + + /* I think key should be deleted only if no subkey exists. */ + FIXME( "unregister %s - key should be removed!\n", + debugstr_guid(pclsid) ); + } + + return NOERROR; +} + + +HRESULT QUARTZ_RegisterCategory( + const CLSID* pguidFilterCategory, /* [IN] Category */ + LPCWSTR lpFriendlyName, /* [IN] friendly name */ + DWORD dwMerit, /* [IN] merit */ + BOOL fRegister ) /* [IN] TRUE = register, FALSE = unregister */ +{ + HRESULT hr; + HKEY hKey; + WCHAR szFilterPath[ 256 ]; + WCHAR szCLSID[ 256 ]; + + QUARTZ_GUIDtoString( szCLSID, pguidFilterCategory ); + strcpyW( szFilterPath, QUARTZ_wszInstance ); + QUARTZ_CatPathSepW( szFilterPath ); + strcatW( szFilterPath, szCLSID ); + + if ( fRegister ) + { + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, TRUE, + &CLSID_ActiveMovieCategories, szFilterPath ); + if ( FAILED(hr) ) + return hr; + + if ( QUARTZ_RegSetValueString( + hKey, QUARTZ_wszCLSID, szCLSID ) != ERROR_SUCCESS ) + hr = E_FAIL; + if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString( + hKey, QUARTZ_wszFriendlyName, + lpFriendlyName ) != ERROR_SUCCESS ) + hr = E_FAIL; + if ( dwMerit != 0 && + QUARTZ_RegSetValueDWord( + hKey, QUARTZ_wszMerit, dwMerit ) != ERROR_SUCCESS ) + hr = E_FAIL; + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + } + else + { + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, FALSE, + &CLSID_ActiveMovieCategories, szFilterPath ); + if ( FAILED(hr) ) + return NOERROR; + + RegDeleteValueW( hKey, QUARTZ_wszCLSID ); + RegDeleteValueW( hKey, QUARTZ_wszFriendlyName ); + RegDeleteValueW( hKey, QUARTZ_wszMerit ); + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + + /* I think key should be deleted only if no subkey exists. */ + FIXME( "unregister category %s - key should be removed!\n", + debugstr_guid(pguidFilterCategory) ); + } + + return NOERROR; +} + + +HRESULT QUARTZ_RegisterAMovieFilter( + const CLSID* pguidFilterCategory, /* [IN] Category */ + const CLSID* pclsid, /* [IN] CLSID of this filter */ + const BYTE* pbFilterData, /* [IN] filter data(no spec) */ + DWORD cbFilterData, /* [IN] size of the filter data */ + LPCWSTR lpFriendlyName, /* [IN] friendly name */ + LPCWSTR lpInstance, /* [IN] instance */ + BOOL fRegister ) /* [IN] TRUE = register, FALSE = unregister */ +{ + HRESULT hr; + HKEY hKey; + WCHAR szFilterPath[ 256 ]; + WCHAR szCLSID[ 256 ]; + + QUARTZ_GUIDtoString( szCLSID, pclsid ); + strcpyW( szFilterPath, QUARTZ_wszInstance ); + QUARTZ_CatPathSepW( szFilterPath ); + strcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID ); + + if ( fRegister ) + { + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, TRUE, + pguidFilterCategory, szFilterPath ); + if ( FAILED(hr) ) + return hr; + + if ( QUARTZ_RegSetValueString( + hKey, QUARTZ_wszCLSID, szCLSID ) != ERROR_SUCCESS ) + hr = E_FAIL; + if ( pbFilterData != NULL && cbFilterData > 0 && + QUARTZ_RegSetValueBinary( + hKey, QUARTZ_wszFilterData, + pbFilterData, cbFilterData ) != ERROR_SUCCESS ) + hr = E_FAIL; + if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString( + hKey, QUARTZ_wszFriendlyName, + lpFriendlyName ) != ERROR_SUCCESS ) + hr = E_FAIL; + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + } + else + { + hr = QUARTZ_OpenCLSIDKey( + &hKey, KEY_ALL_ACCESS, FALSE, + pguidFilterCategory, szFilterPath ); + if ( FAILED(hr) ) + return NOERROR; + + RegDeleteValueW( hKey, QUARTZ_wszCLSID ); + RegDeleteValueW( hKey, QUARTZ_wszFilterData ); + RegDeleteValueW( hKey, QUARTZ_wszFriendlyName ); + + RegCloseKey( hKey ); + if ( FAILED(hr) ) + return hr; + + /* I think key should be deleted only if no subkey exists. */ + FIXME( "unregister category %s filter %s - key should be removed!\n", + debugstr_guid(pguidFilterCategory), + debugstr_guid(pclsid) ); + } + + return NOERROR; } diff --git a/dlls/quartz/regsvr.h b/dlls/quartz/regsvr.h index 71028f7bac6..62b83bd3f42 100644 --- a/dlls/quartz/regsvr.h +++ b/dlls/quartz/regsvr.h @@ -7,23 +7,49 @@ #ifndef QUARTZ_REGSVR_H #define QUARTZ_REGSVR_H +extern const WCHAR QUARTZ_wszREG_SZ[]; +extern const WCHAR QUARTZ_wszInprocServer32[]; +extern const WCHAR QUARTZ_wszThreadingModel[]; +extern const WCHAR QUARTZ_wszBoth[]; +extern const WCHAR QUARTZ_wszCLSID[]; +extern const WCHAR QUARTZ_wszFilterData[]; +extern const WCHAR QUARTZ_wszFriendlyName[]; +extern const WCHAR QUARTZ_wszInstance[]; +extern const WCHAR QUARTZ_wszMerit[]; -HRESULT QUARTZ_RegisterDLLServer( - const CLSID* pclsid, - LPCSTR lpFriendlyName, - LPCSTR lpNameOfDLL ); -HRESULT QUARTZ_UnregisterDLLServer( - const CLSID* pclsid ); -HRESULT QUARTZ_RegisterFilter( - const CLSID* pguidFilterCategory, +HRESULT QUARTZ_CreateCLSIDPath( + WCHAR* pwszBuf, DWORD dwBufLen, const CLSID* pclsid, - const BYTE* pbFilterData, - DWORD cbFilterData, - LPCSTR lpFriendlyName ); -HRESULT QUARTZ_UnregisterFilter( - const CLSID* pguidFilterCategory, - const CLSID* pclsid ); + LPCWSTR lpszPathFromCLSID ); + +HRESULT QUARTZ_OpenCLSIDKey( + HKEY* phkey, /* [OUT] hKey */ + REGSAM rsAccess, /* [IN] access */ + BOOL fCreate, /* TRUE = RegCreateKey, FALSE = RegOpenKey */ + const CLSID* pclsid, /* CLSID */ + LPCWSTR lpszPathFromCLSID ); /* related path from CLSID */ + +HRESULT QUARTZ_RegisterAMovieDLLServer( + const CLSID* pclsid, /* [IN] CLSID */ + LPCWSTR lpFriendlyName, /* [IN] Friendly name */ + LPCWSTR lpNameOfDLL, /* [IN] name of the registered DLL */ + BOOL fRegister ); /* [IN] TRUE = register, FALSE = unregister */ + +HRESULT QUARTZ_RegisterCategory( + const CLSID* pguidFilterCategory, /* [IN] Category */ + LPCWSTR lpFriendlyName, /* [IN] friendly name */ + DWORD dwMerit, /* [IN] merit */ + BOOL fRegister ); /* [IN] TRUE = register, FALSE = unregister */ + +HRESULT QUARTZ_RegisterAMovieFilter( + const CLSID* pguidFilterCategory, /* [IN] Category */ + const CLSID* pclsid, /* [IN] CLSID of this filter */ + const BYTE* pbFilterData, /* [IN] filter data(no spec) */ + DWORD cbFilterData, /* [IN] size of the filter data */ + LPCWSTR lpFriendlyName, /* [IN] friendly name */ + LPCWSTR lpInstance, /* [IN] instance */ + BOOL fRegister ); /* [IN] TRUE = register, FALSE = unregister */ #endif /* QUARTZ_REGSVR_H */ diff --git a/dlls/quartz/sysclock.c b/dlls/quartz/sysclock.c index fd611b8b9df..dd1e2c64393 100644 --- a/dlls/quartz/sysclock.c +++ b/dlls/quartz/sysclock.c @@ -29,9 +29,18 @@ static QUARTZ_IFEntry IFEntries[] = { &IID_IReferenceClock, offsetof(CSystemClock,refclk)-offsetof(CSystemClock,unk) }, }; + +static void QUARTZ_DestroySystemClock(IUnknown* punk) +{ + CSystemClock_THIS(punk,unk); + + CSystemClock_UninitIReferenceClock( This ); +} + HRESULT QUARTZ_CreateSystemClock(IUnknown* punkOuter,void** ppobj) { CSystemClock* psc; + HRESULT hr; TRACE("(%p,%p)\n",punkOuter,ppobj); @@ -40,10 +49,16 @@ HRESULT QUARTZ_CreateSystemClock(IUnknown* punkOuter,void** ppobj) return E_OUTOFMEMORY; QUARTZ_IUnkInit( &psc->unk, punkOuter ); - CSystemClock_InitIReferenceClock( psc ); + hr = CSystemClock_InitIReferenceClock( psc ); + if ( FAILED(hr) ) + { + QUARTZ_FreeObj( psc ); + return hr; + } psc->unk.pEntries = IFEntries; psc->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); + psc->unk.pOnFinalRelease = QUARTZ_DestroySystemClock; *ppobj = (void*)(&psc->unk); diff --git a/dlls/quartz/sysclock.h b/dlls/quartz/sysclock.h index 1e3db405ccf..2fe961386e3 100644 --- a/dlls/quartz/sysclock.h +++ b/dlls/quartz/sysclock.h @@ -31,7 +31,8 @@ typedef struct CSystemClock HRESULT QUARTZ_CreateSystemClock(IUnknown* punkOuter,void** ppobj); -void CSystemClock_InitIReferenceClock( CSystemClock* psc ); +HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc ); +void CSystemClock_UninitIReferenceClock( CSystemClock* psc ); #endif /* WINE_DSHOW_SYSCLOCK_H */ -- GitLab