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(