diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 965fa8f744f..3624c5774ff 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -20,7 +20,6 @@ C_SRCS = \ complist.c \ csconv.c \ devenum.c \ - devmon.c \ enumunk.c \ fgevent.c \ fgpass.c \ diff --git a/dlls/quartz/README b/dlls/quartz/README index d248fa0f1d0..38750919ca8 100644 --- a/dlls/quartz/README +++ b/dlls/quartz/README @@ -1,15 +1,28 @@ +quartz.dll is the basic library of ActiveMovie/DirectShow. + TODO - - merge some C sources. - - implements all filters. - - handles plug-in distributor. - - implements some interfaces as plug-ins(???) - - implements ICM - - implements mciqtz(mci driver for quartz) + - avoid deadlock + - merge some C sources + - implement filters + - restruct color-space converter + - add FilterData to winedefault.reg for Connect() and Render() + - sort active filters in filter graph + - sort regfilters in Merit order + - fix deadlocks in Receive/EndOfStream + - handle plug-in distributor + - handle seeking + - implement some interfaces as plug-ins(???) + - implement ICM drivers (yuv converter) + - implement ACM drivers (g711) + - implement ACM wrapper (improve xform) + - implement mciqtz(mci driver for quartz) + - implement renderer + - handle notification correctly known BUGS - all FIXMEs. - - some filters crash at CoCreateInstance. (ole???) + - some filters crash at CoCreateInstance. (???) diff --git a/dlls/quartz/asyncsrc.c b/dlls/quartz/asyncsrc.c index 8c6678d4689..c72b2455e7d 100644 --- a/dlls/quartz/asyncsrc.c +++ b/dlls/quartz/asyncsrc.c @@ -1217,7 +1217,8 @@ static HRESULT AsyncSourceFileImpl_Read( CAsyncSourceImpl* pImpl, LONGLONG llOfs while ( lLength > 0 ) { - if ( WaitForSingleObject( hEventCancel, 0 ) == WAIT_OBJECT_0 ) + if ( hEventCancel != (HANDLE)NULL && + WaitForSingleObject( hEventCancel, 0 ) == WAIT_OBJECT_0 ) { hr = S_FALSE; break; diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c index 1316b78023e..e2bd156218a 100644 --- a/dlls/quartz/avidec.c +++ b/dlls/quartz/avidec.c @@ -1,8 +1,6 @@ /* * Implements AVI Decompressor(CLSID_AVIDec). * - * FIXME - insufficient buffer for ICDecompress!!!! - * * hidenori@a2.ctktv.ne.jp */ @@ -219,7 +217,7 @@ static HRESULT AVIDec_GetOutputTypes( CTransformBaseImpl* pImpl, const AM_MEDIA_ memcpy( &This->m_mtOut.majortype, &MEDIATYPE_Video, sizeof(GUID) ); memcpy( &This->m_mtOut.formattype, &FORMAT_VideoInfo, sizeof(GUID) ); - This->m_mtOut.cbFormat = sizeof(VIDEOINFOHEADER) + cbFmt; + This->m_mtOut.cbFormat = sizeof(VIDEOINFOHEADER) + cbFmt + sizeof(RGBQUAD)*256; This->m_mtOut.pbFormat = (BYTE*)CoTaskMemAlloc(This->m_mtOut.cbFormat); if ( This->m_mtOut.pbFormat == NULL ) return E_OUTOFMEMORY; @@ -240,6 +238,31 @@ static HRESULT AVIDec_GetOutputTypes( CTransformBaseImpl* pImpl, const AM_MEDIA_ This->m_mtOut.bFixedSizeSamples = (pbiOut->bmiHeader.biCompression == 0) ? 1 : 0; This->m_mtOut.lSampleSize = (pbiOut->bmiHeader.biCompression == 0) ? DIBSIZE(pbiOut->bmiHeader) : pbiOut->bmiHeader.biSizeImage; + /* get palette */ + if ( pbiOut->bmiHeader.biBitCount <= 8 ) + { + TRACE("(%p) - get palette\n",This); + if ( ICDecompressGetPalette( This->hicCached, pbiIn, pbiOut ) != ICERR_OK ) + { + TRACE("(%p) - use the input palette\n",This); + if ( pbiIn->bmiHeader.biBitCount != pbiOut->bmiHeader.biBitCount ) + { + FIXME( "no palette...fixme?\n" ); + return E_FAIL; + } + if ( pbiOut->bmiHeader.biClrUsed == 0 ) + pbiOut->bmiHeader.biClrUsed = 1<bmiHeader.biBitCount; + if ( pbiOut->bmiHeader.biClrUsed > (1<bmiHeader.biBitCount) ) + { + ERR( "biClrUsed=%ld\n", pbiOut->bmiHeader.biClrUsed ); + return E_FAIL; + } + + memcpy( pbiOut->bmiColors, pbiIn->bmiColors, + sizeof(RGBQUAD) * pbiOut->bmiHeader.biClrUsed ); + } + } + TRACE("(%p) - return format\n",This); *ppmtAcceptTypes = &This->m_mtOut; *pcAcceptTypes = 1; @@ -301,7 +324,7 @@ static HRESULT AVIDec_BeginTransform( CTransformBaseImpl* pImpl, const AM_MEDIA_ This->m_pbiOut = AVIDec_DuplicateBitmapInfo(pbiOut); if ( This->m_pbiIn == NULL || This->m_pbiOut == NULL ) return E_OUTOFMEMORY; - if ( This->m_pbiOut->bmiHeader.biCompression == 0 ) + if ( This->m_pbiOut->bmiHeader.biCompression == 0 || This->m_pbiOut->bmiHeader.biCompression == 3 ) This->m_pbiOut->bmiHeader.biSizeImage = DIBSIZE(This->m_pbiOut->bmiHeader); if ( !bReuseSample ) diff --git a/dlls/quartz/basepin.c b/dlls/quartz/basepin.c index 4ad0c4ec4ba..81bdb7653c9 100644 --- a/dlls/quartz/basepin.c +++ b/dlls/quartz/basepin.c @@ -353,7 +353,7 @@ CPinBaseImpl_fnConnectionMediaType(IPin* iface,AM_MEDIA_TYPE* pmt) ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) ); pmt->bFixedSizeSamples = TRUE; pmt->lSampleSize = 1; - hr = NOERROR; + hr = VFW_E_NOT_CONNECTED; } LeaveCriticalSection( This->pcsPin ); diff --git a/dlls/quartz/devenum.c b/dlls/quartz/devenum.c index 70d46e30231..925f9733abb 100644 --- a/dlls/quartz/devenum.c +++ b/dlls/quartz/devenum.c @@ -1,7 +1,7 @@ /* * Implementation of CLSID_SystemDeviceEnum. - * - * FIXME - not tested enough. + * Implements IMoniker for CLSID_CDeviceMoniker. + * Implements IPropertyBag. (internal) * * hidenori@a2.ctktv.ne.jp */ @@ -14,18 +14,25 @@ #include "winuser.h" #include "winreg.h" #include "winerror.h" +#include "objidl.h" +#include "oleidl.h" +#include "ocidl.h" +#include "oleauto.h" #include "strmif.h" +#include "uuids.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" +#include "regsvr.h" +#ifndef NUMELEMS +#define NUMELEMS(elem) (sizeof(elem)/sizeof(elem[0])) +#endif /* NUMELEMS */ /*************************************************************************** * @@ -34,7 +41,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); */ /* can I use offsetof safely? - FIXME? */ -static QUARTZ_IFEntry IFEntries[] = +static QUARTZ_IFEntry CSysDevEnum_IFEntries[] = { { &IID_ICreateDevEnum, offsetof(CSysDevEnum,createdevenum)-offsetof(CSysDevEnum,unk) }, }; @@ -67,8 +74,8 @@ HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj) return hr; } - psde->unk.pEntries = IFEntries; - psde->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); + psde->unk.pEntries = CSysDevEnum_IFEntries; + psde->unk.dwEntries = sizeof(CSysDevEnum_IFEntries)/sizeof(CSysDevEnum_IFEntries[0]); psde->unk.pOnFinalRelease = QUARTZ_DestroySystemDeviceEnum; *ppobj = (void*)(&psde->unk); @@ -143,14 +150,21 @@ ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDevi *ppobj = NULL; hr = QUARTZ_CreateCLSIDPath( - wszPath, sizeof(wszPath)/sizeof(wszPath[0]), + wszPath, sizeof(wszPath)/sizeof(wszPath[0]) - 16, rclsidDeviceClass, QUARTZ_wszInstance ); if ( FAILED(hr) ) return hr; - if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath, - 0, KEY_READ, &hKey ) != ERROR_SUCCESS ) + lr = RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath, + 0, KEY_READ, &hKey ); + if ( lr != ERROR_SUCCESS ) + { + TRACE("cannot open %s\n",debugstr_w(wszPath)); + if ( lr == ERROR_FILE_NOT_FOUND || + lr == ERROR_PATH_NOT_FOUND ) + return S_FALSE; return E_FAIL; + } dwLen = lstrlenW(wszPath); wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0; @@ -175,6 +189,7 @@ ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDevi break; if ( lr != ERROR_SUCCESS ) { + TRACE("RegEnumKeyEx returns %08lx\n",lr); hr = E_FAIL; goto err; } @@ -232,3 +247,1041 @@ void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde ) { TRACE("(%p)\n",psde); } + + +/*************************************************************************** + * + * CDeviceMoniker::IMoniker + * + */ + +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; + IPersistPropertyBag* pPersistPropBag; + 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; + + hr = CoCreateInstance( + &clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult ); + if ( FAILED(hr) ) + return hr; + + hr = IUnknown_QueryInterface((IUnknown*)*ppvResult,&IID_IPersistPropertyBag,(void**)&pPersistPropBag); + if ( hr == E_NOINTERFACE ) + { + hr = S_OK; + } + else + if ( SUCCEEDED(hr) ) + { + hr = QUARTZ_CreateRegPropertyBag( + This->m_hkRoot, This->m_pwszPath, &pPropBag ); + if ( SUCCEEDED(hr) ) + { + hr = IPersistPropertyBag_Load(pPersistPropBag,pPropBag,NULL); + IPropertyBag_Release( pPropBag ); + } + IPersistPropertyBag_Release(pPersistPropBag); + } + + if ( FAILED(hr) ) + { + IUnknown_Release((IUnknown*)*ppvResult); + *ppvResult = NULL; + } + + TRACE( "hr = %08lx\n", hr ); + + return hr; +} + +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)*(lstrlenW(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 ); +} + +/*************************************************************************** + * + * new/delete for CDeviceMoniker + * + */ + +static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk) +{ + CDeviceMoniker_THIS(punk,unk); + + CDeviceMoniker_UninitIMoniker( This ); +} + +/* can I use offsetof safely? - FIXME? */ +static QUARTZ_IFEntry CDeviceMoniker_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 = CDeviceMoniker_IFEntries; + pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]); + pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker; + + *ppMoniker = (IMoniker*)(&pdm->moniker); + + return S_OK; +} + + +/*************************************************************************** + * + * CRegPropertyBag::IPropertyBag + * + */ + +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); + HRESULT hr; + LONG lr; + DWORD dwSize; + DWORD dwValueType; + DWORD dwDWordValue; + SAFEARRAYBOUND sab; + SAFEARRAY* pArray; + + 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 ) + { + WARN( "RegQueryValueExW failed.\n" ); + return E_INVALIDARG; + } + + switch ( dwValueType ) + { + case REG_SZ: + TRACE( "REG_SZ / length = %lu\n", dwSize ); + if ( pVar->n1.n2.vt == VT_EMPTY ) + pVar->n1.n2.vt = VT_BSTR; + if ( pVar->n1.n2.vt != VT_BSTR ) + { + FIXME( "type of VARIANT is not BSTR.\n" ); + return E_FAIL; + } + + pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen( + NULL, dwSize ); + if ( pVar->n1.n2.n3.bstrVal == NULL ) + { + WARN( "out of memory.\n" ); + return E_OUTOFMEMORY; + } + lr = RegQueryValueExW( + This->m_hKey, lpszPropName, NULL, + &dwValueType, + (BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize ); + if ( lr != ERROR_SUCCESS ) + { + WARN( "failed to query value\n" ); + SysFreeString(pVar->n1.n2.n3.bstrVal); + return E_FAIL; + } + TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) ); + break; + case REG_BINARY: + TRACE( "REG_BINARY / length = %lu\n", dwSize ); + if ( pVar->n1.n2.vt == VT_EMPTY ) + pVar->n1.n2.vt = VT_ARRAY|VT_UI1; + if ( pVar->n1.n2.vt != (VT_ARRAY|VT_UI1) ) + { + FIXME( "type of VARIANT is not VT_ARRAY|VT_UI1.\n" ); + return E_FAIL; + } + sab.lLbound = 0; + sab.cElements = dwSize; + pArray = SafeArrayCreate( VT_UI1, 1, &sab ); + if ( pArray == NULL ) + return E_OUTOFMEMORY; + hr = SafeArrayLock( pArray ); + if ( FAILED(hr) ) + { + WARN( "safe array can't be locked\n" ); + SafeArrayDestroy( pArray ); + return hr; + } + lr = RegQueryValueExW( + This->m_hKey, lpszPropName, NULL, + &dwValueType, + (BYTE*)pArray->pvData, &dwSize ); + SafeArrayUnlock( pArray ); + if ( lr != ERROR_SUCCESS ) + { + WARN( "failed to query value\n" ); + SafeArrayDestroy( pArray ); + return E_FAIL; + } + pVar->n1.n2.n3.parray = pArray; + TRACE( "value is SAFEARRAY - array of BYTE; \n" ); + break; + case REG_DWORD: + TRACE( "REG_DWORD / length = %lu\n", dwSize ); + if ( dwSize != sizeof(DWORD) ) + { + WARN( "The length of REG_DWORD value is not sizeof(DWORD).\n" ); + return E_FAIL; + } + if ( pVar->n1.n2.vt == VT_EMPTY ) + pVar->n1.n2.vt = VT_I4; + if ( pVar->n1.n2.vt != VT_I4 ) + { + FIXME( "type of VARIANT is not VT_I4.\n" ); + return E_FAIL; + } + lr = RegQueryValueExW( + This->m_hKey, lpszPropName, NULL, + &dwValueType, + (BYTE*)(&dwDWordValue), &dwSize ); + if ( lr != ERROR_SUCCESS ) + { + WARN( "failed to query value\n" ); + return E_FAIL; + } + pVar->n1.n2.n3.lVal = dwDWordValue; + TRACE( "value is DWORD; %08lx\n", dwDWordValue ); + break; + default: + FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This, + debugstr_w(lpszPropName),pVar,pLog); + return E_FAIL; + } + + TRACE( "returned successfully.\n" ); + return NOERROR; +} + +static HRESULT WINAPI +IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar) +{ + CRegPropertyBag_THIS(iface,propbag); + HRESULT hr; + LONG lr; + DWORD dwDWordValue; + SAFEARRAY* pArray; + + TRACE("(%p)->(%s,%p)\n",This, + debugstr_w(lpszPropName),pVar); + + if ( lpszPropName == NULL || pVar == NULL ) + return E_POINTER; + + switch ( pVar->n1.n2.vt ) + { + case VT_I4: /* REG_DWORD */ + dwDWordValue = pVar->n1.n2.n3.lVal; + lr = RegSetValueExW( + This->m_hKey, lpszPropName, 0, + REG_DWORD, + (const BYTE*)(&dwDWordValue), sizeof(DWORD) ); + if ( lr != ERROR_SUCCESS ) + { + WARN( "failed to set value\n" ); + return E_FAIL; + } + break; + case VT_BSTR: /* REG_SZ */ + lr = RegSetValueExW( + This->m_hKey, lpszPropName, 0, + REG_SZ, + (const BYTE*)(pVar->n1.n2.n3.bstrVal), + SysStringByteLen( pVar->n1.n2.n3.bstrVal ) ); + if ( lr != ERROR_SUCCESS ) + { + WARN( "failed to set value\n" ); + return E_FAIL; + } + break; + case (VT_ARRAY|VT_UI1): /* REG_BINARY */ + pArray = pVar->n1.n2.n3.parray; + if ( pArray->cDims != 1 || pArray->cbElements != 1 || + pArray->rgsabound[0].lLbound != 0 ) + { + WARN( "invalid array\n" ); + return E_INVALIDARG; + } + hr = SafeArrayLock( pArray ); + if ( FAILED(hr) ) + { + WARN( "safe array can't be locked\n" ); + return hr; + } + lr = RegSetValueExW( + This->m_hKey, lpszPropName, 0, + REG_BINARY, + (const BYTE*)pArray->pvData, + pArray->rgsabound[0].cElements ); + SafeArrayUnlock( pArray ); + if ( lr != ERROR_SUCCESS ) + { + WARN( "failed to set value\n" ); + return E_FAIL; + } + break; + default: + FIXME("(%p)->(%s,%p) invalid/unsupported VARIANT type %04x\n",This, + debugstr_w(lpszPropName),pVar,pVar->n1.n2.vt); + return E_INVALIDARG; + } + + TRACE( "returned successfully.\n" ); + return NOERROR; +} + + + + +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 ) +{ + WCHAR wszREG_SZ[ NUMELEMS(QUARTZ_wszREG_SZ) ]; + DWORD dwDisp; + + ICOM_VTBL(&prpb->propbag) = &ipropbag; + + memcpy(wszREG_SZ,QUARTZ_wszREG_SZ,sizeof(QUARTZ_wszREG_SZ) ); + + if ( RegCreateKeyExW( + hkRoot, lpKeyPath, 0, wszREG_SZ, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, + &prpb->m_hKey, &dwDisp ) != ERROR_SUCCESS ) + return E_FAIL; + + return NOERROR; +} + +static void CRegPropertyBag_UninitIPropertyBag( + CRegPropertyBag* prpb ) +{ + RegCloseKey( prpb->m_hKey ); +} + + +/*************************************************************************** + * + * new/delete for CRegPropertyBag + * + */ + +static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk) +{ + CRegPropertyBag_THIS(punk,unk); + + CRegPropertyBag_UninitIPropertyBag(This); +} + + +/* can I use offsetof safely? - FIXME? */ +static QUARTZ_IFEntry CRegPropertyBag_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 = CRegPropertyBag_IFEntries; + prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]); + prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag; + + *ppPropBag = (IPropertyBag*)(&prpb->propbag); + + return S_OK; +} + +/*************************************************************************** + * + * Helper for registering filters. + * + */ + +HRESULT QUARTZ_GetFilterRegPath( + WCHAR** ppwszPath, /* [OUT] path from HKEY_CLASSES_ROOT */ + const CLSID* pguidFilterCategory, /* [IN] Category */ + const CLSID* pclsid, /* [IN] CLSID of this filter */ + LPCWSTR lpInstance ) /* [IN] instance */ +{ + HRESULT hr; + WCHAR szKey[ 1024 ]; + WCHAR szFilterPath[ 512 ]; + WCHAR szCLSID[ 256 ]; + int buflen; + + TRACE("(%p,%s,%s,%s)\n",ppwszPath,debugstr_guid(pguidFilterCategory),debugstr_guid(pclsid),debugstr_w(lpInstance) ); + + *ppwszPath = NULL; + + QUARTZ_GUIDtoString( szCLSID, pclsid ); + lstrcpyW( szFilterPath, QUARTZ_wszInstance ); + QUARTZ_CatPathSepW( szFilterPath ); + if ( lpInstance != NULL ) + { + if ( lstrlenW(lpInstance) >= 256 ) + return E_INVALIDARG; + lstrcatW( szFilterPath, lpInstance ); + } + else + { + lstrcatW( szFilterPath, szCLSID ); + } + + hr = QUARTZ_CreateCLSIDPath( + szKey, NUMELEMS(szKey), + pguidFilterCategory, szFilterPath ); + if ( FAILED(hr) ) + return hr; + + buflen = sizeof(WCHAR)*(lstrlenW(szKey)+1); + *ppwszPath = QUARTZ_AllocMem( buflen ); + if ( *ppwszPath == NULL ) + return E_OUTOFMEMORY; + memcpy( *ppwszPath, szKey, buflen ); + return S_OK; +} + +HRESULT QUARTZ_RegisterFilterToMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + const CLSID* pclsid, /* [IN] CLSID of this filter */ + LPCWSTR lpFriendlyName, /* [IN] friendly name */ + const BYTE* pbFilterData, /* [IN] filter data */ + DWORD cbFilterData ) /* [IN] size of the filter data */ +{ + IPropertyBag* pPropBag = NULL; + WCHAR wszClsid[128]; + VARIANT var; + HRESULT hr; + SAFEARRAYBOUND sab; + SAFEARRAY* pArray = NULL; + + TRACE("(%p,%s,%s,%p,%08lu)\n",pMoniker,debugstr_guid(pclsid),debugstr_w(lpFriendlyName),pbFilterData,cbFilterData); + + hr = IMoniker_BindToStorage(pMoniker,NULL,NULL,&IID_IPropertyBag,(void**)&pPropBag); + if ( FAILED(hr) ) + goto err; + QUARTZ_GUIDtoString( wszClsid, pclsid ); + var.n1.n2.vt = VT_BSTR; + var.n1.n2.n3.bstrVal = SysAllocString(wszClsid); + if ( var.n1.n2.n3.bstrVal == NULL ) + { + hr = E_OUTOFMEMORY; + goto err; + } + hr = IPropertyBag_Write(pPropBag,QUARTZ_wszCLSID,&var); + SysFreeString(var.n1.n2.n3.bstrVal); + if ( FAILED(hr) ) + goto err; + + var.n1.n2.vt = VT_BSTR; + var.n1.n2.n3.bstrVal = SysAllocString(lpFriendlyName); + if ( var.n1.n2.n3.bstrVal == NULL ) + { + hr = E_OUTOFMEMORY; + goto err; + } + hr = IPropertyBag_Write(pPropBag,QUARTZ_wszFriendlyName,&var); + SysFreeString(var.n1.n2.n3.bstrVal); + if ( FAILED(hr) ) + goto err; + + if ( pbFilterData != NULL ) + { + var.n1.n2.vt = VT_ARRAY|VT_UI1; + sab.lLbound = 0; + sab.cElements = cbFilterData; + pArray = SafeArrayCreate( VT_UI1, 1, &sab ); + if ( pArray == NULL ) + { + hr = E_OUTOFMEMORY; + goto err; + } + hr = SafeArrayLock( pArray ); + if ( FAILED(hr) ) + goto err; + var.n1.n2.n3.parray = pArray; + memcpy( pArray->pvData, pbFilterData, cbFilterData ); + hr = IPropertyBag_Write(pPropBag,QUARTZ_wszFilterData,&var); + SafeArrayUnlock( pArray ); + if ( FAILED(hr) ) + goto err; + } + + hr = NOERROR; +err: + if ( pArray != NULL ) + SafeArrayDestroy( pArray ); + if ( pPropBag != NULL ) + IPropertyBag_Release(pPropBag); + + return hr; +} + +HRESULT QUARTZ_RegDeleteKey( HKEY hkRoot, LPCWSTR lpKeyPath ) +{ + LONG lr; + HRESULT hr; + HKEY hKey; + DWORD dwIndex; + DWORD cbName; + FILETIME ftLastWrite; + DWORD dwType; + WCHAR wszPath[ 512 ]; + + TRACE("(%08x,%s)\n",hkRoot,debugstr_w(lpKeyPath)); + + lr = RegOpenKeyExW( hkRoot, lpKeyPath, 0, KEY_ALL_ACCESS, &hKey ); + if ( lr == ERROR_SUCCESS ) + { + dwIndex = 0; + while ( 1 ) + { + cbName = NUMELEMS(wszPath); + lr = RegEnumKeyExW( + hKey, dwIndex, wszPath, &cbName, + NULL, NULL, NULL, &ftLastWrite ); + if ( lr != ERROR_SUCCESS ) + break; + hr = QUARTZ_RegDeleteKey( hKey, wszPath ); + if ( FAILED(hr) ) + return hr; + if ( hr != S_OK ) + dwIndex ++; + } + while ( 1 ) + { + cbName = NUMELEMS(wszPath); + lr = RegEnumValueW( + hKey, 0, wszPath, &cbName, 0, + &dwType, NULL, 0 ); + if ( lr != ERROR_SUCCESS ) + break; + lr = RegDeleteValueW( hKey, wszPath ); + if ( lr != ERROR_SUCCESS ) + { + WARN("RegDeleteValueW - %08lx\n",lr); + return E_FAIL; + } + } + } + RegCloseKey( hKey ); + + lr = RegDeleteKeyW( hkRoot, lpKeyPath ); + WARN("RegDeleteKeyW - %08lx\n",lr); + if ( lr != ERROR_SUCCESS && lr != ERROR_FILE_NOT_FOUND ) + return S_FALSE; + return S_OK; +} + +static +HRESULT QUARTZ_GetPropertyFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + LPCOLESTR lpszPropName, /* [IN] Property */ + VARIANT* pVar ) /* [OUT] */ +{ + IPropertyBag* pPropBag = NULL; + HRESULT hr; + + TRACE("(%p,%s,%p)\n",pMoniker,debugstr_w(lpszPropName),pVar); + + hr = IMoniker_BindToStorage(pMoniker,NULL,NULL,&IID_IPropertyBag,(void**)&pPropBag); + if ( FAILED(hr) ) + return hr; + hr = IPropertyBag_Read(pPropBag,lpszPropName,pVar,NULL); + IPropertyBag_Release(pPropBag); + + return hr; +} + +HRESULT QUARTZ_GetCLSIDFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + CLSID* pclsid ) /* [OUT] */ +{ + VARIANT var; + HRESULT hr; + + var.n1.n2.vt = VT_BSTR; + hr = QUARTZ_GetPropertyFromMoniker( + pMoniker, QUARTZ_wszCLSID, &var ); + if ( hr == S_OK ) + { + hr = CLSIDFromString(var.n1.n2.n3.bstrVal,pclsid); + SysFreeString(var.n1.n2.n3.bstrVal); + } + + return hr; +} + +HRESULT QUARTZ_GetMeritFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + DWORD* pdwMerit ) /* [OUT] */ +{ + VARIANT var; + HRESULT hr; + + var.n1.n2.vt = VT_I4; + hr = QUARTZ_GetPropertyFromMoniker( + pMoniker, QUARTZ_wszMerit, &var ); + if ( hr == S_OK ) + *pdwMerit = var.n1.n2.n3.lVal; + + return hr; +} + +HRESULT QUARTZ_GetFilterDataFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + BYTE** ppbFilterData, /* [OUT] */ + DWORD* pcbFilterData ) /* [OUT] */ +{ + VARIANT var; + HRESULT hr; + SAFEARRAY* pArray; + + var.n1.n2.vt = VT_ARRAY|VT_UI1; + hr = QUARTZ_GetPropertyFromMoniker( + pMoniker, QUARTZ_wszFilterData, &var ); + if ( hr == S_OK ) + { + pArray = var.n1.n2.n3.parray; + hr = SafeArrayLock( pArray ); + if ( SUCCEEDED(hr) ) + { + *pcbFilterData = pArray->rgsabound[0].cElements - pArray->rgsabound[0].lLbound; + *ppbFilterData = (BYTE*)QUARTZ_AllocMem( *pcbFilterData ); + if ( *ppbFilterData == NULL ) + hr = E_OUTOFMEMORY; + else + memcpy( *ppbFilterData, pArray->pvData, *pcbFilterData ); + + SafeArrayUnlock( pArray ); + } + SafeArrayDestroy( pArray ); + } + + return hr; +} + diff --git a/dlls/quartz/devenum.h b/dlls/quartz/devenum.h index 59ff85d2e4a..7fc710b80c7 100644 --- a/dlls/quartz/devenum.h +++ b/dlls/quartz/devenum.h @@ -2,12 +2,12 @@ #define WINE_DSHOW_DEVENUM_H /* - implements CLSID_SystemDeviceEnum. - - - At least, the following interfaces should be implemented: - - IUnknown - + ICreateDevEnum + * implements CLSID_SystemDeviceEnum. + * + * - At least, the following interfaces should be implemented: + * + * IUnknown + * + ICreateDevEnum */ #include "iunk.h" @@ -27,10 +27,100 @@ typedef struct CSysDevEnum HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj); - HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde ); void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde ); -#endif /* WINE_DSHOW_DEVENUM_H */ +/* + * implements CLSID_CDeviceMoniker. + * + * - At least, the following interfaces should be implemented: + * + * IUnknown + * + IPersist - IPersistStream - IMoniker + */ + +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 ); + + +/* + * implements IPropertyBag for accessing registry. + * + * - At least, the following interfaces should be implemented: + * + * IUnknown + * + IPropertyBag + */ + +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 ); + +/*************************************************************************** + * + * related functions (internal). + * + */ + +HRESULT QUARTZ_GetFilterRegPath( + WCHAR** ppwszPath, /* [OUT] path from HKEY_CLASSES_ROOT */ + const CLSID* pguidFilterCategory, /* [IN] Category */ + const CLSID* pclsid, /* [IN] CLSID of this filter */ + LPCWSTR lpInstance ); /* [IN] instance */ + +HRESULT QUARTZ_RegisterFilterToMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + const CLSID* pclsid, /* [IN] CLSID of this filter */ + LPCWSTR lpFriendlyName, /* [IN] friendly name */ + const BYTE* pbFilterData, /* [IN] filter data */ + DWORD cbFilterData ); /* [IN] size of the filter data */ + +HRESULT QUARTZ_RegDeleteKey( HKEY hkRoot, LPCWSTR lpKeyPath ); + +HRESULT QUARTZ_GetCLSIDFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + CLSID* pclsid ); /* [OUT] */ +HRESULT QUARTZ_GetMeritFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + DWORD* pdwMerit ); /* [OUT] */ +HRESULT QUARTZ_GetFilterDataFromMoniker( + IMoniker* pMoniker, /* [IN] Moniker */ + BYTE** ppbFilterData, /* [OUT] */ + DWORD* pcbFilterData ); /* [OUT] */ + + +#endif /* WINE_DSHOW_DEVENUM_H */ diff --git a/dlls/quartz/devmon.c b/dlls/quartz/devmon.c deleted file mode 100644 index cef8eb7090c..00000000000 --- a/dlls/quartz/devmon.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Implements IMoniker for CLSID_CDeviceMoniker. - * 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 "objidl.h" -#include "oleidl.h" -#include "ocidl.h" -#include "oleauto.h" -#include "strmif.h" -#include "uuids.h" - -#include "debugtools.h" -DEFAULT_DEBUG_CHANNEL(quartz); - -#include "quartz_private.h" -#include "devmon.h" -#include "regsvr.h" - - -/*************************************************************************** - * - * CDeviceMoniker::IMoniker - * - */ - -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; - - hr = CoCreateInstance( - &clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult ); - TRACE( "hr = %08lx\n", hr ); - - return hr; -} - -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)*(lstrlenW(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 ); -} - -/*************************************************************************** - * - * new/delete for CDeviceMoniker - * - */ - -static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk) -{ - CDeviceMoniker_THIS(punk,unk); - - CDeviceMoniker_UninitIMoniker( This ); -} - -/* can I use offsetof safely? - FIXME? */ -static QUARTZ_IFEntry CDeviceMoniker_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 = CDeviceMoniker_IFEntries; - pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]); - pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker; - - *ppMoniker = (IMoniker*)(&pdm->moniker); - - return S_OK; -} - - -/*************************************************************************** - * - * CRegPropertyBag::IPropertyBag - * - */ - -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 ) - { - TRACE( "RegQueryValueExW failed.\n" ); - return E_INVALIDARG; - } - - switch ( dwValueType ) - { - case REG_SZ: - TRACE( "REG_SZ / length = %lu\n", dwSize ); - if ( pVar->n1.n2.vt == VT_EMPTY ) - pVar->n1.n2.vt = VT_BSTR; - if ( pVar->n1.n2.vt != VT_BSTR ) - { - TRACE( "type of VARIANT is not BSTR\n" ); - return E_FAIL; - } - - pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen( - NULL, dwSize ); - if ( pVar->n1.n2.n3.bstrVal == NULL ) - { - TRACE( "out of memory.\n" ); - return E_OUTOFMEMORY; - } - lr = RegQueryValueExW( - This->m_hKey, lpszPropName, NULL, - &dwValueType, - (BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize ); - if ( lr != ERROR_SUCCESS ) - { - TRACE( "failed to query value\n" ); - SysFreeString(pVar->n1.n2.n3.bstrVal); - return E_FAIL; - } - TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) ); - break; - default: - FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This, - debugstr_w(lpszPropName),pVar,pLog); - return E_FAIL; - } - - TRACE( "returned successfully.\n" ); - 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 ); -} - - -/*************************************************************************** - * - * new/delete for CRegPropertyBag - * - */ - -static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk) -{ - CRegPropertyBag_THIS(punk,unk); - - CRegPropertyBag_UninitIPropertyBag(This); -} - - -/* can I use offsetof safely? - FIXME? */ -static QUARTZ_IFEntry CRegPropertyBag_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 = CRegPropertyBag_IFEntries; - prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]); - prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag; - - *ppPropBag = (IPropertyBag*)(&prpb->propbag); - - return S_OK; -} - - - diff --git a/dlls/quartz/devmon.h b/dlls/quartz/devmon.h deleted file mode 100644 index 5c5073b85c2..00000000000 --- a/dlls/quartz/devmon.h +++ /dev/null @@ -1,66 +0,0 @@ -#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 ); - - -/* - 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_DEVMON_H */ diff --git a/dlls/quartz/fgpass.c b/dlls/quartz/fgpass.c index 0cffc08c362..eca6b6bef55 100644 --- a/dlls/quartz/fgpass.c +++ b/dlls/quartz/fgpass.c @@ -165,7 +165,9 @@ IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol) TRACE("(%p)->()\n",This); - return IBasicAudio_put_Volume(pAudio,lVol); + hr = IBasicAudio_put_Volume(pAudio,lVol); + IBasicAudio_Release(pAudio); + return hr; } static HRESULT WINAPI @@ -176,7 +178,9 @@ IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol) TRACE("(%p)->()\n",This); - return IBasicAudio_get_Volume(pAudio,plVol); + hr = IBasicAudio_get_Volume(pAudio,plVol); + IBasicAudio_Release(pAudio); + return hr; } static HRESULT WINAPI @@ -187,7 +191,9 @@ IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance) TRACE("(%p)->()\n",This); - return IBasicAudio_put_Balance(pAudio,lBalance); + hr = IBasicAudio_put_Balance(pAudio,lBalance); + IBasicAudio_Release(pAudio); + return hr; } static HRESULT WINAPI @@ -198,7 +204,9 @@ IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance) TRACE("(%p)->()\n",This); - return IBasicAudio_get_Balance(pAudio,plBalance); + hr = IBasicAudio_get_Balance(pAudio,plBalance); + IBasicAudio_Release(pAudio); + return hr; } @@ -337,7 +345,9 @@ IBasicVideo2_fnget_AvgTimePerFrame(IBasicVideo2* iface,REFTIME* prefTime) TRACE("(%p)->()\n",This); - return IBasicVideo_get_AvgTimePerFrame(pVideo,prefTime); + hr = IBasicVideo_get_AvgTimePerFrame(pVideo,prefTime); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -348,7 +358,9 @@ IBasicVideo2_fnget_BitRate(IBasicVideo2* iface,long* plRate) TRACE("(%p)->()\n",This); - return IBasicVideo_get_BitRate(pVideo,plRate); + hr = IBasicVideo_get_BitRate(pVideo,plRate); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -359,7 +371,9 @@ IBasicVideo2_fnget_BitErrorRate(IBasicVideo2* iface,long* plRate) TRACE("(%p)->()\n",This); - return IBasicVideo_get_BitErrorRate(pVideo,plRate); + hr = IBasicVideo_get_BitErrorRate(pVideo,plRate); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -370,7 +384,9 @@ IBasicVideo2_fnget_VideoWidth(IBasicVideo2* iface,long* plWidth) TRACE("(%p)->()\n",This); - return IBasicVideo_get_VideoWidth(pVideo,plWidth); + hr = IBasicVideo_get_VideoWidth(pVideo,plWidth); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -381,7 +397,9 @@ IBasicVideo2_fnget_VideoHeight(IBasicVideo2* iface,long* plHeight) TRACE("(%p)->()\n",This); - return IBasicVideo_get_VideoHeight(pVideo,plHeight); + hr = IBasicVideo_get_VideoHeight(pVideo,plHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -392,7 +410,9 @@ IBasicVideo2_fnput_SourceLeft(IBasicVideo2* iface,long lLeft) TRACE("(%p)->()\n",This); - return IBasicVideo_put_SourceLeft(pVideo,lLeft); + hr = IBasicVideo_put_SourceLeft(pVideo,lLeft); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -403,7 +423,9 @@ IBasicVideo2_fnget_SourceLeft(IBasicVideo2* iface,long* plLeft) TRACE("(%p)->()\n",This); - return IBasicVideo_get_SourceLeft(pVideo,plLeft); + hr = IBasicVideo_get_SourceLeft(pVideo,plLeft); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -414,7 +436,9 @@ IBasicVideo2_fnput_SourceWidth(IBasicVideo2* iface,long lWidth) TRACE("(%p)->()\n",This); - return IBasicVideo_put_SourceWidth(pVideo,lWidth); + hr = IBasicVideo_put_SourceWidth(pVideo,lWidth); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -425,7 +449,9 @@ IBasicVideo2_fnget_SourceWidth(IBasicVideo2* iface,long* plWidth) TRACE("(%p)->()\n",This); - return IBasicVideo_get_SourceWidth(pVideo,plWidth); + hr = IBasicVideo_get_SourceWidth(pVideo,plWidth); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -436,7 +462,9 @@ IBasicVideo2_fnput_SourceTop(IBasicVideo2* iface,long lTop) TRACE("(%p)->()\n",This); - return IBasicVideo_put_SourceTop(pVideo,lTop); + hr = IBasicVideo_put_SourceTop(pVideo,lTop); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -447,7 +475,9 @@ IBasicVideo2_fnget_SourceTop(IBasicVideo2* iface,long* plTop) TRACE("(%p)->()\n",This); - return IBasicVideo_get_SourceTop(pVideo,plTop); + hr = IBasicVideo_get_SourceTop(pVideo,plTop); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -458,7 +488,9 @@ IBasicVideo2_fnput_SourceHeight(IBasicVideo2* iface,long lHeight) TRACE("(%p)->()\n",This); - return IBasicVideo_put_SourceHeight(pVideo,lHeight); + hr = IBasicVideo_put_SourceHeight(pVideo,lHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -469,7 +501,9 @@ IBasicVideo2_fnget_SourceHeight(IBasicVideo2* iface,long* plHeight) TRACE("(%p)->()\n",This); - return IBasicVideo_get_SourceHeight(pVideo,plHeight); + hr = IBasicVideo_get_SourceHeight(pVideo,plHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -480,7 +514,9 @@ IBasicVideo2_fnput_DestinationLeft(IBasicVideo2* iface,long lLeft) TRACE("(%p)->()\n",This); - return IBasicVideo_put_DestinationLeft(pVideo,lLeft); + hr = IBasicVideo_put_DestinationLeft(pVideo,lLeft); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -491,7 +527,9 @@ IBasicVideo2_fnget_DestinationLeft(IBasicVideo2* iface,long* plLeft) TRACE("(%p)->()\n",This); - return IBasicVideo_get_DestinationLeft(pVideo,plLeft); + hr = IBasicVideo_get_DestinationLeft(pVideo,plLeft); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -502,7 +540,9 @@ IBasicVideo2_fnput_DestinationWidth(IBasicVideo2* iface,long lWidth) TRACE("(%p)->()\n",This); - return IBasicVideo_put_DestinationWidth(pVideo,lWidth); + hr = IBasicVideo_put_DestinationWidth(pVideo,lWidth); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -513,7 +553,9 @@ IBasicVideo2_fnget_DestinationWidth(IBasicVideo2* iface,long* plWidth) TRACE("(%p)->()\n",This); - return IBasicVideo_get_DestinationWidth(pVideo,plWidth); + hr = IBasicVideo_get_DestinationWidth(pVideo,plWidth); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -524,7 +566,9 @@ IBasicVideo2_fnput_DestinationTop(IBasicVideo2* iface,long lTop) TRACE("(%p)->()\n",This); - return IBasicVideo_put_DestinationTop(pVideo,lTop); + hr = IBasicVideo_put_DestinationTop(pVideo,lTop); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -535,7 +579,9 @@ IBasicVideo2_fnget_DestinationTop(IBasicVideo2* iface,long* plTop) TRACE("(%p)->()\n",This); - return IBasicVideo_get_DestinationTop(pVideo,plTop); + hr = IBasicVideo_get_DestinationTop(pVideo,plTop); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -546,7 +592,9 @@ IBasicVideo2_fnput_DestinationHeight(IBasicVideo2* iface,long lHeight) TRACE("(%p)->()\n",This); - return IBasicVideo_put_DestinationHeight(pVideo,lHeight); + hr = IBasicVideo_put_DestinationHeight(pVideo,lHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -557,7 +605,9 @@ IBasicVideo2_fnget_DestinationHeight(IBasicVideo2* iface,long* plHeight) TRACE("(%p)->()\n",This); - return IBasicVideo_get_DestinationHeight(pVideo,plHeight); + hr = IBasicVideo_get_DestinationHeight(pVideo,plHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -568,7 +618,9 @@ IBasicVideo2_fnSetSourcePosition(IBasicVideo2* iface,long lLeft,long lTop,long l TRACE("(%p)->()\n",This); - return IBasicVideo_SetSourcePosition(pVideo,lLeft,lTop,lWidth,lHeight); + hr = IBasicVideo_SetSourcePosition(pVideo,lLeft,lTop,lWidth,lHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -579,7 +631,9 @@ IBasicVideo2_fnGetSourcePosition(IBasicVideo2* iface,long* plLeft,long* plTop,lo TRACE("(%p)->()\n",This); - return IBasicVideo_GetSourcePosition(pVideo,plLeft,plTop,plWidth,plHeight); + hr = IBasicVideo_GetSourcePosition(pVideo,plLeft,plTop,plWidth,plHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -590,7 +644,9 @@ IBasicVideo2_fnSetDefaultSourcePosition(IBasicVideo2* iface) TRACE("(%p)->()\n",This); - return IBasicVideo_SetDefaultSourcePosition(pVideo); + hr = IBasicVideo_SetDefaultSourcePosition(pVideo); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -601,7 +657,9 @@ IBasicVideo2_fnSetDestinationPosition(IBasicVideo2* iface,long lLeft,long lTop,l TRACE("(%p)->()\n",This); - return IBasicVideo_SetDestinationPosition(pVideo,lLeft,lTop,lWidth,lHeight); + hr = IBasicVideo_SetDestinationPosition(pVideo,lLeft,lTop,lWidth,lHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -612,7 +670,9 @@ IBasicVideo2_fnGetDestinationPosition(IBasicVideo2* iface,long* plLeft,long* plT TRACE("(%p)->()\n",This); - return IBasicVideo_GetDestinationPosition(pVideo,plLeft,plTop,plWidth,plHeight); + hr = IBasicVideo_GetDestinationPosition(pVideo,plLeft,plTop,plWidth,plHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -623,7 +683,9 @@ IBasicVideo2_fnSetDefaultDestinationPosition(IBasicVideo2* iface) TRACE("(%p)->()\n",This); - return IBasicVideo_SetDefaultDestinationPosition(pVideo); + hr = IBasicVideo_SetDefaultDestinationPosition(pVideo); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -634,7 +696,9 @@ IBasicVideo2_fnGetVideoSize(IBasicVideo2* iface,long* plWidth,long* plHeight) TRACE("(%p)->()\n",This); - return IBasicVideo_GetVideoSize(pVideo,plWidth,plHeight); + hr = IBasicVideo_GetVideoSize(pVideo,plWidth,plHeight); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -645,7 +709,9 @@ IBasicVideo2_fnGetVideoPaletteEntries(IBasicVideo2* iface,long lStart,long lCoun TRACE("(%p)->()\n",This); - return IBasicVideo_GetVideoPaletteEntries(pVideo,lStart,lCount,plRet,plPaletteEntry); + hr = IBasicVideo_GetVideoPaletteEntries(pVideo,lStart,lCount,plRet,plPaletteEntry); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -656,7 +722,9 @@ IBasicVideo2_fnGetCurrentImage(IBasicVideo2* iface,long* plBufferSize,long* plDI TRACE("(%p)->()\n",This); - return IBasicVideo_GetCurrentImage(pVideo,plBufferSize,plDIBBuffer); + hr = IBasicVideo_GetCurrentImage(pVideo,plBufferSize,plDIBBuffer); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -667,7 +735,9 @@ IBasicVideo2_fnIsUsingDefaultSource(IBasicVideo2* iface) TRACE("(%p)->()\n",This); - return IBasicVideo_IsUsingDefaultSource(pVideo); + hr = IBasicVideo_IsUsingDefaultSource(pVideo); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -678,7 +748,9 @@ IBasicVideo2_fnIsUsingDefaultDestination(IBasicVideo2* iface) TRACE("(%p)->()\n",This); - return IBasicVideo_IsUsingDefaultDestination(pVideo); + hr = IBasicVideo_IsUsingDefaultDestination(pVideo); + IBasicVideo_Release(pVideo); + return hr; } static HRESULT WINAPI @@ -689,7 +761,9 @@ IBasicVideo2_fnGetPreferredAspectRatio(IBasicVideo2* iface,long* plRateX,long* p TRACE("(%p)->()\n",This); - return IBasicVideo2_GetPreferredAspectRatio(pVideo,plRateX,plRateY); + hr = IBasicVideo2_GetPreferredAspectRatio(pVideo,plRateX,plRateY); + IBasicVideo2_Release(pVideo); + return hr; } @@ -854,7 +928,9 @@ IVideoWindow_fnput_Caption(IVideoWindow* iface,BSTR strCaption) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Caption(pVidWin,strCaption); + hr = IVideoWindow_put_Caption(pVidWin,strCaption); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -865,7 +941,9 @@ IVideoWindow_fnget_Caption(IVideoWindow* iface,BSTR* pstrCaption) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Caption(pVidWin,pstrCaption); + hr = IVideoWindow_get_Caption(pVidWin,pstrCaption); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -876,7 +954,9 @@ IVideoWindow_fnput_WindowStyle(IVideoWindow* iface,long lStyle) TRACE("(%p)->()\n",This); - return IVideoWindow_put_WindowStyle(pVidWin,lStyle); + hr = IVideoWindow_put_WindowStyle(pVidWin,lStyle); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -887,7 +967,9 @@ IVideoWindow_fnget_WindowStyle(IVideoWindow* iface,long* plStyle) TRACE("(%p)->()\n",This); - return IVideoWindow_get_WindowStyle(pVidWin,plStyle); + hr = IVideoWindow_get_WindowStyle(pVidWin,plStyle); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -898,7 +980,9 @@ IVideoWindow_fnput_WindowStyleEx(IVideoWindow* iface,long lExStyle) TRACE("(%p)->()\n",This); - return IVideoWindow_put_WindowStyleEx(pVidWin,lExStyle); + hr = IVideoWindow_put_WindowStyleEx(pVidWin,lExStyle); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -909,7 +993,9 @@ IVideoWindow_fnget_WindowStyleEx(IVideoWindow* iface,long* plExStyle) TRACE("(%p)->()\n",This); - return IVideoWindow_get_WindowStyleEx(pVidWin,plExStyle); + hr = IVideoWindow_get_WindowStyleEx(pVidWin,plExStyle); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -920,7 +1006,9 @@ IVideoWindow_fnput_AutoShow(IVideoWindow* iface,long lAutoShow) TRACE("(%p)->()\n",This); - return IVideoWindow_put_AutoShow(pVidWin,lAutoShow); + hr = IVideoWindow_put_AutoShow(pVidWin,lAutoShow); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -931,7 +1019,9 @@ IVideoWindow_fnget_AutoShow(IVideoWindow* iface,long* plAutoShow) TRACE("(%p)->()\n",This); - return IVideoWindow_get_AutoShow(pVidWin,plAutoShow); + hr = IVideoWindow_get_AutoShow(pVidWin,plAutoShow); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -942,7 +1032,9 @@ IVideoWindow_fnput_WindowState(IVideoWindow* iface,long lState) TRACE("(%p)->()\n",This); - return IVideoWindow_put_WindowState(pVidWin,lState); + hr = IVideoWindow_put_WindowState(pVidWin,lState); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -953,7 +1045,9 @@ IVideoWindow_fnget_WindowState(IVideoWindow* iface,long* plState) TRACE("(%p)->()\n",This); - return IVideoWindow_get_WindowState(pVidWin,plState); + hr = IVideoWindow_get_WindowState(pVidWin,plState); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -964,7 +1058,9 @@ IVideoWindow_fnput_BackgroundPalette(IVideoWindow* iface,long lBackPal) TRACE("(%p)->()\n",This); - return IVideoWindow_put_BackgroundPalette(pVidWin,lBackPal); + hr = IVideoWindow_put_BackgroundPalette(pVidWin,lBackPal); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -975,7 +1071,9 @@ IVideoWindow_fnget_BackgroundPalette(IVideoWindow* iface,long* plBackPal) TRACE("(%p)->()\n",This); - return IVideoWindow_get_BackgroundPalette(pVidWin,plBackPal); + hr = IVideoWindow_get_BackgroundPalette(pVidWin,plBackPal); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -986,7 +1084,9 @@ IVideoWindow_fnput_Visible(IVideoWindow* iface,long lVisible) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Visible(pVidWin,lVisible); + hr = IVideoWindow_put_Visible(pVidWin,lVisible); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -997,7 +1097,9 @@ IVideoWindow_fnget_Visible(IVideoWindow* iface,long* plVisible) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Visible(pVidWin,plVisible); + hr = IVideoWindow_get_Visible(pVidWin,plVisible); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1008,7 +1110,9 @@ IVideoWindow_fnput_Left(IVideoWindow* iface,long lLeft) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Left(pVidWin,lLeft); + hr = IVideoWindow_put_Left(pVidWin,lLeft); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1019,7 +1123,9 @@ IVideoWindow_fnget_Left(IVideoWindow* iface,long* plLeft) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Left(pVidWin,plLeft); + hr = IVideoWindow_get_Left(pVidWin,plLeft); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1030,7 +1136,9 @@ IVideoWindow_fnput_Width(IVideoWindow* iface,long lWidth) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Width(pVidWin,lWidth); + hr = IVideoWindow_put_Width(pVidWin,lWidth); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1041,7 +1149,9 @@ IVideoWindow_fnget_Width(IVideoWindow* iface,long* plWidth) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Width(pVidWin,plWidth); + hr =IVideoWindow_get_Width(pVidWin,plWidth); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1052,7 +1162,9 @@ IVideoWindow_fnput_Top(IVideoWindow* iface,long lTop) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Top(pVidWin,lTop); + hr = IVideoWindow_put_Top(pVidWin,lTop); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1063,7 +1175,9 @@ IVideoWindow_fnget_Top(IVideoWindow* iface,long* plTop) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Top(pVidWin,plTop); + hr = IVideoWindow_get_Top(pVidWin,plTop); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1074,7 +1188,9 @@ IVideoWindow_fnput_Height(IVideoWindow* iface,long lHeight) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Height(pVidWin,lHeight); + hr = IVideoWindow_put_Height(pVidWin,lHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1085,7 +1201,9 @@ IVideoWindow_fnget_Height(IVideoWindow* iface,long* plHeight) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Height(pVidWin,plHeight); + hr = IVideoWindow_get_Height(pVidWin,plHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1096,7 +1214,9 @@ IVideoWindow_fnput_Owner(IVideoWindow* iface,OAHWND hwnd) TRACE("(%p)->()\n",This); - return IVideoWindow_put_Owner(pVidWin,hwnd); + hr = IVideoWindow_put_Owner(pVidWin,hwnd); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1107,7 +1227,9 @@ IVideoWindow_fnget_Owner(IVideoWindow* iface,OAHWND* phwnd) TRACE("(%p)->()\n",This); - return IVideoWindow_get_Owner(pVidWin,phwnd); + hr = IVideoWindow_get_Owner(pVidWin,phwnd); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1118,7 +1240,9 @@ IVideoWindow_fnput_MessageDrain(IVideoWindow* iface,OAHWND hwnd) TRACE("(%p)->()\n",This); - return IVideoWindow_put_MessageDrain(pVidWin,hwnd); + hr = IVideoWindow_put_MessageDrain(pVidWin,hwnd); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1129,7 +1253,9 @@ IVideoWindow_fnget_MessageDrain(IVideoWindow* iface,OAHWND* phwnd) TRACE("(%p)->()\n",This); - return IVideoWindow_get_MessageDrain(pVidWin,phwnd); + hr = IVideoWindow_get_MessageDrain(pVidWin,phwnd); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1140,7 +1266,9 @@ IVideoWindow_fnget_BorderColor(IVideoWindow* iface,long* plColor) TRACE("(%p)->()\n",This); - return IVideoWindow_get_BorderColor(pVidWin,plColor); + hr = IVideoWindow_get_BorderColor(pVidWin,plColor); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1151,7 +1279,9 @@ IVideoWindow_fnput_BorderColor(IVideoWindow* iface,long lColor) TRACE("(%p)->()\n",This); - return IVideoWindow_put_BorderColor(pVidWin,lColor); + hr = IVideoWindow_put_BorderColor(pVidWin,lColor); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1162,7 +1292,9 @@ IVideoWindow_fnget_FullScreenMode(IVideoWindow* iface,long* plMode) TRACE("(%p)->()\n",This); - return IVideoWindow_get_FullScreenMode(pVidWin,plMode); + hr = IVideoWindow_get_FullScreenMode(pVidWin,plMode); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1173,7 +1305,9 @@ IVideoWindow_fnput_FullScreenMode(IVideoWindow* iface,long lMode) TRACE("(%p)->()\n",This); - return IVideoWindow_put_FullScreenMode(pVidWin,lMode); + hr = IVideoWindow_put_FullScreenMode(pVidWin,lMode); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1184,7 +1318,9 @@ IVideoWindow_fnSetWindowForeground(IVideoWindow* iface,long lFocus) TRACE("(%p)->()\n",This); - return IVideoWindow_SetWindowForeground(pVidWin,lFocus); + hr = IVideoWindow_SetWindowForeground(pVidWin,lFocus); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1195,7 +1331,9 @@ IVideoWindow_fnNotifyOwnerMessage(IVideoWindow* iface,OAHWND hwnd,long message,L TRACE("(%p)->()\n",This); - return IVideoWindow_NotifyOwnerMessage(pVidWin,hwnd,message,wParam,lParam); + hr = IVideoWindow_NotifyOwnerMessage(pVidWin,hwnd,message,wParam,lParam); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1206,7 +1344,9 @@ IVideoWindow_fnSetWindowPosition(IVideoWindow* iface,long lLeft,long lTop,long l TRACE("(%p)->()\n",This); - return IVideoWindow_SetWindowPosition(pVidWin,lLeft,lTop,lWidth,lHeight); + hr = IVideoWindow_SetWindowPosition(pVidWin,lLeft,lTop,lWidth,lHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1217,7 +1357,9 @@ IVideoWindow_fnGetWindowPosition(IVideoWindow* iface,long* plLeft,long* plTop,lo TRACE("(%p)->()\n",This); - return IVideoWindow_GetWindowPosition(pVidWin,plLeft,plTop,plWidth,plHeight); + hr = IVideoWindow_GetWindowPosition(pVidWin,plLeft,plTop,plWidth,plHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1228,7 +1370,9 @@ IVideoWindow_fnGetMinIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHe TRACE("(%p)->()\n",This); - return IVideoWindow_GetMinIdealImageSize(pVidWin,plWidth,plHeight); + hr = IVideoWindow_GetMinIdealImageSize(pVidWin,plWidth,plHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1239,7 +1383,9 @@ IVideoWindow_fnGetMaxIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHe TRACE("(%p)->()\n",This); - return IVideoWindow_GetMaxIdealImageSize(pVidWin,plWidth,plHeight); + hr = IVideoWindow_GetMaxIdealImageSize(pVidWin,plWidth,plHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1250,7 +1396,9 @@ IVideoWindow_fnGetRestorePosition(IVideoWindow* iface,long* plLeft,long* plTop,l TRACE("(%p)->()\n",This); - return IVideoWindow_GetRestorePosition(pVidWin,plLeft,plTop,plWidth,plHeight); + hr = IVideoWindow_GetRestorePosition(pVidWin,plLeft,plTop,plWidth,plHeight); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1261,7 +1409,9 @@ IVideoWindow_fnHideCursor(IVideoWindow* iface,long lHide) TRACE("(%p)->()\n",This); - return IVideoWindow_HideCursor(pVidWin,lHide); + hr = IVideoWindow_HideCursor(pVidWin,lHide); + IVideoWindow_Release(pVidWin); + return hr; } static HRESULT WINAPI @@ -1272,7 +1422,9 @@ IVideoWindow_fnIsCursorHidden(IVideoWindow* iface,long* plHide) TRACE("(%p)->()\n",This); - return IVideoWindow_IsCursorHidden(pVidWin,plHide); + hr = IVideoWindow_IsCursorHidden(pVidWin,plHide); + IVideoWindow_Release(pVidWin); + return hr; } diff --git a/dlls/quartz/fmap.c b/dlls/quartz/fmap.c index a114ec62bed..ac754922988 100644 --- a/dlls/quartz/fmap.c +++ b/dlls/quartz/fmap.c @@ -23,6 +23,383 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "fmap.h" #include "regsvr.h" +#include "devenum.h" +#include "complist.h" +#include "enumunk.h" + +/***************************************************************************/ + +typedef struct QUARTZ_REGFILTERDATA +{ + DWORD dwVersion; /* =2 */ + DWORD dwMerit; + DWORD cPins; /* count of pins */ + DWORD dwZero; /* padding??? */ +} QUARTZ_REGFILTERDATA; + +typedef struct QUARTZ_REGPINDATA +{ + CHAR id[4]; /* '0pi3', '1pi3', ... */ + DWORD dwFlags; /* flags */ + UINT cInstances; /* FIXME - is this correct? */ + UINT nMediaTypes; /* count of media types('0ty3') */ + UINT nMediums; /* FIXME - is this correct? */ + UINT nOfsClsPinCategory; /* FIXME - is this correct? */ +} QUARTZ_REGPINDATA; + +typedef struct QUARTZ_REGMEDIATYPE +{ + CHAR id[4]; /* '0ty3', '1ty3', ... */ + DWORD nZero; /* padding??? */ + UINT nOfsMajorType; + UINT nOfsMinorType; +} QUARTZ_REGMEDIATYPE; + + + +/***************************************************************************/ + +static +REGFILTER2* QUARTZ_RegFilterV2FromFilterData( + const BYTE* pData, DWORD cbData ) +{ + REGFILTER2* pFilter; + REGFILTERPINS2* pPin; + REGPINTYPES* pTypes; + BYTE* pDst; + const QUARTZ_REGFILTERDATA* pRegFilter; + const QUARTZ_REGPINDATA* pRegPin; + const QUARTZ_REGMEDIATYPE* pRegMediaType; + DWORD cPins; + DWORD cbBufSize; + UINT n; + + TRACE("(%p,%lu)\n",pData,cbData); + + if ( cbData < sizeof(QUARTZ_REGFILTERDATA) ) + return NULL; + + pRegFilter = (QUARTZ_REGFILTERDATA*)pData; + + if ( pRegFilter->dwVersion != 2 ) return NULL; /* FIXME */ + + if ( cbData < (sizeof(QUARTZ_REGFILTERDATA)+sizeof(QUARTZ_REGPINDATA)*pRegFilter->cPins) ) + return NULL; + + cbBufSize = sizeof(REGFILTER2); + cPins = pRegFilter->cPins; + pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1); + while ( cPins-- > 0 ) + { + if ( pRegPin->nMediums != 0 || + pRegPin->nOfsClsPinCategory != 0 ) + return NULL; /* FIXME */ + + cbBufSize += sizeof(REGFILTERPINS2) + + pRegPin->nMediaTypes * (sizeof(REGPINTYPES) + sizeof(GUID)*2) + + pRegPin->nMediums * sizeof(REGPINMEDIUM) + + sizeof(CLSID); + pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) + + sizeof(QUARTZ_REGPINDATA) + + sizeof(QUARTZ_REGMEDIATYPE) * pRegPin->nMediaTypes ); + } + + pFilter = (REGFILTER2*)QUARTZ_AllocMem( cbBufSize ); + if ( pFilter == NULL ) return NULL; + ZeroMemory( pFilter, cbBufSize ); + pPin = (REGFILTERPINS2*)(pFilter+1); + pDst = (BYTE*)(pPin + pRegFilter->cPins); + + pFilter->dwVersion = 2; + pFilter->dwMerit = pRegFilter->dwMerit; + pFilter->u.s2.cPins2 = pRegFilter->cPins; + pFilter->u.s2.rgPins2 = pPin; + + cPins = pRegFilter->cPins; + TRACE("cPins = %lu\n",cPins); + + pRegPin = (const QUARTZ_REGPINDATA*)(pRegFilter+1); + while ( cPins-- > 0 ) + { + pPin->dwFlags = pRegPin->dwFlags; + pPin->cInstances = pRegPin->cInstances; + pPin->nMediaTypes = pRegPin->nMediaTypes; + pPin->lpMediaType = NULL; + pPin->nMediums = pRegPin->nMediums; + pPin->lpMedium = NULL; + pPin->clsPinCategory = NULL; + + pTypes = (REGPINTYPES*)pDst; + pPin->lpMediaType = pTypes; + pDst += sizeof(REGPINTYPES) * pRegPin->nMediaTypes; + + pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) + + sizeof(QUARTZ_REGPINDATA) ); + + for ( n = 0; n < pPin->nMediaTypes; n++ ) + { + pRegMediaType = ((const QUARTZ_REGMEDIATYPE*)pRegPin); + TRACE("ofsMajor = %u, ofsMinor = %u\n", pRegMediaType->nOfsMajorType, pRegMediaType->nOfsMinorType); + memcpy( pDst, pData+pRegMediaType->nOfsMajorType, sizeof(GUID) ); + pTypes->clsMajorType = (const GUID*)pDst; pDst += sizeof(GUID); + memcpy( pDst, pData+pRegMediaType->nOfsMinorType, sizeof(GUID) ); + pTypes->clsMinorType = (const GUID*)pDst; pDst += sizeof(GUID); + + pRegPin = (const QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) + + sizeof(QUARTZ_REGMEDIATYPE) ); + pTypes ++; + } + + /* FIXME - pPin->lpMedium */ + /* FIXME - pPin->clsPinCategory */ + + pPin ++; + } + + return pFilter; +} + +static +BYTE* QUARTZ_RegFilterV2ToFilterData( + const REGFILTER2* pFilter, DWORD* pcbData ) +{ + DWORD cbData; + DWORD cbPinData; + DWORD cPins; + const REGFILTERPINS2* pPin; + const REGPINTYPES* pTypes; + BYTE* pRet = NULL; + BYTE* pDst; + QUARTZ_REGFILTERDATA* pRegFilter; + QUARTZ_REGPINDATA* pRegPin; + QUARTZ_REGMEDIATYPE* pRegMediaType; + UINT n; + + if ( pFilter->dwVersion != 2 ) return NULL; /* FIXME */ + + cbData = sizeof(QUARTZ_REGFILTERDATA); + cPins = pFilter->u.s2.cPins2; + pPin = pFilter->u.s2.rgPins2; + if ( cPins > 10 ) return NULL; /* FIXME */ + + cbPinData = 0; + while ( cPins-- > 0 ) + { + if ( pPin->cInstances != 0 || + pPin->nMediaTypes > 10 || + pPin->nMediums != 0 || + pPin->clsPinCategory != 0 ) + { + FIXME( "not implemented.\n" ); + return NULL; /* FIXME */ + } + + cbPinData += sizeof(QUARTZ_REGPINDATA) + + pPin->nMediaTypes * sizeof(QUARTZ_REGMEDIATYPE); + cbData += pPin->nMediaTypes * (sizeof(GUID)*2); + pPin ++; + } + cbData += cbPinData; + TRACE("cbData %lu, cbPinData %lu\n",cbData,cbPinData); + + pRet = (BYTE*)QUARTZ_AllocMem( cbData ); + if ( pRet == NULL ) return NULL; + ZeroMemory( pRet, cbData ); + pDst = pRet; + + pRegFilter = (QUARTZ_REGFILTERDATA*)pDst; + pDst += sizeof(QUARTZ_REGFILTERDATA); + + pRegFilter->dwVersion = 2; + pRegFilter->dwMerit = pFilter->dwMerit; + pRegFilter->cPins = pFilter->u.s2.cPins2; + + pRegPin = (QUARTZ_REGPINDATA*)pDst; + pDst += cbPinData; + + pPin = pFilter->u.s2.rgPins2; + for ( cPins = 0; cPins < pFilter->u.s2.cPins2; cPins++ ) + { + pRegPin->id[0] = '0'+cPins; + pRegPin->id[1] = 'p'; + pRegPin->id[2] = 'i'; + pRegPin->id[3] = '3'; + pRegPin->dwFlags = pPin->dwFlags; /* flags */ + pRegPin->cInstances = pPin->cInstances; + pRegPin->nMediaTypes = pPin->nMediaTypes; + pRegPin->nMediums = pPin->nMediums; + pRegPin->nOfsClsPinCategory = 0; /* FIXME */ + + pTypes = pPin->lpMediaType; + pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) + + sizeof(QUARTZ_REGPINDATA) ); + for ( n = 0; n < pPin->nMediaTypes; n++ ) + { + pRegMediaType = ((QUARTZ_REGMEDIATYPE*)pRegPin); + + pRegMediaType->id[0] = '0'+n; + pRegMediaType->id[1] = 't'; + pRegMediaType->id[2] = 'y'; + pRegMediaType->id[3] = '3'; + + /* FIXME - CLSID should be shared. */ + pRegMediaType->nOfsMajorType = pDst - pRet; + memcpy( pDst, pTypes->clsMajorType, sizeof(GUID) ); + pDst += sizeof(GUID); + pRegMediaType->nOfsMinorType = pDst - pRet; + memcpy( pDst, pTypes->clsMinorType, sizeof(GUID) ); + pDst += sizeof(GUID); + + pRegPin = (QUARTZ_REGPINDATA*)( ((const BYTE*)pRegPin) + + sizeof(QUARTZ_REGMEDIATYPE) ); + pTypes ++; + } + pPin ++; + } + + *pcbData = pDst - pRet; + TRACE("cbData %lu/%lu\n",*pcbData,cbData); + + return pRet; +} + +static +REGFILTER2* QUARTZ_RegFilterV1ToV2( const REGFILTER2* prfV1 ) +{ + REGFILTER2* prfV2; + const REGFILTERPINS* pPinV1; + REGFILTERPINS2* pPinV2; + DWORD cPins; + + if ( prfV1->dwVersion != 1 ) return NULL; + + prfV2 = (REGFILTER2*)QUARTZ_AllocMem( + sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins ); + if ( prfV2 == NULL ) return NULL; + ZeroMemory( prfV2, sizeof(REGFILTER2) + sizeof(REGFILTERPINS2) * prfV1->u.s1.cPins ); + pPinV1 = prfV1->u.s1.rgPins; + pPinV2 = (REGFILTERPINS2*)(prfV2+1); + prfV2->dwVersion = 2; + prfV2->dwMerit = prfV1->dwMerit; + prfV2->u.s2.cPins2 = prfV1->u.s1.cPins; + prfV2->u.s2.rgPins2 = pPinV2; + + cPins = prfV1->u.s1.cPins; + while ( cPins-- > 0 ) + { + pPinV2->dwFlags = 0; + pPinV2->cInstances = 0; + pPinV2->nMediaTypes = pPinV1->nMediaTypes; + pPinV2->lpMediaType = pPinV1->lpMediaType; + pPinV2->nMediums = 0; + pPinV2->lpMedium = NULL; + pPinV2->clsPinCategory = NULL; + + if ( pPinV1->bRendered ) + pPinV2->dwFlags |= REG_PINFLAG_B_RENDERER; + if ( pPinV1->bOutput ) + pPinV2->dwFlags |= REG_PINFLAG_B_OUTPUT; + if ( pPinV1->bZero ) + pPinV2->dwFlags |= REG_PINFLAG_B_ZERO; + if ( pPinV1->bMany ) + pPinV2->dwFlags |= REG_PINFLAG_B_MANY; + + pPinV1 ++; + pPinV2 ++; + } + + return prfV2; +} + +static +BYTE* QUARTZ_RegFilterToFilterData( + const REGFILTER2* pFilter, DWORD* pcbData ) +{ + REGFILTER2* prfV2; + BYTE* pRet = NULL; + + *pcbData = 0; + switch ( pFilter->dwVersion ) + { + case 1: + prfV2 = QUARTZ_RegFilterV1ToV2( pFilter ); + if ( prfV2 != NULL ) + { + pRet = QUARTZ_RegFilterV2ToFilterData( prfV2, pcbData ); + QUARTZ_FreeMem( prfV2 ); + } + break; + case 2: + pRet = QUARTZ_RegFilterV2ToFilterData( pFilter, pcbData ); + break; + default: + FIXME( "unknown REGFILTER2 version - %08lu\n", pFilter->dwVersion ); + break; + } + + return pRet; +} + +/***************************************************************************/ + +static +BOOL QUARTZ_CheckPinType( BOOL bExactMatch, const REGFILTERPINS2* pPin, DWORD cTypes, const GUID* pTypes, const REGPINMEDIUM* pMedium, const CLSID* pCategory, BOOL bRender ) +{ + DWORD n1, n2; + BOOL bMatch; + + if ( cTypes > 0 && pTypes != NULL ) + { + bMatch = FALSE; + for ( n1 = 0; n1 < pPin->nMediaTypes; n1++ ) + { + for ( n2 = 0; n2 < cTypes; n2++ ) + { + if ( IsEqualGUID(pPin->lpMediaType[n1].clsMajorType,&GUID_NULL) || IsEqualGUID(pPin->lpMediaType[n1].clsMajorType, &pTypes[n2*2+0]) || (!bExactMatch && IsEqualGUID(pPin->lpMediaType[n1].clsMajorType,&GUID_NULL)) ) + { + if ( IsEqualGUID(pPin->lpMediaType[n1].clsMinorType,&GUID_NULL) || IsEqualGUID(pPin->lpMediaType[n1].clsMinorType, &pTypes[n2*2+1]) || (!bExactMatch && IsEqualGUID(pPin->lpMediaType[n1].clsMinorType,&GUID_NULL)) ) + { + bMatch = TRUE; + break; + } + } + } + } + if ( !bMatch ) + return FALSE; + } + + if ( pMedium != NULL ) + { + bMatch = FALSE; + for ( n1 = 0; n1 < pPin->nMediums; n1++ ) + { + if ( IsEqualGUID( &pPin->lpMedium[n1].clsMedium, &pMedium->clsMedium ) && pPin->lpMedium[n1].dw1 == pMedium->dw1 && pPin->lpMedium[n1].dw2 == pMedium->dw2 ) + { + bMatch = TRUE; + break; + } + } + if ( !bMatch ) + return FALSE; + } + + if ( pCategory != NULL ) + { + if ( pPin->clsPinCategory == NULL ) + return FALSE; + if ( (!bExactMatch && IsEqualGUID(pCategory,&GUID_NULL)) || IsEqualGUID(pCategory,pPin->clsPinCategory) ) + return TRUE; + return FALSE; + } + + if ( bRender && (!(pPin->dwFlags & REG_PINFLAG_B_RENDERER)) ) + return FALSE; + + return TRUE; +} + + /*************************************************************************** @@ -356,8 +733,10 @@ static HRESULT WINAPI IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter) { CFilterMapper2_THIS(iface,fmap3); + WCHAR* pwszPath = NULL; + HRESULT hr; - FIXME("(%p)->(%s,%s,%s) stub!\n",This, + TRACE("(%p)->(%s,%s,%s)\n",This, debugstr_guid(pclsidCategory), debugstr_w(lpwszInst), debugstr_guid(rclsidFilter)); @@ -365,12 +744,15 @@ IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCateg if ( pclsidCategory == NULL ) pclsidCategory = &CLSID_LegacyAmFilterCategory; - /* FIXME */ - return QUARTZ_RegisterAMovieFilter( - pclsidCategory, - rclsidFilter, - NULL, 0, - NULL, lpwszInst, FALSE ); + hr = QUARTZ_GetFilterRegPath( + &pwszPath, pclsidCategory, rclsidFilter, lpwszInst ); + if ( FAILED(hr) ) + return hr; + + hr = QUARTZ_RegDeleteKey(HKEY_CLASSES_ROOT,pwszPath); + QUARTZ_FreeMem(pwszPath); + + return hr; } @@ -378,8 +760,13 @@ static HRESULT WINAPI IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2) { CFilterMapper2_THIS(iface,fmap3); + WCHAR* pwszPath = NULL; + IMoniker* pMoniker = NULL; + BYTE* pFilterData = NULL; + DWORD cbFilterData = 0; + HRESULT hr; - FIXME( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This, + TRACE( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This, debugstr_guid(rclsidFilter),debugstr_w(lpName), ppMoniker,debugstr_guid(pclsidCategory), debugstr_w(lpwszInst),pRF2 ); @@ -387,33 +774,245 @@ IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCW if ( lpName == NULL || pRF2 == NULL ) return E_POINTER; - if ( ppMoniker != NULL ) + if ( ppMoniker != NULL && *ppMoniker != NULL ) { - FIXME( "ppMoniker != NULL - not implemented!\n" ); + FIXME( "ppMoniker != NULL - not implemented! *ppMoniker = %p\n",*ppMoniker ); return E_NOTIMPL; } if ( pclsidCategory == NULL ) pclsidCategory = &CLSID_LegacyAmFilterCategory; - /* FIXME!! - all members in REGFILTER2 are ignored ! */ + if ( pMoniker == NULL ) + { + hr = QUARTZ_GetFilterRegPath( + &pwszPath, pclsidCategory, rclsidFilter, lpwszInst ); + if ( FAILED(hr) ) + return hr; + hr = QUARTZ_CreateDeviceMoniker( + HKEY_CLASSES_ROOT,pwszPath,&pMoniker); + QUARTZ_FreeMem(pwszPath); + if ( FAILED(hr) ) + return hr; + } - return QUARTZ_RegisterAMovieFilter( - pclsidCategory, - rclsidFilter, - NULL, 0, - lpName, lpwszInst, TRUE ); + pFilterData = QUARTZ_RegFilterToFilterData( pRF2, &cbFilterData ); + if ( pFilterData == NULL || cbFilterData == 0 ) + { + hr = E_FAIL; + goto err; + } + + hr = QUARTZ_RegisterFilterToMoniker( + pMoniker, rclsidFilter, lpName, pFilterData, cbFilterData ); + if ( FAILED(hr) ) + goto err; + + if ( ppMoniker != NULL ) + { + *ppMoniker = pMoniker; + pMoniker = NULL; + } +err: + if ( pFilterData != NULL ) + QUARTZ_FreeMem(pFilterData); + if ( pMoniker != NULL ) + IMoniker_Release(pMoniker); + + return hr; } static HRESULT WINAPI -IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,IEnumMoniker** ppMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut) +IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface, + IEnumMoniker** ppEnumMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit, + BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender, + BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut) { CFilterMapper2_THIS(iface,fmap3); + ICreateDevEnum* pEnum = NULL; + IEnumMoniker* pCategories = NULL; + IMoniker* pCat = NULL; + DWORD dwCatMerit; + IEnumMoniker* pCatFilters = NULL; + IMoniker* pFilter = NULL; + CLSID clsid; + ULONG cReturned; + BYTE* pbFilterData = NULL; + DWORD cbFilterData = 0; + REGFILTER2* prf2 = NULL; + QUARTZ_CompList* pList = NULL; + const REGFILTERPINS2* pRegFilterPin; + DWORD n; + BOOL bMatch; + HRESULT hr; - FIXME("(%p)->() stub!\n",This); + FIXME("(%p)->(%p,%08lx,%d,%08lx,%d,%lu,%p,%p,%p,%d,%d,%lu,%p,%p,%p)\n",This,ppEnumMoniker,dwFlags,bExactMatch,dwMerit,bInputNeeded,cInputTypes,pguidInputTypes,pPinMediumIn,pPinCategoryIn,bRender,bOutputNeeded,cOutputTypes,pguidOutputTypes,pPinMediumOut,pPinCategoryOut); - return E_NOTIMPL; + if ( ppEnumMoniker == NULL ) + return E_POINTER; + *ppEnumMoniker = NULL; + if ( dwFlags != 0 ) + return E_INVALIDARG; + + hr = CoCreateInstance( + &CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, + &IID_ICreateDevEnum, (void**)&pEnum ); + if ( FAILED(hr) ) + goto err; + + hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&CLSID_ActiveMovieCategories,&pCategories,0); + if ( hr != S_OK ) + goto err; + + while ( 1 ) + { + if ( pCat != NULL ) + { + IMoniker_Release(pCat); + pCat = NULL; + } + hr = IEnumMoniker_Next(pCategories,1,&pCat,&cReturned); + if ( FAILED(hr) ) + goto err; + if ( hr != S_OK ) + break; + hr = QUARTZ_GetMeritFromMoniker(pCat,&dwCatMerit); + if ( hr != S_OK || dwMerit > dwCatMerit ) + continue; + hr = QUARTZ_GetCLSIDFromMoniker(pCat,&clsid); + if ( hr != S_OK ) + continue; + + if ( pCatFilters != NULL ) + { + IEnumMoniker_Release(pCatFilters); + pCatFilters = NULL; + } + hr = ICreateDevEnum_CreateClassEnumerator(pEnum,&clsid,&pCatFilters,0); + if ( FAILED(hr) ) + goto err; + if ( hr != S_OK ) + continue; + + while ( 1 ) + { + if ( pFilter != NULL ) + { + IMoniker_Release(pFilter); + pFilter = NULL; + } + hr = IEnumMoniker_Next(pCatFilters,1,&pFilter,&cReturned); + if ( FAILED(hr) ) + goto err; + if ( hr != S_OK ) + break; + if ( pbFilterData != NULL ) + { + QUARTZ_FreeMem(pbFilterData); + pbFilterData = NULL; + } + hr = QUARTZ_GetFilterDataFromMoniker(pFilter,&pbFilterData,&cbFilterData); + if ( hr != S_OK ) + continue; + + if ( prf2 != NULL ) + { + QUARTZ_FreeMem(prf2); + prf2 = NULL; + } + prf2 = QUARTZ_RegFilterV2FromFilterData(pbFilterData,cbFilterData); + if ( prf2 == NULL ) + continue; + TRACE("prf2 %p, Merit %lu\n",prf2,prf2->dwMerit); + if ( prf2->dwMerit < dwMerit || prf2->dwVersion != 2 ) + continue; + + /* check input pins. */ + if ( bInputNeeded ) + { + bMatch = FALSE; + for ( n = 0; n < prf2->u.s2.cPins2; n++ ) + { + pRegFilterPin = &prf2->u.s2.rgPins2[n]; + if ( pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT ) + continue; + bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cInputTypes, pguidInputTypes, pPinMediumIn, pPinCategoryIn, bRender ); + if ( bMatch ) + break; + } + if ( !bMatch ) + continue; + } + + /* check output pins. */ + if ( bOutputNeeded ) + { + bMatch = FALSE; + for ( n = 0; n < prf2->u.s2.cPins2; n++ ) + { + pRegFilterPin = &prf2->u.s2.rgPins2[n]; + if ( !(pRegFilterPin->dwFlags & REG_PINFLAG_B_OUTPUT) ) + continue; + bMatch = QUARTZ_CheckPinType( bExactMatch, pRegFilterPin, cOutputTypes, pguidOutputTypes, pPinMediumOut, pPinCategoryOut, FALSE ); + if ( bMatch ) + break; + } + if ( !bMatch ) + continue; + } + + /* matched - add pFilter to the list. */ + if ( pList == NULL ) + { + pList = QUARTZ_CompList_Alloc(); + if ( pList == NULL ) + { + hr = E_OUTOFMEMORY; + goto err; + } + } + hr = QUARTZ_CompList_AddComp( + pList, (IUnknown*)pFilter, NULL, 0 ); + if ( FAILED(hr) ) + goto err; + } + } + + if ( pList == NULL ) + { + hr = S_FALSE; + goto err; + } + + FIXME("create IEnumMoniker - not sorted\n"); + /* FIXME - should be sorted?(in Merit order) */ + hr = QUARTZ_CreateEnumUnknown( &IID_IEnumMoniker, (void**)ppEnumMoniker, pList ); + if ( FAILED(hr) ) + goto err; + + hr = S_OK; +err: + if ( pEnum != NULL ) + ICreateDevEnum_Release(pEnum); + if ( pCategories != NULL ) + IEnumMoniker_Release(pCategories); + if ( pCat != NULL ) + IMoniker_Release(pCat); + if ( pCatFilters != NULL ) + IEnumMoniker_Release(pCatFilters); + if ( pFilter != NULL ) + IMoniker_Release(pFilter); + if ( pbFilterData != NULL ) + QUARTZ_FreeMem(pbFilterData); + if ( prf2 != NULL ) + QUARTZ_FreeMem(prf2); + if ( pList != NULL ) + QUARTZ_CompList_Free( pList ); + + TRACE("returns %08lx\n",hr); + + return hr; } static HRESULT WINAPI diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c index e86979e44a8..f054162d37c 100644 --- a/dlls/quartz/ifgraph.c +++ b/dlls/quartz/ifgraph.c @@ -18,6 +18,7 @@ #include "wingdi.h" #include "winuser.h" #include "winerror.h" +#include "winreg.h" #include "strmif.h" #include "control.h" #include "uuids.h" @@ -31,8 +32,13 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "fgraph.h" #include "enumunk.h" #include "sysclock.h" +#include "regsvr.h" +#ifndef NUMELEMS +#define NUMELEMS(elem) (sizeof(elem)/sizeof(elem[0])) +#endif /* NUMELEMS */ + static HRESULT CFilterGraph_DisconnectAllPins( IBaseFilter* pFilter ) { IEnumPins* pEnum = NULL; @@ -89,6 +95,289 @@ static HRESULT CFilterGraph_GraphChanged( CFilterGraph* This ) return NOERROR; } +/*************************************************************************** + * + * CFilterGraph internal methods for IFilterGraph2::AddSourceFilter(). + * + */ + +static HRESULT QUARTZ_PeekFile( + const WCHAR* pwszFileName, + BYTE* pData, DWORD cbData, DWORD* pcbRead ) +{ + HANDLE hFile; + HRESULT hr = E_FAIL; + + *pcbRead = 0; + hFile = CreateFileW( pwszFileName, + GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL ); + if ( hFile == INVALID_HANDLE_VALUE ) + return E_FAIL; + if ( ReadFile( hFile, pData, cbData, pcbRead, NULL ) ) + hr = NOERROR; + CloseHandle( hFile ); + + return hr; +} + + +static const WCHAR* skip_space(const WCHAR* pwsz) +{ + if ( pwsz == NULL ) return NULL; + while ( *pwsz == (WCHAR)' ' ) pwsz++; + return pwsz; +} + +static const WCHAR* get_dword(const WCHAR* pwsz,DWORD* pdw) +{ + DWORD dw = 0; + + *pdw = 0; + if ( pwsz == NULL ) return NULL; + while ( *pwsz >= (WCHAR)'0' && *pwsz <= (WCHAR)'9' ) + { + dw = dw * 10 + (DWORD)(*pwsz-(WCHAR)'0'); + pwsz ++; + } + *pdw = dw; + return pwsz; +} + +static int wchar_to_hex(WCHAR wch) +{ + if ( wch >= (WCHAR)'0' && wch <= (WCHAR)'9' ) + return (int)(wch - (WCHAR)'0'); + if ( wch >= (WCHAR)'A' && wch <= (WCHAR)'F' ) + return (int)(wch - (WCHAR)'A' + 10); + if ( wch >= (WCHAR)'a' && wch <= (WCHAR)'f' ) + return (int)(wch - (WCHAR)'a' + 10); + return -1; +} + +static const WCHAR* get_hex(const WCHAR* pwsz,BYTE* pb) +{ + int hi,lo; + + *pb = 0; + if ( pwsz == NULL ) return NULL; + hi = wchar_to_hex(*pwsz); if ( hi < 0 ) return NULL; pwsz++; + lo = wchar_to_hex(*pwsz); if ( lo < 0 ) return NULL; pwsz++; + *pb = (BYTE)( (hi << 4) | lo ); + return pwsz; +} + +static const WCHAR* skip_hex(const WCHAR* pwsz) +{ + if ( pwsz == NULL ) return NULL; + while ( 1 ) + { + if ( wchar_to_hex(*pwsz) < 0 ) + break; + pwsz++; + } + return pwsz; +} + +static const WCHAR* next_token(const WCHAR* pwsz) +{ + if ( pwsz == NULL ) return NULL; + pwsz = skip_space(pwsz); + if ( *pwsz != (WCHAR)',' ) return NULL; pwsz++; + return skip_space(pwsz); +} + + +static HRESULT QUARTZ_SourceTypeIsMatch( + const BYTE* pData, DWORD cbData, + const WCHAR* pwszTempl, DWORD cchTempl ) +{ + DWORD dwOfs; + DWORD n; + DWORD cbLen; + const WCHAR* pwszMask; + const WCHAR* pwszValue; + BYTE bMask; + BYTE bValue; + + TRACE("(%p,%lu,%s,%lu)\n",pData,cbData,debugstr_w(pwszTempl),cchTempl); + + pwszTempl = skip_space(pwszTempl); + while ( 1 ) + { + pwszTempl = get_dword(pwszTempl,&dwOfs); + pwszTempl = next_token(pwszTempl); + pwszTempl = get_dword(pwszTempl,&cbLen); + pwszMask = pwszTempl = next_token(pwszTempl); + pwszTempl = skip_hex(pwszTempl); + pwszValue = pwszTempl = next_token(pwszTempl); + pwszTempl = skip_hex(pwszValue); + pwszTempl = skip_space(pwszTempl); + if ( pwszValue == NULL ) + { + WARN( "parse error\n" ); + return S_FALSE; + } + + if ( dwOfs >= cbData || ( (dwOfs+cbLen) >= cbData ) ) + { + WARN( "length of given data is too short\n" ); + return S_FALSE; + } + + for ( n = 0; n < cbLen; n++ ) + { + pwszMask = get_hex(pwszMask,&bMask); + if ( pwszMask == NULL ) bMask = 0xff; + pwszValue = get_hex(pwszValue,&bValue); + if ( pwszValue == NULL ) + { + WARN( "parse error - invalid hex data\n" ); + return S_FALSE; + } + if ( (pData[dwOfs+n]&bMask) != (bValue&bMask) ) + { + TRACE( "not matched\n" ); + return S_FALSE; + } + } + + if ( *pwszTempl == 0 ) + break; + pwszTempl = next_token(pwszTempl); + if ( pwszTempl == NULL ) + { + WARN( "parse error\n" ); + return S_FALSE; + } + } + + TRACE( "matched\n" ); + return NOERROR; +} + +static HRESULT QUARTZ_GetSourceTypeFromData( + const BYTE* pData, DWORD cbData, + GUID* pidMajor, GUID* pidSub, CLSID* pidSource ) +{ + HRESULT hr = S_FALSE; + LONG lr; + WCHAR wszMajor[128]; + WCHAR wszSub[128]; + WCHAR wszSource[128]; + WCHAR wszSourceFilter[128]; + WCHAR* pwszLocalBuf = NULL; + WCHAR* pwszTemp; + DWORD cbLocalBuf = 0; + DWORD cbPath; + DWORD dwIndexMajor; + HKEY hkMajor; + DWORD dwIndexSub; + HKEY hkSub; + DWORD dwIndexSource; + HKEY hkSource; + DWORD dwRegType; + DWORD cbRegData; + FILETIME ftLastWrite; + static const WCHAR wszFmt[] = {'%','l','u',0}; + + if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, QUARTZ_wszMediaType, 0, KEY_READ, &hkMajor ) == ERROR_SUCCESS ) + { + dwIndexMajor = 0; + while ( hr == S_FALSE ) + { + cbPath = NUMELEMS(wszMajor)-1; + lr = RegEnumKeyExW( + hkMajor, dwIndexMajor ++, wszMajor, &cbPath, + NULL, NULL, NULL, &ftLastWrite ); + if ( lr != ERROR_SUCCESS ) + break; + if ( RegOpenKeyExW( hkMajor, wszMajor, 0, KEY_READ, &hkSub ) == ERROR_SUCCESS ) + { + dwIndexSub = 0; + while ( hr == S_FALSE ) + { + cbPath = NUMELEMS(wszSub)-1; + lr = RegEnumKeyExW( + hkSub, dwIndexSub ++, wszSub, &cbPath, + NULL, NULL, NULL, &ftLastWrite ); + if ( lr != ERROR_SUCCESS ) + break; + if ( RegOpenKeyExW( hkSub, wszSub, 0, KEY_READ, &hkSource ) == ERROR_SUCCESS ) + { + dwIndexSource = 0; + while ( hr == S_FALSE ) + { + wsprintfW(wszSource,wszFmt,dwIndexSource++); + lr = RegQueryValueExW( + hkSource, wszSource, NULL, + &dwRegType, NULL, &cbRegData ); + if ( lr != ERROR_SUCCESS ) + break; + if ( cbLocalBuf < cbRegData ) + { + pwszTemp = (WCHAR*)QUARTZ_ReallocMem( pwszLocalBuf, cbRegData+sizeof(WCHAR) ); + if ( pwszTemp == NULL ) + { + hr = E_OUTOFMEMORY; + break; + } + pwszLocalBuf = pwszTemp; + cbLocalBuf = cbRegData+sizeof(WCHAR); + } + cbRegData = cbLocalBuf; + lr = RegQueryValueExW( + hkSource, wszSource, NULL, + &dwRegType, (BYTE*)pwszLocalBuf, &cbRegData ); + if ( lr != ERROR_SUCCESS ) + break; + + hr = QUARTZ_SourceTypeIsMatch( + pData, cbData, + pwszLocalBuf, cbRegData / sizeof(WCHAR) ); + if ( hr == S_OK ) + { + hr = CLSIDFromString(wszMajor,pidMajor); + if ( hr == NOERROR ) + hr = CLSIDFromString(wszSub,pidSub); + if ( hr == NOERROR ) + { + lstrcpyW(wszSource,QUARTZ_wszSourceFilter); + cbRegData = NUMELEMS(wszSourceFilter)-sizeof(WCHAR); + lr = RegQueryValueExW( + hkSource, wszSource, NULL, + &dwRegType, + (BYTE*)wszSourceFilter, &cbRegData ); + if ( lr == ERROR_SUCCESS ) + { + hr = CLSIDFromString(wszSourceFilter,pidSource); + } + else + hr = E_FAIL; + } + + if ( hr != NOERROR && SUCCEEDED(hr) ) + hr = E_FAIL; + } + if ( hr != S_FALSE ) + break; + } + RegCloseKey( hkSource ); + } + } + RegCloseKey( hkSub ); + } + } + RegCloseKey( hkMajor ); + } + + if ( pwszLocalBuf != NULL ) + QUARTZ_FreeMem(pwszLocalBuf); + + return hr; +} + + /*************************************************************************** * @@ -178,7 +467,7 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa pItem = QUARTZ_CompList_SearchData( This->m_pFilterList, info.achName, sizeof(WCHAR)*(iLen+1) ); - if ( pItem == NULL ) + if ( iLen > 0 && pItem == NULL ) { pName = info.achName; goto name_ok; @@ -210,7 +499,7 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa goto end; name_ok: - TRACE( "(%p) add this filter.\n",This ); + TRACE( "(%p) add this filter - %s.\n",This,debugstr_w(pName) ); /* register this filter. */ hr = QUARTZ_CompList_AddComp( @@ -511,6 +800,20 @@ static HRESULT WINAPI IFilterGraph2_fnConnect(IFilterGraph2* iface,IPin* pOut,IPin* pIn) { CFilterGraph_THIS(iface,fgraph); + IFilterMapper2* pMap2 = NULL; + IEnumMoniker* pEnumMon = NULL; + IMoniker* pMon = NULL; + IBaseFilter* pFilter = NULL; + IEnumPins* pEnumPin = NULL; + IPin* pPinTry = NULL; + PIN_INFO info; + PIN_DIRECTION pindir; + ULONG cReturned; + BOOL bTryConnect; + BOOL bConnected = FALSE; + CLSID clsidOutFilter; + CLSID clsidInFilter; + CLSID clsid; HRESULT hr; TRACE( "(%p)->(%p,%p)\n",This,pOut,pIn ); @@ -523,17 +826,232 @@ IFilterGraph2_fnConnect(IFilterGraph2* iface,IPin* pOut,IPin* pIn) /* FIXME - try to connect indirectly. */ FIXME( "(%p)->(%p,%p) stub!\n",This,pOut,pIn ); + info.pFilter = NULL; + hr = IPin_QueryPinInfo(pOut,&info); + if ( FAILED(hr) ) + return hr; + if ( info.pFilter == NULL ) + return E_FAIL; + hr = IBaseFilter_GetClassID(info.pFilter,&clsidOutFilter); + IBaseFilter_Release(info.pFilter); + if ( FAILED(hr) ) + return hr; - return E_NOTIMPL; + info.pFilter = NULL; + hr = IPin_QueryPinInfo(pIn,&info); + if ( FAILED(hr) ) + return hr; + if ( info.pFilter == NULL ) + return E_FAIL; + hr = IBaseFilter_GetClassID(info.pFilter,&clsidInFilter); + IBaseFilter_Release(info.pFilter); + if ( FAILED(hr) ) + return hr; + + /* FIXME - try to connect with unused filters. */ + /* FIXME - try to connect with cached filters. */ + /* FIXME - enumerate transform filters and try to connect */ + hr = CoCreateInstance( + &CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void**)&pMap2 ); + if ( FAILED(hr) ) + return hr; + hr = IFilterMapper2_EnumMatchingFilters( + pMap2,&pEnumMon,0,FALSE,MERIT_DO_NOT_USE+1, + TRUE,0,NULL,NULL,NULL,FALSE, + TRUE,0,NULL,NULL,NULL); + IFilterMapper2_Release(pMap2); + if ( FAILED(hr) ) + return hr; + TRACE("try to connect indirectly\n"); + + if ( hr == S_OK ) + { + while ( !bConnected && hr == S_OK ) + { + hr = IEnumMoniker_Next(pEnumMon,1,&pMon,&cReturned); + if ( hr != S_OK ) + break; + hr = IMoniker_BindToObject(pMon,NULL,NULL,&IID_IBaseFilter,(void**)&pFilter ); + if ( hr == S_OK ) + { + hr = IBaseFilter_GetClassID(pFilter,&clsid); + if ( hr == S_OK && + ( IsEqualGUID(&clsidOutFilter,&clsid) || IsEqualGUID(&clsidInFilter,&clsid) ) ) + hr = S_FALSE; + else + hr = IFilterGraph2_AddFilter(iface,pFilter,NULL); + if ( hr == S_OK ) + { + bTryConnect = FALSE; + hr = IBaseFilter_EnumPins(pFilter,&pEnumPin); + if ( hr == S_OK ) + { + { + while ( !bTryConnect ) + { + hr = IEnumPins_Next(pEnumPin,1,&pPinTry,&cReturned); + if ( hr != S_OK ) + break; + hr = IPin_QueryDirection(pPinTry,&pindir); + if ( hr == S_OK && pindir == PINDIR_INPUT ) + { + /* try to connect directly. */ + hr = IFilterGraph2_ConnectDirect(iface,pOut,pPinTry,NULL); + if ( hr == S_OK ) + bTryConnect = TRUE; + hr = S_OK; + } + IPin_Release(pPinTry); pPinTry = NULL; + } + } + IEnumPins_Release(pEnumPin); pEnumPin = NULL; + } + TRACE("TryConnect %d\n",bTryConnect); + + if ( bTryConnect ) + { + hr = IBaseFilter_EnumPins(pFilter,&pEnumPin); + if ( hr == S_OK ) + { + while ( !bConnected ) + { + hr = IEnumPins_Next(pEnumPin,1,&pPinTry,&cReturned); + if ( hr != S_OK ) + break; + hr = IPin_QueryDirection(pPinTry,&pindir); + if ( hr == S_OK && pindir == PINDIR_OUTPUT ) + { + /* try to connect indirectly. */ + hr = IFilterGraph2_Connect(iface,pPinTry,pIn); + if ( hr == S_OK ) + bConnected = TRUE; + hr = S_OK; + } + IPin_Release(pPinTry); pPinTry = NULL; + } + IEnumPins_Release(pEnumPin); pEnumPin = NULL; + } + } + if ( !bConnected ) + hr = IFilterGraph2_RemoveFilter(iface,pFilter); + } + IBaseFilter_Release(pFilter); pFilter = NULL; + if ( SUCCEEDED(hr) ) + hr = S_OK; + } + IMoniker_Release(pMon); pMon = NULL; + } + IEnumMoniker_Release(pEnumMon); pEnumMon = NULL; + } + + if ( SUCCEEDED(hr) && !bConnected ) + hr = VFW_E_CANNOT_CONNECT; + + return hr; } static HRESULT WINAPI IFilterGraph2_fnRender(IFilterGraph2* iface,IPin* pOut) { CFilterGraph_THIS(iface,fgraph); + HRESULT hr; + IFilterMapper2* pMap2 = NULL; + IEnumMoniker* pEnumMon = NULL; + IMoniker* pMon = NULL; + IBaseFilter* pFilter = NULL; + IEnumPins* pEnumPin = NULL; + IPin* pPin = NULL; + PIN_DIRECTION pindir; + BOOL bRendered = FALSE; + ULONG cReturned; - FIXME( "(%p)->(%p) stub!\n",This,pOut ); - return E_NOTIMPL; + FIXME( "(%p)->(%p)\n",This,pOut ); + + /* FIXME - must be locked */ + /*QUARTZ_CompList_Lock( This->m_pFilterList );*/ + + if ( pOut == NULL ) + return E_POINTER; + + hr = CoCreateInstance( + &CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper2, (void**)&pMap2 ); + if ( FAILED(hr) ) + return hr; + hr = IFilterMapper2_EnumMatchingFilters( + pMap2,&pEnumMon,0,FALSE,MERIT_DO_NOT_USE+1, + TRUE,0,NULL,NULL,NULL,TRUE, + FALSE,0,NULL,NULL,NULL); + IFilterMapper2_Release(pMap2); + if ( FAILED(hr) ) + return hr; + TRACE("try to render pin\n"); + + if ( hr == S_OK ) + { + /* try to render pin. */ + while ( !bRendered && hr == S_OK ) + { + hr = IEnumMoniker_Next(pEnumMon,1,&pMon,&cReturned); + if ( hr != S_OK ) + break; + hr = IMoniker_BindToObject(pMon,NULL,NULL,&IID_IBaseFilter,(void**)&pFilter ); + if ( hr == S_OK ) + { + hr = IFilterGraph2_AddFilter(iface,pFilter,NULL); + if ( hr == S_OK ) + { + hr = IBaseFilter_EnumPins(pFilter,&pEnumPin); + if ( hr == S_OK ) + { + while ( !bRendered ) + { + hr = IEnumPins_Next(pEnumPin,1,&pPin,&cReturned); + if ( hr != S_OK ) + break; + hr = IPin_QueryDirection(pPin,&pindir); + if ( hr == S_OK && pindir == PINDIR_INPUT ) + { + /* try to connect. */ + hr = IFilterGraph2_Connect(iface,pOut,pPin); + if ( hr == S_OK ) + bRendered = TRUE; + hr = S_OK; + } + IPin_Release(pPin); pPin = NULL; + } + IEnumPins_Release(pEnumPin); pEnumPin = NULL; + } + if ( !bRendered ) + hr = IFilterGraph2_RemoveFilter(iface,pFilter); + } + IBaseFilter_Release(pFilter); pFilter = NULL; + if ( SUCCEEDED(hr) ) + hr = S_OK; + } + IMoniker_Release(pMon); pMon = NULL; + } + IEnumMoniker_Release(pEnumMon); pEnumMon = NULL; + } + + if ( bRendered ) + { + /* successfully rendered(but may be partial now) */ + hr = S_OK; + + /* FIXME - try to render all inserted filters. */ + /* hr = VFW_S_PARTIAL_RENDER; */ + } + else + { + if ( SUCCEEDED(hr) ) + hr = VFW_E_CANNOT_RENDER; + } + + /*QUARTZ_CompList_Unlock( This->m_pFilterList );*/ + + return hr; } static HRESULT WINAPI @@ -564,6 +1082,8 @@ IFilterGraph2_fnRenderFile(IFilterGraph2* iface,LPCWSTR lpFileName,LPCWSTR lpPla hr = E_FAIL; goto end; } + TRACE("(%p) source filter %p\n",This,pFilter); + pEnum = NULL; hr = IBaseFilter_EnumPins( pFilter, &pEnum ); if ( FAILED(hr) ) @@ -621,10 +1141,67 @@ static HRESULT WINAPI IFilterGraph2_fnAddSourceFilter(IFilterGraph2* iface,LPCWSTR lpFileName,LPCWSTR lpFilterName,IBaseFilter** ppBaseFilter) { CFilterGraph_THIS(iface,fgraph); + HRESULT hr; + BYTE bStartData[512]; + DWORD cbStartData; + AM_MEDIA_TYPE mt; + CLSID clsidSource; + IFileSourceFilter* pSource; - FIXME( "(%p)->(%s,%s,%p) stub!\n",This, + FIXME( "(%p)->(%s,%s,%p)\n",This, debugstr_w(lpFileName),debugstr_w(lpFilterName),ppBaseFilter ); - return E_NOTIMPL; + + if ( lpFileName == NULL || ppBaseFilter == NULL ) + return E_POINTER; + *ppBaseFilter = NULL; + + hr = QUARTZ_PeekFile( lpFileName, bStartData, 512, &cbStartData ); + if ( FAILED(hr) ) + { + FIXME("cannot open %s (NOTE: URL is not implemented)\n", debugstr_w(lpFileName)); + return hr; + } + ZeroMemory( &mt, sizeof(AM_MEDIA_TYPE) ); + mt.bFixedSizeSamples = 1; + mt.lSampleSize = 1; + memcpy( &mt.majortype, &MEDIATYPE_Stream, sizeof(GUID) ); + memcpy( &mt.subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) ); + memcpy( &mt.formattype, &FORMAT_None, sizeof(GUID) ); + hr = QUARTZ_GetSourceTypeFromData( + bStartData, cbStartData, + &mt.majortype, &mt.subtype, &clsidSource ); + if ( FAILED(hr) ) + { + ERR("QUARTZ_GetSourceTypeFromData() failed - return %08lx\n",hr); + return hr; + } + if ( hr != S_OK ) + { + FIXME( "file %s - unknown format\n", debugstr_w(lpFileName) ); + return VFW_E_INVALID_FILE_FORMAT; + } + + hr = CoCreateInstance( + &clsidSource, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void**)ppBaseFilter ); + if ( FAILED(hr) ) + return hr; + hr = IBaseFilter_QueryInterface(*ppBaseFilter,&IID_IFileSourceFilter,(void**)&pSource); + if ( SUCCEEDED(hr) ) + { + hr = IFileSourceFilter_Load(pSource,lpFileName,&mt); + IFileSourceFilter_Release(pSource); + } + if ( SUCCEEDED(hr) ) + hr = IFilterGraph2_AddFilter(iface,*ppBaseFilter,lpFilterName); + if ( FAILED(hr) ) + { + IBaseFilter_Release(*ppBaseFilter); + *ppBaseFilter = NULL; + return hr; + } + + return S_OK; } static HRESULT WINAPI diff --git a/dlls/quartz/iunk.c b/dlls/quartz/iunk.c index ba23f656736..4f0133e28c8 100644 --- a/dlls/quartz/iunk.c +++ b/dlls/quartz/iunk.c @@ -99,8 +99,10 @@ IUnknown_fnRelease(IUnknown* iface) if ( ref > 0 ) return (ULONG)ref; + This->ref ++; if ( This->pOnFinalRelease != NULL ) (*(This->pOnFinalRelease))(iface); + This->ref --; QUARTZ_FreeObj(This); diff --git a/dlls/quartz/mtype.c b/dlls/quartz/mtype.c index 441f3fc8d47..00dcfad9409 100644 --- a/dlls/quartz/mtype.c +++ b/dlls/quartz/mtype.c @@ -105,6 +105,11 @@ void QUARTZ_MediaType_Destroy( void QUARTZ_MediaSubType_FromFourCC( GUID* psubtype, DWORD dwFourCC ) { + TRACE( "FourCC %c%c%c%c\n", + (int)(dwFourCC>> 0)&0xff, + (int)(dwFourCC>> 8)&0xff, + (int)(dwFourCC>>16)&0xff, + (int)(dwFourCC>>24)&0xff ); memcpy( psubtype, &MEDIASUBTYPE_PCM, sizeof(GUID) ); psubtype->Data1 = dwFourCC; } @@ -125,7 +130,7 @@ HRESULT QUARTZ_MediaSubType_FromBitmap( HRESULT hr; DWORD* pdwBitf; - if ( (pbi->biCompression & 0xffff) != 0 ) + if ( (pbi->biCompression & 0xffff0000) != 0 ) return S_FALSE; if ( pbi->biWidth <= 0 || pbi->biHeight == 0 ) @@ -219,6 +224,25 @@ HRESULT QUARTZ_MediaSubType_FromBitmap( return hr; } +void QUARTZ_PatchBitmapInfoHeader( BITMAPINFOHEADER* pbi ) +{ + switch ( pbi->biCompression ) + { + case mmioFOURCC('R','G','B',' '): + pbi->biCompression = 0; + break; + case mmioFOURCC('R','L','E',' '): + case mmioFOURCC('M','R','L','E'): + case mmioFOURCC('R','L','E','8'): + case mmioFOURCC('R','L','E','4'): + if ( pbi->biBitCount == 4 ) + pbi->biCompression = 2; + else + pbi->biCompression = 1; + break; + } +} + BOOL QUARTZ_BitmapHasFixedSample( const BITMAPINFOHEADER* pbi ) { switch ( pbi->biCompression ) diff --git a/dlls/quartz/mtype.h b/dlls/quartz/mtype.h index 50d325282a4..f9e2da5f4b1 100644 --- a/dlls/quartz/mtype.h +++ b/dlls/quartz/mtype.h @@ -25,6 +25,7 @@ BOOL QUARTZ_MediaSubType_IsFourCC( HRESULT QUARTZ_MediaSubType_FromBitmap( GUID* psubtype, const BITMAPINFOHEADER* pbi ); +void QUARTZ_PatchBitmapInfoHeader( BITMAPINFOHEADER* pbi ); BOOL QUARTZ_BitmapHasFixedSample( const BITMAPINFOHEADER* pbi ); diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index fafc0fe9013..16ce54f8a39 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -18,6 +18,7 @@ #include "strmif.h" #include "control.h" #include "vfwmsgs.h" +#include "evcode.h" #include "uuids.h" #include "debugtools.h" @@ -28,7 +29,6 @@ DEFAULT_DEBUG_CHANNEL(quartz); #include "mtype.h" #include "memalloc.h" -#define QUARTZ_MSG_FLUSH (WM_APP+1) #define QUARTZ_MSG_EXITTHREAD (WM_APP+2) #define QUARTZ_MSG_SEEK (WM_APP+3) @@ -37,6 +37,372 @@ void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This ); HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This ); void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This ); +/*************************************************************************** + * + * CParserImpl internal thread + * + */ + +static +void CParserImplThread_ClearAllRequests( CParserImpl* This ) +{ + ULONG nIndex; + + TRACE("(%p)\n",This); + + for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) + { + This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE; + This->m_ppOutPins[nIndex]->m_pReqSample = NULL; + } +} + +static +void CParserImplThread_ReleaseAllRequests( CParserImpl* This ) +{ + ULONG nIndex; + + TRACE("(%p)\n",This); + + for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) + { + if ( This->m_ppOutPins[nIndex]->m_bReqUsed ) + { + if ( This->m_ppOutPins[nIndex]->m_pReqSample != NULL ) + { + IMediaSample_Release(This->m_ppOutPins[nIndex]->m_pReqSample); + This->m_ppOutPins[nIndex]->m_pReqSample = NULL; + } + This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE; + } + } +} + +static +BOOL CParserImplThread_HasPendingSamples( CParserImpl* This ) +{ + ULONG nIndex; + + for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) + { + if ( This->m_ppOutPins[nIndex]->m_bReqUsed && + This->m_ppOutPins[nIndex]->m_pReqSample != NULL ) + return TRUE; + } + + return FALSE; +} + +static +HRESULT CParserImplThread_FlushAllPendingSamples( CParserImpl* This ) +{ + HRESULT hr; + IMediaSample* pSample; + DWORD_PTR dwContext; + + TRACE("(%p)\n",This); + + /* remove all samples from queue. */ + hr = IAsyncReader_BeginFlush(This->m_pReader); + if ( FAILED(hr) ) + return hr; + IAsyncReader_EndFlush(This->m_pReader); + + /* remove all processed samples from queue. */ + while ( 1 ) + { + hr = IAsyncReader_WaitForNext(This->m_pReader,0,&pSample,&dwContext); + if ( hr != S_OK ) + break; + } + + CParserImplThread_ReleaseAllRequests(This); + + return NOERROR; +} + +static HRESULT CParserImplThread_SendEndOfStream( CParserImpl* This ) +{ + ULONG nIndex; + HRESULT hr; + HRESULT hrRet; + CParserOutPinImpl* pOutPin; + + TRACE("(%p)\n",This); + if ( This->m_bSendEOS ) + return NOERROR; + This->m_bSendEOS = TRUE; + + hrRet = S_OK; + for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) + { + pOutPin = This->m_ppOutPins[nIndex]; + hr = CPinBaseImpl_SendEndOfStream(&pOutPin->pin); + if ( FAILED(hr) ) + { + if ( SUCCEEDED(hrRet) ) + hrRet = hr; + } + else + { + if ( hr != S_OK && hrRet == S_OK ) + hrRet = hr; + } + } + + return hrRet; +} + +static HRESULT CParserImplThread_SendFlush( CParserImpl* This ) +{ + ULONG nIndex; + HRESULT hr; + HRESULT hrRet; + CParserOutPinImpl* pOutPin; + + TRACE("(%p)\n",This); + hrRet = S_OK; + for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) + { + pOutPin = This->m_ppOutPins[nIndex]; + hr = CPinBaseImpl_SendBeginFlush(&pOutPin->pin); + if ( FAILED(hr) ) + { + if ( SUCCEEDED(hrRet) ) + hrRet = hr; + } + else + { + if ( hr != S_OK && hrRet == S_OK ) + hrRet = hr; + hr = CPinBaseImpl_SendEndFlush(&pOutPin->pin); + if ( FAILED(hr) ) + hrRet = hr; + } + } + + return hrRet; +} + +static void CParserImplThread_ErrorAbort( CParserImpl* This, HRESULT hr ) +{ + CBaseFilterImpl_MediaEventNotify( + &This->basefilter,EC_ERRORABORT,(LONG_PTR)hr,(LONG_PTR)0); + CParserImplThread_SendEndOfStream(This); +} + +static +HRESULT CParserImplThread_ProcessNextSample( CParserImpl* This ) +{ + IMediaSample* pSample; + DWORD_PTR dwContext; + ULONG nIndex; + HRESULT hr; + CParserOutPinImpl* pOutPin; + MSG msg; + + while ( 1 ) + { + if ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) ) + { + hr = NOERROR; + switch ( msg.message ) + { + case QUARTZ_MSG_EXITTHREAD: + TRACE("(%p) EndThread\n",This); + CParserImplThread_FlushAllPendingSamples(This); + CParserImplThread_ClearAllRequests(This); + CParserImplThread_SendFlush(This); + CParserImplThread_SendEndOfStream(This); + TRACE("(%p) exit thread\n",This); + return S_FALSE; + case QUARTZ_MSG_SEEK: + FIXME("(%p) Seek\n",This); + CParserImplThread_FlushAllPendingSamples(This); + hr = CParserImplThread_SendFlush(This); + CParserImplThread_SendEndOfStream(This); + /* FIXME - process seeking. */ + /* FIXME - Send NewSegment. */ + break; + default: + FIXME( "invalid message %04u\n", (unsigned)msg.message ); + hr = E_FAIL; + CParserImplThread_ErrorAbort(This,hr); + } + + return hr; + } + + hr = IAsyncReader_WaitForNext(This->m_pReader,PARSER_POLL_INTERVAL,&pSample,&dwContext); + nIndex = (ULONG)dwContext; + if ( hr != VFW_E_TIMEOUT ) + break; + } + if ( FAILED(hr) ) + { + CParserImplThread_ErrorAbort(This,hr); + return hr; + } + + pOutPin = This->m_ppOutPins[nIndex]; + if ( pOutPin != NULL && pOutPin->m_bReqUsed ) + { + if ( This->m_pHandler->pProcessSample != NULL ) + hr = This->m_pHandler->pProcessSample(This,nIndex,pOutPin->m_llReqStart,pOutPin->m_lReqLength,pOutPin->m_pReqSample); + + if ( SUCCEEDED(hr) ) + { + if ( pOutPin->m_pOutPinAllocator != NULL && + pOutPin->m_pOutPinAllocator != This->m_pAllocator ) + { + /* if pin has its own allocator, sample must be copied */ + hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 ); + if ( SUCCEEDED(hr) ) + { + hr = QUARTZ_IMediaSample_Copy( + pSample, pOutPin->m_pReqSample, TRUE ); + if ( SUCCEEDED(hr) ) + hr = CPinBaseImpl_SendSample(&pOutPin->pin,pSample); + IMediaSample_Release(pSample); + } + } + else + { + hr = CPinBaseImpl_SendSample(&pOutPin->pin,pOutPin->m_pReqSample); + } + } + + if ( FAILED(hr) ) + CParserImplThread_ErrorAbort(This,hr); + + IMediaSample_Release(pOutPin->m_pReqSample); + pOutPin->m_pReqSample = NULL; + pOutPin->m_bReqUsed = FALSE; + } + + if ( SUCCEEDED(hr) ) + hr = NOERROR; + + TRACE("return %08lx\n",hr); + + return hr; +} + +static +DWORD WINAPI CParserImplThread_Entry( LPVOID pv ) +{ + CParserImpl* This = (CParserImpl*)pv; + BOOL bReqNext; + ULONG nIndex = 0; + HRESULT hr; + REFERENCE_TIME rtSampleTimeStart, rtSampleTimeEnd; + LONGLONG llReqStart; + LONG lReqLength; + REFERENCE_TIME rtReqStart, rtReqStop; + IMediaSample* pSample; + MSG msg; + + /* initialize the message queue. */ + PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE ); + + CParserImplThread_ClearAllRequests(This); + + /* resume the owner thread. */ + SetEvent( This->m_hEventInit ); + + TRACE( "Enter message loop.\n" ); + + bReqNext = TRUE; + while ( 1 ) + { + if ( bReqNext ) + { + /* Get the next request. */ + hr = This->m_pHandler->pGetNextRequest( This, &nIndex, &llReqStart, &lReqLength, &rtReqStart, &rtReqStop ); + if ( FAILED(hr) ) + { + CParserImplThread_ErrorAbort(This,hr); + break; + } + if ( hr != S_OK ) + { + /* Flush pending samples. */ + hr = S_OK; + while ( CParserImplThread_HasPendingSamples(This) ) + { + hr = CParserImplThread_ProcessNextSample(This); + if ( hr != S_OK ) + break; + } + if ( hr != S_OK ) + { + /* notification is already sent */ + break; + } + + /* Send End Of Stream. */ + hr = CParserImplThread_SendEndOfStream(This); + if ( hr != S_OK ) + { + /* notification is already sent */ + break; + } + + /* Blocking... */ + hr = CParserImplThread_ProcessNextSample(This); + if ( hr != S_OK ) + { + /* notification is already sent */ + break; + } + continue; + } + if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL ) + continue; + + rtSampleTimeStart = This->basefilter.rtStart + llReqStart * QUARTZ_TIMEUNITS; + rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS; + bReqNext = FALSE; + } + + if ( !This->m_ppOutPins[nIndex]->m_bReqUsed ) + { + hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 ); + if ( FAILED(hr) ) + { + CParserImplThread_ErrorAbort(This,hr); + break; + } + hr = IMediaSample_SetTime(pSample,&rtSampleTimeStart,&rtSampleTimeEnd); + if ( SUCCEEDED(hr) ) + hr = IAsyncReader_Request(This->m_pReader,pSample,nIndex); + if ( FAILED(hr) ) + { + CParserImplThread_ErrorAbort(This,hr); + break; + } + + This->m_ppOutPins[nIndex]->m_bReqUsed = TRUE; + This->m_ppOutPins[nIndex]->m_pReqSample = pSample; + This->m_ppOutPins[nIndex]->m_llReqStart = llReqStart; + This->m_ppOutPins[nIndex]->m_lReqLength = lReqLength; + This->m_ppOutPins[nIndex]->m_rtReqStart = rtSampleTimeStart; + This->m_ppOutPins[nIndex]->m_rtReqStop = rtSampleTimeEnd; + bReqNext = TRUE; + continue; + } + + hr = CParserImplThread_ProcessNextSample(This); + if ( hr != S_OK ) + { + /* notification is already sent */ + break; + } + } + + return 0; +} + /*************************************************************************** * * CParserImpl internal methods @@ -126,358 +492,6 @@ void CParserImpl_ReleaseListOfOutPins( CParserImpl* This ) QUARTZ_CompList_Unlock( This->basefilter.pOutPins ); } -static -void CParserImpl_ClearAllRequests( CParserImpl* This ) -{ - ULONG nIndex; - - TRACE("(%p)\n",This); - - for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) - { - This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE; - This->m_ppOutPins[nIndex]->m_pReqSample = NULL; - } -} - -static -void CParserImpl_ReleaseAllRequests( CParserImpl* This ) -{ - ULONG nIndex; - - TRACE("(%p)\n",This); - - for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) - { - if ( This->m_ppOutPins[nIndex]->m_bReqUsed ) - { - if ( This->m_ppOutPins[nIndex]->m_pReqSample != NULL ) - { - IMediaSample_Release(This->m_ppOutPins[nIndex]->m_pReqSample); - This->m_ppOutPins[nIndex]->m_pReqSample = NULL; - } - This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE; - } - } -} - -static -BOOL CParserImpl_HasPendingSamples( CParserImpl* This ) -{ - ULONG nIndex; - - for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) - { - if ( This->m_ppOutPins[nIndex]->m_bReqUsed && - This->m_ppOutPins[nIndex]->m_pReqSample != NULL ) - return TRUE; - } - - return FALSE; -} - -static -HRESULT CParserImpl_FlushAllPendingSamples( CParserImpl* This ) -{ - HRESULT hr; - IMediaSample* pSample; - DWORD_PTR dwContext; - - TRACE("(%p)\n",This); - - /* remove all samples from queue */ - hr = IAsyncReader_BeginFlush(This->m_pReader); - if ( FAILED(hr) ) - return hr; - IAsyncReader_EndFlush(This->m_pReader); - - while ( 1 ) - { - hr = IAsyncReader_WaitForNext(This->m_pReader,0,&pSample,&dwContext); - if ( hr != S_OK ) - break; - } - CParserImpl_ReleaseAllRequests(This); - - return NOERROR; -} - -static HRESULT CParserImpl_SendEndOfStream( CParserImpl* This ) -{ - ULONG nIndex; - HRESULT hr; - HRESULT hrRet; - CParserOutPinImpl* pOutPin; - - TRACE("(%p)\n",This); - if ( This->m_bSendEOS ) - return NOERROR; - This->m_bSendEOS = TRUE; - - hrRet = S_OK; - for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) - { - pOutPin = This->m_ppOutPins[nIndex]; - hr = CPinBaseImpl_SendEndOfStream(&pOutPin->pin); - if ( FAILED(hr) ) - { - if ( SUCCEEDED(hrRet) ) - hrRet = hr; - } - else - { - if ( hr != S_OK && hrRet == S_OK ) - hrRet = hr; - } - } - - return hrRet; -} - -static HRESULT CParserImpl_SendFlush( CParserImpl* This ) -{ - ULONG nIndex; - HRESULT hr; - HRESULT hrRet; - CParserOutPinImpl* pOutPin; - - TRACE("(%p)\n",This); - hrRet = S_OK; - for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ ) - { - pOutPin = This->m_ppOutPins[nIndex]; - hr = CPinBaseImpl_SendBeginFlush(&pOutPin->pin); - if ( FAILED(hr) ) - { - if ( SUCCEEDED(hrRet) ) - hrRet = hr; - } - else - { - if ( hr != S_OK && hrRet == S_OK ) - hrRet = hr; - hr = CPinBaseImpl_SendEndFlush(&pOutPin->pin); - if ( FAILED(hr) ) - hrRet = hr; - } - } - - return hrRet; -} - -static -HRESULT CParserImpl_ProcessNextSample( CParserImpl* This ) -{ - IMediaSample* pSample; - DWORD_PTR dwContext; - ULONG nIndex; - HRESULT hr; - CParserOutPinImpl* pOutPin; - MSG msg; - - while ( 1 ) - { - if ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) ) - { - hr = NOERROR; - switch ( msg.message ) - { - case QUARTZ_MSG_FLUSH: - TRACE("Flush\n"); - CParserImpl_FlushAllPendingSamples(This); - hr = CParserImpl_SendFlush(This); - break; - case QUARTZ_MSG_EXITTHREAD: - TRACE("(%p) EndThread\n",This); - CParserImpl_FlushAllPendingSamples(This); - CParserImpl_ClearAllRequests(This); - CParserImpl_SendFlush(This); - CParserImpl_SendEndOfStream(This); - TRACE("(%p) exit thread\n",This); - return S_FALSE; - case QUARTZ_MSG_SEEK: - FIXME("Seek\n"); - CParserImpl_FlushAllPendingSamples(This); - break; - default: - FIXME( "invalid message %04u\n", (unsigned)msg.message ); - /* Notify (ABORT) */ - hr = E_FAIL; - } - - return hr; - } - - hr = IAsyncReader_WaitForNext(This->m_pReader,PARSER_POLL_INTERVAL,&pSample,&dwContext); - nIndex = (ULONG)dwContext; - if ( hr != VFW_E_TIMEOUT ) - break; - } - if ( FAILED(hr) ) - { - return hr; - } - - pOutPin = This->m_ppOutPins[nIndex]; - if ( pOutPin != NULL && pOutPin->m_bReqUsed ) - { - if ( This->m_pHandler->pProcessSample != NULL ) - hr = This->m_pHandler->pProcessSample(This,nIndex,pOutPin->m_llReqStart,pOutPin->m_lReqLength,pOutPin->m_pReqSample); - - if ( SUCCEEDED(hr) ) - { - if ( pOutPin->m_pOutPinAllocator != NULL && - pOutPin->m_pOutPinAllocator != This->m_pAllocator ) - { - /* if pin has its own allocator, sample must be copied */ - hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 ); - if ( SUCCEEDED(hr) ) - { - hr = QUARTZ_IMediaSample_Copy( - pSample, pOutPin->m_pReqSample, TRUE ); - if ( SUCCEEDED(hr) ) - hr = CPinBaseImpl_SendSample(&pOutPin->pin,pSample); - IMediaSample_Release(pSample); - } - } - else - { - hr = CPinBaseImpl_SendSample(&pOutPin->pin,pOutPin->m_pReqSample); - } - } - - if ( FAILED(hr) ) - { - /* Notify (ABORT) */ - } - - IMediaSample_Release(pOutPin->m_pReqSample); - pOutPin->m_pReqSample = NULL; - pOutPin->m_bReqUsed = FALSE; - } - - if ( SUCCEEDED(hr) ) - hr = NOERROR; - - TRACE("return %08lx\n",hr); - - return hr; -} - -static -DWORD WINAPI CParserImpl_ThreadEntry( LPVOID pv ) -{ - CParserImpl* This = (CParserImpl*)pv; - BOOL bReqNext; - ULONG nIndex = 0; - HRESULT hr; - REFERENCE_TIME rtSampleTimeStart, rtSampleTimeEnd; - LONGLONG llReqStart; - LONG lReqLength; - REFERENCE_TIME rtReqStart, rtReqStop; - IMediaSample* pSample; - MSG msg; - - /* initialize the message queue. */ - PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE ); - - CParserImpl_ClearAllRequests(This); - - /* resume the owner thread. */ - SetEvent( This->m_hEventInit ); - - TRACE( "Enter message loop.\n" ); - - bReqNext = TRUE; - while ( 1 ) - { - if ( bReqNext ) - { - /* Get the next request. */ - hr = This->m_pHandler->pGetNextRequest( This, &nIndex, &llReqStart, &lReqLength, &rtReqStart, &rtReqStop ); - if ( FAILED(hr) ) - { - /* Notify (ABORT) */ - break; - } - if ( hr != S_OK ) - { - /* Flush pending samples. */ - hr = S_OK; - while ( CParserImpl_HasPendingSamples(This) ) - { - hr = CParserImpl_ProcessNextSample(This); - if ( hr != S_OK ) - break; - } - if ( hr != S_OK ) - { - /* notification is already sent */ - break; - } - - /* Send End Of Stream. */ - hr = CParserImpl_SendEndOfStream(This); - if ( hr != S_OK ) - { - /* notification is already sent */ - break; - } - - /* Blocking... */ - hr = CParserImpl_ProcessNextSample(This); - if ( hr != S_OK ) - { - /* notification is already sent */ - break; - } - continue; - } - if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL ) - continue; - - rtSampleTimeStart = This->basefilter.rtStart + llReqStart * QUARTZ_TIMEUNITS; - rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS; - bReqNext = FALSE; - } - - if ( !This->m_ppOutPins[nIndex]->m_bReqUsed ) - { - hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 ); - if ( FAILED(hr) ) - { - /* Notify (ABORT) */ - break; - } - hr = IMediaSample_SetTime(pSample,&rtSampleTimeStart,&rtSampleTimeEnd); - if ( SUCCEEDED(hr) ) - hr = IAsyncReader_Request(This->m_pReader,pSample,nIndex); - if ( FAILED(hr) ) - { - /* Notify (ABORT) */ - break; - } - - This->m_ppOutPins[nIndex]->m_bReqUsed = TRUE; - This->m_ppOutPins[nIndex]->m_pReqSample = pSample; - This->m_ppOutPins[nIndex]->m_llReqStart = llReqStart; - This->m_ppOutPins[nIndex]->m_lReqLength = lReqLength; - This->m_ppOutPins[nIndex]->m_rtReqStart = rtSampleTimeStart; - This->m_ppOutPins[nIndex]->m_rtReqStop = rtSampleTimeEnd; - bReqNext = TRUE; - continue; - } - - hr = CParserImpl_ProcessNextSample(This); - if ( hr != S_OK ) - { - /* notification is already sent */ - break; - } - } - - return 0; -} static HRESULT CParserImpl_BeginThread( CParserImpl* This ) @@ -496,7 +510,7 @@ HRESULT CParserImpl_BeginThread( CParserImpl* This ) /* create the processing thread. */ This->m_hThread = CreateThread( NULL, 0, - CParserImpl_ThreadEntry, + CParserImplThread_Entry, (LPVOID)This, 0, &This->m_dwThreadId ); if ( This->m_hThread == (HANDLE)NULL ) diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c index 01fb32780c6..21990c1b205 100644 --- a/dlls/quartz/regsvr.c +++ b/dlls/quartz/regsvr.c @@ -23,7 +23,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); #define NUMELEMS(elem) (sizeof(elem)/sizeof((elem)[0])) #endif /* NUMELEMS */ -const WCHAR QUARTZ_wszREG_SZ[] = +const WCHAR QUARTZ_wszREG_SZ[7] = {'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}; @@ -34,15 +34,22 @@ const WCHAR QUARTZ_wszBoth[] = 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}; + {'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}; +const WCHAR QUARTZ_wszMediaType[] = + {'M','e','d','i','a',' ','T','y','p','e',0}; +const WCHAR QUARTZ_wszSubType[] = + {'S','u','b','T','y','p','e',0}; +const WCHAR QUARTZ_wszExtensions[] = + {'E','x','t','e','n','s','i','o','n','s',0}; +const WCHAR QUARTZ_wszSourceFilter[] = + {'S','o','u','r','c','e',' ','F','i','l','t','e','r',0}; -static void QUARTZ_CatPathSepW( WCHAR* pBuf ) { int len = lstrlenW(pBuf); @@ -50,7 +57,6 @@ void QUARTZ_CatPathSepW( WCHAR* pBuf ) 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}" */ @@ -367,4 +373,3 @@ HRESULT QUARTZ_RegisterAMovieFilter( } - diff --git a/dlls/quartz/regsvr.h b/dlls/quartz/regsvr.h index 62b83bd3f42..2b5d771d3cc 100644 --- a/dlls/quartz/regsvr.h +++ b/dlls/quartz/regsvr.h @@ -7,7 +7,7 @@ #ifndef QUARTZ_REGSVR_H #define QUARTZ_REGSVR_H -extern const WCHAR QUARTZ_wszREG_SZ[]; +extern const WCHAR QUARTZ_wszREG_SZ[7]; extern const WCHAR QUARTZ_wszInprocServer32[]; extern const WCHAR QUARTZ_wszThreadingModel[]; extern const WCHAR QUARTZ_wszBoth[]; @@ -16,8 +16,15 @@ extern const WCHAR QUARTZ_wszFilterData[]; extern const WCHAR QUARTZ_wszFriendlyName[]; extern const WCHAR QUARTZ_wszInstance[]; extern const WCHAR QUARTZ_wszMerit[]; +extern const WCHAR QUARTZ_wszMediaType[]; +extern const WCHAR QUARTZ_wszSubType[]; +extern const WCHAR QUARTZ_wszExtensions[]; +extern const WCHAR QUARTZ_wszSourceFilter[]; +void QUARTZ_CatPathSepW( WCHAR* pBuf ); +void QUARTZ_GUIDtoString( WCHAR* pBuf, const GUID* pguid ); + HRESULT QUARTZ_CreateCLSIDPath( WCHAR* pwszBuf, DWORD dwBufLen, const CLSID* pclsid, diff --git a/dlls/quartz/seekpass.c b/dlls/quartz/seekpass.c index 62072ea8f16..98824c2667d 100644 --- a/dlls/quartz/seekpass.c +++ b/dlls/quartz/seekpass.c @@ -352,7 +352,9 @@ IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime) TRACE("(%p)->()\n",This); - return IMediaPosition_get_Duration(pPos,prefTime); + hr = IMediaPosition_get_Duration(pPos,prefTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -363,7 +365,9 @@ IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime) TRACE("(%p)->()\n",This); - return IMediaPosition_put_CurrentPosition(pPos,refTime); + hr = IMediaPosition_put_CurrentPosition(pPos,refTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -374,7 +378,9 @@ IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime) TRACE("(%p)->()\n",This); - return IMediaPosition_get_CurrentPosition(pPos,prefTime); + hr = IMediaPosition_get_CurrentPosition(pPos,prefTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -385,7 +391,9 @@ IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime) TRACE("(%p)->()\n",This); - return IMediaPosition_get_StopTime(pPos,prefTime); + hr = IMediaPosition_get_StopTime(pPos,prefTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -396,7 +404,9 @@ IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime) TRACE("(%p)->()\n",This); - return IMediaPosition_put_StopTime(pPos,refTime); + hr = IMediaPosition_put_StopTime(pPos,refTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -407,7 +417,9 @@ IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime) TRACE("(%p)->()\n",This); - return IMediaPosition_get_PrerollTime(pPos,prefTime); + hr = IMediaPosition_get_PrerollTime(pPos,prefTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -418,7 +430,9 @@ IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime) TRACE("(%p)->()\n",This); - return IMediaPosition_put_PrerollTime(pPos,refTime); + hr = IMediaPosition_put_PrerollTime(pPos,refTime); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -429,7 +443,9 @@ IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate) TRACE("(%p)->()\n",This); - return IMediaPosition_put_Rate(pPos,dblRate); + hr = IMediaPosition_put_Rate(pPos,dblRate); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -440,7 +456,9 @@ IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate) TRACE("(%p)->()\n",This); - return IMediaPosition_get_Rate(pPos,pdblRate); + hr = IMediaPosition_get_Rate(pPos,pdblRate); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -451,7 +469,9 @@ IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek) TRACE("(%p)->()\n",This); - return IMediaPosition_CanSeekForward(pPos,pCanSeek); + hr = IMediaPosition_CanSeekForward(pPos,pCanSeek); + IMediaPosition_Release(pPos); + return hr; } static HRESULT WINAPI @@ -462,7 +482,9 @@ IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek) TRACE("(%p)->()\n",This); - return IMediaPosition_CanSeekBackward(pPos,pCanSeek); + hr = IMediaPosition_CanSeekBackward(pPos,pCanSeek); + IMediaPosition_Release(pPos); + return hr; } @@ -561,7 +583,9 @@ IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetCapabilities(pSeek,pdwCaps); + hr = IMediaSeeking_GetCapabilities(pSeek,pdwCaps); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -572,7 +596,9 @@ IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps) TRACE("(%p)->()\n",This); - return IMediaSeeking_CheckCapabilities(pSeek,pdwCaps); + hr = IMediaSeeking_CheckCapabilities(pSeek,pdwCaps); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -583,7 +609,9 @@ IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat) TRACE("(%p)->()\n",This); - return IMediaSeeking_IsFormatSupported(pSeek,pidFormat); + hr = IMediaSeeking_IsFormatSupported(pSeek,pidFormat); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -594,7 +622,9 @@ IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat) TRACE("(%p)->()\n",This); - return IMediaSeeking_QueryPreferredFormat(pSeek,pidFormat); + hr = IMediaSeeking_QueryPreferredFormat(pSeek,pidFormat); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -605,7 +635,9 @@ IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetTimeFormat(pSeek,pidFormat); + hr = IMediaSeeking_GetTimeFormat(pSeek,pidFormat); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -616,7 +648,9 @@ IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat) TRACE("(%p)->()\n",This); - return IMediaSeeking_IsUsingTimeFormat(pSeek,pidFormat); + hr = IMediaSeeking_IsUsingTimeFormat(pSeek,pidFormat); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -627,7 +661,9 @@ IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat) TRACE("(%p)->()\n",This); - return IMediaSeeking_SetTimeFormat(pSeek,pidFormat); + hr = IMediaSeeking_SetTimeFormat(pSeek,pidFormat); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -638,7 +674,9 @@ IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetDuration(pSeek,pllDuration); + hr = IMediaSeeking_GetDuration(pSeek,pllDuration); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -649,7 +687,9 @@ IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetStopPosition(pSeek,pllPos); + hr = IMediaSeeking_GetStopPosition(pSeek,pllPos); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -660,7 +700,9 @@ IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetCurrentPosition(pSeek,pllPos); + hr = IMediaSeeking_GetCurrentPosition(pSeek,pllPos); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -671,7 +713,9 @@ IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GU TRACE("(%p)->()\n",This); - return IMediaSeeking_ConvertTimeFormat(pSeek,pllOut,pidFmtOut,llIn,pidFmtIn); + hr = IMediaSeeking_ConvertTimeFormat(pSeek,pllOut,pidFmtOut,llIn,pidFmtIn); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -682,7 +726,9 @@ IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFl TRACE("(%p)->()\n",This); - return IMediaSeeking_SetPositions(pSeek,pllCur,dwCurFlags,pllStop,dwStopFlags); + hr = IMediaSeeking_SetPositions(pSeek,pllCur,dwCurFlags,pllStop,dwStopFlags); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -693,7 +739,9 @@ IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pll TRACE("(%p)->()\n",This); - return IMediaSeeking_GetPositions(pSeek,pllCur,pllStop); + hr = IMediaSeeking_GetPositions(pSeek,pllCur,pllStop); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -704,7 +752,9 @@ IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* p TRACE("(%p)->()\n",This); - return IMediaSeeking_GetAvailable(pSeek,pllFirst,pllLast); + hr = IMediaSeeking_GetAvailable(pSeek,pllFirst,pllLast); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -715,7 +765,9 @@ IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate) TRACE("(%p)->()\n",This); - return IMediaSeeking_SetRate(pSeek,dblRate); + hr = IMediaSeeking_SetRate(pSeek,dblRate); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -726,7 +778,9 @@ IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetRate(pSeek,pdblRate); + hr = IMediaSeeking_GetRate(pSeek,pdblRate); + IMediaSeeking_Release(pSeek); + return hr; } static HRESULT WINAPI @@ -737,7 +791,9 @@ IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll) TRACE("(%p)->()\n",This); - return IMediaSeeking_GetPreroll(pSeek,pllPreroll); + hr = IMediaSeeking_GetPreroll(pSeek,pllPreroll); + IMediaSeeking_Release(pSeek); + return hr; } diff --git a/dlls/quartz/vidren.c b/dlls/quartz/vidren.c index dd136aac748..aafcfe5dbcd 100644 --- a/dlls/quartz/vidren.c +++ b/dlls/quartz/vidren.c @@ -187,8 +187,9 @@ static HWND VIDREN_Create( HWND hwndOwner, CVideoRendererImpl* This ) HINSTANCE hInst = (HINSTANCE)GetModuleHandleA(NULL); const VIDEOINFOHEADER* pinfo; DWORD dwExStyle = 0; - DWORD dwStyle = WS_OVERLAPPED|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX; + DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_CLIPCHILDREN; RECT rcWnd; + HWND hwnd; if ( !VIDREN_Register( hInst ) ) return (HWND)NULL; @@ -206,14 +207,18 @@ static HWND VIDREN_Create( HWND hwndOwner, CVideoRendererImpl* This ) TRACE("window width %d,height %d\n", rcWnd.right-rcWnd.left,rcWnd.bottom-rcWnd.top); - return CreateWindowExA( + hwnd = CreateWindowExA( dwExStyle, VIDREN_szWndClass, VIDREN_szWndName, - dwStyle | WS_VISIBLE, + dwStyle, 100,100, /* FIXME */ rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top, hwndOwner, (HMENU)NULL, hInst, (LPVOID)This ); + if ( hwnd != (HWND)NULL ) + ShowWindow(hwnd,SW_SHOW); + + return hwnd; } static DWORD WINAPI VIDREN_ThreadEntry( LPVOID pv ) diff --git a/dlls/quartz/wavparse.c b/dlls/quartz/wavparse.c index 3fd0bb1a0bf..a7706bbfe26 100644 --- a/dlls/quartz/wavparse.c +++ b/dlls/quartz/wavparse.c @@ -284,6 +284,8 @@ static HRESULT CWavParseImpl_InitAU( CParserImpl* pImpl, CWavParseImpl* This ) This->llDataStart = dataofs; This->llBytesTotal = datalen; + TRACE("offset %lu, length %lu\n",dataofs,datalen); + return NOERROR; } @@ -460,7 +462,7 @@ static HRESULT CWavParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStream llAvail = This->llBytesTotal - This->llBytesProcessed; if ( llAvail > (LONGLONG)This->dwBlockSize ) llAvail = (LONGLONG)This->dwBlockSize; - llStart = This->llBytesProcessed; + llStart = This->llDataStart + This->llBytesProcessed; llEnd = llStart + llAvail; This->llBytesProcessed = llEnd; diff --git a/winedefault.reg b/winedefault.reg index 776fde21f0a..1e54ac7ca27 100644 --- a/winedefault.reg +++ b/winedefault.reg @@ -306,6 +306,7 @@ [HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11D0-BD50-00A0C911CE86}\Instance\{083863F1-70DE-11D0-BD40-00A0C911CE86}] "CLSID"="{083863F1-70DE-11D0-BD40-00A0C911CE86}" "FriendlyName"="DirectShow Filters" +"Merit"=dword:00600000 [HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11D0-BD50-00A0C911CE86}\Instance\{33D9A760-90C8-11D0-BD43-00A0C911CE86}] "CLSID"="{33D9A760-90C8-11D0-BD43-00A0C911CE86}" @@ -322,6 +323,7 @@ [HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11D0-BD50-00A0C911CE86}\Instance\{4EFE2452-168A-11D1-BC76-00C04FB9453B}] "CLSID"="{4EFE2452-168A-11D1-BC76-00C04FB9453B}" "FriendlyName"="Midi Renderers" +"Merit"=dword:00600000 [HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11D0-BD50-00A0C911CE86}\Instance\{860BB310-5D01-11D0-BD3B-00A0C911CE86}] "CLSID"="{860BB310-5D01-11D0-BD3B-00A0C911CE86}" @@ -338,20 +340,25 @@ [HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11D0-BD50-00A0C911CE86}\Instance\{E0F158E1-CB04-11D0-BD4E-00A0C911CE86}] "CLSID"="{E0F158E1-CB04-11D0-BD4E-00A0C911CE86}" "FriendlyName"="Audio Renderers" - +"Merit"=dword:00600000 # CLSID_AudioRender +[HKEY_CLASSES_ROOT\CLSID\{e30629d1-27e5-11ce-875d-00608cb78066}] +@="Audio Renderer" [HKEY_CLASSES_ROOT\CLSID\{e30629d1-27e5-11ce-875d-00608cb78066}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" [HKEY_CLASSES_ROOT\CLSID\{E0F158E1-CB04-11D0-BD4E-00A0C911CE86}\Instance\{e30629d1-27e5-11ce-875d-00608cb78066}] "CLSID"="{e30629d1-27e5-11ce-875d-00608cb78066}" +# FriendlyName seems to be the driver name and to be generated dynamically. "FriendlyName"="Waveout audio renderer" # CLSID_VideoRenderer +[HKEY_CLASSES_ROOT\CLSID\{70e102b0-5556-11ce-97c0-00aa0055595a}] +@="Video Renderer" [HKEY_CLASSES_ROOT\CLSID\{70e102b0-5556-11ce-97c0-00aa0055595a}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" @@ -362,6 +369,8 @@ # Wave Parser +[HKEY_CLASSES_ROOT\CLSID\{D51BD5A1-7548-11CF-A520-0080C77EF58A}] +@="Wave Parser" [HKEY_CLASSES_ROOT\CLSID\{D51BD5A1-7548-11CF-A520-0080C77EF58A}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" @@ -370,8 +379,10 @@ "CLSID"="{D51BD5A1-7548-11CF-A520-0080C77EF58A}" "FriendlyName"="Wave Parser" -# CLSID_AVIDec(AVI Decompressor) (not implemented yet) +# CLSID_AVIDec(AVI Decompressor) +[HKEY_CLASSES_ROOT\CLSID\{CF49D4E0-1115-11CE-B03A-0020AF0BA770}] +@="AVI Decompressor" [HKEY_CLASSES_ROOT\CLSID\{CF49D4E0-1115-11CE-B03A-0020AF0BA770}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" @@ -380,28 +391,34 @@ "CLSID"="{CF49D4E0-1115-11CE-B03A-0020AF0BA770}" "FriendlyName"="AVI Decompressor" -# CLSID_AsyncReader (not implemented yet) +# CLSID_AsyncReader +[HKEY_CLASSES_ROOT\CLSID\{E436EBB5-524F-11CE-9F53-0020AF0BA770}] +@="File Source (Async.)" [HKEY_CLASSES_ROOT\CLSID\{E436EBB5-524F-11CE-9F53-0020AF0BA770}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" [HKEY_CLASSES_ROOT\CLSID\{083863F1-70DE-11D0-BD40-00A0C911CE86}\Instance\{E436EBB5-524F-11CE-9F53-0020AF0BA770}] "CLSID"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" -"FriendlyName"="Async Reader" +"FriendlyName"="File Source (Async.)" # CLSID_URLReader (not implemented yet) +[HKEY_CLASSES_ROOT\CLSID\{E436EBB6-524F-11CE-9F53-0020AF0BA770}] +@="File Source (URL)" [HKEY_CLASSES_ROOT\CLSID\{E436EBB6-524F-11CE-9F53-0020AF0BA770}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" [HKEY_CLASSES_ROOT\CLSID\{083863F1-70DE-11D0-BD40-00A0C911CE86}\Instance\{E436EBB6-524F-11CE-9F53-0020AF0BA770}] "CLSID"="{E436EBB6-524F-11CE-9F53-0020AF0BA770}" -"FriendlyName"="URL Reader" +"FriendlyName"="File Source (URL)" -# CLSID_AviSplitter (not implemented yet) +# CLSID_AviSplitter +[HKEY_CLASSES_ROOT\CLSID\{1B544C20-FD0B-11CE-8C63-00AA0044B51E}] +@="AVI Splitter" [HKEY_CLASSES_ROOT\CLSID\{1B544C20-FD0B-11CE-8C63-00AA0044B51E}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" @@ -412,6 +429,8 @@ # CLSID_QuickTimeParser (not implemented yet) +[HKEY_CLASSES_ROOT\CLSID\{D51BD5A0-7548-11CF-A520-0080C77EF58A}] +@="QuickTime Movie Parser" [HKEY_CLASSES_ROOT\CLSID\{D51BD5A0-7548-11CF-A520-0080C77EF58A}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" @@ -420,15 +439,72 @@ "CLSID"="{D51BD5A0-7548-11CF-A520-0080C77EF58A}" "FriendlyName"="QuickTime Movie Parser" -# CLSID_Colour(Color space converter) (not implemented yet) +# CLSID_Colour(Color space converter) +[HKEY_CLASSES_ROOT\CLSID\{1643E180-90F5-11CE-97D5-00AA0055595A}] +@="Color Space Converter" [HKEY_CLASSES_ROOT\CLSID\{1643E180-90F5-11CE-97D5-00AA0055595A}\InprocServer32] @="quartz.dll" "ThreadingModel"="Both" [HKEY_CLASSES_ROOT\CLSID\{083863F1-70DE-11D0-BD40-00A0C911CE86}\Instance\{1643E180-90F5-11CE-97D5-00AA0055595A}] "CLSID"="{1643E180-90F5-11CE-97D5-00AA0055595A}" -"FriendlyName"="Color space converter" +"FriendlyName"="Color Space Converter" + + + +# +# quartz Media Types. +# + +# audio/wav +# RIFF****WAVE +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB8B-524F-11CE-9F53-0020AF0BA770}] +"0"="0,4,,52494646, 8,4,,57415645" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# audio/basic +# .snd +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB8C-524F-11CE-9F53-0020AF0BA770}] +"0"="0,4,,2E736E64" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# audio/aiff +# FORM****AIFF +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB8D-524F-11CE-9F53-0020AF0BA770}] +"0"="0,4,,464F524D, 8,4,,41494646" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# video/x-msvideo +# RIFF****AVI +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB88-524F-11CE-9F53-0020AF0BA770}] +"0"="0,4,,52494646, 8,4,,41564920" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# video/quicktime +# ****mdat / ****moov +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB89-524F-11CE-9F53-0020AF0BA770}] +"0"="4,4,,6D646174" +"1"="4,4,,6D6F6F76" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# video/mpeg (MPEG-1/System) +# 0x00 0x00 0x01 0xba +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB84-524F-11CE-9F53-0020AF0BA770}] +"0"="0,4,,000001BA" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# video/mpeg (MPEG-1/Video) +# 0x00 0x00 0x01 0xb3 +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB86-524F-11CE-9F53-0020AF0BA770}] +"0"="0,4,,000001B3" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}" + +# audio/mpeg +# 12bit 0xFFF + 1bit 0 + 2bit Layer(non-zero) + 1bit flag +[HKEY_CLASSES_ROOT\Media Type\{E436EB83-524F-11CE-9F53-0020AF0BA770}\{E436EB87-524F-11CE-9F53-0020AF0BA770}] +"0"="0,2,FFF8,FFF8" +"Source Filter"="{E436EBB5-524F-11CE-9F53-0020AF0BA770}"