static HRESULT handle_mime_filter(BindProtocol *This, IInternetProtocol *mime_filter) { PROTOCOLFILTERDATA filter_data = { sizeof(PROTOCOLFILTERDATA), NULL, NULL, NULL, 0 }; HRESULT hres; hres = IInternetProtocol_QueryInterface(mime_filter, &IID_IInternetProtocolSink, (void**)&This->protocol_sink_handler); if(FAILED(hres)) { This->protocol_sink_handler = &This->default_protocol_handler.IInternetProtocolSink_iface; return hres; } IInternetProtocol_AddRef(mime_filter); This->protocol_handler = mime_filter; filter_data.pProtocol = &This->default_protocol_handler.IInternetProtocol_iface; hres = IInternetProtocol_Start(mime_filter, This->mime, &This->default_protocol_handler.IInternetProtocolSink_iface, &This->IInternetBindInfo_iface, PI_FILTER_MODE|PI_FORCE_ASYNC, (HANDLE_PTR)&filter_data); if(FAILED(hres)) { IInternetProtocolSink_Release(This->protocol_sink_handler); IInternetProtocol_Release(This->protocol_handler); This->protocol_sink_handler = &This->default_protocol_handler.IInternetProtocolSink_iface; This->protocol_handler = &This->default_protocol_handler.IInternetProtocol_iface; return hres; } /* NOTE: IE9 calls it on the new protocol_sink. It doesn't make sense to is seems to be a bug there. */ IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_LOADINGMIMEHANDLER, NULL); return S_OK; }
static void WINAPI internet_status_callback(HINTERNET internet, DWORD_PTR context, DWORD internet_status, LPVOID status_info, DWORD status_info_len) { Protocol *protocol = (Protocol*)context; switch(internet_status) { case INTERNET_STATUS_RESOLVING_NAME: TRACE("%p INTERNET_STATUS_RESOLVING_NAME\n", protocol); report_progress(protocol, BINDSTATUS_FINDINGRESOURCE, (LPWSTR)status_info); break; case INTERNET_STATUS_CONNECTING_TO_SERVER: TRACE("%p INTERNET_STATUS_CONNECTING_TO_SERVER\n", protocol); report_progress(protocol, BINDSTATUS_CONNECTING, (LPWSTR)status_info); break; case INTERNET_STATUS_SENDING_REQUEST: TRACE("%p INTERNET_STATUS_SENDING_REQUEST\n", protocol); report_progress(protocol, BINDSTATUS_SENDINGREQUEST, (LPWSTR)status_info); break; case INTERNET_STATUS_REDIRECT: TRACE("%p INTERNET_STATUS_REDIRECT\n", protocol); report_progress(protocol, BINDSTATUS_REDIRECTING, (LPWSTR)status_info); break; case INTERNET_STATUS_REQUEST_COMPLETE: request_complete(protocol, status_info); break; case INTERNET_STATUS_HANDLE_CREATED: TRACE("%p INTERNET_STATUS_HANDLE_CREATED\n", protocol); IInternetProtocol_AddRef(protocol->protocol); break; case INTERNET_STATUS_HANDLE_CLOSING: TRACE("%p INTERNET_STATUS_HANDLE_CLOSING\n", protocol); if(*(HINTERNET *)status_info == protocol->request) { protocol->request = NULL; if(protocol->protocol_sink) { IInternetProtocolSink_Release(protocol->protocol_sink); protocol->protocol_sink = NULL; } if(protocol->bind_info.cbSize) { ReleaseBindInfo(&protocol->bind_info); memset(&protocol->bind_info, 0, sizeof(protocol->bind_info)); } }else if(*(HINTERNET *)status_info == protocol->connection) { protocol->connection = NULL; } IInternetProtocol_Release(protocol->protocol); break; default: WARN("Unhandled Internet status callback %d\n", internet_status); } }
static HRESULT handle_mime_filter(BindProtocol *This, IInternetProtocol *mime_filter, LPCWSTR mime) { PROTOCOLFILTERDATA filter_data = { sizeof(PROTOCOLFILTERDATA), NULL, NULL, NULL, 0 }; IInternetProtocolSink *protocol_sink, *old_sink; ProtocolProxy *filter_proxy; HRESULT hres; hres = IInternetProtocol_QueryInterface(mime_filter, &IID_IInternetProtocolSink, (void**)&protocol_sink); if(FAILED(hres)) return hres; hres = create_protocol_proxy(PROTOCOLHANDLER(This), This->protocol_sink, &filter_proxy); if(FAILED(hres)) { IInternetProtocolSink_Release(protocol_sink); return hres; } old_sink = This->protocol_sink; This->protocol_sink = protocol_sink; This->filter_proxy = filter_proxy; IInternetProtocol_AddRef(mime_filter); This->protocol_handler = mime_filter; filter_data.pProtocol = PROTOCOL(filter_proxy); hres = IInternetProtocol_Start(mime_filter, mime, PROTSINK(filter_proxy), BINDINFO(This), PI_FILTER_MODE|PI_FORCE_ASYNC, (HANDLE_PTR)&filter_data); if(FAILED(hres)) { IInternetProtocolSink_Release(old_sink); return hres; } IInternetProtocolSink_ReportProgress(old_sink, BINDSTATUS_LOADINGMIMEHANDLER, NULL); IInternetProtocolSink_Release(old_sink); This->pi &= ~PI_MIMEVERIFICATION; /* FIXME: more tests */ return S_OK; }
void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink) { BindProtocol *This = PROTOCOL_THIS(bind_protocol); IInternetProtocolSink *prev_sink; IServiceProvider *service_provider = NULL; if(sink) IInternetProtocolSink_AddRef(sink); prev_sink = InterlockedExchangePointer((void**)&This->protocol_sink, sink); if(prev_sink) IInternetProtocolSink_Release(prev_sink); if(sink) IInternetProtocolSink_QueryInterface(sink, &IID_IServiceProvider, (void**)&service_provider); service_provider = InterlockedExchangePointer((void**)&This->service_provider, service_provider); if(service_provider) IServiceProvider_Release(service_provider); }
static ULONG WINAPI ProtocolProxy_Release(IInternetProtocol *iface) { ProtocolProxy *This = PROTOCOL_THIS(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); if(!ref) { if(This->protocol_sink) IInternetProtocolSink_Release(This->protocol_sink); if(This->protocol) IInternetProtocol_Release(This->protocol); heap_free(This); URLMON_UnlockModule(); } return ref; }
static ULONG WINAPI BindProtocol_Release(IInternetProtocolEx *iface) { BindProtocol *This = impl_from_IInternetProtocolEx(iface); LONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) ref=%d\n", This, ref); if(!ref) { if(This->wininet_info) IWinInetInfo_Release(This->wininet_info); if(This->wininet_http_info) IWinInetHttpInfo_Release(This->wininet_http_info); if(This->protocol) IInternetProtocol_Release(This->protocol); if(This->bind_info) IInternetBindInfo_Release(This->bind_info); if(This->protocol_handler && This->protocol_handler != &This->default_protocol_handler.IInternetProtocol_iface) IInternetProtocol_Release(This->protocol_handler); if(This->protocol_sink_handler && This->protocol_sink_handler != &This->default_protocol_handler.IInternetProtocolSink_iface) IInternetProtocolSink_Release(This->protocol_sink_handler); if(This->uri) IUri_Release(This->uri); SysFreeString(This->display_uri); set_binding_sink(This, NULL, NULL); if(This->notif_hwnd) release_notif_hwnd(This->notif_hwnd); This->section.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->section); heap_free(This->mime); heap_free(This); URLMON_UnlockModule(); } return ref; }
void set_binding_sink(BindProtocol *This, IInternetProtocolSink *sink, IInternetBindInfo *bind_info) { IInternetProtocolSink *prev_sink; IServiceProvider *service_provider = NULL; if(sink) IInternetProtocolSink_AddRef(sink); prev_sink = InterlockedExchangePointer((void**)&This->protocol_sink, sink); if(prev_sink) IInternetProtocolSink_Release(prev_sink); if(sink) IInternetProtocolSink_QueryInterface(sink, &IID_IServiceProvider, (void**)&service_provider); service_provider = InterlockedExchangePointer((void**)&This->service_provider, service_provider); if(service_provider) IServiceProvider_Release(service_provider); if(bind_info) IInternetBindInfo_AddRef(bind_info); bind_info = InterlockedExchangePointer((void**)&This->bind_info, bind_info); if(bind_info) IInternetBindInfo_Release(bind_info); }