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, &regfilter2);
+    {
+        BYTE *pData;
+        ULONG cbData;
+
+        hr = FM2_WriteFilterData(&regfilter2, &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