quartz: Implement IAMFilterData interface for IFilterMapper.
This commit is contained in:
parent
1f692cdcaa
commit
2faaa3b8de
|
@ -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, ®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)
|
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
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue