quartz: Implement IAMFilterData interface for IFilterMapper.

This commit is contained in:
Chris Robinson 2007-04-10 08:15:09 -07:00 committed by Alexandre Julliard
parent 1f692cdcaa
commit 2faaa3b8de
1 changed files with 198 additions and 55 deletions

View File

@ -41,21 +41,71 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz); 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 typedef struct FilterMapper2Impl
{ {
const IFilterMapper2Vtbl *lpVtbl; const IFilterMapper2Vtbl *lpVtbl;
const IFilterMapperVtbl *lpVtblFilterMapper; const IFilterMapperVtbl *lpVtblFilterMapper;
const IAMFilterDataVtbl *lpVtblAMFilterData;
LONG refCount; LONG refCount;
} FilterMapper2Impl; } FilterMapper2Impl;
static const IFilterMapper2Vtbl fm2vtbl; static const IFilterMapper2Vtbl fm2vtbl;
static const IFilterMapperVtbl fmvtbl; static const IFilterMapperVtbl fmvtbl;
static const IAMFilterDataVtbl AMFilterDataVtbl;
static inline FilterMapper2Impl *impl_from_IFilterMapper( IFilterMapper *iface ) static inline FilterMapper2Impl *impl_from_IFilterMapper( IFilterMapper *iface )
{ {
return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblFilterMapper)); 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 wszClsidSlash[] = {'C','L','S','I','D','\\',0};
static const WCHAR wszSlashInstance[] = {'\\','I','n','s','t','a','n','c','e','\\',0}; static const WCHAR wszSlashInstance[] = {'\\','I','n','s','t','a','n','c','e','\\',0};
static const WCHAR wszSlash[] = {'\\',0}; static const WCHAR wszSlash[] = {'\\',0};
@ -171,6 +221,7 @@ HRESULT FilterMapper2_create(IUnknown *pUnkOuter, LPVOID *ppObj)
pFM2impl->lpVtbl = &fm2vtbl; pFM2impl->lpVtbl = &fm2vtbl;
pFM2impl->lpVtblFilterMapper = &fmvtbl; pFM2impl->lpVtblFilterMapper = &fmvtbl;
pFM2impl->lpVtblAMFilterData = &AMFilterDataVtbl;
pFM2impl->refCount = 1; pFM2impl->refCount = 1;
*ppObj = pFM2impl; *ppObj = pFM2impl;
@ -212,6 +263,8 @@ static HRESULT WINAPI FilterMapper2_QueryInterface(IFilterMapper2 * iface, REFII
*ppv = iface; *ppv = iface;
else if (IsEqualIID(riid, &IID_IFilterMapper)) else if (IsEqualIID(riid, &IID_IFilterMapper))
*ppv = &This->lpVtblFilterMapper; *ppv = &This->lpVtblFilterMapper;
else if (IsEqualIID(riid, &IID_IAMFilterData))
*ppv = &This->lpVtblAMFilterData;
if (*ppv != NULL) if (*ppv != NULL)
{ {
@ -381,16 +434,13 @@ static HRESULT FM2_WriteClsid(IPropertyBag * pPropBag, REFCLSID clsid)
return hr; 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); int size = sizeof(struct REG_RF);
unsigned int i; unsigned int i;
struct Vector mainStore = {NULL, 0, 0}; struct Vector mainStore = {NULL, 0, 0};
struct Vector clsidStore = {NULL, 0, 0}; struct Vector clsidStore = {NULL, 0, 0};
struct REG_RF rrf; struct REG_RF rrf;
SAFEARRAY * psa;
SAFEARRAYBOUND saBound;
HRESULT hr = S_OK; HRESULT hr = S_OK;
rrf.dwVersion = prf2->dwVersion; rrf.dwVersion = prf2->dwVersion;
@ -470,70 +520,41 @@ static HRESULT FM2_WriteFilterData(IPropertyBag * pPropBag, const REGFILTER2 * p
} }
} }
saBound.lLbound = 0; if (SUCCEEDED(hr))
saBound.cElements = mainStore.current + clsidStore.current;
psa = SafeArrayCreate(VT_UI1, 1, &saBound);
if (!psa)
{ {
ERR("Couldn't create SAFEARRAY\n"); *pcbData = mainStore.current + clsidStore.current;
hr = E_FAIL; *ppData = CoTaskMemAlloc(*pcbData);
if (!*ppData)
hr = E_OUTOFMEMORY;
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
LPBYTE pbSAData; memcpy(*ppData, mainStore.pData, mainStore.current);
hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData); memcpy((*ppData) + mainStore.current, clsidStore.pData, clsidStore.current);
if (SUCCEEDED(hr))
{
memcpy(pbSAData, mainStore.pData, mainStore.current);
memcpy(pbSAData + mainStore.current, clsidStore.pData, clsidStore.current);
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);
delete_vector(&mainStore); delete_vector(&mainStore);
delete_vector(&clsidStore); delete_vector(&clsidStore);
return hr; return hr;
} }
static HRESULT FM2_ReadFilterData(IPropertyBag * pPropBag, REGFILTER2 * prf2) static HRESULT FM2_ReadFilterData(BYTE *pData, REGFILTER2 * prf2)
{ {
VARIANT var; HRESULT hr = S_OK;
HRESULT hr;
LPBYTE pData = NULL;
struct REG_RF * prrf; struct REG_RF * prrf;
LPBYTE pCurrent; LPBYTE pCurrent;
DWORD i; DWORD i;
REGFILTERPINS2 * rgPins2; REGFILTERPINS2 * rgPins2;
VariantInit(&var); prrf = (struct REG_RF *)pData;
V_VT(&var) = VT_ARRAY | VT_UI1; pCurrent = pData;
hr = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL); if (prrf->dwVersion != 2)
if (SUCCEEDED(hr))
hr = SafeArrayAccessData(V_UNION(&var, parray), (LPVOID*)&pData);
if (SUCCEEDED(hr))
{ {
prrf = (struct REG_RF *)pData; FIXME("Filter registry version %d not supported\n", prrf->dwVersion);
pCurrent = pData; ZeroMemory(prf2, sizeof(*prf2));
hr = E_FAIL;
if (prrf->dwVersion != 2)
{
FIXME("Filter registry version %d not supported\n", prrf->dwVersion);
ZeroMemory(prf2, sizeof(*prf2));
hr = E_FAIL;
}
} }
if (SUCCEEDED(hr)) 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; return hr;
} }
@ -789,7 +805,48 @@ static HRESULT WINAPI FilterMapper2_RegisterFilter(
hr = FM2_WriteClsid(pPropBag, clsidFilter); hr = FM2_WriteClsid(pPropBag, clsidFilter);
if (SUCCEEDED(hr)) 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) if (pPropBag)
IPropertyBag_Release(pPropBag); IPropertyBag_Release(pPropBag);
@ -953,12 +1010,15 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters(
while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK) while (IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL) == S_OK)
{ {
IPropertyBag * pPropBag = NULL; IPropertyBag * pPropBag = NULL;
VARIANT var;
BYTE *pData = NULL;
REGFILTER2 rf2; REGFILTER2 rf2;
DWORD i; DWORD i;
BOOL bInputMatch = !bInputNeeded; BOOL bInputMatch = !bInputNeeded;
BOOL bOutputMatch = !bOutputNeeded; BOOL bOutputMatch = !bOutputNeeded;
ZeroMemory(&rf2, sizeof(rf2)); ZeroMemory(&rf2, sizeof(rf2));
VariantInit(&var);
hrSub = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBag); hrSub = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBag);
@ -972,7 +1032,21 @@ static HRESULT WINAPI FilterMapper2_EnumMatchingFilters(
} }
if (SUCCEEDED(hrSub)) 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: /* Logic used for bInputMatch expression:
* There exists some pin such that bInputNeeded implies (pin is an input and * There exists some pin such that bInputNeeded implies (pin is an input and
@ -1568,3 +1642,72 @@ static const IFilterMapperVtbl fmvtbl =
FilterMapper_UnregisterPin, FilterMapper_UnregisterPin,
FilterMapper_EnumMatchingFilters 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
};