Jacek Caban : inetcomm: Added IInternetProtocolInfo:: CombineUrl implementation.

Alexandre Julliard julliard at winehq.org
Wed Feb 1 15:26:06 CST 2017


Module: wine
Branch: master
Commit: 3f644cb0bfdba11432f730c9cd1fb95cdb63c4b7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3f644cb0bfdba11432f730c9cd1fb95cdb63c4b7

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Feb  1 11:22:39 2017 +0100

inetcomm: Added IInternetProtocolInfo::CombineUrl implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/inetcomm/protocol.c      | 74 ++++++++++++++++++++++++++++++++++++--
 dlls/inetcomm/tests/mimeole.c | 83 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/dlls/inetcomm/protocol.c b/dlls/inetcomm/protocol.c
index f6600b9..300c139 100644
--- a/dlls/inetcomm/protocol.c
+++ b/dlls/inetcomm/protocol.c
@@ -24,6 +24,7 @@
 #include "inetcomm_private.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
 
@@ -36,6 +37,39 @@ typedef struct {
     IUnknown *outer_unk;
 } MimeHtmlProtocol;
 
+typedef struct {
+    const WCHAR *mhtml;
+    size_t mhtml_len;
+    const WCHAR *location;
+} mhtml_url_t;
+
+static const WCHAR mhtml_prefixW[] = {'m','h','t','m','l',':'};
+static const WCHAR mhtml_separatorW[] = {'!','x','-','u','s','c',':'};
+
+static HRESULT parse_mhtml_url(const WCHAR *url, mhtml_url_t *r)
+{
+    const WCHAR *p;
+
+    if(strncmpiW(url, mhtml_prefixW, sizeof(mhtml_prefixW)/sizeof(WCHAR)))
+        return E_FAIL;
+
+    r->mhtml = url + sizeof(mhtml_prefixW)/sizeof(WCHAR);
+    p = strchrW(r->mhtml, '!');
+    if(p) {
+        r->mhtml_len = p - r->mhtml;
+        /* FIXME: We handle '!' and '!x-usc:' in URLs as the same thing. Those should not be the same. */
+        if(!strncmpW(p, mhtml_separatorW, sizeof(mhtml_separatorW)/sizeof(WCHAR)))
+            p += sizeof(mhtml_separatorW)/sizeof(WCHAR);
+        else
+            p++;
+    }else {
+        r->mhtml_len = strlenW(r->mhtml);
+    }
+
+    r->location = p;
+    return S_OK;
+}
+
 static inline MimeHtmlProtocol *impl_from_IUnknown(IUnknown *iface)
 {
     return CONTAINING_RECORD(iface, MimeHtmlProtocol, IUnknown_inner);
@@ -247,10 +281,46 @@ static HRESULT WINAPI MimeHtmlProtocolInfo_CombineUrl(IInternetProtocolInfo *ifa
         DWORD cchResult, DWORD* pcchResult, DWORD dwReserved)
 {
     MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
-    FIXME("(%p)->(%s %s %08x %p %d %p %d)\n", This, debugstr_w(pwzBaseUrl),
+    size_t len = sizeof(mhtml_prefixW)/sizeof(WCHAR);
+    mhtml_url_t url;
+    WCHAR *p;
+    HRESULT hres;
+
+    TRACE("(%p)->(%s %s %08x %p %d %p %d)\n", This, debugstr_w(pwzBaseUrl),
           debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult,
           pcchResult, dwReserved);
-    return E_NOTIMPL;
+
+    hres = parse_mhtml_url(pwzBaseUrl, &url);
+    if(FAILED(hres))
+        return hres;
+
+    if(!strncmpiW(pwzRelativeUrl, mhtml_prefixW, sizeof(mhtml_prefixW)/sizeof(WCHAR))) {
+        FIXME("Relative URL is mhtml protocol\n");
+        return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
+    }
+
+    len += url.mhtml_len;
+    if(*pwzRelativeUrl)
+        len += strlenW(pwzRelativeUrl) + sizeof(mhtml_separatorW)/sizeof(WCHAR);
+    if(len >= cchResult) {
+        *pcchResult = 0;
+        return E_FAIL;
+    }
+
+    memcpy(pwzResult, mhtml_prefixW, sizeof(mhtml_prefixW));
+    p = pwzResult + sizeof(mhtml_prefixW)/sizeof(WCHAR);
+    memcpy(p, url.mhtml, url.mhtml_len*sizeof(WCHAR));
+    p += url.mhtml_len;
+    if(*pwzRelativeUrl) {
+        memcpy(p, mhtml_separatorW, sizeof(mhtml_separatorW));
+        p += sizeof(mhtml_separatorW)/sizeof(WCHAR);
+        strcpyW(p, pwzRelativeUrl);
+    }else {
+        *p = 0;
+    }
+
+    *pcchResult = len;
+    return S_OK;
 }
 
 static HRESULT WINAPI MimeHtmlProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
diff --git a/dlls/inetcomm/tests/mimeole.c b/dlls/inetcomm/tests/mimeole.c
index fe19893..3f07adc 100644
--- a/dlls/inetcomm/tests/mimeole.c
+++ b/dlls/inetcomm/tests/mimeole.c
@@ -27,6 +27,7 @@
 #include "ocidl.h"
 
 #include "mimeole.h"
+#include "wininet.h"
 
 #include <stdio.h>
 
@@ -1161,15 +1162,91 @@ static void test_MimeOleGetPropertySchema(void)
     IMimePropertySchema_Release(schema);
 }
 
+static const struct {
+    const char *base_url;
+    const char *relative_url;
+    const char *expected_result;
+    BOOL todo;
+} combine_tests[] = {
+    {
+        "mhtml:file:///c:/dir/test.mht", "http://test.org",
+        "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org"
+    }, {
+        "mhtml:file:///c:/dir/test.mht", "3D\"http://test.org\"",
+        "mhtml:file:///c:/dir/test.mht!x-usc:3D\"http://test.org\""
+    }, {
+        "mhtml:file:///c:/dir/test.mht", "123abc",
+        "mhtml:file:///c:/dir/test.mht!x-usc:123abc"
+    }, {
+        "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "123abc",
+        "mhtml:file:///c:/dir/test.mht!x-usc:123abc"
+    }, {
+        "MhtMl:file:///c:/dir/test.mht!x-usc:http://test.org/dir/dir2/file.html", "../..",
+        "mhtml:file:///c:/dir/test.mht!x-usc:../.."
+    }, {"mhtml:file:///c:/dir/test.mht!x-usc:file:///c:/dir/dir2/file.html", "../..",
+        "mhtml:file:///c:/dir/test.mht!x-usc:../.."
+    }, {
+        "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "",
+        "mhtml:file:///c:/dir/test.mht"
+    }, {
+        "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "mhtml:file:///d:/file.html",
+        "file:///d:/file.html", TRUE
+    }, {
+        "mhtml:file:///c:/dir/test.mht!x-usc:http://test.org", "mhtml:file:///c:/dir2/test.mht!x-usc:http://test.org",
+        "mhtml:file:///c:/dir2/test.mht!x-usc:http://test.org", TRUE
+    }, {
+        "mhtml:file:///c:/dir/test.mht!http://test.org", "123abc",
+        "mhtml:file:///c:/dir/test.mht!x-usc:123abc"
+    }, {
+        "mhtml:file:///c:/dir/test.mht!http://test.org", "",
+        "mhtml:file:///c:/dir/test.mht"
+    }
+};
+
 static void test_mhtml_protocol_info(void)
 {
+    WCHAR *base_url, *relative_url, combined_url[INTERNET_MAX_URL_LENGTH];
     IInternetProtocolInfo *protocol_info;
+    DWORD combined_len;
+    unsigned i, exlen;
     HRESULT hres;
 
+    static const WCHAR http_url[] = {'h','t','t','p',':','/','/','t','e','s','t','.','o','r','g',0};
+
     hres = CoCreateInstance(&CLSID_IMimeHtmlProtocol, NULL, CLSCTX_INPROC_SERVER,
                             &IID_IInternetProtocolInfo, (void**)&protocol_info);
     ok(hres == S_OK, "Could not create protocol info: %08x\n", hres);
 
+    for(i = 0; i < sizeof(combine_tests)/sizeof(*combine_tests); i++) {
+        base_url = a2w(combine_tests[i].base_url);
+        relative_url = a2w(combine_tests[i].relative_url);
+
+        combined_len = 0xdeadbeef;
+        hres = IInternetProtocolInfo_CombineUrl(protocol_info, base_url, relative_url, ICU_BROWSER_MODE,
+                                                combined_url, sizeof(combined_url)/sizeof(WCHAR), &combined_len, 0);
+        todo_wine_if(combine_tests[i].todo)
+        ok(hres == S_OK, "[%u] CombineUrl failed: %08x\n", i, hres);
+        if(SUCCEEDED(hres)) {
+            exlen = strlen(combine_tests[i].expected_result);
+            ok(combined_len == exlen, "[%u] combined len is %u, expected %u\n", i, combined_len, exlen);
+            ok(!strcmp_wa(combined_url, combine_tests[i].expected_result), "[%u] combined URL is %s, expected %s\n",
+               i, wine_dbgstr_w(combined_url), combine_tests[i].expected_result);
+
+            combined_len = 0xdeadbeef;
+            hres = IInternetProtocolInfo_CombineUrl(protocol_info, base_url, relative_url, ICU_BROWSER_MODE,
+                                                    combined_url, exlen, &combined_len, 0);
+            ok(hres == E_FAIL, "[%u] CombineUrl returned: %08x\n", i, hres);
+            ok(!combined_len, "[%u] combined_len = %u\n", i, combined_len);
+        }
+
+        HeapFree(GetProcessHeap(), 0, base_url);
+        HeapFree(GetProcessHeap(), 0, relative_url);
+    }
+
+    hres = IInternetProtocolInfo_CombineUrl(protocol_info, http_url, http_url, ICU_BROWSER_MODE,
+                                            combined_url, sizeof(combined_url)/sizeof(WCHAR), &combined_len, 0);
+    ok(hres == E_FAIL, "CombineUrl failed: %08x\n", hres);
+
     IInternetProtocolInfo_Release(protocol_info);
 }
 
@@ -1195,6 +1272,8 @@ static const IUnknownVtbl outer_vtbl = {
     outer_Release
 };
 
+static BOOL broken_mhtml_resolver;
+
 static void test_mhtml_protocol(void)
 {
     IUnknown outer = { &outer_vtbl };
@@ -1225,7 +1304,8 @@ static void test_mhtml_protocol(void)
 
     IClassFactory_Release(class_factory);
 
-    test_mhtml_protocol_info();
+    if(!broken_mhtml_resolver)
+        test_mhtml_protocol_info();
 }
 
 static void test_MimeOleObjectFromMoniker(void)
@@ -1261,6 +1341,7 @@ static void test_MimeOleObjectFromMoniker(void)
         IBindCtx_Release(bind_ctx);
         if(hres == INET_E_RESOURCE_NOT_FOUND) { /* winxp */
             win_skip("Broken MHTML behaviour found. Skipping some tests.\n");
+            broken_mhtml_resolver = TRUE;
             return;
         }
 




More information about the wine-cvs mailing list