diff --git a/dlls/mshtml/protocol.c b/dlls/mshtml/protocol.c index 6f5b6be866..c0a1aa389e 100644 --- a/dlls/mshtml/protocol.c +++ b/dlls/mshtml/protocol.c @@ -32,6 +32,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +/* On https://docs.microsoft.com/en-us/previous-versions//aa767740(v=vs.85) + * the only mentioned resource types are RT_HTML and RT_FILE. + * RT_FILE is completely undocumented and doesn't appear in any headers, + * but by a process of elimination, the 2110 magic number used in + * https://www.codeproject.com/Articles/435/How-to-use-the-res-protocol-in-Developer-Studio + * must be RT_FILE. + */ +#define RT_FILE MAKEINTRESOURCE(2110) + typedef struct { IUnknown IUnknown_inner; IInternetProtocol IInternetProtocol_iface; @@ -540,6 +549,7 @@ static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, { InternetProtocol *This = impl_from_IInternetProtocol(iface); WCHAR *url_dll, *url_file, *url, *mime, *res_type = (LPWSTR)RT_HTML, *ptr; + BOOL restype_defaulted = FALSE; DWORD grfBINDF = 0, len; BINDINFO bindinfo; HMODULE hdll; @@ -594,6 +604,7 @@ static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, }else { url_file = res_type; res_type = (LPWSTR)RT_HTML; + restype_defaulted = TRUE; } /* Ignore query and hash parts. */ @@ -613,12 +624,16 @@ static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, TRACE("trying to find resource type %s, name %s\n", debugstr_w(res_type), debugstr_w(url_file)); src = FindResourceW(hdll, url_file, res_type); + if(!src && restype_defaulted) + src = FindResourceW(hdll, url_file, (LPCWSTR)RT_FILE); if(!src) { LPWSTR endpoint = NULL; DWORD file_id = wcstol(url_file, &endpoint, 10); - if(endpoint == url_file+lstrlenW(url_file)) + if(!*endpoint) { src = FindResourceW(hdll, MAKEINTRESOURCEW(file_id), res_type); - + if(!src && restype_defaulted) + src = FindResourceW(hdll, MAKEINTRESOURCEW(file_id), (LPCWSTR)RT_FILE); + } if(!src) { WARN("Could not find resource\n"); IInternetProtocolSink_ReportResult(pOIProtSink, diff --git a/dlls/mshtml/tests/protocol.c b/dlls/mshtml/tests/protocol.c index 75063f5ecf..66382507f2 100644 --- a/dlls/mshtml/tests/protocol.c +++ b/dlls/mshtml/tests/protocol.c @@ -262,6 +262,44 @@ static void protocol_start(IInternetProtocol *protocol, const WCHAR *url) CHECK_CALLED(ReportResult); } +static void test_res_url_fail(const char *url_suffix, HRESULT expected_hres, + BOOL expect_win32err) +{ + WCHAR url[INTERNET_MAX_URL_LENGTH]; + IInternetProtocol *protocol; + HRESULT hres; + + memcpy(url, res_url_base, res_url_base_len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, url_suffix, -1, url+res_url_base_len, ARRAY_SIZE(url)-res_url_base_len); + + hres = CoCreateInstance(&CLSID_ResProtocol, NULL, CLSCTX_INPROC_SERVER, &IID_IInternetProtocol, (void**)&protocol); + ok(hres == S_OK, "Could not create ResProtocol instance: %08x\n", hres); + + SET_EXPECT(GetBindInfo); + SET_EXPECT(ReportResult); + if (SUCCEEDED(expected_hres)) { + SET_EXPECT(ReportProgress); + SET_EXPECT(ReportData); + } + expect_hrResult = expected_hres; + expect_hr_win32err = expect_win32err; + hres = IInternetProtocol_Start(protocol, url, &protocol_sink, &bind_info, 0, 0); + if (expect_win32err) + ok((hres&0xffff0000) == ((FACILITY_WIN32 << 16)|0x80000000) || hres == expected_hres, + "%s: expected win32 err or %08x got: %08x\n", url_suffix, expected_hres, hres); + else + ok(hres == expected_hres, "%s: expected: %08x got: %08x\n", url_suffix, expected_hres, hres); + + + CHECK_CALLED(GetBindInfo); + if (SUCCEEDED(expected_hres)) { + CHECK_CALLED(ReportProgress); + CHECK_CALLED(ReportData); + } + CHECK_CALLED(ReportResult); + IInternetProtocol_Release(protocol); +} + static void test_res_url(const char *url_suffix) { WCHAR url[INTERNET_MAX_URL_LENGTH]; @@ -604,6 +642,17 @@ static void test_res_protocol(void) test_res_url("/23/123"); test_res_url("/jstest.html"); + test_res_url("/jstest-rtfile.html"); + test_res_url("/#2110/jstest-rtfile.html"); + test_res_url("/2110/jstest-rtfile.html"); + /* won't fall back to RT_FILE from: */ + /* - invalid string resource type: */ + test_res_url_fail("/doesntexist/jstest-rtfile.html", HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), TRUE); + /* - other numeric resource types (eg. 2 = RT_BITMAP): */ + test_res_url_fail("/2/jstest-rtfile.html", HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), TRUE); + /* - even from 23 = RT_HTML: */ + test_res_url_fail("/23/jstest-rtfile.html", HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), TRUE); + test_res_url("/Test/res.html"); test_res_url("/test/dir/dir2/res.html"); diff --git a/dlls/mshtml/tests/rsrc.rc b/dlls/mshtml/tests/rsrc.rc index 05bc836ac6..12e95b7456 100644 --- a/dlls/mshtml/tests/rsrc.rc +++ b/dlls/mshtml/tests/rsrc.rc @@ -28,6 +28,9 @@ asyncscriptload.js HTML "asyncscriptload.js" /* @makedep: jstest.html */ jstest.html HTML "jstest.html" +/* @makedep: jstest.html */ +jstest-rtfile.html 2110 "jstest.html" + /* @makedep: vbtest.html */ vbtest.html HTML "vbtest.html"