quartz: Implement IAMFilterData interface for IFilterMapper.
This commit is contained in:
parent
1f692cdcaa
commit
2faaa3b8de
|
@ -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,61 +520,33 @@ 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;
|
||||
|
||||
hr = IPropertyBag_Read(pPropBag, wszFilterDataName, &var, NULL);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hr = SafeArrayAccessData(V_UNION(&var, parray), (LPVOID*)&pData);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
prrf = (struct REG_RF *)pData;
|
||||
pCurrent = pData;
|
||||
|
||||
|
@ -534,7 +556,6 @@ static HRESULT FM2_ReadFilterData(IPropertyBag * pPropBag, REGFILTER2 * prf2)
|
|||
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, ®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)
|
||||
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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue