Signed-off-by: Nikolay Sivov nsivov@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);