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 HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, DWORD *grfBINDF, BINDINFO *pbindinfo) { BindProtocol *This = BINDINFO_THIS(iface); HRESULT hres; TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); hres = IInternetBindInfo_GetBindInfo(This->bind_info, grfBINDF, pbindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); return hres; } *grfBINDF |= BINDF_FROMURLMON; return hres; }
HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, IUri *uri, IInternetProtocolSink *protocol_sink, IInternetBindInfo *bind_info) { DWORD request_flags; HRESULT hres; protocol->protocol = prot; IInternetProtocolSink_AddRef(protocol_sink); protocol->protocol_sink = protocol_sink; memset(&protocol->bind_info, 0, sizeof(protocol->bind_info)); protocol->bind_info.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(bind_info, &protocol->bindf, &protocol->bind_info); if(hres != S_OK) { WARN("GetBindInfo failed: %08x\n", hres); return report_result(protocol, hres); } if(!(protocol->bindf & BINDF_FROMURLMON)) report_progress(protocol, BINDSTATUS_DIRECTBIND, NULL); if(!get_internet_session(bind_info)) return report_result(protocol, INET_E_NO_SESSION); request_flags = INTERNET_FLAG_KEEP_CONNECTION; if(protocol->bindf & BINDF_NOWRITECACHE) request_flags |= INTERNET_FLAG_NO_CACHE_WRITE; if(protocol->bindf & BINDF_NEEDFILE) request_flags |= INTERNET_FLAG_NEED_FILE; hres = protocol->vtbl->open_request(protocol, uri, request_flags, internet_session, bind_info); if(FAILED(hres)) { protocol_close_connection(protocol); return report_result(protocol, hres); } return S_OK; }
static HRESULT WINAPI ITSProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { ITSProtocol *This = impl_from_IInternetProtocol(iface); BINDINFO bindinfo; DWORD bindf = 0, len; LPWSTR file_name, mime, object_name, p; LPCWSTR ptr; struct chmFile *chm_file; struct chmUnitInfo chm_object; int res; HRESULT hres; static const WCHAR separator[] = {':',':',0}; TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved); ptr = skip_schema(szUrl); if(!ptr) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); return hres; } ReleaseBindInfo(&bindinfo); len = strlenW(ptr)+3; file_name = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); memcpy(file_name, ptr, len*sizeof(WCHAR)); hres = UrlUnescapeW(file_name, NULL, &len, URL_UNESCAPE_INPLACE); if(FAILED(hres)) { WARN("UrlUnescape failed: %08x\n", hres); HeapFree(GetProcessHeap(), 0, file_name); return hres; } p = strstrW(file_name, separator); if(!p) { WARN("invalid url\n"); HeapFree(GetProcessHeap(), 0, file_name); return report_result(pOIProtSink, STG_E_FILENOTFOUND); } *p = 0; chm_file = chm_openW(file_name); if(!chm_file) { WARN("Could not open chm file\n"); HeapFree(GetProcessHeap(), 0, file_name); return report_result(pOIProtSink, STG_E_FILENOTFOUND); } object_name = p+2; len = strlenW(object_name); if(*object_name != '/' && *object_name != '\\') { memmove(object_name+1, object_name, (len+1)*sizeof(WCHAR)); *object_name = '/'; len++; } if(object_name[len-1] == '/') object_name[--len] = 0; for(p=object_name; *p; p++) { if(*p == '\\') *p = '/'; } remove_dot_segments(object_name); TRACE("Resolving %s\n", debugstr_w(object_name)); memset(&chm_object, 0, sizeof(chm_object)); res = chm_resolve_object(chm_file, object_name, &chm_object); if(res != CHM_RESOLVE_SUCCESS) { WARN("Could not resolve chm object\n"); HeapFree(GetProcessHeap(), 0, file_name); chm_close(chm_file); return report_result(pOIProtSink, STG_E_FILENOTFOUND); } IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, strrchrW(object_name, '/')+1); /* FIXME: Native doesn't use FindMimeFromData */ hres = FindMimeFromData(NULL, object_name, NULL, 0, NULL, 0, &mime, 0); HeapFree(GetProcessHeap(), 0, file_name); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } release_chm(This); /* Native leaks handle here */ This->chm_file = chm_file; This->chm_object = chm_object; hres = IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE, chm_object.length, chm_object.length); if(FAILED(hres)) { WARN("ReportData failed: %08x\n", hres); release_chm(This); return report_result(pOIProtSink, hres); } hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL); return report_result(pOIProtSink, hres); }
static HRESULT WINAPI MkProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE *dwReserved) { MkProtocol *This = impl_from_IInternetProtocolEx(iface); LPWSTR mime, progid, display_name, colon_ptr; DWORD bindf=0, eaten=0, scheme=0, len; BSTR url, path = NULL; IParseDisplayName *pdn; BINDINFO bindinfo; STATSTG statstg; IMoniker *mon; HRESULT hres; CLSID clsid; TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink, pOIBindInfo, grfPI, dwReserved); hres = IUri_GetScheme(pUri, &scheme); if(FAILED(hres)) return hres; if(scheme != URL_SCHEME_MK) return INET_E_INVALID_URL; memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(BINDINFO); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo); if(FAILED(hres)) { WARN("GetBindInfo failed: %08x\n", hres); return hres; } ReleaseBindInfo(&bindinfo); IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, NULL); hres = IUri_GetDisplayUri(pUri, &url); if(FAILED(hres)) return hres; hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0); SysFreeString(url); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } hres = IUri_GetPath(pUri, &path); if(FAILED(hres)) return hres; len = SysStringLen(path)+1; hres = UrlUnescapeW(path, NULL, &len, URL_UNESCAPE_INPLACE); if (FAILED(hres)) { SysFreeString(path); return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); } progid = path+1; /* skip '@' symbol */ colon_ptr = strchrW(path, ':'); if(!colon_ptr) { SysFreeString(path); return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); } len = strlenW(path); display_name = heap_alloc((len+1)*sizeof(WCHAR)); memcpy(display_name, path, (len+1)*sizeof(WCHAR)); progid[colon_ptr-progid] = 0; /* overwrite ':' with NULL terminator */ hres = CLSIDFromProgID(progid, &clsid); SysFreeString(path); if(FAILED(hres)) { heap_free(display_name); return report_result(pOIProtSink, INET_E_RESOURCE_NOT_FOUND, ERROR_INVALID_PARAMETER); } hres = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, &IID_IParseDisplayName, (void**)&pdn); if(FAILED(hres)) { WARN("Could not create object %s\n", debugstr_guid(&clsid)); heap_free(display_name); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } hres = IParseDisplayName_ParseDisplayName(pdn, NULL /* FIXME */, display_name, &eaten, &mon); heap_free(display_name); IParseDisplayName_Release(pdn); if(FAILED(hres)) { WARN("ParseDisplayName failed: %08x\n", hres); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } if(This->stream) { IStream_Release(This->stream); This->stream = NULL; } hres = IMoniker_BindToStorage(mon, NULL /* FIXME */, NULL, &IID_IStream, (void**)&This->stream); IMoniker_Release(mon); if(FAILED(hres)) { WARN("BindToStorage failed: %08x\n", hres); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } hres = IStream_Stat(This->stream, &statstg, STATFLAG_NONAME); if(FAILED(hres)) { WARN("Stat failed: %08x\n", hres); return report_result(pOIProtSink, hres, ERROR_INVALID_PARAMETER); } IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION, statstg.cbSize.u.LowPart, statstg.cbSize.u.LowPart); return report_result(pOIProtSink, S_OK, ERROR_SUCCESS); }
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 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], *ptr; LARGE_INTEGER file_size; HANDLE file_handle; BINDINFO bindinfo; DWORD grfBINDF = 0; DWORD scheme, size; LPWSTR mime = NULL; WCHAR null_char = 0; BSTR ext; HRESULT hres; TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink, pOIBindInfo, grfPI, dwReserved); if(!pUri) return E_INVALIDARG; scheme = 0; hres = IUri_GetScheme(pUri, &scheme); if(FAILED(hres)) return hres; if(scheme != URL_SCHEME_FILE) 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); if(!(grfBINDF & BINDF_FROMURLMON)) IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL); if(This->file != INVALID_HANDLE_VALUE) { IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION, This->size, This->size); return S_OK; } IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char); size = 0; hres = CoInternetParseIUri(pUri, PARSE_PATH_FROM_URL, 0, path, sizeof(path)/sizeof(WCHAR), &size, 0); if(FAILED(hres)) { WARN("CoInternetParseIUri failed: %08x\n", hres); return report_result(pOIProtSink, hres, 0); } 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, (grfBINDF & BINDF_FROMURLMON) ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } } SysFreeString(ext); } IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION, This->size, This->size); return report_result(pOIProtSink, S_OK, 0); }
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]; BINDINFO bindinfo; DWORD grfBINDF = 0; DWORD scheme, size; LPWSTR mime = NULL; WCHAR null_char = 0; BSTR url; HRESULT hres; TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink, pOIBindInfo, grfPI, dwReserved); if(!pUri) return E_INVALIDARG; scheme = 0; hres = IUri_GetScheme(pUri, &scheme); if(FAILED(hres)) return hres; if(scheme != URL_SCHEME_FILE) 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); if(!(grfBINDF & BINDF_FROMURLMON)) IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DIRECTBIND, NULL); if(This->file != INVALID_HANDLE_VALUE) { IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION, This->size, This->size); return S_OK; } IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char); size = 0; hres = CoInternetParseIUri(pUri, PARSE_PATH_FROM_URL, 0, path, sizeof(path)/sizeof(WCHAR), &size, 0); if(FAILED(hres)) { WARN("CoInternetParseIUri failed: %08x\n", hres); return report_result(pOIProtSink, hres, 0); } hres = open_file(This, path, pOIProtSink); if(FAILED(hres)) return hres; hres = IUri_GetDisplayUri(pUri, &url); if(hres == S_OK) { hres = FindMimeFromData(NULL, url, NULL, 0, NULL, 0, &mime, 0); SysFreeString(url); if(SUCCEEDED(hres)) { IInternetProtocolSink_ReportProgress(pOIProtSink, (grfBINDF & BINDF_FROMURLMON) ? BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE : BINDSTATUS_MIMETYPEAVAILABLE, mime); CoTaskMemFree(mime); } } IInternetProtocolSink_ReportData(pOIProtSink, BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION, This->size, This->size); return report_result(pOIProtSink, S_OK, 0); }