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