{
const IAMFilterDataVtbl *lpVtbl;
};
-const GUID IID_IAMFilterData = {
+static const GUID IID_IAMFilterData = {
0x97f7c4d4, 0x547b, 0x4a5f, { 0x83,0x32, 0x53,0x64,0x30,0xad,0x2e,0x4d }
};
const IFilterMapper2Vtbl *lpVtbl;
const IFilterMapperVtbl *lpVtblFilterMapper;
const IAMFilterDataVtbl *lpVtblAMFilterData;
+ const IUnknownVtbl *IInner_vtbl;
LONG refCount;
+ IUnknown * pUnkOuter;
+ BOOL bUnkOuterValid;
+ BOOL bAggregatable;
} FilterMapper2Impl;
+static const IUnknownVtbl IInner_VTable;
static const IFilterMapper2Vtbl fm2vtbl;
static const IFilterMapperVtbl fmvtbl;
static const IAMFilterDataVtbl AMFilterDataVtbl;
return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, lpVtblAMFilterData));
}
+static inline FilterMapper2Impl *impl_from_inner_IUnknown( IUnknown *iface )
+{
+ return (FilterMapper2Impl *)((char*)iface - FIELD_OFFSET(FilterMapper2Impl, IInner_vtbl));
+}
+
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};
TRACE("(%p, %p)\n", pUnkOuter, ppObj);
- if (pUnkOuter)
- return CLASS_E_NOAGGREGATION;
-
pFM2impl = CoTaskMemAlloc(sizeof(*pFM2impl));
if (!pFM2impl)
return E_OUTOFMEMORY;
+ pFM2impl->pUnkOuter = pUnkOuter;
+ pFM2impl->bUnkOuterValid = FALSE;
+ pFM2impl->bAggregatable = FALSE;
+ pFM2impl->IInner_vtbl = &IInner_VTable;
pFM2impl->lpVtbl = &fm2vtbl;
pFM2impl->lpVtblFilterMapper = &fmvtbl;
pFM2impl->lpVtblAMFilterData = &AMFilterDataVtbl;
return hr;
}
-/*** IUnknown methods ***/
+/*** IUnknown (inner) methods ***/
-static HRESULT WINAPI FilterMapper2_QueryInterface(IFilterMapper2 * iface, REFIID riid, LPVOID *ppv)
+static HRESULT WINAPI Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
{
- FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
-
+ FilterMapper2Impl *This = impl_from_inner_IUnknown(iface);
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
+ if (This->bAggregatable)
+ This->bUnkOuterValid = TRUE;
+
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
+ *ppv = &This->IInner_vtbl;
else if (IsEqualIID(riid, &IID_IFilterMapper2))
- *ppv = iface;
+ *ppv = This;
else if (IsEqualIID(riid, &IID_IFilterMapper))
*ppv = &This->lpVtblFilterMapper;
else if (IsEqualIID(riid, &IID_IAMFilterData))
return E_NOINTERFACE;
}
-static ULONG WINAPI FilterMapper2_AddRef(IFilterMapper2 * iface)
+static ULONG WINAPI Inner_AddRef(IUnknown * iface)
{
- FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
+ FilterMapper2Impl *This = impl_from_inner_IUnknown(iface);
ULONG refCount = InterlockedIncrement(&This->refCount);
TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
return refCount;
}
-static ULONG WINAPI FilterMapper2_Release(IFilterMapper2 * iface)
+static ULONG WINAPI Inner_Release(IUnknown * iface)
{
- FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
+ FilterMapper2Impl *This = impl_from_inner_IUnknown(iface);
ULONG refCount = InterlockedDecrement(&This->refCount);
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
return refCount;
}
+static const IUnknownVtbl IInner_VTable =
+{
+ Inner_QueryInterface,
+ Inner_AddRef,
+ Inner_Release
+};
+
+static HRESULT WINAPI FilterMapper2_QueryInterface(IFilterMapper2 * iface, REFIID riid, LPVOID *ppv)
+{
+ FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
+
+ if (This->bAggregatable)
+ This->bUnkOuterValid = TRUE;
+
+ if (This->pUnkOuter)
+ {
+ if (This->bAggregatable)
+ return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv);
+
+ if (IsEqualIID(riid, &IID_IUnknown))
+ {
+ HRESULT hr;
+
+ IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
+ hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
+ IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
+ This->bAggregatable = TRUE;
+ return hr;
+ }
+
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv);
+}
+
+static ULONG WINAPI FilterMapper2_AddRef(IFilterMapper2 * iface)
+{
+ FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
+
+ if (This->pUnkOuter && This->bUnkOuterValid)
+ return IUnknown_AddRef(This->pUnkOuter);
+ return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
+}
+
+static ULONG WINAPI FilterMapper2_Release(IFilterMapper2 * iface)
+{
+ FilterMapper2Impl *This = (FilterMapper2Impl *)iface;
+
+ if (This->pUnkOuter && This->bUnkOuterValid)
+ return IUnknown_Release(This->pUnkOuter);
+ return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
+}
+
/*** IFilterMapper2 methods ***/
static HRESULT WINAPI FilterMapper2_CreateCategory(
for (j = 0; j < rgPin2.nMediaTypes; j++)
{
struct REG_TYPE rt;
+ const CLSID * clsMinorType = rgPin2.lpMediaType[j].clsMinorType ? rgPin2.lpMediaType[j].clsMinorType : &MEDIASUBTYPE_NULL;
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));
+ rt.dwOffsetMinor = find_data(&clsidStore, (const BYTE*)clsMinorType, sizeof(CLSID));
if (rt.dwOffsetMinor == -1)
- rt.dwOffsetMinor = add_data(&clsidStore, (const BYTE*)rgPin2.lpMediaType[j].clsMinorType, sizeof(CLSID));
+ rt.dwOffsetMinor = add_data(&clsidStore, (const BYTE*)clsMinorType, sizeof(CLSID));
rt.dwOffsetMinor += size;
add_data(&mainStore, (LPBYTE)&rt, sizeof(rt));
/* internal helper function for qsort of MONIKER_MERIT array */
static int mm_compare(const void * left, const void * right)
{
- const struct MONIKER_MERIT * mmLeft = (const struct MONIKER_MERIT *)left;
- const struct MONIKER_MERIT * mmRight = (const struct MONIKER_MERIT *)right;
+ const struct MONIKER_MERIT * mmLeft = left;
+ const struct MONIKER_MERIT * mmRight = right;
if (mmLeft->dwMerit == mmRight->dwMerit)
return 0;
OutputType[0] = clsOutMaj;
OutputType[1] = clsOutSub;
+ *ppEnum = NULL;
+
hr = IFilterMapper2_EnumMatchingFilters((IFilterMapper2*)This,
&ppEnumMoniker,
0,
NULL,
&GUID_NULL);
- if (!SUCCEEDED(hr))
+ if (FAILED(hr))
return hr;
while(IEnumMoniker_Next(ppEnumMoniker, 1, &IMon, &nb) == S_OK)
nb_mon++;
}
- *ppEnum = NULL;
if (!nb_mon)
{
IEnumMoniker_Release(ppEnumMoniker);
IEnumMoniker_Release(ppEnumMoniker);
return E_OUTOFMEMORY;
}
+ ZeroMemory(regfilters, nb_mon * sizeof(REGFILTER)); /* will prevent bad free of Name in case of error. */
IEnumMoniker_Reset(ppEnumMoniker);
while(IEnumMoniker_Next(ppEnumMoniker, 1, &IMon, &nb) == S_OK)
if (SUCCEEDED(hrSub))
{
- len = (strlenW((WCHAR*)V_UNION(&var, bstrVal))+1) * sizeof(WCHAR);
+ len = (strlenW(V_UNION(&var, bstrVal))+1) * sizeof(WCHAR);
if (!(regfilters[idx].Name = CoTaskMemAlloc(len*2)))
hr = E_OUTOFMEMORY;
}
- if (SUCCEEDED(hrSub))
+ if (SUCCEEDED(hrSub) && regfilters[idx].Name)
{
memcpy(regfilters[idx].Name, V_UNION(&var, bstrVal), len);
regfilters[idx].Clsid = clsid;
VariantClear(&var);
}
- /* In case of release all resources */
- if (!SUCCEEDED(hr))
+ if (SUCCEEDED(hr))
{
- for (idx = 0; idx < nb_mon; idx++)
- CoTaskMemFree(regfilters[idx].Name);
- CoTaskMemFree(regfilters);
- IEnumMoniker_Release(ppEnumMoniker);
- return hr;
+ hr = IEnumRegFiltersImpl_Construct(regfilters, nb_mon, ppEnum);
}
- hr = IEnumRegFiltersImpl_Construct(regfilters, nb_mon, ppEnum);
+ for (idx = 0; idx < nb_mon; idx++)
+ CoTaskMemFree(regfilters[idx].Name);
CoTaskMemFree(regfilters);
IEnumMoniker_Release(ppEnumMoniker);
LPWSTR wszClsid = NULL;
HKEY hKey;
LONG lRet;
- WCHAR wszKeyName[strlenW(wszFilterSlash) + (CHARS_IN_GUID-1) + 1];
+ WCHAR wszKeyName[ARRAYSIZE(wszFilterSlash)-1 + (CHARS_IN_GUID-1) + 1];
TRACE("(%p)->(%s, %s, %x)\n", iface, debugstr_guid(&clsid), debugstr_w(szName), dwMerit);
CloseHandle(hKey);
}
+ CoTaskMemFree(wszClsid);
+
return hr;
}
HKEY hKey = NULL;
HKEY hPinsKey = NULL;
WCHAR * wszPinsKeyName;
- WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];
+ WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + (CHARS_IN_GUID-1) + 1];
TRACE("(%p)->(%s, %s, %d, %d, %d, %d, %s, %s)\n", iface, debugstr_guid(&Filter), debugstr_w(szName), bRendered,
bOutput, bZero, bMany, debugstr_guid(&ConnectsToFilter), debugstr_w(ConnectsToPin));
LONG lRet;
LPWSTR wszClsid = NULL;
HKEY hKey;
- WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];
+ WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + (CHARS_IN_GUID-1) + 1];
TRACE("(%p)->(%s)\n", iface, debugstr_guid(&Filter));
LPWSTR wszClsid = NULL;
HKEY hKey = NULL;
WCHAR * wszPinNameKey;
- WCHAR wszKeyName[strlenW(wszClsidSlash) + (CHARS_IN_GUID-1) + 1];
+ WCHAR wszKeyName[ARRAYSIZE(wszClsidSlash)-1 + (CHARS_IN_GUID-1) + 1];
TRACE("(%p)->(%s, %s)\n", iface, debugstr_guid(&Filter), debugstr_w(Name));