From 2faaa3b8dee030c874d02b065eb40a482447719c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 Apr 2007 08:15:09 -0700 Subject: [PATCH] quartz: Implement IAMFilterData interface for IFilterMapper. --- dlls/quartz/filtermapper.c | 253 +++++++++++++++++++++++++++++-------- 1 file changed, 198 insertions(+), 55 deletions(-) diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index e4c70a7b389..6adce619e12 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -41,21 +41,71 @@ WINE_DEFAULT_DEBUG_CHANNEL(quartz); +/* Unexposed IAMFilterData interface */ +typedef struct IAMFilterData IAMFilterData; + +typedef struct IAMFilterDataVtbl +{ + BEGIN_INTERFACE + + /*** IUnknown methods ***/ + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IAMFilterData *This, + REFIID riid, + void **ppvObject); + + ULONG (STDMETHODCALLTYPE *AddRef)( + IAMFilterData *This); + + ULONG (STDMETHODCALLTYPE *Release)( + IAMFilterData *This); + + /*** IAMFilterData methods ***/ + HRESULT (STDMETHODCALLTYPE *ParseFilterData)( + IAMFilterData *This, + BYTE *pData, + ULONG cb, + BYTE **ppRegFilter2); + + HRESULT (STDMETHODCALLTYPE *CreateFilterData)( + IAMFilterData* This, + REGFILTER2 *prf2, + BYTE **pRegFilterData, + ULONG *pcb); + + END_INTERFACE +} IAMFilterDataVtbl; +struct IAMFilterData +{ + const IAMFilterDataVtbl *lpVtbl; +}; +const GUID IID_IAMFilterData = { + 0x97f7c4d4, 0x547b, 0x4a5f, { 0x83,0x32, 0x53,0x64,0x30,0xad,0x2e,0x4d } +}; + + typedef struct FilterMapper2Impl { const IFilterMapper2Vtbl *lpVtbl; const IFilterMapperVtbl *lpVtblFilterMapper; + const IAMFilterDataVtbl *lpVtblAMFilterData; LONG refCount; } FilterMapper2Impl; static const IFilterMapper2Vtbl fm2vtbl; static const IFilterMapperVtbl fmvtbl; +static const IAMFilterDataVtbl AMFilterDataVtbl; static inline FilterMapper2Impl *impl_from_IFilterMapper( IFilterMapper *iface ) { return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblFilterMapper)); } +static inline FilterMapper2Impl *impl_from_IAMFilterData( IAMFilterData *iface ) +{ + return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblAMFilterData)); +} + static const WCHAR wszClsidSlash[] = {'C','L','S','I','D','\\',0}; static const WCHAR wszSlashInstance[] = {'\\','I','n','s','t','a','n','c','e','\\',0}; static const WCHAR wszSlash[] = {'\\',0}; @@ -171,6 +221,7 @@ HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj) pFM2impl->lpVtbl = &fm2vtbl; pFM2impl->lpVtblFilterMapper = &fmvtbl; + pFM2impl->lpVtblAMFilterData = &AMFilterDataVtbl; pFM2impl->refCount = 1; *ppObj = pFM2impl; @@ -212,6 +263,8 @@ static HRESULT WINAPI FilterMapper2_QueryInterface(IFilterMapper2 * iface, REFII *ppv = iface; else if (IsEqualIID(riid, &IID_IFilterMapper)) *ppv = &This->lpVtblFilterMapper; + else if (IsEqualIID(riid, &IID_IAMFilterData)) + *ppv = &This->lpVtblAMFilterData; if (*ppv != NULL) { @@ -381,16 +434,13 @@ static HRESULT FM2_WriteClsid(IPropertyBag * pPropBag, REFCLSID clsid) return hr; } -static HRESULT FM2_WriteFilterData(IPropertyBag * pPropBag, const REGFILTER2 * prf2) +static HRESULT FM2_WriteFilterData(const REGFILTER2 * prf2, BYTE **ppData, ULONG *pcbData) { - VARIANT var; int size = sizeof(struct REG_RF); unsigned int i; struct Vector mainStore = {NULL, 0, 0}; struct Vector clsidStore = {NULL, 0, 0}; struct REG_RF rrf; - SAFEARRAY * psa; - SAFEARRAYBOUND saBound; HRESULT hr = S_OK; rrf.dwVersion = prf2->dwVersion; @@ -470,70 +520,41 @@ static HRESULT FM2_WriteFilterData(IPropertyBag * pPropBag, const REGFILTER2 * p } } - saBound.lLbound = 0; - saBound.cElements = mainStore.current + clsidStore.current; - psa = SafeArrayCreate(VT_UI1, 1, &saBound); - if (!psa) + if (SUCCEEDED(hr)) { - ERR("Couldn't create SAFEARRAY\n"); - hr = E_FAIL; + *pcbData = mainStore.current + clsidStore.current; + *ppData = CoTaskMemAlloc(*pcbData); + if (!*ppData) + hr = E_OUTOFMEMORY; } if (SUCCEEDED(hr)) { - LPBYTE pbSAData; - hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData); - if (SUCCEEDED(hr)) - { - memcpy(pbSAData, mainStore.pData, mainStore.current); - memcpy(pbSAData + mainStore.current, clsidStore.pData, clsidStore.current); - hr = SafeArrayUnaccessData(psa); - } + memcpy(*ppData, mainStore.pData, mainStore.current); + memcpy((*ppData) + mainStore.current, clsidStore.pData, clsidStore.current); } - V_VT(&var) = VT_ARRAY | VT_UI1; - V_UNION(&var, parray) = psa; - - if (SUCCEEDED(hr)) - hr = IPropertyBag_Write(pPropBag, wszFilterDataName, &var); - - if (psa) - SafeArrayDestroy(psa); - delete_vector(&mainStore); delete_vector(&clsidStore); return hr; } -static HRESULT FM2_ReadFilterData(IPropertyBag * pPropBag, REGFILTER2 * prf2) +static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 * prf2) { - VARIANT var; - HRESULT hr; - LPBYTE pData = NULL; + HRESULT hr = S_OK; struct REG_RF * prrf; LPBYTE pCurrent; DWORD i; REGFILTERPINS2 * rgPins2; - VariantInit(&var); - V_VT(&var) = VT_ARRAY | VT_UI1; + prrf = (struct REG_RF *)pData; + pCurrent = pData; - hr = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL); - - if (SUCCEEDED(hr)) - hr = SafeArrayAccessData(V_UNION(&var, parray), (LPVOID*)&pData); - - if (SUCCEEDED(hr)) + if (prrf->dwVersion != 2) { - prrf = (struct REG_RF *)pData; - pCurrent = pData; - - if (prrf->dwVersion != 2) - { - FIXME("Filter registry version %d not supported\n", prrf->dwVersion); - ZeroMemory(prf2, sizeof(*prf2)); - hr = E_FAIL; - } + FIXME("Filter registry version %d not supported\n", prrf->dwVersion); + ZeroMemory(prf2, sizeof(*prf2)); + hr = E_FAIL; } if (SUCCEEDED(hr)) @@ -621,11 +642,6 @@ static HRESULT FM2_ReadFilterData(IPropertyBag * pPropBag, REGFILTER2 * prf2) } - if (pData) - SafeArrayUnaccessData(V_UNION(&var, parray)); - - VariantClear(&var); - return hr; } @@ -789,7 +805,48 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter( hr = FM2_WriteClsid(pPropBag, clsidFilter); if (SUCCEEDED(hr)) - hr = FM2_WriteFilterData(pPropBag, ®filter2); + { + BYTE *pData; + ULONG cbData; + + hr = FM2_WriteFilterData(®filter2, &pData, &cbData); + if (SUCCEEDED(hr)) + { + VARIANT var; + SAFEARRAY *psa; + SAFEARRAYBOUND saBound; + + saBound.lLbound = 0; + saBound.cElements = cbData; + psa = SafeArrayCreate(VT_UI1, 1, &saBound); + if (!psa) + { + ERR("Couldn't create SAFEARRAY\n"); + hr = E_FAIL; + } + + if (SUCCEEDED(hr)) + { + LPBYTE pbSAData; + hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData); + if (SUCCEEDED(hr)) + { + memcpy(pbSAData, pData, cbData); + hr = SafeArrayUnaccessData(psa); + } + } + + V_VT(&var) = VT_ARRAY | VT_UI1; + V_UNION(&var, parray) = psa; + + if (SUCCEEDED(hr)) + hr = IPropertyBag_Write(pPropBag, wszFilterDataName, &var); + + if (psa) + SafeArrayDestroy(psa); + CoTaskMemFree(pData); + } + } if (pPropBag) IPropertyBag_Release(pPropBag); @@ -953,12 +1010,15 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK) { IPropertyBag * pPropBag = NULL; + VARIANT var; + BYTE *pData = NULL; REGFILTER2 rf2; DWORD i; BOOL bInputMatch = !bInputNeeded; BOOL bOutputMatch = !bOutputNeeded; ZeroMemory(&rf2, sizeof(rf2)); + VariantInit(&var); hrSub = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBag); @@ -972,7 +1032,21 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters( } if (SUCCEEDED(hrSub)) - hrSub = FM2_ReadFilterData(pPropBag, &rf2); + { + V_VT(&var) = VT_ARRAY | VT_UI1; + hrSub = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL); + } + + if (SUCCEEDED(hrSub)) + hrSub = SafeArrayAccessData(V_UNION(&var, parray), (LPVOID*)&pData); + + if (SUCCEEDED(hrSub)) + hrSub = FM2_ReadFilterData(pData, &rf2); + + if (pData) + SafeArrayUnaccessData(V_UNION(&var, parray)); + + VariantClear(&var); /* Logic used for bInputMatch expression: * There exists some pin such that bInputNeeded implies (pin is an input and @@ -1568,3 +1642,72 @@ static const IFilterMapperVtbl fmvtbl = FilterMapper_UnregisterPin, FilterMapper_EnumMatchingFilters }; + + +/*** IUnknown methods ***/ +static HRESULT WINAPI AMFilterData_QueryInterface(IAMFilterData * iface, REFIID riid, LPVOID *ppv) +{ + FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + + return FilterMapper2_QueryInterface((IFilterMapper2*)This, riid, ppv); +} + +static ULONG WINAPI AMFilterData_AddRef(IAMFilterData * iface) +{ + FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + + return FilterMapper2_AddRef((IFilterMapper2*)This); +} + +static ULONG WINAPI AMFilterData_Release(IAMFilterData * iface) +{ + FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + + return FilterMapper2_Release((IFilterMapper2*)This); +} + +/*** IAMFilterData methods ***/ +static HRESULT WINAPI AMFilterData_ParseFilterData(IAMFilterData* iface, + BYTE *pData, ULONG cb, + BYTE **ppRegFilter2) +{ + FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + HRESULT hr = S_OK; + REGFILTER2 *prf2; + + TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pData, cb, ppRegFilter2); + + prf2 = CoTaskMemAlloc(sizeof(*prf2)); + if (!prf2) + return E_OUTOFMEMORY; + *ppRegFilter2 = (BYTE *)&prf2; + + hr = FM2_ReadFilterData(pData, prf2); + if (FAILED(hr)) + { + CoTaskMemFree(prf2); + *ppRegFilter2 = NULL; + } + + return hr; +} + +static HRESULT WINAPI AMFilterData_CreateFilterData(IAMFilterData* iface, + REGFILTER2 *prf2, + BYTE **pRegFilterData, + ULONG *pcb) +{ + FilterMapper2Impl *This = impl_from_IAMFilterData(iface); + + TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, prf2, pRegFilterData, pcb); + + return FM2_WriteFilterData(prf2, pRegFilterData, pcb); +} + +static const IAMFilterDataVtbl AMFilterDataVtbl = { + AMFilterData_QueryInterface, + AMFilterData_AddRef, + AMFilterData_Release, + AMFilterData_ParseFilterData, + AMFilterData_CreateFilterData +};