[PATCH] msxml3: Allow DOMDocument in VT_DISPATCH slot for put_output.

Jefferson Carpenter jeffersoncarpenter2 at gmail.com
Thu Nov 4 15:58:40 CDT 2021


Regarding locking the DOMDocument while it is being written to:

It looks like DOMDocument is meant to be used in a single-threaded 
manner[1], so it should be all right to just grab an interface and not 
worry about threads attempting to manipulate the document while it is 
being written to by an mxwriter.

For how to lock it, unless anyone has a better idea I think it would 
work to add an IWineXMLDOMDocumentLock interface with lock() and 
unlock() methods, and output a FIXME if this interface is unavailable.


thanks,
Jefferson

[1] 
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms756987(v=vs.85)?redirectedfrom=MSDN
-------------- next part --------------
From 9cb9b89082c01af1d3d9e2f65cbc6d80deeb2c13 Mon Sep 17 00:00:00 2001
From: Jefferson Carpenter <jeffersoncarpenter2 at gmail.com>
Date: Thu, 4 Nov 2021 22:30:05 +0000
Subject: [PATCH] msxml3: Allow DOMDocument in VT_DISPATCH slot for put_output.

Signed-off-by: Jefferson Carpenter <jeffersoncarpenter2 at gmail.com>
---
 dlls/msxml3/mxwriter.c        | 26 ++++++++++++++++++++++++++
 dlls/msxml3/tests/saxreader.c |  2 +-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index e0dd0e3c6e0..2cfb4b75d18 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -189,6 +189,7 @@ typedef struct
     BSTR element;
 
     IStream *dest;
+    IXMLDOMDocument *dest_doc;
 
     output_buffer buffer;
 } mxwriter;
@@ -850,6 +851,7 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
         free_output_buffer(&This->buffer);
 
         if (This->dest) IStream_Release(This->dest);
+        if (This->dest_doc) IXMLDOMDocument_Release(This->dest_doc);
         SysFreeString(This->version);
         SysFreeString(This->encoding);
 
@@ -914,6 +916,8 @@ static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
     {
         if (This->dest) IStream_Release(This->dest);
         This->dest = NULL;
+        if (This->dest_doc) IXMLDOMDocument_Release(This->dest_doc);
+        This->dest_doc = NULL;
         close_output_buffer(This);
         break;
     }
@@ -929,12 +933,33 @@ static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
 
             if (This->dest) IStream_Release(This->dest);
             This->dest = stream;
+            if (This->dest_doc) IXMLDOMDocument_Release(This->dest_doc);
+            This->dest_doc = NULL;
             break;
         }
 
         FIXME("unhandled interface type for VT_UNKNOWN destination\n");
         return E_NOTIMPL;
     }
+    case VT_DISPATCH:
+    {
+        IXMLDOMDocument *doc;
+
+        hr = IDispatch_QueryInterface(V_DISPATCH(&dest), &IID_IXMLDOMDocument, (void**)&doc);
+        if (hr == S_OK)
+        {
+            close_output_buffer(This);
+
+            if (This->dest) IStream_Release(This->dest);
+            This->dest = NULL;
+            if (This->dest_doc) IXMLDOMDocument_Release(This->dest_doc);
+            This->dest_doc = doc;
+            break;
+        }
+
+        FIXME("unhandled interface type for VT_DISPATCH destination\n");
+        return E_NOTIMPL;
+    }
     default:
         FIXME("unhandled destination type %s\n", debugstr_variant(&dest));
         return E_NOTIMPL;
@@ -2639,6 +2664,7 @@ HRESULT MXWriter_create(MSXML_VERSION version, void **ppObj)
     This->newline = FALSE;
 
     This->dest = NULL;
+    This->dest_doc = NULL;
 
     hr = init_output_buffer(This->xml_enc, &This->buffer);
     if (hr != S_OK) {
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 20c5e07443b..752ea2e485f 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -4504,7 +4504,6 @@ static void test_mxwriter_domdoc(void)
     V_DISPATCH(&dest) = (IDispatch *)domdoc;
 
     hr = IMXWriter_put_output(writer, dest);
-todo_wine
     ok(hr == S_OK, "Failed to set writer output, hr %#x.\n", hr);
     if (FAILED(hr))
     {
@@ -4567,6 +4566,7 @@ todo_wine
 todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
+    if (!node) return;
     hr = IXMLDOMNode_get_nodeName(node, &str);
 todo_wine {
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-- 
2.32.0



More information about the wine-devel mailing list