urlmon: Correctly handle hash part in file protocol handler.

This commit is contained in:
Jacek Caban 2015-05-19 16:36:48 +02:00 committed by Alexandre Julliard
parent 817d903cb9
commit 16274e78b6
2 changed files with 53 additions and 30 deletions

View file

@ -217,35 +217,14 @@ static inline HRESULT report_result(IInternetProtocolSink *protocol_sink, HRESUL
return hres;
}
static HRESULT open_file(FileProtocol *This, const WCHAR *path, IInternetProtocolSink *protocol_sink)
{
LARGE_INTEGER size;
HANDLE file;
file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(file == INVALID_HANDLE_VALUE)
return report_result(protocol_sink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
if(!GetFileSizeEx(file, &size)) {
CloseHandle(file);
return report_result(protocol_sink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
}
This->file = file;
This->size = size.u.LowPart;
IInternetProtocolSink_ReportProgress(protocol_sink,
BINDSTATUS_CACHEFILENAMEAVAILABLE, path);
return S_OK;
}
static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri,
IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
DWORD grfPI, HANDLE *dwReserved)
{
FileProtocol *This = impl_from_IInternetProtocolEx(iface);
WCHAR path[MAX_PATH];
WCHAR path[MAX_PATH], *ptr;
LARGE_INTEGER file_size;
HANDLE file_handle;
BINDINFO bindinfo;
DWORD grfBINDF = 0;
DWORD scheme, size;
@ -296,13 +275,31 @@ static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr
return report_result(pOIProtSink, hres, 0);
}
hres = open_file(This, path, pOIProtSink);
if(FAILED(hres))
return hres;
file_handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(file_handle == INVALID_HANDLE_VALUE && (ptr = strrchrW(path, '#'))) {
/* If path contains fragment part, try without it. */
*ptr = 0;
file_handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
if(file_handle == INVALID_HANDLE_VALUE)
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
if(!GetFileSizeEx(file_handle, &file_size)) {
CloseHandle(file_handle);
return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError());
}
This->file = file_handle;
This->size = file_size.u.LowPart;
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_CACHEFILENAMEAVAILABLE, path);
hres = IUri_GetExtension(pUri, &ext);
if(SUCCEEDED(hres)) {
if(hres == S_OK && *ext) {
if((ptr = strchrW(ext, '#')))
*ptr = 0;
hres = find_mime_from_ext(ext, &mime);
if(SUCCEEDED(hres)) {
IInternetProtocolSink_ReportProgress(pOIProtSink,

View file

@ -153,7 +153,7 @@ static PROTOCOLDATA protocoldata, *pdata, continue_protdata;
static DWORD prot_read, filter_state, http_post_test, thread_id;
static BOOL security_problem, test_async_req, impl_protex;
static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort;
static BOOL empty_file, no_mime, bind_from_cache;
static BOOL empty_file, no_mime, bind_from_cache, file_with_hash;
enum {
STATE_CONNECTING,
@ -907,7 +907,8 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR
ok(ulProgress == ulProgressMax, "ulProgress (%d) != ulProgressMax (%d)\n",
ulProgress, ulProgressMax);
ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
if(!file_with_hash)
ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
/* BSCF_SKIPDRAINDATAFORFILEURLS added in IE8 */
if(tested_protocol == FILE_TEST)
ok((grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION)) ||
@ -2396,6 +2397,7 @@ static void init_test(int prot, DWORD flags)
impl_protex = (flags & TEST_IMPLPROTEX) != 0;
empty_file = (flags & TEST_EMPTY) != 0;
bind_from_cache = (flags & TEST_FROMCACHE) != 0;
file_with_hash = FALSE;
register_filter(mimefilter_test);
}
@ -2530,6 +2532,8 @@ static void test_file_protocol_url(LPCWSTR url)
hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
ok(hres == S_OK, "Read failed: %08x\n", hres);
ok(cb == 2, "cb=%u expected 2\n", cb);
buf[2] = 0;
ok(!memcmp(buf, file_with_hash ? "XX" : "<H", 2), "Unexpected data %s\n", buf);
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
ok(hres == S_FALSE, "Read failed: %08x\n", hres);
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
@ -2564,7 +2568,10 @@ static void test_file_protocol_url(LPCWSTR url)
hres = IInternetProtocol_UnlockRequest(protocol);
ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
hres = IInternetProtocol_Read(protocol, buf, 2, &cb);
ok(hres == S_OK, "Read failed: %08x\n", hres);
if(file_with_hash) /* FIXME: An effect of UnlockRequest call? */
todo_wine ok(hres == S_OK, "Read failed: %08x\n", hres);
else
ok(hres == S_OK, "Read failed: %08x\n", hres);
hres = IInternetProtocol_Terminate(protocol, 0);
ok(hres == S_OK, "Terminate failed: %08x\n", hres);
}
@ -2717,6 +2724,7 @@ static void test_file_protocol(void) {
static const WCHAR wszFile3[] = {'f','i','l','e',':','/','/','/',0};
static const WCHAR wszFile4[] = {'f','i','l','e',':','\\','\\',0};
static const char html_doc[] = "<HTML></HTML>";
static const WCHAR fragmentW[] = {'#','f','r','a','g',0};
trace("Testing file protocol...\n");
init_test(FILE_TEST, 0);
@ -2790,7 +2798,25 @@ static void test_file_protocol(void) {
buf[sizeof(wszFile4)/sizeof(WCHAR)] = '|';
test_file_protocol_url(buf);
/* Fragment part of URL is skipped if the file doesn't exist. */
lstrcatW(buf, fragmentW);
test_file_protocol_url(buf);
/* Fragment part is considered a part of the file name, if the file exsists. */
len = lstrlenW(file_name_buf);
lstrcpyW(file_name_buf+len, fragmentW);
file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
WriteFile(file, "XXX", 3, &size, NULL);
CloseHandle(file);
file_name_buf[len] = 0;
file_with_hash = TRUE;
test_file_protocol_url(buf);
DeleteFileW(wszIndexHtml);
DeleteFileW(file_name_buf);
bindf = 0;
test_file_protocol_fail();