Jacek Caban : mshtml: Added support for COM aggregation in HTMLDocument object.

Alexandre Julliard julliard at winehq.org
Thu Feb 2 15:49:27 CST 2017


Module: wine
Branch: master
Commit: 6e94b955c229db99910cede9554843e55031a75a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6e94b955c229db99910cede9554843e55031a75a

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Feb  2 16:10:05 2017 +0100

mshtml: Added support for COM aggregation in HTMLDocument object.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/htmldoc.c        | 93 ++++++++++++++++++++++++++++++++------------
 dlls/mshtml/mshtml_private.h |  1 +
 dlls/msxml3/tests/xmlview.c  |  2 +-
 3 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index f0b203e..940519a 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;
 
+    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, (IUnknown*)&doc->ICustomDoc_iface, &doc->dispex.IDispatchEx_iface);
+    init_doc(&doc->basedoc, outer ? outer : &doc->IUnknown_outer, &doc->dispex.IDispatchEx_iface);
     TargetContainer_Init(doc);
-
-    doc->ICustomDoc_iface.lpVtbl = &CustomDocVtbl;
-    doc->ref = 1;
     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 a18ddafe..9c8b94c 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 3e3bd29..3c1d8d9 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);
 




More information about the wine-cvs mailing list