diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index d62a8a467d2..e46642d84b6 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -135,7 +135,7 @@ extern LONG xmldoc_release( xmlDocPtr doc ); extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ); extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ); -extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj ); +extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own ); extern xmlDocPtr parse_xml(char *ptr, int len); diff --git a/dlls/msxml3/tests/xmlelem.c b/dlls/msxml3/tests/xmlelem.c index bcbae948414..3304d5a59bd 100644 --- a/dlls/msxml3/tests/xmlelem.c +++ b/dlls/msxml3/tests/xmlelem.c @@ -523,6 +523,7 @@ static void test_xmlelem_children(void) ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(child2 != NULL, "Expected not NULL child\n"); IXMLElementCollection_Release(collection); + IXMLElement_Release(child2); /* add element->child->child2 structure, then remove child2 from node */ V_VT(&vType) = VT_I4; diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c index af67d4e048b..b77fd00f14d 100644 --- a/dlls/msxml3/xmldoc.c +++ b/dlls/msxml3/xmldoc.c @@ -209,7 +209,7 @@ static HRESULT WINAPI xmldoc_get_root(IXMLDocument *iface, IXMLElement **p) if (!(root = xmlDocGetRootElement(This->xmldoc))) return E_FAIL; - return XMLElement_create((IUnknown *)This, root, (LPVOID *)p); + return XMLElement_create((IUnknown *)This, root, (LPVOID *)p, FALSE); } static HRESULT WINAPI xmldoc_get_fileSize(IXMLDocument *iface, BSTR *p) @@ -520,7 +520,7 @@ static HRESULT WINAPI xmldoc_createElement(IXMLDocument *iface, VARIANT vType, node->type = type_msxml_to_libxml(V_I4(&vType)); /* FIXME: create xmlNodePtr based on vType and var1 */ - return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem); + return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem, TRUE); } static const struct IXMLDocumentVtbl xmldoc_vtbl = diff --git a/dlls/msxml3/xmlelem.c b/dlls/msxml3/xmlelem.c index b96df3abf96..3c1f4f2a418 100644 --- a/dlls/msxml3/xmlelem.c +++ b/dlls/msxml3/xmlelem.c @@ -48,6 +48,7 @@ typedef struct _xmlelem const IXMLElementVtbl *lpVtbl; LONG ref; xmlNodePtr node; + BOOL own; } xmlelem; static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface) @@ -94,6 +95,7 @@ static ULONG WINAPI xmlelem_Release(IXMLElement *iface) ref = InterlockedDecrement(&This->ref); if (ref == 0) { + if (This->own) xmlFreeNode(This->node); HeapFree(GetProcessHeap(), 0, This); } @@ -212,7 +214,7 @@ static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **paren if (!This->node->parent) return S_FALSE; - return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent); + return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent, FALSE); } static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName, @@ -407,6 +409,9 @@ static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildEl else child = xmlAddNextSibling(This->node, childElem->node->last); + /* parent is responsible for child data */ + if (child) childElem->own = FALSE; + return (child) ? S_OK : S_FALSE; } @@ -425,6 +430,8 @@ static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChil return E_INVALIDARG; xmlUnlinkNode(childElem->node); + /* standalone element now */ + childElem->own = TRUE; return S_OK; } @@ -452,7 +459,7 @@ static const struct IXMLElementVtbl xmlelem_vtbl = xmlelem_removeChild }; -HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj) +HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own) { xmlelem *elem; @@ -470,6 +477,7 @@ HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj) elem->lpVtbl = &xmlelem_vtbl; elem->ref = 1; elem->node = node; + elem->own = own; *ppObj = &elem->lpVtbl; @@ -652,7 +660,7 @@ static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARI for (i = 0; i < index; i++) ptr = ptr->next; - return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp); + return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp, FALSE); } static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl = @@ -712,7 +720,7 @@ static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next( This->current = This->current->next; V_VT(rgVar) = VT_DISPATCH; - return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar)); + return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE); } static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(