static HRESULT WINAPI ResProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, DWORD dwOptions) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); return E_NOTIMPL; }
static HRESULT WINAPI ResProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); return E_NOTIMPL; }
static ULONG WINAPI ResProtocol_AddRef(IInternetProtocol *iface) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p) ref=%d\n", iface, ref); return This->pUnkOuter ? IUnknown_AddRef(This->pUnkOuter) : ref; }
static HRESULT WINAPI ResProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); *ppv = NULL; if(IsEqualGUID(&IID_IUnknown, riid)) { TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); if(This->pUnkOuter) return IUnknown_QueryInterface(This->pUnkOuter, &IID_IUnknown, ppv); *ppv = &This->IInternetProtocol_iface; }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv); *ppv = &This->IInternetProtocol_iface; }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv); *ppv = &This->IInternetProtocol_iface; }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { FIXME("IServiceProvider is not implemented\n"); return E_NOINTERFACE; } if(!*ppv) { TRACE("unknown interface %s\n", debugstr_guid(riid)); return E_NOINTERFACE; } IInternetProtocol_AddRef(iface); return S_OK; }
static HRESULT WINAPI ResProtocol_UnlockRequest(IInternetProtocol *iface) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); TRACE("(%p)\n", This); /* test show that we don't have to do anything here */ return S_OK; }
static HRESULT WINAPI ResProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); TRACE("(%p)->(%d)\n", This, dwOptions); /* test show that we don't have to do anything here */ return S_OK; }
static ULONG WINAPI ResProtocol_Release(IInternetProtocol *iface) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); IUnknown *pUnkOuter = This->pUnkOuter; ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%x\n", iface, ref); if(!ref) { heap_free(This->data); heap_free(This); } return pUnkOuter ? IUnknown_Release(pUnkOuter) : ref; }
static HRESULT WINAPI ResProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); if(!This->data) return E_FAIL; *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb); if(!*pcbRead) return S_FALSE; memcpy(pv, This->data+This->cur, *pcbRead); This->cur += *pcbRead; return S_OK; }
static HRESULT WINAPI ResProtocol_Resume(IInternetProtocol *iface) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); FIXME("(%p)\n", This); return E_NOTIMPL; }
static HRESULT WINAPI ResProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData) { ResProtocol *This = ResProtocol_from_IInternetProtocol(iface); FIXME("(%p)->(%p)\n", This, pProtocolData); return E_NOTIMPL; }
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; }