msxml3: Store xmlnode reference in xmlnodemap object.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2016-03-16 13:52:57 +01:00 committed by Alexandre Julliard
parent 05edc1bd78
commit 8c810372bc
4 changed files with 42 additions and 3 deletions

View File

@ -296,6 +296,8 @@ extern LONG xmldoc_add_ref( xmlDocPtr doc ) DECLSPEC_HIDDEN;
extern LONG xmldoc_release( xmlDocPtr doc ) DECLSPEC_HIDDEN;
extern LONG xmldoc_add_refs( xmlDocPtr doc, LONG refs ) DECLSPEC_HIDDEN;
extern LONG xmldoc_release_refs ( xmlDocPtr doc, LONG refs ) DECLSPEC_HIDDEN;
extern void xmlnode_add_ref(xmlNodePtr node) DECLSPEC_HIDDEN;
extern void xmlnode_release(xmlNodePtr node) DECLSPEC_HIDDEN;
extern int xmlnode_get_inst_cnt( xmlnode *node ) DECLSPEC_HIDDEN;
extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ) DECLSPEC_HIDDEN;
extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ) DECLSPEC_HIDDEN;

View File

@ -431,13 +431,13 @@ int xmlnode_get_inst_cnt(xmlnode *node)
/* _private field holds a number of COM instances spawned from this libxml2 node
* most significant bits are used to store information about ignorrable whitespace nodes */
static void xmlnode_add_ref(xmlNodePtr node)
void xmlnode_add_ref(xmlNodePtr node)
{
if (node->type == XML_DOCUMENT_NODE) return;
InterlockedIncrement((LONG*)&node->_private);
}
static void xmlnode_release(xmlNodePtr node)
void xmlnode_release(xmlNodePtr node)
{
if (node->type == XML_DOCUMENT_NODE) return;
InterlockedDecrement((LONG*)&node->_private);

View File

@ -140,6 +140,7 @@ static ULONG WINAPI xmlnodemap_Release(
TRACE("(%p)->(%d)\n", This, ref);
if ( ref == 0 )
{
xmlnode_release( This->node );
xmldoc_release( This->node->doc );
if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
heap_free( This );
@ -450,6 +451,7 @@ IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
xmlnode_add_ref(node);
xmldoc_add_ref(node->doc);
return &This->IXMLDOMNamedNodeMap_iface;

View File

@ -9259,10 +9259,12 @@ static void test_get_attributes(void)
{
const get_attributes_t *entry = get_attributes;
IXMLDOMNamedNodeMap *map;
IXMLDOMDocument *doc;
IXMLDOMDocument *doc, *doc2;
IXMLDOMNode *node, *node2;
IXMLDOMElement *elem;
VARIANT_BOOL b;
HRESULT hr;
VARIANT v;
BSTR str;
LONG length;
@ -9434,6 +9436,39 @@ static void test_get_attributes(void)
IXMLDOMNamedNodeMap_Release(map);
/* append created element a different document, map still works */
hr = IXMLDOMDocument_createElement(doc, _bstr_("test"), &elem);
ok(hr == S_OK, "createElement failed: %08x\n", hr);
V_VT(&v) = VT_I4;
V_I4(&v) = 1;
hr = IXMLDOMElement_setAttribute(elem, _bstr_("testattr"), v);
ok(hr == S_OK, "setAttribute failed: %08x\n", hr);
hr = IXMLDOMElement_get_attributes(elem, &map);
ok(hr == S_OK, "get_attributes failed: %08x\n", hr);
length = 0;
hr = IXMLDOMNamedNodeMap_get_length(map, &length);
ok(hr == S_OK, "got %08x\n", hr);
ok(length == 1, "got %d\n", length);
doc2 = create_document(&IID_IXMLDOMDocument);
hr = IXMLDOMDocument_appendChild(doc2, (IXMLDOMNode*)elem, &node);
ok(hr == S_OK, "appendChild failed: %08x\n", hr);
ok(node == (IXMLDOMNode*)elem, "node != elem\n");
IXMLDOMNode_Release(node);
IXMLDOMElement_Release(elem);
IXMLDOMDocument_Release(doc2);
length = 0;
hr = IXMLDOMNamedNodeMap_get_length(map, &length);
ok(hr == S_OK, "got %08x\n", hr);
ok(length == 1, "got %d\n", length);
IXMLDOMNamedNodeMap_Release(map);
while (entry->type)
{
VARIANT var;