>From 88e6a6680bb95ac2d9c086e0bcf30ac760306486 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Mon, 31 Oct 2011 22:09:12 +0300
Subject: [PATCH 2/2] Init IDispatchEx data for all node types

---
 dlls/msxml3/attribute.c    |   14 ++++-
 dlls/msxml3/cdata.c        |   14 ++++-
 dlls/msxml3/comment.c      |   14 ++++-
 dlls/msxml3/docfrag.c      |   14 ++++-
 dlls/msxml3/domdoc.c       |    1 -
 dlls/msxml3/entityref.c    |   14 ++++-
 dlls/msxml3/node.c         |    7 +--
 dlls/msxml3/pi.c           |   14 ++++-
 dlls/msxml3/tests/domdoc.c |  159 +++++++++++++++++++++++++++++---------------
 dlls/msxml3/text.c         |   14 ++++-
 10 files changed, 197 insertions(+), 68 deletions(-)

diff --git a/dlls/msxml3/attribute.c b/dlls/msxml3/attribute.c
index 603477c..b67a5b4 100644
--- a/dlls/msxml3/attribute.c
+++ b/dlls/msxml3/attribute.c
@@ -654,6 +654,18 @@ static const struct IXMLDOMAttributeVtbl domattr_vtbl =
     domattr_put_value
 };
 
+static const tid_t domattr_iface_tids[] = {
+    IXMLDOMAttribute_tid,
+    0
+};
+
+static dispex_static_data_t domattr_dispex = {
+    NULL,
+    IXMLDOMAttribute_tid,
+    NULL,
+    domattr_iface_tids
+};
+
 IUnknown* create_attribute( xmlNodePtr attribute )
 {
     domattr *This;
@@ -665,7 +677,7 @@ IUnknown* create_attribute( xmlNodePtr attribute )
     This->IXMLDOMAttribute_iface.lpVtbl = &domattr_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, attribute, (IXMLDOMNode*)&This->IXMLDOMAttribute_iface, NULL);
+    init_xmlnode(&This->node, attribute, (IXMLDOMNode*)&This->IXMLDOMAttribute_iface, &domattr_dispex);
 
     return (IUnknown*)&This->IXMLDOMAttribute_iface;
 }
diff --git a/dlls/msxml3/cdata.c b/dlls/msxml3/cdata.c
index 2622e1b..348abb8 100644
--- a/dlls/msxml3/cdata.c
+++ b/dlls/msxml3/cdata.c
@@ -905,6 +905,18 @@ static const struct IXMLDOMCDATASectionVtbl domcdata_vtbl =
     domcdata_splitText
 };
 
+static const tid_t domcdata_iface_tids[] = {
+    IXMLDOMCDATASection_tid,
+    0
+};
+
+static dispex_static_data_t domcdata_dispex = {
+    NULL,
+    IXMLDOMCDATASection_tid,
+    NULL,
+    domcdata_iface_tids
+};
+
 IUnknown* create_cdata( xmlNodePtr text )
 {
     domcdata *This;
@@ -916,7 +928,7 @@ IUnknown* create_cdata( xmlNodePtr text )
     This->IXMLDOMCDATASection_iface.lpVtbl = &domcdata_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMCDATASection_iface, NULL);
+    init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMCDATASection_iface, &domcdata_dispex);
 
     return (IUnknown*)&This->IXMLDOMCDATASection_iface;
 }
diff --git a/dlls/msxml3/comment.c b/dlls/msxml3/comment.c
index cb5cada..6ae9965 100644
--- a/dlls/msxml3/comment.c
+++ b/dlls/msxml3/comment.c
@@ -855,6 +855,18 @@ static const struct IXMLDOMCommentVtbl domcomment_vtbl =
     domcomment_replaceData
 };
 
+static const tid_t domcomment_iface_tids[] = {
+    IXMLDOMComment_tid,
+    0
+};
+
+static dispex_static_data_t domcomment_dispex = {
+    NULL,
+    IXMLDOMComment_tid,
+    NULL,
+    domcomment_iface_tids
+};
+
 IUnknown* create_comment( xmlNodePtr comment )
 {
     domcomment *This;
@@ -866,7 +878,7 @@ IUnknown* create_comment( xmlNodePtr comment )
     This->IXMLDOMComment_iface.lpVtbl = &domcomment_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, comment, (IXMLDOMNode*)&This->IXMLDOMComment_iface, NULL);
+    init_xmlnode(&This->node, comment, (IXMLDOMNode*)&This->IXMLDOMComment_iface, &domcomment_dispex);
 
     return (IUnknown*)&This->IXMLDOMComment_iface;
 }
diff --git a/dlls/msxml3/docfrag.c b/dlls/msxml3/docfrag.c
index 0342bae..892ed4b 100644
--- a/dlls/msxml3/docfrag.c
+++ b/dlls/msxml3/docfrag.c
@@ -606,6 +606,18 @@ static const struct IXMLDOMDocumentFragmentVtbl domfrag_vtbl =
     domfrag_transformNodeToObject
 };
 
+static const tid_t domfrag_iface_tids[] = {
+    IXMLDOMDocumentFragment_tid,
+    0
+};
+
+static dispex_static_data_t domfrag_dispex = {
+    NULL,
+    IXMLDOMDocumentFragment_tid,
+    NULL,
+    domfrag_iface_tids
+};
+
 IUnknown* create_doc_fragment( xmlNodePtr fragment )
 {
     domfrag *This;
@@ -617,7 +629,7 @@ IUnknown* create_doc_fragment( xmlNodePtr fragment )
     This->IXMLDOMDocumentFragment_iface.lpVtbl = &domfrag_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, fragment, (IXMLDOMNode*)&This->IXMLDOMDocumentFragment_iface, NULL);
+    init_xmlnode(&This->node, fragment, (IXMLDOMNode*)&This->IXMLDOMDocumentFragment_iface, &domfrag_dispex);
 
     return (IUnknown*)&This->IXMLDOMDocumentFragment_iface;
 }
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 24df895..30b63de 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -47,7 +47,6 @@
 #include "shlwapi.h"
 #include "ocidl.h"
 #include "objsafe.h"
-#include "dispex.h"
 
 #include "wine/debug.h"
 #include "wine/list.h"
diff --git a/dlls/msxml3/entityref.c b/dlls/msxml3/entityref.c
index b317606..79b53be 100644
--- a/dlls/msxml3/entityref.c
+++ b/dlls/msxml3/entityref.c
@@ -600,6 +600,18 @@ static const struct IXMLDOMEntityReferenceVtbl entityref_vtbl =
     entityref_transformNodeToObject,
 };
 
+static const tid_t domentityref_iface_tids[] = {
+    IXMLDOMEntityReference_tid,
+    0
+};
+
+static dispex_static_data_t domentityref_dispex = {
+    NULL,
+    IXMLDOMEntityReference_tid,
+    NULL,
+    domentityref_iface_tids
+};
+
 IUnknown* create_doc_entity_ref( xmlNodePtr entity )
 {
     entityref *This;
@@ -611,7 +623,7 @@ IUnknown* create_doc_entity_ref( xmlNodePtr entity )
     This->IXMLDOMEntityReference_iface.lpVtbl = &entityref_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, entity, (IXMLDOMNode*)&This->IXMLDOMEntityReference_iface, NULL);
+    init_xmlnode(&This->node, entity, (IXMLDOMNode*)&This->IXMLDOMEntityReference_iface, &domentityref_dispex);
 
     return (IUnknown*)&This->IXMLDOMEntityReference_iface;
 }
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 0e00b38..3a104cd 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -113,10 +113,7 @@ BOOL node_query_interface(xmlnode *This, REFIID riid, void **ppv)
         return TRUE;
     }
 
-    if(This->dispex.outer)
-        return dispex_query_interface(&This->dispex, riid, ppv);
-
-    return FALSE;
+    return dispex_query_interface(&This->dispex, riid, ppv);
 }
 
 xmlnode *get_node_obj(IXMLDOMNode *node)
@@ -1122,7 +1119,7 @@ void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispe
     This->iface = node_iface;
     This->parent = NULL;
 
-    init_dispex(&This->dispex, dispex_data ? (IUnknown*)This->iface : NULL, dispex_data);
+    init_dispex(&This->dispex, (IUnknown*)This->iface, dispex_data);
 }
 
 typedef struct {
diff --git a/dlls/msxml3/pi.c b/dlls/msxml3/pi.c
index 302aea2..13b03a4 100644
--- a/dlls/msxml3/pi.c
+++ b/dlls/msxml3/pi.c
@@ -705,6 +705,18 @@ static const struct IXMLDOMProcessingInstructionVtbl dom_pi_vtbl =
     dom_pi_put_data
 };
 
+static const tid_t dompi_iface_tids[] = {
+    IXMLDOMProcessingInstruction_tid,
+    0
+};
+
+static dispex_static_data_t dompi_dispex = {
+    NULL,
+    IXMLDOMProcessingInstruction_tid,
+    NULL,
+    dompi_iface_tids
+};
+
 IUnknown* create_pi( xmlNodePtr pi )
 {
     dom_pi *This;
@@ -716,7 +728,7 @@ IUnknown* create_pi( xmlNodePtr pi )
     This->IXMLDOMProcessingInstruction_iface.lpVtbl = &dom_pi_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, pi, (IXMLDOMNode*)&This->IXMLDOMProcessingInstruction_iface, NULL);
+    init_xmlnode(&This->node, pi, (IXMLDOMNode*)&This->IXMLDOMProcessingInstruction_iface, &dompi_dispex);
 
     return (IUnknown*)&This->IXMLDOMProcessingInstruction_iface;
 }
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index ee2128b..41fb835 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -1899,55 +1899,6 @@ static void get_str_for_type(DOMNodeType type, char *buf)
     }
 }
 
-#define test_disp(u) _test_disp(__LINE__,u)
-static void _test_disp(unsigned line, IUnknown *unk)
-{
-    DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
-    IDispatchEx *dispex;
-    DWORD dwProps = 0;
-    BSTR sName;
-    UINT ticnt;
-    IUnknown *pUnk;
-    HRESULT hres;
-
-    hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
-    ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
-    if(FAILED(hres))
-        return;
-
-    ticnt = 0xdeadbeef;
-    hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
-    ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
-    ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
-
-    sName = SysAllocString( szstar );
-    hres = IDispatchEx_DeleteMemberByName(dispex, sName, fdexNameCaseSensitive);
-    ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
-    SysFreeString( sName );
-
-    hres = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
-    ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
-
-    hres = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &dwProps);
-    ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
-    ok(dwProps == 0, "expected 0 got %d\n", dwProps);
-
-    hres = IDispatchEx_GetMemberName(dispex, dispid, &sName);
-    ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
-    if(SUCCEEDED(hres))
-        SysFreeString(sName);
-
-    hres = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
-    ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
-
-    hres = IDispatchEx_GetNameSpaceParent(dispex, &pUnk);
-    ok(hres == E_NOTIMPL, "expected E_NOTIMPL got %08x\n", hres);
-    if(hres == S_OK && pUnk)
-        IUnknown_Release(pUnk);
-
-    IDispatchEx_Release(dispex);
-}
-
 static int get_node_position(IXMLDOMNode *node)
 {
     HRESULT r;
@@ -2069,8 +2020,6 @@ static void test_domdoc( void )
     doc = create_document(&IID_IXMLDOMDocument);
     if (!doc) return;
 
-    test_disp((IUnknown*)doc);
-
 if (0)
 {
     /* crashes on native */
@@ -2197,8 +2146,6 @@ if (0)
     {
         IObjectIdentity *ident;
 
-        test_disp((IUnknown*)element);
-
         r = IXMLDOMElement_QueryInterface( element, &IID_IObjectIdentity, (void**)&ident );
         ok( r == E_NOINTERFACE, "ret %08x\n", r);
 
@@ -3735,8 +3682,6 @@ static void test_getElementsByTagName(void)
     ok( r == S_OK, "ret %08x\n", r );
     ok( len == 6, "len %d\n", len );
 
-    test_disp((IUnknown*)node_list);
-
     IXMLDOMNodeList_Release( node_list );
     SysFreeString( str );
 
@@ -10619,6 +10564,109 @@ static void test_nsnamespacemanager_override(void)
     free_bstrs();
 }
 
+static void test_domobj_dispex(IUnknown *obj)
+{
+    DISPID dispid = DISPID_XMLDOM_NODELIST_RESET;
+    IDispatchEx *dispex;
+    IUnknown *unk;
+    DWORD props;
+    UINT ticnt;
+    HRESULT hr;
+    BSTR name;
+
+    hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
+    EXPECT_HR(hr, S_OK);
+    if (FAILED(hr)) return;
+
+    ticnt = 0;
+    hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
+    EXPECT_HR(hr, S_OK);
+    ok(ticnt == 1, "ticnt=%u\n", ticnt);
+
+    name = SysAllocString(szstar);
+    hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
+    EXPECT_HR(hr, E_NOTIMPL);
+    SysFreeString(name);
+
+    hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
+    EXPECT_HR(hr, E_NOTIMPL);
+
+    props = 0;
+    hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
+    EXPECT_HR(hr, E_NOTIMPL);
+    ok(props == 0, "expected 0 got %d\n", props);
+
+    hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
+    EXPECT_HR(hr, E_NOTIMPL);
+    if (SUCCEEDED(hr)) SysFreeString(name);
+
+    hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_XMLDOM_NODELIST_RESET, &dispid);
+    EXPECT_HR(hr, E_NOTIMPL);
+
+    hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
+    EXPECT_HR(hr, E_NOTIMPL);
+    if (hr == S_OK && unk) IUnknown_Release(unk);
+
+    IDispatchEx_Release(dispex);
+}
+
+static const DOMNodeType dispex_types_test[] =
+{
+    NODE_ELEMENT,
+    NODE_ATTRIBUTE,
+    NODE_TEXT,
+    NODE_CDATA_SECTION,
+    NODE_ENTITY_REFERENCE,
+    NODE_PROCESSING_INSTRUCTION,
+    NODE_COMMENT,
+    NODE_DOCUMENT_FRAGMENT,
+    NODE_INVALID
+};
+
+static void test_dispex(void)
+{
+    const DOMNodeType *type = dispex_types_test;
+    IXMLDOMNodeList *node_list;
+    IXMLDOMDocument *doc;
+    IUnknown *unk;
+    HRESULT hr;
+
+    doc = create_document(&IID_IXMLDOMDocument);
+
+    IXMLDOMDocument_QueryInterface(doc, &IID_IUnknown, (void**)&unk);
+    test_domobj_dispex(unk);
+    IUnknown_Release(unk);
+
+    for(; *type != NODE_INVALID; type++)
+    {
+        IXMLDOMNode *node;
+        VARIANT v;
+
+        V_VT(&v) = VT_I2;
+        V_I2(&v) = *type;
+
+        hr = IXMLDOMDocument_createNode(doc, v, _bstr_("name"), NULL, &node);
+        ok(hr == S_OK, "failed to create node type %d\n", *type);
+
+        IXMLDOMNode_QueryInterface(node, &IID_IUnknown, (void**)&unk);
+
+        test_domobj_dispex(unk);
+        IUnknown_Release(unk);
+        IXMLDOMNode_Release(node);
+    }
+
+    /* IXMLDOMNodeList */
+    hr = IXMLDOMDocument_getElementsByTagName(doc, _bstr_("*"), &node_list);
+    EXPECT_HR(hr, S_OK);
+    IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk);
+    test_domobj_dispex(unk);
+    IUnknown_Release(unk);
+    IXMLDOMNodeList_Release(node_list);
+
+    IXMLDOMDocument_Release(doc);
+    free_bstrs();
+}
+
 START_TEST(domdoc)
 {
     IXMLDOMDocument *doc;
@@ -10690,6 +10738,7 @@ START_TEST(domdoc)
     test_get_attributes();
     test_selection();
     test_load();
+    test_dispex();
 
     test_xsltemplate();
 
diff --git a/dlls/msxml3/text.c b/dlls/msxml3/text.c
index 0f40cf5..9bda653 100644
--- a/dlls/msxml3/text.c
+++ b/dlls/msxml3/text.c
@@ -948,6 +948,18 @@ static const struct IXMLDOMTextVtbl domtext_vtbl =
     domtext_splitText
 };
 
+static const tid_t domtext_iface_tids[] = {
+    IXMLDOMText_tid,
+    0
+};
+
+static dispex_static_data_t domtext_dispex = {
+    NULL,
+    IXMLDOMText_tid,
+    NULL,
+    domtext_iface_tids
+};
+
 IUnknown* create_text( xmlNodePtr text )
 {
     domtext *This;
@@ -959,7 +971,7 @@ IUnknown* create_text( xmlNodePtr text )
     This->IXMLDOMText_iface.lpVtbl = &domtext_vtbl;
     This->ref = 1;
 
-    init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMText_iface, NULL);
+    init_xmlnode(&This->node, text, (IXMLDOMNode*)&This->IXMLDOMText_iface, &domtext_dispex);
 
     return (IUnknown*)&This->IXMLDOMText_iface;
 }
-- 
1.5.6.5

