[PATCH 1/3] msxml3: Use IUri API to load documents

Nikolay Sivov nsivov at codeweavers.com
Tue Jan 23 02:27:54 CST 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/msxml3/bsc.c           |  25 ++++++++--
 dlls/msxml3/domdoc.c        |  49 ++++++++----------
 dlls/msxml3/msxml_private.h |   1 +
 dlls/msxml3/tests/domdoc.c  | 118 ++++++++++++++++++++++++++++----------------
 4 files changed, 118 insertions(+), 75 deletions(-)

diff --git a/dlls/msxml3/bsc.c b/dlls/msxml3/bsc.c
index d9519f37a8..05977a610b 100644
--- a/dlls/msxml3/bsc.c
+++ b/dlls/msxml3/bsc.c
@@ -242,24 +242,24 @@ static const struct IBindStatusCallbackVtbl bsc_vtbl =
     bsc_OnObjectAvailable
 };
 
-HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
+HRESULT create_uri(const WCHAR *url, IUri **uri)
 {
     WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
 
     TRACE("%s\n", debugstr_w(url));
 
-    if(!PathIsURLW(url))
+    if (!PathIsURLW(url))
     {
         WCHAR fullpath[MAX_PATH];
         DWORD needed = sizeof(fileUrl)/sizeof(WCHAR);
 
-        if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
+        if (!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
         {
             WARN("can't find path\n");
             return E_FAIL;
         }
 
-        if(FAILED(UrlCreateFromPathW(fullpath, fileUrl, &needed, 0)))
+        if (FAILED(UrlCreateFromPathW(fullpath, fileUrl, &needed, 0)))
         {
             ERR("can't create url from path\n");
             return E_FAIL;
@@ -267,7 +267,22 @@ HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
         url = fileUrl;
     }
 
-    return CreateURLMonikerEx(NULL, url, mon, 0);
+    return CreateUri(url, Uri_CREATE_ALLOW_RELATIVE | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, uri);
+}
+
+HRESULT create_moniker_from_url(LPCWSTR url, IMoniker **mon)
+{
+    HRESULT hr;
+    IUri *uri;
+
+    TRACE("%s\n", debugstr_w(url));
+
+    if (FAILED(hr = create_uri(url, &uri)))
+        return hr;
+
+    hr = CreateURLMonikerEx2(NULL, uri, mon, 0);
+    IUri_Release(uri);
+    return hr;
 }
 
 HRESULT bind_url(IMoniker *mon, HRESULT (*onDataAvailable)(void*,char*,DWORD),
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index a40fac2106..87a167e46e 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -86,7 +86,7 @@ typedef struct {
     xmlChar const* selectNsStr;
     LONG selectNsStr_len;
     BOOL XPath;
-    WCHAR *url;
+    IUri *uri;
 } domdoc_properties;
 
 typedef struct ConnectionPoint ConnectionPoint;
@@ -298,8 +298,8 @@ static domdoc_properties *create_properties(MSXML_VERSION version)
     properties->version = version;
     properties->XPath = (version == MSXML4 || version == MSXML6);
 
-    /* document url */
-    properties->url = NULL;
+    /* document uri */
+    properties->uri = NULL;
 
     return properties;
 }
@@ -335,16 +335,9 @@ static domdoc_properties* copy_properties(domdoc_properties const* properties)
             list_add_tail(&pcopy->selectNsList, &new_ns->entry);
         }
 
-        if (properties->url)
-        {
-            int len = strlenW(properties->url);
-
-            pcopy->url = CoTaskMemAlloc((len+1)*sizeof(WCHAR));
-            memcpy(pcopy->url, properties->url, len*sizeof(WCHAR));
-            pcopy->url[len] = 0;
-        }
-        else
-            pcopy->url = NULL;
+        pcopy->uri = properties->uri;
+        if (pcopy->uri)
+            IUri_AddRef(pcopy->uri);
     }
 
     return pcopy;
@@ -358,7 +351,8 @@ static void free_properties(domdoc_properties* properties)
             IXMLDOMSchemaCollection2_Release(properties->schemaCache);
         clear_selectNsList(&properties->selectNsList);
         heap_free((xmlChar*)properties->selectNsStr);
-        CoTaskMemFree(properties->url);
+        if (properties->uri)
+            IUri_Release(properties->uri);
         heap_free(properties);
     }
 }
@@ -2293,16 +2287,20 @@ static HRESULT WINAPI domdoc_load(
     if ( filename )
     {
         IMoniker *mon;
+        IUri *uri;
 
-        CoTaskMemFree(This->properties->url);
-        This->properties->url = NULL;
+        if (This->properties->uri)
+        {
+            IUri_Release(This->properties->uri);
+            This->properties->uri = NULL;
+        }
 
-        hr = create_moniker_from_url( filename, &mon);
+        hr = create_uri(filename, &uri);
+        if (SUCCEEDED(hr))
+            hr = CreateURLMonikerEx2(NULL, uri, &mon, 0);
         if ( SUCCEEDED(hr) )
         {
             hr = domdoc_load_moniker( This, mon );
-            if (hr == S_OK)
-                IMoniker_GetDisplayName(mon, NULL, NULL, &This->properties->url);
             IMoniker_Release(mon);
         }
 
@@ -2310,6 +2308,7 @@ static HRESULT WINAPI domdoc_load(
             This->error = E_FAIL;
         else
         {
+            This->properties->uri = uri;
             hr = This->error = S_OK;
             *isSuccessful = VARIANT_TRUE;
         }
@@ -2374,16 +2373,10 @@ static HRESULT WINAPI domdoc_get_url(
     if (!url)
         return E_INVALIDARG;
 
-    if (This->properties->url)
-    {
-        *url = SysAllocString(This->properties->url);
-        if (!*url)
-            return E_OUTOFMEMORY;
-
-        return S_OK;
-    }
-    else
+    if (!This->properties->uri)
         return return_null_bstr(url);
+
+    return IUri_GetPropertyBSTR(This->properties->uri, Uri_PROPERTY_DISPLAY_URI, url, 0);
 }
 
 
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 4bcac932d0..8d7833b083 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -544,6 +544,7 @@ static inline const CLSID* SchemaCache_version(MSXML_VERSION v)
 typedef struct bsc_t bsc_t;
 
 HRESULT create_moniker_from_url(LPCWSTR, IMoniker**) DECLSPEC_HIDDEN;
+HRESULT create_uri(const WCHAR *, IUri **) DECLSPEC_HIDDEN;
 HRESULT bind_url(IMoniker*, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, bsc_t**) DECLSPEC_HIDDEN;
 HRESULT detach_bsc(bsc_t*) DECLSPEC_HIDDEN;
 
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 7c56015235..81e24935a4 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -10152,13 +10152,68 @@ static void write_to_file(const char *name, const char *data)
     CloseHandle(hfile);
 }
 
+static void test_doc_load_from_path(IXMLDOMDocument *doc, const char *path)
+{
+    IXMLDOMDocument *doc2;
+    IXMLDOMElement *elem;
+    BSTR url, url2;
+    VARIANT_BOOL b;
+    VARIANT src;
+    HRESULT hr;
+
+    url = _bstr_(path);
+
+    V_VT(&src) = VT_BSTR;
+    V_BSTR(&src) = url;
+    hr = IXMLDOMDocument_load(doc, src, &b);
+    ok(hr == S_OK, "Failed to load document, %#x.\n", hr);
+    ok(b == VARIANT_TRUE, "got %d\n", b);
+
+    V_VT(&src) = VT_BSTR | VT_BYREF;
+    V_BSTRREF(&src) = &url;
+    hr = IXMLDOMDocument_load(doc, src, &b);
+    ok(hr == S_OK, "Failed to load document, %#x.\n", hr);
+    ok(b == VARIANT_TRUE, "got %d\n", b);
+
+    url = NULL;
+    hr = IXMLDOMDocument_get_url(doc, &url);
+    ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr);
+
+    hr = IXMLDOMDocument_get_documentElement(doc, &elem);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    /* Create another instance for the same document, check url */
+    hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
+    ok(hr == S_OK, "Failed to get owner document, hr %#x.\n", hr);
+
+    hr = IXMLDOMDocument_get_url(doc2, &url2);
+    ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr);
+    ok(!lstrcmpW(url, url2), "Unexpected url %s.\n", wine_dbgstr_w(url2));
+
+    IXMLDOMDocument_Release(doc2);
+    IXMLDOMElement_Release(elem);
+    SysFreeString(url2);
+    SysFreeString(url);
+}
+
+static void url_forward_slash(char *url)
+{
+    char *p = url;
+
+    while (*p)
+    {
+        if (*p == '\\')
+            *p = '/';
+        p++;
+    }
+}
+
 static void test_load(void)
 {
-    IXMLDOMDocument *doc, *doc2;
-    BSTR pathW, bstr1, bstr2;
+    char path[MAX_PATH], path2[MAX_PATH];
     IXMLDOMNodeList *list;
-    IXMLDOMElement *elem;
-    char path[MAX_PATH];
+    IXMLDOMDocument *doc;
+    BSTR bstr1, bstr2;
     VARIANT_BOOL b;
     VARIANT src;
     HRESULT hr;
@@ -10179,47 +10234,26 @@ static void test_load(void)
     EXPECT_HR(hr, E_INVALIDARG);
     ok(b == VARIANT_FALSE, "got %d\n", b);
 
-    pathW = _bstr_(path);
-
-    /* load from path: VT_BSTR */
-    V_VT(&src) = VT_BSTR;
-    V_BSTR(&src) = pathW;
-    hr = IXMLDOMDocument_load(doc, src, &b);
-    EXPECT_HR(hr, S_OK);
-    ok(b == VARIANT_TRUE, "got %d\n", b);
-
-    bstr1 = NULL;
-    hr = IXMLDOMDocument_get_url(doc, &bstr1);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-    SysFreeString(bstr1);
-
-    /* load from a path: VT_BSTR|VT_BYREF */
-    V_VT(&src) = VT_BSTR | VT_BYREF;
-    V_BSTRREF(&src) = &pathW;
-    hr = IXMLDOMDocument_load(doc, src, &b);
-    EXPECT_HR(hr, S_OK);
-    ok(b == VARIANT_TRUE, "got %d\n", b);
-
-    bstr1 = NULL;
-    hr = IXMLDOMDocument_get_url(doc, &bstr1);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-
-    hr = IXMLDOMDocument_get_documentElement(doc, &elem);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
+    /* "file://" url */
+    strcpy(path2, "file://");
+    strcat(path2, path);
+    test_doc_load_from_path(doc, path2);
 
-    /* create another instance for the same document, check url */
-    hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
+    /* file:// url, forward slashes */
+    url_forward_slash(path2);
+    test_doc_load_from_path(doc, path2);
 
-    hr = IXMLDOMDocument_get_url(doc, &bstr2);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-    ok(!lstrcmpW(bstr1, bstr2), "got %s\n", wine_dbgstr_w(bstr2));
+    /* "file:/" url */
+    strcpy(path2, "file:/");
+    strcat(path2, path);
+    test_doc_load_from_path(doc, path);
 
-    IXMLDOMDocument_Release(doc2);
-    IXMLDOMElement_Release(elem);
+    /* file:/ with forward slashes. */
+    url_forward_slash(path2);
+    test_doc_load_from_path(doc, path2);
 
-    SysFreeString(bstr1);
-    SysFreeString(bstr2);
+    /* Regular local path. */
+    test_doc_load_from_path(doc, path);
 
     /* load from a path: VT_BSTR|VT_BYREF, null ptr */
     V_VT(&src) = VT_BSTR | VT_BYREF;
@@ -10239,7 +10273,7 @@ static void test_load(void)
     write_to_file(path, nocontent);
 
     V_VT(&src) = VT_BSTR;
-    V_BSTR(&src) = pathW;
+    V_BSTR(&src) = _bstr_(path);
     b = VARIANT_TRUE;
     hr = IXMLDOMDocument_load(doc, src, &b);
     ok(hr == S_FALSE, "got 0x%08x\n", hr);
-- 
2.15.1




More information about the wine-devel mailing list