static HRESULT start_downloading(Protocol *protocol) { HRESULT hres; hres = protocol->vtbl->start_downloading(protocol); if(FAILED(hres)) { protocol_close_connection(protocol); report_result(protocol, hres); return hres; } if(protocol->bindf & BINDF_NEEDFILE) { WCHAR cache_file[MAX_PATH]; DWORD buflen = sizeof(cache_file); if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, cache_file, &buflen)) { report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file); }else { FIXME("Could not get cache file\n"); } } protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE; return S_OK; }
static HRESULT WINAPI FtpProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions) { FtpProtocol *This = impl_from_IInternetProtocolEx(iface); TRACE("(%p)->(%08x)\n", This, dwOptions); protocol_close_connection(&This->base); return S_OK; }
static HRESULT WINAPI HttpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions) { HttpProtocol *This = PROTOCOL_THIS(iface); TRACE("(%p)->(%08x)\n", This, dwOptions); protocol_close_connection(&This->base); return S_OK; }
static ULONG WINAPI FtpProtocol_Release(IInternetProtocolEx *iface) { FtpProtocol *This = impl_from_IInternetProtocolEx(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); if(!ref) { protocol_close_connection(&This->base); heap_free(This); URLMON_UnlockModule(); } return ref; }
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 void HttpProtocol_on_error(Protocol *prot, DWORD error) { HttpProtocol *This = impl_from_Protocol(prot); HRESULT hres; TRACE("(%p) %d\n", prot, error); if(prot->flags & FLAG_FIRST_CONTINUE_COMPLETE) { FIXME("Not handling error %d\n", error); return; } while((hres = handle_http_error(This, error)) == RPC_E_RETRY) { error = send_http_request(This); if(error == ERROR_IO_PENDING || error == ERROR_SUCCESS) return; } protocol_abort(prot, hres); protocol_close_connection(prot); return; }
HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data) { HRESULT hres; if (!data) { WARN("Expected pProtocolData to be non-NULL\n"); return S_OK; } if(!protocol->request) { WARN("Expected request to be non-NULL\n"); return S_OK; } if(!protocol->protocol_sink) { WARN("Expected IInternetProtocolSink pointer to be non-NULL\n"); return S_OK; } if(protocol->flags & FLAG_ERROR) { protocol->flags &= ~FLAG_ERROR; protocol->vtbl->on_error(protocol, (DWORD)data->pData); return S_OK; } if(protocol->post_stream) return write_post_stream(protocol); if(data->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA) { hres = protocol->vtbl->start_downloading(protocol); if(FAILED(hres)) { protocol_close_connection(protocol); report_result(protocol, hres); return S_OK; } if(protocol->bindf & BINDF_NEEDFILE) { WCHAR cache_file[MAX_PATH]; DWORD buflen = sizeof(cache_file); if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME, cache_file, &buflen)) { report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE, cache_file); }else { FIXME("Could not get cache file\n"); } } protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE; } if(data->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA) { BOOL res; /* InternetQueryDataAvailable may immediately fork and perform its asynchronous * read, so clear the flag _before_ calling so it does not incorrectly get cleared * after the status callback is called */ protocol->flags &= ~FLAG_REQUEST_COMPLETE; res = InternetQueryDataAvailable(protocol->request, &protocol->available_bytes, 0, 0); if(res) { protocol->flags |= FLAG_REQUEST_COMPLETE; report_data(protocol); }else if(GetLastError() != ERROR_IO_PENDING) { protocol->flags |= FLAG_REQUEST_COMPLETE; WARN("InternetQueryDataAvailable failed: %d\n", GetLastError()); report_result(protocol, INET_E_DATA_NOT_AVAILABLE); } } return S_OK; }