Commit 3f644cb0 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

inetcomm: Added IInternetProtocolInfo::CombineUrl implementation.

parent 37792a26
......@@ -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,
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment