From 59f7b8899bf355dfc18164b1bdc40414a8e56eb7 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 3 Mar 2011 03:57:01 +0300 Subject: [PATCH] msxml3: Link dom attribute with parent interface pointer. --- dlls/msxml3/element.c | 16 ++++++++++++++++ dlls/msxml3/msxml_private.h | 5 +++-- dlls/msxml3/node.c | 1 + dlls/msxml3/tests/domdoc.c | 23 +++++++++++++++++------ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c index b1de8df5397..f2c5bbbfdd0 100644 --- a/dlls/msxml3/element.c +++ b/dlls/msxml3/element.c @@ -1182,6 +1182,7 @@ static HRESULT WINAPI domelem_setAttributeNode( static const WCHAR xmlnsW[] = {'x','m','l','n','s',0}; xmlChar *name, *value; BSTR nameW, prefix; + xmlnode *attr_node; xmlAttrPtr attr; VARIANT valueW; HRESULT hr; @@ -1190,6 +1191,19 @@ static HRESULT WINAPI domelem_setAttributeNode( if (!attribute) return E_INVALIDARG; + attr_node = get_node_obj((IXMLDOMNode*)attribute); + if (!attr_node) + { + FIXME("att_node is not our node implementation\n"); + return E_FAIL; + } + + if (attr_node->parent) + { + WARN("attempt to add already used attribute\n"); + return E_FAIL; + } + hr = IXMLDOMAttribute_get_nodeName(attribute, &nameW); if (hr != S_OK) return hr; @@ -1231,6 +1245,8 @@ static HRESULT WINAPI domelem_setAttributeNode( } attr = xmlSetNsProp(get_element(This), NULL, name, value); + if (attr) + attr_node->parent = (IXMLDOMNode*)iface; SysFreeString(nameW); VariantClear(&valueW); diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index ab7820f549f..72de7ba708c 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -233,9 +233,10 @@ extern void set_xpathmode(xmlDocPtr doc, BOOL xpath); /* IXMLDOMNode Internal Structure */ typedef struct _xmlnode { - DispatchEx dispex; + DispatchEx dispex; IXMLDOMNode *iface; - xmlNodePtr node; + IXMLDOMNode *parent; + xmlNodePtr node; } xmlnode; extern void init_xmlnode(xmlnode*,xmlNodePtr,IXMLDOMNode*,dispex_static_data_t*); diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index a952ac0795f..71b95a80ef6 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1106,6 +1106,7 @@ void init_xmlnode(xmlnode *This, xmlNodePtr node, IXMLDOMNode *node_iface, dispe This->node = node; This->iface = node_iface; + This->parent = NULL; if(dispex_data) init_dispex(&This->dispex, (IUnknown*)This->iface, dispex_data); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index c1548603c2d..82961f0a2e3 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -7213,7 +7213,7 @@ static void test_get_ownerDocument(void) static void test_setAttributeNode(void) { IXMLDOMDocument *doc, *doc2; - IXMLDOMElement *elem; + IXMLDOMElement *elem, *elem2; IXMLDOMAttribute *attr, *attr2, *ret_attr; VARIANT_BOOL b; HRESULT hr; @@ -7233,6 +7233,10 @@ static void test_setAttributeNode(void) hr = IXMLDOMDocument_get_documentElement(doc, &elem); ok( hr == S_OK, "got 0x%08x\n", hr); + hr = IXMLDOMDocument_get_documentElement(doc, &elem2); + ok( hr == S_OK, "got 0x%08x\n", hr); + ok( elem2 != elem, "got same instance\n"); + ret_attr = (void*)0xdeadbeef; hr = IXMLDOMElement_setAttributeNode(elem, NULL, &ret_attr); ok( hr == E_INVALIDARG, "got 0x%08x\n", hr); @@ -7259,16 +7263,23 @@ static void test_setAttributeNode(void) ok( hr == S_OK, "got 0x%08x\n", hr); ok(b == VARIANT_TRUE, "got %d\n", b); + b = VARIANT_FALSE; + hr = IXMLDOMElement_hasChildNodes(elem2, &b); + ok( hr == S_OK, "got 0x%08x\n", hr); + ok(b == VARIANT_TRUE, "got %d\n", b); + IXMLDOMElement_Release(elem2); + attr2 = NULL; hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2); ok( hr == S_OK, "got 0x%08x\n", hr); + ok( attr2 != attr, "got same instance %p\n", attr2); IXMLDOMAttribute_Release(attr2); /* try to add it another time */ ret_attr = (void*)0xdeadbeef; hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); - todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr); - todo_wine ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); + ok( hr == E_FAIL, "got 0x%08x\n", hr); + ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); IXMLDOMElement_Release(elem); @@ -7277,8 +7288,8 @@ static void test_setAttributeNode(void) ok( hr == S_OK, "got 0x%08x\n", hr); ret_attr = (void*)0xdeadbeef; hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr); - todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr); - todo_wine ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); + ok( hr == E_FAIL, "got 0x%08x\n", hr); + ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr); IXMLDOMElement_Release(elem); /* add attribute already attached to another document */ @@ -7293,7 +7304,7 @@ static void test_setAttributeNode(void) hr = IXMLDOMDocument_get_documentElement(doc2, &elem); ok( hr == S_OK, "got 0x%08x\n", hr); hr = IXMLDOMElement_setAttributeNode(elem, attr, NULL); - todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr); + ok( hr == E_FAIL, "got 0x%08x\n", hr); IXMLDOMElement_Release(elem); IXMLDOMAttribute_Release(attr);