diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index f0b203e4c5..940519af7a 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -4886,25 +4886,22 @@ static HRESULT create_document_fragment(nsIDOMNode *nsnode, HTMLDocumentNode *do
return S_OK;
}
-/**********************************************************
- * ICustomDoc implementation
- */
-
-static inline HTMLDocumentObj *impl_from_ICustomDoc(ICustomDoc *iface)
+static inline HTMLDocumentObj *impl_from_IUnknown(IUnknown *iface)
{
- return CONTAINING_RECORD(iface, HTMLDocumentObj, ICustomDoc_iface);
+ return CONTAINING_RECORD(iface, HTMLDocumentObj, IUnknown_outer);
}
-static HRESULT WINAPI CustomDoc_QueryInterface(ICustomDoc *iface, REFIID riid, void **ppv)
+static HRESULT WINAPI HTMLDocumentObj_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
- HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
+ HTMLDocumentObj *This = impl_from_IUnknown(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
- if(htmldoc_qi(&This->basedoc, riid, ppv))
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ *ppv = &This->IUnknown_outer;
+ }else if(htmldoc_qi(&This->basedoc, riid, ppv)) {
return *ppv ? S_OK : E_NOINTERFACE;
-
- if(IsEqualGUID(&IID_ICustomDoc, riid)) {
+ }else if(IsEqualGUID(&IID_ICustomDoc, riid)) {
*ppv = &This->ICustomDoc_iface;
}else if(IsEqualGUID(&IID_ITargetContainer, riid)) {
*ppv = &This->ITargetContainer_iface;
@@ -4920,9 +4917,9 @@ static HRESULT WINAPI CustomDoc_QueryInterface(ICustomDoc *iface, REFIID riid, v
return S_OK;
}
-static ULONG WINAPI CustomDoc_AddRef(ICustomDoc *iface)
+static ULONG WINAPI HTMLDocumentObj_AddRef(IUnknown *iface)
{
- HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
+ HTMLDocumentObj *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref = %u\n", This, ref);
@@ -4930,9 +4927,9 @@ static ULONG WINAPI CustomDoc_AddRef(ICustomDoc *iface)
return ref;
}
-static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface)
+static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface)
{
- HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
+ HTMLDocumentObj *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref = %u\n", This, ref);
@@ -4992,6 +4989,42 @@ static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface)
return ref;
}
+static const IUnknownVtbl HTMLDocumentObjVtbl = {
+ HTMLDocumentObj_QueryInterface,
+ HTMLDocumentObj_AddRef,
+ HTMLDocumentObj_Release
+};
+
+/**********************************************************
+ * ICustomDoc implementation
+ */
+
+static inline HTMLDocumentObj *impl_from_ICustomDoc(ICustomDoc *iface)
+{
+ return CONTAINING_RECORD(iface, HTMLDocumentObj, ICustomDoc_iface);
+}
+
+static HRESULT WINAPI CustomDoc_QueryInterface(ICustomDoc *iface, REFIID riid, void **ppv)
+{
+ HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
+
+ return htmldoc_query_interface(&This->basedoc, riid, ppv);
+}
+
+static ULONG WINAPI CustomDoc_AddRef(ICustomDoc *iface)
+{
+ HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
+
+ return htmldoc_addref(&This->basedoc);
+}
+
+static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface)
+{
+ HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
+
+ return htmldoc_release(&This->basedoc);
+}
+
static HRESULT WINAPI CustomDoc_SetUIHandler(ICustomDoc *iface, IDocHostUIHandler *pUIHandler)
{
HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
@@ -5042,7 +5075,7 @@ static dispex_static_data_t HTMLDocumentObj_dispex = {
HTMLDocumentObj_iface_tids
};
-HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
+HRESULT HTMLDocument_Create(IUnknown *outer, REFIID riid, void **ppv)
{
mozIDOMWindowProxy *mozwindow;
HTMLDocumentObj *doc;
@@ -5050,18 +5083,24 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
nsresult nsres;
HRESULT hres;
- TRACE("(%p %s %p)\n", pUnkOuter, debugstr_mshtml_guid(riid), ppvObject);
+ TRACE("(%p %s %p)\n", outer, debugstr_mshtml_guid(riid), ppv);
+
+ if(outer && !IsEqualGUID(&IID_IUnknown, riid)) {
+ *ppv = NULL;
+ return E_INVALIDARG;
+ }
doc = heap_alloc_zero(sizeof(HTMLDocumentObj));
if(!doc)
return E_OUTOFMEMORY;
- init_dispex(&doc->dispex, (IUnknown*)&doc->ICustomDoc_iface, &HTMLDocumentObj_dispex);
- init_doc(&doc->basedoc, (IUnknown*)&doc->ICustomDoc_iface, &doc->dispex.IDispatchEx_iface);
- TargetContainer_Init(doc);
-
- doc->ICustomDoc_iface.lpVtbl = &CustomDocVtbl;
doc->ref = 1;
+ doc->IUnknown_outer.lpVtbl = &HTMLDocumentObjVtbl;
+ doc->ICustomDoc_iface.lpVtbl = &CustomDocVtbl;
+
+ init_dispex(&doc->dispex, (IUnknown*)&doc->ICustomDoc_iface, &HTMLDocumentObj_dispex);
+ init_doc(&doc->basedoc, outer ? outer : &doc->IUnknown_outer, &doc->dispex.IDispatchEx_iface);
+ TargetContainer_Init(doc);
doc->basedoc.doc_obj = doc;
doc->usermode = UNKNOWN_USERMODE;
@@ -5075,10 +5114,14 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
return hres;
}
- hres = htmldoc_query_interface(&doc->basedoc, riid, ppvObject);
- htmldoc_release(&doc->basedoc);
- if(FAILED(hres))
- return hres;
+ if(IsEqualGUID(&IID_IUnknown, riid)) {
+ *ppv = &doc->IUnknown_outer;
+ }else {
+ hres = htmldoc_query_interface(&doc->basedoc, riid, ppv);
+ htmldoc_release(&doc->basedoc);
+ if(FAILED(hres))
+ return hres;
+ }
nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &mozwindow);
if(NS_FAILED(nsres))
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index a18ddafe61..9c8b94cc8a 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -609,6 +609,7 @@ static inline ULONG htmldoc_release(HTMLDocument *This)
struct HTMLDocumentObj {
HTMLDocument basedoc;
DispatchEx dispex;
+ IUnknown IUnknown_outer;
ICustomDoc ICustomDoc_iface;
ITargetContainer ITargetContainer_iface;
diff --git a/dlls/msxml3/tests/xmlview.c b/dlls/msxml3/tests/xmlview.c
index 3e3bd295a7..3c1d8d9f81 100644
--- a/dlls/msxml3/tests/xmlview.c
+++ b/dlls/msxml3/tests/xmlview.c
@@ -181,7 +181,7 @@ static void test_QueryInterface(void)
ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument) returned %x, expected S_OK\n", hres);
hres = IHTMLDocument_QueryInterface(htmldoc, &IID_IUnknown, (void**)&unk);
ok(hres == S_OK, "QueryInterface(IID_IUnknown) returned %x, expected S_OK\n", hres);
- todo_wine ok(unk == xmlview, "Aggregation is not working as expected\n");
+ ok(unk == xmlview, "Aggregation is not working as expected\n");
IUnknown_Release(unk);
IHTMLDocument_Release(htmldoc);