quartz: Implement IAMFilterData for IFilterMapper

Chris Robinson chris.kcat at gmail.com
Mon Apr 9 18:23:06 CDT 2007


-------------- next part --------------
From a6b43517b4ed552aa59b01893ba5d777c63cbc58 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat at gmail.com>
Date: Mon, 9 Apr 2007 12:55:32 -0700
Subject: [PATCH] quartz: Implement IAMFilterData for IFilterMapper

---
 dlls/quartz/filtermapper.c |  302 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 302 insertions(+), 0 deletions(-)

diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c
index e4c70a7..c3078c8 100644
--- a/dlls/quartz/filtermapper.c
+++ b/dlls/quartz/filtermapper.c
@@ -41,21 +41,70 @@
 
 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);
+
+    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 +220,7 @@ HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj)
 
     pFM2impl->lpVtbl = &fm2vtbl;
     pFM2impl->lpVtblFilterMapper = &fmvtbl;
+    pFM2impl->lpVtblAMFilterData = &AMFilterDataVtbl;
     pFM2impl->refCount = 1;
 
     *ppObj = pFM2impl;
@@ -212,6 +262,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)
     {
@@ -1568,3 +1620,253 @@ 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;
+    struct REG_RF * prrf;
+    LPBYTE pCurrent;
+    DWORD i;
+    REGFILTERPINS2 * rgPins2;
+    REGFILTER2 *prf2;
+
+    TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pData, cb, ppRegFilter2);
+
+    prf2 = CoTaskMemAlloc(sizeof(*prf2));
+    *ppRegFilter2 = (BYTE *)&prf2;
+
+    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;
+    }
+
+    if (SUCCEEDED(hr))
+    {
+        TRACE("version = %d, merit = %x, #pins = %d, unused = %x\n",
+            prrf->dwVersion, prrf->dwMerit, prrf->dwPins, prrf->dwUnused);
+
+        prf2->dwVersion = prrf->dwVersion;
+        prf2->dwMerit = prrf->dwMerit;
+        prf2->u.s1.cPins2 = prrf->dwPins;
+        rgPins2 = CoTaskMemAlloc(prrf->dwPins * sizeof(*rgPins2));
+        prf2->u.s1.rgPins2 = rgPins2;
+        pCurrent += sizeof(struct REG_RF);
+
+        for (i = 0; i < prrf->dwPins; i++)
+        {
+            struct REG_RFP * prrfp = (struct REG_RFP *)pCurrent;
+            REGPINTYPES * lpMediaType;
+            REGPINMEDIUM * lpMedium;
+            UINT j;
+
+            /* FIXME: check signature */
+
+            TRACE("\tsignature = %s\n", debugstr_an((const char*)prrfp->signature, 4));
+
+            TRACE("\tpin[%d]: flags = %x, instances = %d, media types = %d, mediums = %d\n",
+                i, prrfp->dwFlags, prrfp->dwInstances, prrfp->dwMediaTypes, prrfp->dwMediums);
+
+            rgPins2[i].dwFlags = prrfp->dwFlags;
+            rgPins2[i].cInstances = prrfp->dwInstances;
+            rgPins2[i].nMediaTypes = prrfp->dwMediaTypes;
+            rgPins2[i].nMediums = prrfp->dwMediums;
+            pCurrent += sizeof(struct REG_RFP);
+            if (prrfp->bCategory)
+            {
+                CLSID * clsCat = CoTaskMemAlloc(sizeof(CLSID));
+                memcpy(clsCat, pData + *(DWORD*)(pCurrent), sizeof(CLSID));
+                pCurrent += sizeof(DWORD);
+                rgPins2[i].clsPinCategory = clsCat;
+            }
+            else
+                rgPins2[i].clsPinCategory = NULL;
+
+            if (rgPins2[i].nMediaTypes > 0)
+                lpMediaType = CoTaskMemAlloc(rgPins2[i].nMediaTypes * sizeof(*lpMediaType));
+            else
+                lpMediaType = NULL;
+
+            rgPins2[i].lpMediaType = lpMediaType;
+
+            for (j = 0; j < rgPins2[i].nMediaTypes; j++)
+            {
+                struct REG_TYPE * prt = (struct REG_TYPE *)pCurrent;
+                CLSID * clsMajor = CoTaskMemAlloc(sizeof(CLSID));
+                CLSID * clsMinor = CoTaskMemAlloc(sizeof(CLSID));
+
+                /* FIXME: check signature */
+                TRACE("\t\tsignature = %s\n", debugstr_an((const char*)prt->signature, 4));
+
+                memcpy(clsMajor, pData + prt->dwOffsetMajor, sizeof(CLSID));
+                memcpy(clsMinor, pData + prt->dwOffsetMinor, sizeof(CLSID));
+
+                lpMediaType[j].clsMajorType = clsMajor;
+                lpMediaType[j].clsMinorType = clsMinor;
+
+                pCurrent += sizeof(*prt);
+            }
+
+            if (rgPins2[i].nMediums > 0)
+                lpMedium = CoTaskMemAlloc(rgPins2[i].nMediums * sizeof(*lpMedium));
+            else
+                lpMedium = NULL;
+
+            rgPins2[i].lpMedium = lpMedium;
+
+            for (j = 0; j < rgPins2[i].nMediums; j++)
+            {
+                DWORD dwOffset = *(DWORD *)pCurrent;
+
+                memcpy(lpMedium + j, pData + dwOffset, sizeof(REGPINMEDIUM));
+
+                pCurrent += sizeof(dwOffset);
+            }
+        }
+    }
+
+    return hr;
+}
+
+static HRESULT WINAPI AMFilterData_CreateFilterData(IAMFilterData* iface,
+                          REGFILTER2 *prf2, BYTE **pRegFilterData, ULONG *pcb)
+{
+    FilterMapper2Impl *This = impl_from_IAMFilterData(iface);
+    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;
+
+    TRACE("(%p/%p)->(%p, %p, %p)\n", This, iface, prf2, pRegFilterData, pcb);
+
+    if (prf2->dwVersion != 2)
+    {
+        FIXME("Filter registry version %d not supported\n", prf2->dwVersion);
+        ZeroMemory(prf2, sizeof(*prf2));
+        return E_FAIL;
+    }
+
+    rrf.dwVersion = prf2->dwVersion;
+    rrf.dwMerit = prf2->dwMerit;
+    rrf.dwPins = prf2->u.s1.cPins2;
+    rrf.dwUnused = 0;
+
+    add_data(&mainStore, (LPBYTE)&rrf, sizeof(rrf));
+
+    for (i = 0; i < prf2->u.s1.cPins2; i++)
+    {
+        size += sizeof(struct REG_RFP);
+        if (prf2->u.s1.rgPins2[i].clsPinCategory)
+            size += sizeof(DWORD);
+        size += prf2->u.s1.rgPins2[i].nMediaTypes * sizeof(struct REG_TYPE);
+        size += prf2->u.s1.rgPins2[i].nMediums * sizeof(DWORD);
+    }
+
+    for (i = 0; i < prf2->u.s1.cPins2; i++)
+    {
+        struct REG_RFP rrfp;
+        REGFILTERPINS2 rgPin2 = prf2->u.s1.rgPins2[i];
+        unsigned int j;
+
+        rrfp.signature[0] = '0';
+        rrfp.signature[1] = 'p';
+        rrfp.signature[2] = 'i';
+        rrfp.signature[3] = '3';
+        rrfp.signature[0] += i;
+        rrfp.dwFlags = rgPin2.dwFlags;
+        rrfp.dwInstances = rgPin2.cInstances;
+        rrfp.dwMediaTypes = rgPin2.nMediaTypes;
+        rrfp.dwMediums = rgPin2.nMediums;
+        rrfp.bCategory = rgPin2.clsPinCategory ? 1 : 0;
+
+        add_data(&mainStore, (LPBYTE)&rrfp, sizeof(rrfp));
+        if (rrfp.bCategory)
+        {
+            DWORD index = find_data(&clsidStore, (const BYTE*)rgPin2.clsPinCategory, sizeof(CLSID));
+            if (index == -1)
+                index = add_data(&clsidStore, (const BYTE*)rgPin2.clsPinCategory, sizeof(CLSID));
+            index += size;
+
+            add_data(&mainStore, (LPBYTE)&index, sizeof(index));
+        }
+
+        for (j = 0; j < rgPin2.nMediaTypes; j++)
+        {
+            struct REG_TYPE rt;
+            rt.signature[0] = '0';
+            rt.signature[1] = 't';
+            rt.signature[2] = 'y';
+            rt.signature[3] = '3';
+            rt.signature[0] += j;
+
+            rt.dwUnused = 0;
+            rt.dwOffsetMajor = find_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMajorType, sizeof(CLSID));
+            if (rt.dwOffsetMajor == -1)
+                rt.dwOffsetMajor = add_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMajorType, sizeof(CLSID));
+            rt.dwOffsetMajor += size;
+            rt.dwOffsetMinor = find_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMinorType, sizeof(CLSID));
+            if (rt.dwOffsetMinor == -1)
+                rt.dwOffsetMinor = add_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMinorType, sizeof(CLSID));
+            rt.dwOffsetMinor += size;
+
+            add_data(&mainStore, (LPBYTE)&rt, sizeof(rt));
+        }
+
+        for (j = 0; j < rgPin2.nMediums; j++)
+        {
+            DWORD index = find_data(&clsidStore, (const BYTE*)(rgPin2.lpMedium + j), sizeof(REGPINMEDIUM));
+            if (index == -1)
+                index = add_data(&clsidStore, (const BYTE*)(rgPin2.lpMedium + j), sizeof(REGPINMEDIUM));
+            index += size;
+
+            add_data(&mainStore, (LPBYTE)&index, sizeof(index));
+        }
+    }
+
+    *pcb = mainStore.current;
+    *pRegFilterData = CoTaskMemAlloc(mainStore.current);
+    memcpy(*pRegFilterData, mainStore.pData, mainStore.current);
+
+    delete_vector(&mainStore);
+    delete_vector(&clsidStore);
+    return S_OK;
+}
+
+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