diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 985d33a4378..bec6ed41e34 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -301,6 +301,11 @@ static void free_properties(domdoc_properties* properties)
}
}
+static BOOL xmldoc_has_decl(xmlDocPtr doc)
+{
+ return doc->children && (xmlStrEqual(doc->children->name, (xmlChar*)"xml") == 1);
+}
+
/* links a "(%p)\n", This, p);
- return node_get_xml(&This->node, TRUE, TRUE, p);
+ if(!p)
+ return E_INVALIDARG;
+
+ *p = NULL;
+
+ buf = xmlBufferCreate();
+ if(!buf)
+ return E_OUTOFMEMORY;
+
+ options = xmldoc_has_decl(get_doc(This)) ? XML_SAVE_NO_DECL : 0;
+ options |= XML_SAVE_FORMAT;
+ ctxt = xmlSaveToBuffer(buf, "UTF-8", options);
+ if(!ctxt)
+ {
+ xmlBufferFree(buf);
+ return E_OUTOFMEMORY;
+ }
+
+ ret = xmlSaveDoc(ctxt, get_doc(This));
+ /* flushes on close */
+ xmlSaveClose(ctxt);
+
+ TRACE("%ld, len=%d\n", ret, xmlBufferLength(buf));
+ if(ret != -1 && xmlBufferLength(buf) > 0)
+ {
+ BSTR content;
+
+ content = bstr_from_xmlChar(xmlBufferContent(buf));
+ content = EnsureCorrectEOL(content);
+
+ *p = content;
+ }
+ else
+ {
+ *p = SysAllocStringLen(NULL, 0);
+ }
+
+ xmlBufferFree(buf);
+
+ return *p ? S_OK : E_OUTOFMEMORY;
}
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 1fd91b1cb42..c2f80a010fc 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -204,6 +204,8 @@ extern HRESULT node_get_base_name(xmlnode*,BSTR*);
extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document);
extern HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tree);
+extern BSTR EnsureCorrectEOL(BSTR);
+
static inline BSTR bstr_from_xmlChar(const xmlChar *str)
{
BSTR ret = NULL;
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c
index 3c6748bdb46..f01c00e2512 100644
--- a/dlls/msxml3/node.c
+++ b/dlls/msxml3/node.c
@@ -951,7 +951,7 @@ static HRESULT WINAPI xmlnode_put_dataType(
return hr;
}
-static BSTR EnsureCorrectEOL(BSTR sInput)
+BSTR EnsureCorrectEOL(BSTR sInput)
{
int nNum = 0;
BSTR sNew;
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index e8f010229ff..aa7ea5bedd1 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -7544,6 +7544,51 @@ static void test_put_nodeTypedValue(void)
free_bstrs();
}
+static void test_get_xml(void)
+{
+ static const char xmlA[] = "\r\ntest\r\n";
+ IXMLDOMProcessingInstruction *pi;
+ IXMLDOMNode *first;
+ IXMLDOMDocument *doc;
+ VARIANT_BOOL b;
+ VARIANT v;
+ BSTR xml;
+ HRESULT hr;
+
+ doc = create_document(&IID_IXMLDOMDocument);
+ if (!doc) return;
+
+ b = VARIANT_TRUE;
+ hr = IXMLDOMDocument_loadXML( doc, _bstr_("test"), &b );
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok( b == VARIANT_TRUE, "got %d\n", b);
+
+ hr = IXMLDOMDocument_createProcessingInstruction(doc, _bstr_("xml"),
+ _bstr_("version=\"1.0\" encoding=\"UTF-16\""), &pi);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IXMLDOMDocument_get_firstChild(doc, &first);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ V_UNKNOWN(&v) = (IUnknown*)first;
+ V_VT(&v) = VT_UNKNOWN;
+
+ hr = IXMLDOMDocument_insertBefore(doc, (IXMLDOMNode*)pi, v, NULL);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ IXMLDOMProcessingInstruction_Release(pi);
+ IXMLDOMNode_Release(first);
+
+ hr = IXMLDOMDocument_get_xml(doc, &xml);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ ok(memcmp(xml, _bstr_(xmlA), sizeof(xmlA)*sizeof(WCHAR)) == 0,
+ "got %s, expected %s\n", wine_dbgstr_w(xml), xmlA);
+ SysFreeString(xml);
+
+ IXMLDOMDocument_Release(doc);
+}
+
START_TEST(domdoc)
{
IXMLDOMDocument *doc;
@@ -7607,6 +7652,7 @@ START_TEST(domdoc)
test_events();
test_createProcessingInstruction();
test_put_nodeTypedValue();
+ test_get_xml();
CoUninitialize();
}
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 370f4b3b4ba..d2bf5c25020 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -584,6 +584,7 @@ static void test_saxreader(void)
}
bstrData = SysAllocString(szSimpleXML);
hr = IXMLDOMDocument_loadXML(domDocument, bstrData, &vBool);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
V_VT(&var) = VT_UNKNOWN;
V_UNKNOWN(&var) = (IUnknown*)domDocument;