Nikolay Sivov : msxml3: Correct IEnumVARIANT regarding IUnknown forwarding.

Alexandre Julliard julliard at winehq.org
Mon Jul 2 13:22:01 CDT 2012


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sat Jun 30 16:16:33 2012 +0400

msxml3: Correct IEnumVARIANT regarding IUnknown forwarding.

---

 dlls/msxml3/nodelist.c     |    2 +-
 dlls/msxml3/selection.c    |   14 +++++-
 dlls/msxml3/tests/domdoc.c |   93 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 100 insertions(+), 9 deletions(-)

diff --git a/dlls/msxml3/nodelist.c b/dlls/msxml3/nodelist.c
index 5710d48..f948fcf 100644
--- a/dlls/msxml3/nodelist.c
+++ b/dlls/msxml3/nodelist.c
@@ -40,7 +40,7 @@
 #include "wine/debug.h"
 
 /* This file implements the object returned by childNodes property. Note that this is
- * not the IXMLDOMNodeList returned by XPath querites - it's implemented in queryresult.c.
+ * not the IXMLDOMNodeList returned by XPath queries - it's implemented in selection.c.
  * They are different because the list returned by childNodes:
  *  - is "live" - changes to the XML tree are automatically reflected in the list
  *  - doesn't supports IXMLDOMSelection
diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c
index ba173f9..55873bb 100644
--- a/dlls/msxml3/selection.c
+++ b/dlls/msxml3/selection.c
@@ -433,8 +433,14 @@ static HRESULT WINAPI enumvariant_QueryInterface(
 
     *ppvObject = NULL;
 
-    if ( IsEqualGUID( riid, &IID_IUnknown ) ||
-         IsEqualGUID( riid, &IID_IEnumVARIANT ))
+    if (IsEqualGUID( riid, &IID_IUnknown ))
+    {
+        if (This->own)
+            *ppvObject = &This->IEnumVARIANT_iface;
+        else
+            return IXMLDOMSelection_QueryInterface(This->selection, riid, ppvObject);
+    }
+    else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
     {
         *ppvObject = &This->IEnumVARIANT_iface;
     }
@@ -563,7 +569,9 @@ static HRESULT create_enumvariant(IXMLDOMSelection *selection, BOOL own, IUnknow
     if (This->own)
         IXMLDOMSelection_AddRef(selection);
 
-    return IEnumVARIANT_QueryInterface(&This->IEnumVARIANT_iface, &IID_IUnknown, (void**)penum);
+    *penum = (IUnknown*)&This->IEnumVARIANT_iface;
+    IUnknown_AddRef(*penum);
+    return S_OK;
 }
 
 static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 7a02e19..4b73d47 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -4122,13 +4122,15 @@ static void test_get_text(void)
 
 static void test_get_childNodes(void)
 {
-    BSTR str;
+    IXMLDOMNodeList *node_list, *node_list2;
+    IEnumVARIANT *enum1, *enum2, *enum3;
     VARIANT_BOOL b;
     IXMLDOMDocument *doc;
-    IXMLDOMElement *element;
     IXMLDOMNode *node, *node2;
-    IXMLDOMNodeList *node_list, *node_list2;
+    IXMLDOMElement *element;
+    IUnknown *unk1, *unk2;
     HRESULT hr;
+    BSTR str;
     LONG len;
 
     doc = create_document(&IID_IXMLDOMDocument);
@@ -4148,6 +4150,58 @@ static void test_get_childNodes(void)
     EXPECT_HR(hr, S_OK);
     ok( len == 4, "len %d\n", len);
 
+    /* refcount tests for IEnumVARIANT support */
+    EXPECT_REF(node_list, 1);
+    hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum1);
+if (hr == S_OK)
+{
+    EXPECT_REF(node_list, 1);
+    EXPECT_REF(enum1, 2);
+
+    EXPECT_REF(node_list, 1);
+    hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IEnumVARIANT, (void**)&enum2);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(node_list, 1);
+    ok(enum2 == enum1, "got %p, %p\n", enum2, enum1);
+    IEnumVARIANT_Release(enum2);
+
+    hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
+    EXPECT_HR(hr, S_OK);
+    hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(node_list, 3);
+    EXPECT_REF(enum1, 2);
+    ok(unk1 == unk2, "got %p, %p\n", unk1, unk2);
+    IUnknown_Release(unk1);
+    IUnknown_Release(unk2);
+
+    EXPECT_REF(node_list, 1);
+    hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum2);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(node_list, 2);
+    EXPECT_REF(enum2, 1);
+    ok(enum2 != enum1, "got %p, %p\n", enum2, enum1);
+
+    /* enumerator created with _newEnum() doesn't share IUnknown* with main object */
+    hr = IXMLDOMNodeList_QueryInterface(node_list, &IID_IUnknown, (void**)&unk1);
+    EXPECT_HR(hr, S_OK);
+    hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(node_list, 3);
+    EXPECT_REF(enum2, 2);
+    ok(unk1 != unk2, "got %p, %p\n", unk1, unk2);
+    IUnknown_Release(unk1);
+    IUnknown_Release(unk2);
+
+    hr = IXMLDOMNodeList__newEnum(node_list, (IUnknown**)&enum3);
+    EXPECT_HR(hr, S_OK);
+    ok(enum2 != enum3, "got %p, %p\n", enum2, enum3);
+    IEnumVARIANT_Release(enum3);
+    IEnumVARIANT_Release(enum2);
+
+    IEnumVARIANT_Release(enum1);
+}
+
     hr = IXMLDOMNodeList_get_item( node_list, 2, &node );
     EXPECT_HR(hr, S_OK);
 
@@ -10171,6 +10225,7 @@ static void test_selection(void)
     IXMLDOMSelection *selection, *selection2;
     IEnumVARIANT *enum1, *enum2, *enum3;
     IXMLDOMNodeList *list;
+    IUnknown *unk1, *unk2;
     IXMLDOMDocument *doc;
     IDispatchEx *dispex;
     IXMLDOMNode *node;
@@ -10218,6 +10273,25 @@ static void test_selection(void)
     ok(enum1 != NULL, "got %p\n", enum1);
     EXPECT_REF(enum1, 2);
 
+    EXPECT_REF(selection, 1);
+    hr = IXMLDOMSelection_QueryInterface(selection, &IID_IUnknown, (void**)&unk1);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(selection, 2);
+    EXPECT_REF(enum1, 2);
+
+    /* enumerator and selection object return same IUnknown* */
+    hr = IEnumVARIANT_QueryInterface(enum1, &IID_IUnknown, (void**)&unk2);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(selection, 3);
+    EXPECT_REF(enum1, 2);
+    ok(unk2 == unk1, "got %p, %p\n", unk1, unk2);
+    IUnknown_Release(unk2);
+
+    EXPECT_REF(selection, 2);
+    IEnumVARIANT_AddRef(enum1);
+    EXPECT_REF(selection, 2);
+    IEnumVARIANT_Release(enum1);
+
     enum3 = NULL;
     hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
     EXPECT_HR(hr, S_OK);
@@ -10226,7 +10300,7 @@ static void test_selection(void)
     EXPECT_REF(enum1, 3);
     IEnumVARIANT_Release(enum3);
 
-    EXPECT_REF(selection, 1);
+    EXPECT_REF(selection, 2);
     EXPECT_REF(enum1, 2);
 
     enum2 = NULL;
@@ -10234,12 +10308,20 @@ static void test_selection(void)
     EXPECT_HR(hr, S_OK);
     ok(enum2 != NULL, "got %p\n", enum2);
 
-    EXPECT_REF(selection, 2);
+    EXPECT_REF(selection, 3);
     EXPECT_REF(enum1, 2);
     EXPECT_REF(enum2, 1);
 
     ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
 
+    hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2);
+    EXPECT_HR(hr, S_OK);
+    EXPECT_REF(selection, 3);
+    EXPECT_REF(enum2, 2);
+    ok(unk2 != unk1, "got %p, %p\n", unk1, unk2);
+    IUnknown_Release(unk2);
+    IUnknown_Release(unk1);
+
     selection2 = NULL;
     hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
     EXPECT_HR(hr, S_OK);
@@ -10368,6 +10450,7 @@ static void test_selection(void)
     SysFreeString(name);
     IXMLDOMNode_Release(node);
     VariantClear(&v);
+    IEnumVARIANT_Release(enum1);
 
     hr = IXMLDOMSelection_nextNode(selection, &node);
     EXPECT_HR(hr, S_OK);




More information about the wine-cvs mailing list