static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { BindProtocol *This = impl_from_IInternetProtocolSink(iface); TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); if(!This->protocol_sink) return E_FAIL; This->reported_result = TRUE; if(!do_direct_notif(This)) { report_result_task_t *task; task = heap_alloc(sizeof(report_result_task_t)); if(!task) return E_OUTOFMEMORY; task->hres = hrResult; task->err = dwError; task->str = heap_strdupW(szResult); push_task(This, &task->header, report_result_proc); return S_OK; } return IInternetProtocolSink_ReportResult(This->protocol_sink_handler, hrResult, dwError, szResult); }
static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { AboutProtocol *This = PROTOCOL_THIS(iface); BINDINFO bindinfo; DWORD grfBINDF = 0; LPCWSTR text = NULL; static const WCHAR html_begin[] = {0xfeff,'<','H','T','M','L','>',0}; static const WCHAR html_end[] = {'<','/','H','T','M','L','>',0}; static const WCHAR wszBlank[] = {'b','l','a','n','k',0}; static const WCHAR wszAbout[] = {'a','b','o','u','t',':'}; static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; /* NOTE: * the about protocol seems not to work as I would expect. It creates html document * for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when * some_text = "blank", when document is blank (<HTML></HMTL>). The same happens * when the url does not have "about:" in the beginning. */ TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo); ReleaseBindInfo(&bindinfo); TRACE("bindf %x\n", grfBINDF); if(strlenW(szUrl)>=sizeof(wszAbout)/sizeof(WCHAR) && !memcmp(wszAbout, szUrl, sizeof(wszAbout))) { text = szUrl + sizeof(wszAbout)/sizeof(WCHAR); if(!strcmpW(wszBlank, text)) text = NULL; } This->data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR) + (text ? strlenW(text)*sizeof(WCHAR) : 0); This->data = heap_alloc(This->data_len); memcpy(This->data, html_begin, sizeof(html_begin)); if(text) strcatW((LPWSTR)This->data, text); strcatW((LPWSTR)This->data, html_end); This->cur = 0; IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml); IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, This->data_len, This->data_len); IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); return S_OK; }
static inline HRESULT report_result(Protocol *protocol, HRESULT hres) { if (!(protocol->flags & FLAG_RESULT_REPORTED) && protocol->protocol_sink) { protocol->flags |= FLAG_RESULT_REPORTED; IInternetProtocolSink_ReportResult(protocol->protocol_sink, hres, 0, NULL); } return hres; }
static void report_result_proc(BindProtocol *This, task_header_t *t) { report_result_task_t *task = (report_result_task_t*)t; IInternetProtocolSink_ReportResult(This->protocol_sink_handler, task->hres, task->err, task->str); heap_free(task->str); heap_free(task); }
static HRESULT WINAPI ProtocolProxySink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { ProtocolProxy *This = PROTSINK_THIS(iface); TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); }
static HRESULT WINAPI ProtocolSinkHandler_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { BindProtocol *This = impl_from_IInternetProtocolSinkHandler(iface); TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); if(This->protocol_sink) return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); return S_OK; }
static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface, HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { BindProtocol *This = PROTSINK_THIS(iface); TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); if(!This->protocol_sink) return E_FAIL; This->reported_result = TRUE; return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); }
static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres) { IInternetProtocolSink_ReportResult(sink, hres, 0, NULL); return hres; }
static HRESULT report_result(IInternetProtocolSink *sink, HRESULT hres, DWORD dwError) { IInternetProtocolSink_ReportResult(sink, hres, dwError, NULL); return hres; }
static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { FileProtocol *This = PROTOCOL_THIS(iface); BINDINFO bindinfo; DWORD grfBINDF = 0; LARGE_INTEGER size; DWORD len; LPWSTR url, mime = NULL, file_name; WCHAR null_char = 0; BOOL first_call = FALSE; HRESULT hres; static const WCHAR wszFile[] = {'f','i','l','e',':'}; TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); if(!szUrl || strlenW(szUrl) < sizeof(wszFile)/sizeof(WCHAR) || memcmp(szUrl, wszFile, sizeof(wszFile))) return E_INVALIDARG; memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); return hres; } ReleaseBindInfo(&bindinfo); len = lstrlenW(szUrl)+16; url = heap_alloc(len*sizeof(WCHAR)); hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0); if(FAILED(hres)) { heap_free(url); return hres; } if(!(grfBINDF & BINDF_FROMURLMON)) IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL); if(!This->file) { WCHAR *ptr; first_call = TRUE; IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char); file_name = url+sizeof(wszFile)/sizeof(WCHAR); /* Strip both forward and back slashes */ if( (file_name[0] == '/' && file_name[1] == '/') || (file_name[0] == '\\' && file_name[1] == '\\')) file_name += 2; if(*file_name == '/') file_name++; for(ptr = file_name; *ptr; ptr++) { if(*ptr == '?' || *ptr == '#') { *ptr = 0; break; } } if(file_name[1] == '|') file_name[1] = ':'; This->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(This->file == INVALID_HANDLE_VALUE) { This->file = NULL; IInternetProtocolSink_ReportResult(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, GetLastError(), NULL); heap_free(url); return INET_E_RESOURCE_NOT_FOUND; } IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_CACHEFILENAMEAVAILABLE, file_name); hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, (grfBINDF & BINDF_FROMURLMON) ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } } heap_free(url); if(GetFileSizeEx(This->file, &size)) IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION, size.u.LowPart, size.u.LowPart); if(first_call) IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); return S_OK; }
static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); WCHAR *url_dll, *url_file, *url, *mime, *res_type = (LPWSTR)RT_HTML, *ptr; DWORD grfBINDF = 0, len; BINDINFO bindinfo; HMODULE hdll; HRSRC src; HRESULT hres; static const WCHAR wszRes[] = {'r','e','s',':','/','/'}; TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo); if(FAILED(hres)) return hres; ReleaseBindInfo(&bindinfo); len = strlenW(szUrl)+16; url = heap_alloc(len*sizeof(WCHAR)); hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0); if(FAILED(hres)) { WARN("CoInternetParseUrl failed: %08x\n", hres); heap_free(url); IInternetProtocolSink_ReportResult(pOIProtSink, hres, 0, NULL); return hres; } if(len < sizeof(wszRes)/sizeof(wszRes[0]) || memcmp(url, wszRes, sizeof(wszRes))) { WARN("Wrong protocol of url: %s\n", debugstr_w(url)); IInternetProtocolSink_ReportResult(pOIProtSink, E_INVALIDARG, 0, NULL); heap_free(url); return E_INVALIDARG; } url_dll = url + sizeof(wszRes)/sizeof(wszRes[0]); if(!(res_type = strchrW(url_dll, '/'))) { WARN("wrong url: %s\n", debugstr_w(url)); IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL); heap_free(url); return MK_E_SYNTAX; } *res_type++ = 0; if ((url_file = strchrW(res_type, '/'))) { *url_file++ = 0; }else { url_file = res_type; res_type = MAKEINTRESOURCEW(RT_HTML); } /* Ignore query and hash parts. */ if((ptr = strchrW(url_file, '?'))) *ptr = 0; if((ptr = strchrW(url_file, '#'))) *ptr = 0; hdll = LoadLibraryExW(url_dll, NULL, LOAD_LIBRARY_AS_DATAFILE); if(!hdll) { WARN("Could not open dll: %s\n", debugstr_w(url_dll)); IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL); heap_free(url); return HRESULT_FROM_WIN32(GetLastError()); } 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) { LPWSTR endpoint = NULL; DWORD file_id = strtolW(url_file, &endpoint, 10); if(endpoint == url_file+strlenW(url_file)) src = FindResourceW(hdll, MAKEINTRESOURCEW(file_id), res_type); if(!src) { WARN("Could not find resource\n"); IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL); heap_free(url); return HRESULT_FROM_WIN32(GetLastError()); } } if(This->data) { WARN("data already loaded\n"); heap_free(This->data); } This->data_len = SizeofResource(hdll, src); This->data = heap_alloc(This->data_len); memcpy(This->data, LoadResource(hdll, src), This->data_len); This->cur = 0; FreeLibrary(hdll); hres = FindMimeFromData(NULL, url_file, This->data, This->data_len, NULL, 0, &mime, 0); heap_free(url); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, This->data_len, This->data_len); IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); return S_OK; }
static inline HRESULT report_result(IInternetProtocolSink *protocol_sink, HRESULT hres, DWORD res) { IInternetProtocolSink_ReportResult(protocol_sink, hres, res, NULL); return hres; }
static HRESULT HttpProtocol_start_downloading(Protocol *prot) { HttpProtocol *This = impl_from_Protocol(prot); LPWSTR content_type, content_length, ranges; DWORD len = sizeof(DWORD); DWORD status_code; BOOL res; HRESULT hres; static const WCHAR wszDefaultContentType[] = {'t','e','x','t','/','h','t','m','l',0}; if(!This->http_negotiate) { WARN("Expected IHttpNegotiate pointer to be non-NULL\n"); return S_OK; } res = HttpQueryInfoW(This->base.request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status_code, &len, NULL); if(res) { WCHAR *response_headers; if((This->base.bind_info.dwOptions & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS) && is_redirect_response(status_code)) { WCHAR *location; TRACE("Got redirect with disabled auto redirects\n"); location = query_http_info(This, HTTP_QUERY_LOCATION); This->base.flags |= FLAG_RESULT_REPORTED | FLAG_LAST_DATA_REPORTED; IInternetProtocolSink_ReportResult(This->base.protocol_sink, INET_E_REDIRECT_FAILED, 0, location); heap_free(location); return INET_E_REDIRECT_FAILED; } response_headers = query_http_info(This, HTTP_QUERY_RAW_HEADERS_CRLF); if(response_headers) { hres = IHttpNegotiate_OnResponse(This->http_negotiate, status_code, response_headers, NULL, NULL); heap_free(response_headers); if (hres != S_OK) { WARN("IHttpNegotiate_OnResponse failed: %08x\n", hres); return S_OK; } } }else { WARN("HttpQueryInfo failed: %d\n", GetLastError()); } ranges = query_http_info(This, HTTP_QUERY_ACCEPT_RANGES); if(ranges) { IInternetProtocolSink_ReportProgress(This->base.protocol_sink, BINDSTATUS_ACCEPTRANGES, NULL); heap_free(ranges); } content_type = query_http_info(This, HTTP_QUERY_CONTENT_TYPE); if(content_type) { /* remove the charset, if present */ LPWSTR p = strchrW(content_type, ';'); if (p) *p = '\0'; IInternetProtocolSink_ReportProgress(This->base.protocol_sink, (This->base.bindf & BINDF_FROMURLMON) ? BINDSTATUS_MIMETYPEAVAILABLE : BINDSTATUS_RAWMIMETYPE, content_type); heap_free(content_type); }else { WARN("HttpQueryInfo failed: %d\n", GetLastError()); IInternetProtocolSink_ReportProgress(This->base.protocol_sink, (This->base.bindf & BINDF_FROMURLMON) ? BINDSTATUS_MIMETYPEAVAILABLE : BINDSTATUS_RAWMIMETYPE, wszDefaultContentType); } content_length = query_http_info(This, HTTP_QUERY_CONTENT_LENGTH); if(content_length) { This->base.content_length = atoiW(content_length); heap_free(content_length); } return S_OK; }