[PATCH] msxml3: Add support for loading document from relative URL provided by hosting site.

Dmitry Timoshkov dmitry at baikal.ru
Thu Jun 18 22:18:59 CDT 2020


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/msxml3/domdoc.c | 86 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 71 insertions(+), 15 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 76d3fdb601..390644d5da 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -41,6 +41,9 @@
 #include "ole2.h"
 #include "olectl.h"
 #include "msxml6.h"
+#include "mshtml.h"
+#include "docobj.h"
+#include "urlmon.h"
 #include "wininet.h"
 #include "winreg.h"
 #include "shlwapi.h"
@@ -2155,16 +2158,78 @@ static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
     return E_FAIL;
 }
 
-static HRESULT domdoc_load_moniker(domdoc *This, IMoniker *mon)
+static HRESULT domdoc_load_file(domdoc *This, LPWSTR filename, IUri **uri)
 {
+    IMoniker *mon, *base_mon = NULL;
     bsc_t *bsc;
     HRESULT hr;
 
-    hr = bind_url(mon, domdoc_onDataAvailable, This, &bsc);
-    if(FAILED(hr))
-        return hr;
+    if (This->site)
+    {
+        BSTR base_url = NULL;
+        IXMLDOMDocument *doc;
+        IHTMLDocument2 *doc2;
+        IOleClientSite *site;
+        IServiceProvider *sp;
 
-    return detach_bsc(bsc);
+        if (IUnknown_QueryInterface(This->site, &IID_IXMLDOMDocument, (void **)&doc) == S_OK)
+        {
+            IXMLDOMDocument_get_url(doc, &base_url);
+            IXMLDOMDocument_Release(doc);
+        }
+        else if (IUnknown_QueryInterface(This->site, &IID_IHTMLDocument2, (void **)&doc2) == S_OK)
+        {
+            IHTMLDocument2_get_URL(doc2, &base_url);
+            IHTMLDocument2_Release(doc2);
+        }
+        else if (IUnknown_QueryInterface(This->site, &IID_IServiceProvider, (void **)&sp) == S_OK)
+        {
+            if (IServiceProvider_QueryService(sp, &SID_SContainerDispatch, &IID_IXMLDOMDocument, (void **)&doc) == S_OK)
+            {
+                IXMLDOMDocument_get_url(doc, &base_url);
+                IXMLDOMDocument_Release(doc);
+            }
+            else if (IServiceProvider_QueryService(sp, &SID_SContainerDispatch, &IID_IHTMLDocument2, (void **)&doc2) == S_OK)
+            {
+                IHTMLDocument2_get_URL(doc2, &base_url);
+                IHTMLDocument2_Release(doc2);
+            }
+            IServiceProvider_Release(sp);
+        }
+        else if (IUnknown_QueryInterface(This->site, &IID_IOleClientSite, (void **)&site) == S_OK)
+        {
+            FIXME("IID_IOleClientSite => %p\n", site);
+            IOleClientSite_Release(site);
+        }
+
+        if (base_url)
+        {
+            TRACE("base_url: %s\n", debugstr_w(base_url));
+            CreateURLMonikerEx(NULL, base_url, &base_mon, 0);
+            SysFreeString(base_url);
+        }
+    }
+
+    if (base_mon) /* look for file starting from base URL */
+        hr = CreateUri(filename, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri);
+    else /* look for file in the PATH */
+        hr = create_uri(filename, uri);
+    if (hr == S_OK)
+    {
+        hr = CreateURLMonikerEx2(base_mon, *uri, &mon, 0);
+        if (hr == S_OK)
+        {
+            hr = bind_url(mon, domdoc_onDataAvailable, This, &bsc);
+            if (hr == S_OK)
+                hr = detach_bsc(bsc);
+            IMoniker_Release(mon);
+        }
+    }
+
+    if (base_mon)
+        IMoniker_Release(base_mon);
+
+    return hr;
 }
 
 static HRESULT WINAPI domdoc_load(
@@ -2293,7 +2358,6 @@ static HRESULT WINAPI domdoc_load(
     if ( filename )
     {
         IUri *uri = NULL;
-        IMoniker *mon;
 
         if (This->properties->uri)
         {
@@ -2301,15 +2365,7 @@ static HRESULT WINAPI domdoc_load(
             This->properties->uri = NULL;
         }
 
-        hr = create_uri(filename, &uri);
-        if (SUCCEEDED(hr))
-            hr = CreateURLMonikerEx2(NULL, uri, &mon, 0);
-        if ( SUCCEEDED(hr) )
-        {
-            hr = domdoc_load_moniker( This, mon );
-            IMoniker_Release(mon);
-        }
-
+        hr = domdoc_load_file(This, filename, &uri);
         if (SUCCEEDED(hr))
         {
             get_doc(This)->name = (char *)xmlchar_from_wcharn(filename, -1, TRUE);
-- 
2.26.2




More information about the wine-devel mailing list