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