quartz: Implement IAMFilterData interface for IFilterMapper [try 2]
Chris Robinson
chris.kcat at gmail.com
Tue Apr 10 10:18:38 CDT 2007
Now with less code duplication
-------------- next part --------------
From be0dd91c3cb30098648d3b39bb500f9114c31702 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat at gmail.com>
Date: Tue, 10 Apr 2007 08:15:09 -0700
Subject: [PATCH] quartz: Implement IAMFilterData interface for IFilterMapper
---
dlls/quartz/filtermapper.c | 253 ++++++++++++++++++++++++++++++++++----------
1 files changed, 198 insertions(+), 55 deletions(-)
diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c
index e4c70a7..6adce61 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
+};
--
1.4.4.4
More information about the wine-patches
mailing list