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