Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbindprot.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2007-2009 Jacek Caban for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "urlmon_main.h" 00020 #include "wine/debug.h" 00021 00022 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 00023 00024 typedef void (*task_proc_t)(BindProtocol*,task_header_t*); 00025 00026 struct _task_header_t { 00027 task_proc_t proc; 00028 task_header_t *next; 00029 }; 00030 00031 #define BUFFER_SIZE 2048 00032 #define MIME_TEST_SIZE 255 00033 00034 #define WM_MK_CONTINUE (WM_USER+101) 00035 #define WM_MK_RELEASE (WM_USER+102) 00036 00037 static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 00038 { 00039 switch(msg) { 00040 case WM_MK_CONTINUE: { 00041 BindProtocol *This = (BindProtocol*)lParam; 00042 task_header_t *task; 00043 00044 while(1) { 00045 EnterCriticalSection(&This->section); 00046 00047 task = This->task_queue_head; 00048 if(task) { 00049 This->task_queue_head = task->next; 00050 if(!This->task_queue_head) 00051 This->task_queue_tail = NULL; 00052 } 00053 00054 LeaveCriticalSection(&This->section); 00055 00056 if(!task) 00057 break; 00058 00059 This->continue_call++; 00060 task->proc(This, task); 00061 This->continue_call--; 00062 } 00063 00064 IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 00065 return 0; 00066 } 00067 case WM_MK_RELEASE: { 00068 tls_data_t *data = get_tls_data(); 00069 00070 if(!--data->notif_hwnd_cnt) { 00071 DestroyWindow(hwnd); 00072 data->notif_hwnd = NULL; 00073 } 00074 } 00075 } 00076 00077 return DefWindowProcW(hwnd, msg, wParam, lParam); 00078 } 00079 00080 HWND get_notif_hwnd(void) 00081 { 00082 static ATOM wnd_class = 0; 00083 tls_data_t *tls_data; 00084 00085 static const WCHAR wszURLMonikerNotificationWindow[] = 00086 {'U','R','L',' ','M','o','n','i','k','e','r',' ', 00087 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0}; 00088 00089 tls_data = get_tls_data(); 00090 if(!tls_data) 00091 return NULL; 00092 00093 if(tls_data->notif_hwnd_cnt) { 00094 tls_data->notif_hwnd_cnt++; 00095 return tls_data->notif_hwnd; 00096 } 00097 00098 if(!wnd_class) { 00099 static WNDCLASSEXW wndclass = { 00100 sizeof(wndclass), 0, 00101 notif_wnd_proc, 0, 0, 00102 NULL, NULL, NULL, NULL, NULL, 00103 wszURLMonikerNotificationWindow, 00104 NULL 00105 }; 00106 00107 wndclass.hInstance = hProxyDll; 00108 00109 wnd_class = RegisterClassExW(&wndclass); 00110 if (!wnd_class && GetLastError() == ERROR_CLASS_ALREADY_EXISTS) 00111 wnd_class = 1; 00112 } 00113 00114 tls_data->notif_hwnd = CreateWindowExW(0, wszURLMonikerNotificationWindow, 00115 wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE, 00116 NULL, hProxyDll, NULL); 00117 if(tls_data->notif_hwnd) 00118 tls_data->notif_hwnd_cnt++; 00119 00120 TRACE("hwnd = %p\n", tls_data->notif_hwnd); 00121 00122 return tls_data->notif_hwnd; 00123 } 00124 00125 void release_notif_hwnd(HWND hwnd) 00126 { 00127 tls_data_t *data = get_tls_data(); 00128 00129 if(!data) 00130 return; 00131 00132 if(data->notif_hwnd != hwnd) { 00133 PostMessageW(data->notif_hwnd, WM_MK_RELEASE, 0, 0); 00134 return; 00135 } 00136 00137 if(!--data->notif_hwnd_cnt) { 00138 DestroyWindow(data->notif_hwnd); 00139 data->notif_hwnd = NULL; 00140 } 00141 } 00142 00143 static void push_task(BindProtocol *This, task_header_t *task, task_proc_t proc) 00144 { 00145 BOOL do_post = FALSE; 00146 00147 task->proc = proc; 00148 task->next = NULL; 00149 00150 EnterCriticalSection(&This->section); 00151 00152 if(This->task_queue_tail) { 00153 This->task_queue_tail->next = task; 00154 This->task_queue_tail = task; 00155 }else { 00156 This->task_queue_tail = This->task_queue_head = task; 00157 do_post = !This->continue_call; 00158 } 00159 00160 LeaveCriticalSection(&This->section); 00161 00162 if(do_post) { 00163 IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 00164 PostMessageW(This->notif_hwnd, WM_MK_CONTINUE, 0, (LPARAM)This); 00165 } 00166 } 00167 00168 static inline BOOL do_direct_notif(BindProtocol *This) 00169 { 00170 return !(This->pi & PI_APARTMENTTHREADED) || (This->apartment_thread == GetCurrentThreadId() && !This->continue_call); 00171 } 00172 00173 static HRESULT handle_mime_filter(BindProtocol *This, IInternetProtocol *mime_filter, LPCWSTR mime) 00174 { 00175 PROTOCOLFILTERDATA filter_data = { sizeof(PROTOCOLFILTERDATA), NULL, NULL, NULL, 0 }; 00176 IInternetProtocolSink *protocol_sink, *old_sink; 00177 ProtocolProxy *filter_proxy; 00178 HRESULT hres; 00179 00180 hres = IInternetProtocol_QueryInterface(mime_filter, &IID_IInternetProtocolSink, (void**)&protocol_sink); 00181 if(FAILED(hres)) 00182 return hres; 00183 00184 hres = create_protocol_proxy(&This->default_protocol_handler.IInternetProtocol_iface, This->protocol_sink, &filter_proxy); 00185 if(FAILED(hres)) { 00186 IInternetProtocolSink_Release(protocol_sink); 00187 return hres; 00188 } 00189 00190 old_sink = This->protocol_sink; 00191 This->protocol_sink = protocol_sink; 00192 This->filter_proxy = filter_proxy; 00193 00194 IInternetProtocol_AddRef(mime_filter); 00195 This->protocol_handler = mime_filter; 00196 00197 filter_data.pProtocol = &filter_proxy->IInternetProtocol_iface; 00198 hres = IInternetProtocol_Start(mime_filter, mime, &filter_proxy->IInternetProtocolSink_iface, 00199 &This->IInternetBindInfo_iface, PI_FILTER_MODE|PI_FORCE_ASYNC, 00200 (HANDLE_PTR)&filter_data); 00201 if(FAILED(hres)) { 00202 IInternetProtocolSink_Release(old_sink); 00203 return hres; 00204 } 00205 00206 IInternetProtocolSink_ReportProgress(old_sink, BINDSTATUS_LOADINGMIMEHANDLER, NULL); 00207 IInternetProtocolSink_Release(old_sink); 00208 00209 This->pi &= ~PI_MIMEVERIFICATION; /* FIXME: more tests */ 00210 return S_OK; 00211 } 00212 00213 static void mime_available(BindProtocol *This, LPCWSTR mime, BOOL verified) 00214 { 00215 IInternetProtocol *mime_filter; 00216 HRESULT hres; 00217 00218 heap_free(This->mime); 00219 This->mime = NULL; 00220 00221 mime_filter = get_mime_filter(mime); 00222 if(mime_filter) { 00223 TRACE("Got mime filter for %s\n", debugstr_w(mime)); 00224 00225 hres = handle_mime_filter(This, mime_filter, mime); 00226 IInternetProtocol_Release(mime_filter); 00227 if(FAILED(hres)) 00228 FIXME("MIME filter failed: %08x\n", hres); 00229 }else { 00230 This->mime = heap_strdupW(mime); 00231 00232 if(verified || !(This->pi & PI_MIMEVERIFICATION)) { 00233 This->reported_mime = TRUE; 00234 00235 if(This->protocol_sink) 00236 IInternetProtocolSink_ReportProgress(This->protocol_sink, BINDSTATUS_MIMETYPEAVAILABLE, mime); 00237 } 00238 } 00239 } 00240 00241 static inline BindProtocol *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) 00242 { 00243 return CONTAINING_RECORD(iface, BindProtocol, IInternetProtocolEx_iface); 00244 } 00245 00246 static HRESULT WINAPI BindProtocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) 00247 { 00248 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00249 00250 *ppv = NULL; 00251 if(IsEqualGUID(&IID_IUnknown, riid)) { 00252 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 00253 *ppv = &This->IInternetProtocolEx_iface; 00254 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { 00255 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv); 00256 *ppv = &This->IInternetProtocolEx_iface; 00257 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { 00258 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv); 00259 *ppv = &This->IInternetProtocolEx_iface; 00260 }else if(IsEqualGUID(&IID_IInternetProtocolEx, riid)) { 00261 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This, ppv); 00262 *ppv = &This->IInternetProtocolEx_iface; 00263 }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) { 00264 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv); 00265 *ppv = &This->IInternetBindInfo_iface; 00266 }else if(IsEqualGUID(&IID_IInternetPriority, riid)) { 00267 TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv); 00268 *ppv = &This->IInternetPriority_iface; 00269 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) { 00270 FIXME("(%p)->(IID_IAuthenticate %p)\n", This, ppv); 00271 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { 00272 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); 00273 *ppv = &This->IServiceProvider_iface; 00274 }else if(IsEqualGUID(&IID_IInternetProtocolSink, riid)) { 00275 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This, ppv); 00276 *ppv = &This->IInternetProtocolSink_iface; 00277 }else if(IsEqualGUID(&IID_IWinInetInfo, riid)) { 00278 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This, ppv); 00279 00280 if(This->protocol) { 00281 IWinInetInfo *inet_info; 00282 HRESULT hres; 00283 00284 hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetInfo, (void**)&inet_info); 00285 if(SUCCEEDED(hres)) { 00286 *ppv = &This->IWinInetHttpInfo_iface; 00287 IWinInetInfo_Release(inet_info); 00288 } 00289 } 00290 }else if(IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { 00291 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This, ppv); 00292 00293 if(This->protocol) { 00294 IWinInetHttpInfo *http_info; 00295 HRESULT hres; 00296 00297 hres = IInternetProtocol_QueryInterface(This->protocol, &IID_IWinInetHttpInfo, (void**)&http_info); 00298 if(SUCCEEDED(hres)) { 00299 *ppv = &This->IWinInetHttpInfo_iface; 00300 IWinInetHttpInfo_Release(http_info); 00301 } 00302 } 00303 }else { 00304 WARN("not supported interface %s\n", debugstr_guid(riid)); 00305 } 00306 00307 if(!*ppv) 00308 return E_NOINTERFACE; 00309 00310 IUnknown_AddRef((IUnknown*)*ppv); 00311 return S_OK; 00312 } 00313 00314 static ULONG WINAPI BindProtocol_AddRef(IInternetProtocolEx *iface) 00315 { 00316 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00317 LONG ref = InterlockedIncrement(&This->ref); 00318 TRACE("(%p) ref=%d\n", This, ref); 00319 return ref; 00320 } 00321 00322 static ULONG WINAPI BindProtocol_Release(IInternetProtocolEx *iface) 00323 { 00324 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00325 LONG ref = InterlockedDecrement(&This->ref); 00326 00327 TRACE("(%p) ref=%d\n", This, ref); 00328 00329 if(!ref) { 00330 if(This->wininet_info) 00331 IWinInetInfo_Release(This->wininet_info); 00332 if(This->wininet_http_info) 00333 IWinInetHttpInfo_Release(This->wininet_http_info); 00334 if(This->protocol) 00335 IInternetProtocol_Release(This->protocol); 00336 if(This->bind_info) 00337 IInternetBindInfo_Release(This->bind_info); 00338 if(This->protocol_handler && This->protocol_handler != &This->default_protocol_handler.IInternetProtocol_iface) 00339 IInternetProtocol_Release(This->protocol_handler); 00340 if(This->filter_proxy) 00341 IInternetProtocol_Release(&This->filter_proxy->IInternetProtocol_iface); 00342 if(This->uri) 00343 IUri_Release(This->uri); 00344 00345 set_binding_sink(This, NULL, NULL); 00346 00347 if(This->notif_hwnd) 00348 release_notif_hwnd(This->notif_hwnd); 00349 DeleteCriticalSection(&This->section); 00350 00351 heap_free(This->mime); 00352 heap_free(This); 00353 00354 URLMON_UnlockModule(); 00355 } 00356 00357 return ref; 00358 } 00359 00360 static HRESULT WINAPI BindProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, 00361 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, 00362 DWORD grfPI, HANDLE_PTR dwReserved) 00363 { 00364 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00365 IUri *uri; 00366 HRESULT hres; 00367 00368 TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, 00369 pOIBindInfo, grfPI, dwReserved); 00370 00371 hres = CreateUri(szUrl, Uri_CREATE_FILE_USE_DOS_PATH, 0, &uri); 00372 if(FAILED(hres)) 00373 return hres; 00374 00375 hres = IInternetProtocolEx_StartEx(&This->IInternetProtocolEx_iface, uri, pOIProtSink, 00376 pOIBindInfo, grfPI, (HANDLE*)dwReserved); 00377 00378 IUri_Release(uri); 00379 return hres; 00380 } 00381 00382 static HRESULT WINAPI BindProtocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData) 00383 { 00384 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00385 00386 TRACE("(%p)->(%p)\n", This, pProtocolData); 00387 00388 return IInternetProtocol_Continue(This->protocol_handler, pProtocolData); 00389 } 00390 00391 static HRESULT WINAPI BindProtocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason, 00392 DWORD dwOptions) 00393 { 00394 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00395 00396 TRACE("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); 00397 00398 return IInternetProtocol_Abort(This->protocol_handler, hrReason, dwOptions); 00399 } 00400 00401 static HRESULT WINAPI BindProtocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions) 00402 { 00403 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00404 00405 TRACE("(%p)->(%08x)\n", This, dwOptions); 00406 00407 return IInternetProtocol_Terminate(This->protocol_handler, dwOptions); 00408 } 00409 00410 static HRESULT WINAPI BindProtocol_Suspend(IInternetProtocolEx *iface) 00411 { 00412 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00413 FIXME("(%p)\n", This); 00414 return E_NOTIMPL; 00415 } 00416 00417 static HRESULT WINAPI BindProtocol_Resume(IInternetProtocolEx *iface) 00418 { 00419 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00420 FIXME("(%p)\n", This); 00421 return E_NOTIMPL; 00422 } 00423 00424 static HRESULT WINAPI BindProtocol_Read(IInternetProtocolEx *iface, void *pv, 00425 ULONG cb, ULONG *pcbRead) 00426 { 00427 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00428 00429 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); 00430 00431 if(pcbRead) 00432 *pcbRead = 0; 00433 return IInternetProtocol_Read(This->protocol_handler, pv, cb, pcbRead); 00434 } 00435 00436 static HRESULT WINAPI BindProtocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove, 00437 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) 00438 { 00439 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00440 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); 00441 return E_NOTIMPL; 00442 } 00443 00444 static HRESULT WINAPI BindProtocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions) 00445 { 00446 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00447 00448 TRACE("(%p)->(%08x)\n", This, dwOptions); 00449 00450 return IInternetProtocol_LockRequest(This->protocol_handler, dwOptions); 00451 } 00452 00453 static HRESULT WINAPI BindProtocol_UnlockRequest(IInternetProtocolEx *iface) 00454 { 00455 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00456 00457 TRACE("(%p)\n", This); 00458 00459 return IInternetProtocol_UnlockRequest(This->protocol_handler); 00460 } 00461 00462 static HRESULT WINAPI BindProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUri, 00463 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, 00464 DWORD grfPI, HANDLE *dwReserved) 00465 { 00466 BindProtocol *This = impl_from_IInternetProtocolEx(iface); 00467 IInternetProtocol *protocol = NULL; 00468 IInternetProtocolEx *protocolex; 00469 IInternetPriority *priority; 00470 IServiceProvider *service_provider; 00471 BOOL urlmon_protocol = FALSE; 00472 CLSID clsid = IID_NULL; 00473 LPOLESTR clsid_str; 00474 HRESULT hres; 00475 00476 TRACE("(%p)->(%p %p %p %08x %p)\n", This, pUri, pOIProtSink, pOIBindInfo, grfPI, dwReserved); 00477 00478 if(!pUri || !pOIProtSink || !pOIBindInfo) 00479 return E_INVALIDARG; 00480 00481 This->pi = grfPI; 00482 00483 IUri_AddRef(pUri); 00484 This->uri = pUri; 00485 00486 hres = IInternetProtocolSink_QueryInterface(pOIProtSink, &IID_IServiceProvider, 00487 (void**)&service_provider); 00488 if(SUCCEEDED(hres)) { 00489 /* FIXME: What's protocol CLSID here? */ 00490 IServiceProvider_QueryService(service_provider, &IID_IInternetProtocol, 00491 &IID_IInternetProtocol, (void**)&protocol); 00492 IServiceProvider_Release(service_provider); 00493 } 00494 00495 if(!protocol) { 00496 IClassFactory *cf; 00497 IUnknown *unk; 00498 00499 hres = get_protocol_handler(pUri, &clsid, &urlmon_protocol, &cf); 00500 if(FAILED(hres)) 00501 return hres; 00502 00503 if(This->from_urlmon) { 00504 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IInternetProtocol, (void**)&protocol); 00505 IClassFactory_Release(cf); 00506 if(FAILED(hres)) 00507 return hres; 00508 }else { 00509 hres = IClassFactory_CreateInstance(cf, (IUnknown*)&This->IInternetBindInfo_iface, 00510 &IID_IUnknown, (void**)&unk); 00511 IClassFactory_Release(cf); 00512 if(FAILED(hres)) 00513 return hres; 00514 00515 hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocol, (void**)&protocol); 00516 IUnknown_Release(unk); 00517 if(FAILED(hres)) 00518 return hres; 00519 } 00520 } 00521 00522 StringFromCLSID(&clsid, &clsid_str); 00523 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_PROTOCOLCLASSID, clsid_str); 00524 CoTaskMemFree(clsid_str); 00525 00526 This->protocol = protocol; 00527 00528 if(urlmon_protocol) { 00529 IInternetProtocol_QueryInterface(protocol, &IID_IWinInetInfo, (void**)&This->wininet_info); 00530 IInternetProtocol_QueryInterface(protocol, &IID_IWinInetHttpInfo, (void**)&This->wininet_http_info); 00531 } 00532 00533 set_binding_sink(This, pOIProtSink, pOIBindInfo); 00534 00535 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetPriority, (void**)&priority); 00536 if(SUCCEEDED(hres)) { 00537 IInternetPriority_SetPriority(priority, This->priority); 00538 IInternetPriority_Release(priority); 00539 } 00540 00541 hres = IInternetProtocol_QueryInterface(protocol, &IID_IInternetProtocolEx, (void**)&protocolex); 00542 if(SUCCEEDED(hres)) { 00543 hres = IInternetProtocolEx_StartEx(protocolex, pUri, &This->IInternetProtocolSink_iface, 00544 &This->IInternetBindInfo_iface, 0, NULL); 00545 IInternetProtocolEx_Release(protocolex); 00546 }else { 00547 BSTR display_uri; 00548 00549 hres = IUri_GetDisplayUri(pUri, &display_uri); 00550 if(FAILED(hres)) 00551 return hres; 00552 00553 hres = IInternetProtocol_Start(protocol, display_uri, &This->IInternetProtocolSink_iface, 00554 &This->IInternetBindInfo_iface, 0, 0); 00555 SysFreeString(display_uri); 00556 } 00557 00558 return hres; 00559 } 00560 00561 void set_binding_sink(BindProtocol *This, IInternetProtocolSink *sink, IInternetBindInfo *bind_info) 00562 { 00563 IInternetProtocolSink *prev_sink; 00564 IServiceProvider *service_provider = NULL; 00565 00566 if(sink) 00567 IInternetProtocolSink_AddRef(sink); 00568 prev_sink = InterlockedExchangePointer((void**)&This->protocol_sink, sink); 00569 if(prev_sink) 00570 IInternetProtocolSink_Release(prev_sink); 00571 00572 if(sink) 00573 IInternetProtocolSink_QueryInterface(sink, &IID_IServiceProvider, (void**)&service_provider); 00574 service_provider = InterlockedExchangePointer((void**)&This->service_provider, service_provider); 00575 if(service_provider) 00576 IServiceProvider_Release(service_provider); 00577 00578 if(bind_info) 00579 IInternetBindInfo_AddRef(bind_info); 00580 bind_info = InterlockedExchangePointer((void**)&This->bind_info, bind_info); 00581 if(bind_info) 00582 IInternetBindInfo_Release(bind_info); 00583 } 00584 00585 static const IInternetProtocolExVtbl BindProtocolVtbl = { 00586 BindProtocol_QueryInterface, 00587 BindProtocol_AddRef, 00588 BindProtocol_Release, 00589 BindProtocol_Start, 00590 BindProtocol_Continue, 00591 BindProtocol_Abort, 00592 BindProtocol_Terminate, 00593 BindProtocol_Suspend, 00594 BindProtocol_Resume, 00595 BindProtocol_Read, 00596 BindProtocol_Seek, 00597 BindProtocol_LockRequest, 00598 BindProtocol_UnlockRequest, 00599 BindProtocol_StartEx 00600 }; 00601 00602 static inline BindProtocol *impl_from_IInternetProtocol(IInternetProtocol *iface) 00603 { 00604 return CONTAINING_RECORD(iface, BindProtocol, default_protocol_handler.IInternetProtocol_iface); 00605 } 00606 00607 static HRESULT WINAPI ProtocolHandler_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) 00608 { 00609 ERR("should not be called\n"); 00610 return E_NOINTERFACE; 00611 } 00612 00613 static ULONG WINAPI ProtocolHandler_AddRef(IInternetProtocol *iface) 00614 { 00615 BindProtocol *This = impl_from_IInternetProtocol(iface); 00616 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 00617 } 00618 00619 static ULONG WINAPI ProtocolHandler_Release(IInternetProtocol *iface) 00620 { 00621 BindProtocol *This = impl_from_IInternetProtocol(iface); 00622 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 00623 } 00624 00625 static HRESULT WINAPI ProtocolHandler_Start(IInternetProtocol *iface, LPCWSTR szUrl, 00626 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, 00627 DWORD grfPI, HANDLE_PTR dwReserved) 00628 { 00629 ERR("Should not be called\n"); 00630 return E_NOTIMPL; 00631 } 00632 00633 static HRESULT WINAPI ProtocolHandler_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData) 00634 { 00635 BindProtocol *This = impl_from_IInternetProtocol(iface); 00636 HRESULT hres; 00637 00638 TRACE("(%p)->(%p)\n", This, pProtocolData); 00639 00640 hres = IInternetProtocol_Continue(This->protocol, pProtocolData); 00641 00642 heap_free(pProtocolData); 00643 return hres; 00644 } 00645 00646 static HRESULT WINAPI ProtocolHandler_Abort(IInternetProtocol *iface, HRESULT hrReason, 00647 DWORD dwOptions) 00648 { 00649 BindProtocol *This = impl_from_IInternetProtocol(iface); 00650 00651 TRACE("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); 00652 00653 if(This->protocol && !This->reported_result) 00654 return IInternetProtocol_Abort(This->protocol, hrReason, dwOptions); 00655 00656 return S_OK; 00657 } 00658 00659 static HRESULT WINAPI ProtocolHandler_Terminate(IInternetProtocol *iface, DWORD dwOptions) 00660 { 00661 BindProtocol *This = impl_from_IInternetProtocol(iface); 00662 00663 TRACE("(%p)->(%08x)\n", This, dwOptions); 00664 00665 if(!This->reported_result) 00666 return E_FAIL; 00667 00668 IInternetProtocol_Terminate(This->protocol, 0); 00669 00670 if(This->filter_proxy) { 00671 IInternetProtocol_Release(&This->filter_proxy->IInternetProtocol_iface); 00672 This->filter_proxy = NULL; 00673 } 00674 00675 set_binding_sink(This, NULL, NULL); 00676 00677 if(This->bind_info) { 00678 IInternetBindInfo_Release(This->bind_info); 00679 This->bind_info = NULL; 00680 } 00681 00682 return S_OK; 00683 } 00684 00685 static HRESULT WINAPI ProtocolHandler_Suspend(IInternetProtocol *iface) 00686 { 00687 BindProtocol *This = impl_from_IInternetProtocol(iface); 00688 FIXME("(%p)\n", This); 00689 return E_NOTIMPL; 00690 } 00691 00692 static HRESULT WINAPI ProtocolHandler_Resume(IInternetProtocol *iface) 00693 { 00694 BindProtocol *This = impl_from_IInternetProtocol(iface); 00695 FIXME("(%p)\n", This); 00696 return E_NOTIMPL; 00697 } 00698 00699 static HRESULT WINAPI ProtocolHandler_Read(IInternetProtocol *iface, void *pv, 00700 ULONG cb, ULONG *pcbRead) 00701 { 00702 BindProtocol *This = impl_from_IInternetProtocol(iface); 00703 ULONG read = 0; 00704 HRESULT hres = S_OK; 00705 00706 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); 00707 00708 if(This->buf_size) { 00709 read = min(cb, This->buf_size); 00710 memcpy(pv, This->buf, read); 00711 00712 if(read == This->buf_size) { 00713 heap_free(This->buf); 00714 This->buf = NULL; 00715 }else { 00716 memmove(This->buf, This->buf+cb, This->buf_size-cb); 00717 } 00718 00719 This->buf_size -= read; 00720 } 00721 00722 if(read < cb) { 00723 ULONG cread = 0; 00724 00725 hres = IInternetProtocol_Read(This->protocol, (BYTE*)pv+read, cb-read, &cread); 00726 read += cread; 00727 } 00728 00729 *pcbRead = read; 00730 return hres; 00731 } 00732 00733 static HRESULT WINAPI ProtocolHandler_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, 00734 DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) 00735 { 00736 BindProtocol *This = impl_from_IInternetProtocol(iface); 00737 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); 00738 return E_NOTIMPL; 00739 } 00740 00741 static HRESULT WINAPI ProtocolHandler_LockRequest(IInternetProtocol *iface, DWORD dwOptions) 00742 { 00743 BindProtocol *This = impl_from_IInternetProtocol(iface); 00744 00745 TRACE("(%p)->(%08x)\n", This, dwOptions); 00746 00747 return IInternetProtocol_LockRequest(This->protocol, dwOptions); 00748 } 00749 00750 static HRESULT WINAPI ProtocolHandler_UnlockRequest(IInternetProtocol *iface) 00751 { 00752 BindProtocol *This = impl_from_IInternetProtocol(iface); 00753 00754 TRACE("(%p)\n", This); 00755 00756 return IInternetProtocol_UnlockRequest(This->protocol); 00757 } 00758 00759 static const IInternetProtocolVtbl InternetProtocolHandlerVtbl = { 00760 ProtocolHandler_QueryInterface, 00761 ProtocolHandler_AddRef, 00762 ProtocolHandler_Release, 00763 ProtocolHandler_Start, 00764 ProtocolHandler_Continue, 00765 ProtocolHandler_Abort, 00766 ProtocolHandler_Terminate, 00767 ProtocolHandler_Suspend, 00768 ProtocolHandler_Resume, 00769 ProtocolHandler_Read, 00770 ProtocolHandler_Seek, 00771 ProtocolHandler_LockRequest, 00772 ProtocolHandler_UnlockRequest 00773 }; 00774 00775 static inline BindProtocol *impl_from_IInternetBindInfo(IInternetBindInfo *iface) 00776 { 00777 return CONTAINING_RECORD(iface, BindProtocol, IInternetBindInfo_iface); 00778 } 00779 00780 static HRESULT WINAPI BindInfo_QueryInterface(IInternetBindInfo *iface, 00781 REFIID riid, void **ppv) 00782 { 00783 BindProtocol *This = impl_from_IInternetBindInfo(iface); 00784 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv); 00785 } 00786 00787 static ULONG WINAPI BindInfo_AddRef(IInternetBindInfo *iface) 00788 { 00789 BindProtocol *This = impl_from_IInternetBindInfo(iface); 00790 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 00791 } 00792 00793 static ULONG WINAPI BindInfo_Release(IInternetBindInfo *iface) 00794 { 00795 BindProtocol *This = impl_from_IInternetBindInfo(iface); 00796 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 00797 } 00798 00799 static HRESULT WINAPI BindInfo_GetBindInfo(IInternetBindInfo *iface, 00800 DWORD *grfBINDF, BINDINFO *pbindinfo) 00801 { 00802 BindProtocol *This = impl_from_IInternetBindInfo(iface); 00803 HRESULT hres; 00804 00805 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); 00806 00807 hres = IInternetBindInfo_GetBindInfo(This->bind_info, grfBINDF, pbindinfo); 00808 if(FAILED(hres)) { 00809 WARN("GetBindInfo failed: %08x\n", hres); 00810 return hres; 00811 } 00812 00813 *grfBINDF |= BINDF_FROMURLMON; 00814 return hres; 00815 } 00816 00817 static HRESULT WINAPI BindInfo_GetBindString(IInternetBindInfo *iface, 00818 ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched) 00819 { 00820 BindProtocol *This = impl_from_IInternetBindInfo(iface); 00821 00822 TRACE("(%p)->(%d %p %d %p)\n", This, ulStringType, ppwzStr, cEl, pcElFetched); 00823 00824 return IInternetBindInfo_GetBindString(This->bind_info, ulStringType, ppwzStr, cEl, pcElFetched); 00825 } 00826 00827 static const IInternetBindInfoVtbl InternetBindInfoVtbl = { 00828 BindInfo_QueryInterface, 00829 BindInfo_AddRef, 00830 BindInfo_Release, 00831 BindInfo_GetBindInfo, 00832 BindInfo_GetBindString 00833 }; 00834 00835 static inline BindProtocol *impl_from_IInternetPriority(IInternetPriority *iface) 00836 { 00837 return CONTAINING_RECORD(iface, BindProtocol, IInternetPriority_iface); 00838 } 00839 00840 static HRESULT WINAPI InternetPriority_QueryInterface(IInternetPriority *iface, 00841 REFIID riid, void **ppv) 00842 { 00843 BindProtocol *This = impl_from_IInternetPriority(iface); 00844 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv); 00845 } 00846 00847 static ULONG WINAPI InternetPriority_AddRef(IInternetPriority *iface) 00848 { 00849 BindProtocol *This = impl_from_IInternetPriority(iface); 00850 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 00851 } 00852 00853 static ULONG WINAPI InternetPriority_Release(IInternetPriority *iface) 00854 { 00855 BindProtocol *This = impl_from_IInternetPriority(iface); 00856 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 00857 } 00858 00859 static HRESULT WINAPI InternetPriority_SetPriority(IInternetPriority *iface, LONG nPriority) 00860 { 00861 BindProtocol *This = impl_from_IInternetPriority(iface); 00862 00863 TRACE("(%p)->(%d)\n", This, nPriority); 00864 00865 This->priority = nPriority; 00866 return S_OK; 00867 } 00868 00869 static HRESULT WINAPI InternetPriority_GetPriority(IInternetPriority *iface, LONG *pnPriority) 00870 { 00871 BindProtocol *This = impl_from_IInternetPriority(iface); 00872 00873 TRACE("(%p)->(%p)\n", This, pnPriority); 00874 00875 *pnPriority = This->priority; 00876 return S_OK; 00877 } 00878 00879 static const IInternetPriorityVtbl InternetPriorityVtbl = { 00880 InternetPriority_QueryInterface, 00881 InternetPriority_AddRef, 00882 InternetPriority_Release, 00883 InternetPriority_SetPriority, 00884 InternetPriority_GetPriority 00885 00886 }; 00887 00888 static inline BindProtocol *impl_from_IInternetProtocolSink(IInternetProtocolSink *iface) 00889 { 00890 return CONTAINING_RECORD(iface, BindProtocol, IInternetProtocolSink_iface); 00891 } 00892 00893 static HRESULT WINAPI BPInternetProtocolSink_QueryInterface(IInternetProtocolSink *iface, 00894 REFIID riid, void **ppv) 00895 { 00896 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 00897 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv); 00898 } 00899 00900 static ULONG WINAPI BPInternetProtocolSink_AddRef(IInternetProtocolSink *iface) 00901 { 00902 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 00903 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 00904 } 00905 00906 static ULONG WINAPI BPInternetProtocolSink_Release(IInternetProtocolSink *iface) 00907 { 00908 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 00909 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 00910 } 00911 00912 typedef struct { 00913 task_header_t header; 00914 PROTOCOLDATA *data; 00915 } switch_task_t; 00916 00917 static void switch_proc(BindProtocol *bind, task_header_t *t) 00918 { 00919 switch_task_t *task = (switch_task_t*)t; 00920 00921 IInternetProtocol_Continue(bind->protocol_handler, task->data); 00922 00923 heap_free(task); 00924 } 00925 00926 static HRESULT WINAPI BPInternetProtocolSink_Switch(IInternetProtocolSink *iface, 00927 PROTOCOLDATA *pProtocolData) 00928 { 00929 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 00930 PROTOCOLDATA *data; 00931 00932 TRACE("(%p)->(%p)\n", This, pProtocolData); 00933 00934 TRACE("flags %x state %x data %p cb %u\n", pProtocolData->grfFlags, pProtocolData->dwState, 00935 pProtocolData->pData, pProtocolData->cbData); 00936 00937 data = heap_alloc(sizeof(PROTOCOLDATA)); 00938 if(!data) 00939 return E_OUTOFMEMORY; 00940 memcpy(data, pProtocolData, sizeof(PROTOCOLDATA)); 00941 00942 if(!do_direct_notif(This)) { 00943 switch_task_t *task; 00944 00945 task = heap_alloc(sizeof(switch_task_t)); 00946 if(!task) 00947 return E_OUTOFMEMORY; 00948 00949 task->data = data; 00950 00951 push_task(This, &task->header, switch_proc); 00952 return S_OK; 00953 } 00954 00955 if(!This->protocol_sink) { 00956 IInternetProtocol_Continue(This->protocol_handler, data); 00957 return S_OK; 00958 } 00959 00960 return IInternetProtocolSink_Switch(This->protocol_sink, data); 00961 } 00962 00963 static void report_progress(BindProtocol *This, ULONG status_code, LPCWSTR status_text) 00964 { 00965 switch(status_code) { 00966 case BINDSTATUS_FINDINGRESOURCE: 00967 case BINDSTATUS_CONNECTING: 00968 case BINDSTATUS_REDIRECTING: 00969 case BINDSTATUS_SENDINGREQUEST: 00970 case BINDSTATUS_CACHEFILENAMEAVAILABLE: 00971 case BINDSTATUS_DIRECTBIND: 00972 case BINDSTATUS_ACCEPTRANGES: 00973 if(This->protocol_sink) 00974 IInternetProtocolSink_ReportProgress(This->protocol_sink, status_code, status_text); 00975 break; 00976 00977 case BINDSTATUS_BEGINDOWNLOADDATA: 00978 if(This->protocol_sink) 00979 IInternetProtocolSink_ReportData(This->protocol_sink, This->bscf, This->progress, This->progress_max); 00980 break; 00981 00982 case BINDSTATUS_MIMETYPEAVAILABLE: 00983 mime_available(This, status_text, FALSE); 00984 break; 00985 00986 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE: 00987 mime_available(This, status_text, TRUE); 00988 break; 00989 00990 default: 00991 FIXME("unsupported ulStatusCode %u\n", status_code); 00992 } 00993 } 00994 00995 typedef struct { 00996 task_header_t header; 00997 00998 ULONG status_code; 00999 LPWSTR status_text; 01000 } on_progress_task_t; 01001 01002 static void on_progress_proc(BindProtocol *This, task_header_t *t) 01003 { 01004 on_progress_task_t *task = (on_progress_task_t*)t; 01005 01006 report_progress(This, task->status_code, task->status_text); 01007 01008 heap_free(task->status_text); 01009 heap_free(task); 01010 } 01011 01012 static HRESULT WINAPI BPInternetProtocolSink_ReportProgress(IInternetProtocolSink *iface, 01013 ULONG ulStatusCode, LPCWSTR szStatusText) 01014 { 01015 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 01016 01017 TRACE("(%p)->(%u %s)\n", This, ulStatusCode, debugstr_w(szStatusText)); 01018 01019 if(do_direct_notif(This)) { 01020 report_progress(This, ulStatusCode, szStatusText); 01021 }else { 01022 on_progress_task_t *task; 01023 01024 task = heap_alloc(sizeof(on_progress_task_t)); 01025 01026 task->status_code = ulStatusCode; 01027 task->status_text = heap_strdupW(szStatusText); 01028 01029 push_task(This, &task->header, on_progress_proc); 01030 } 01031 01032 return S_OK; 01033 } 01034 01035 static HRESULT report_data(BindProtocol *This, DWORD bscf, ULONG progress, ULONG progress_max) 01036 { 01037 This->bscf = bscf; 01038 This->progress = progress; 01039 This->progress_max = progress_max; 01040 01041 if(!This->protocol_sink) 01042 return S_OK; 01043 01044 if((This->pi & PI_MIMEVERIFICATION) && !This->reported_mime) { 01045 BYTE buf[BUFFER_SIZE]; 01046 DWORD read = 0; 01047 LPWSTR mime; 01048 HRESULT hres; 01049 01050 do { 01051 read = 0; 01052 hres = IInternetProtocol_Read(This->protocol, buf, 01053 sizeof(buf)-This->buf_size, &read); 01054 if(FAILED(hres) && hres != E_PENDING) 01055 return hres; 01056 01057 if(!This->buf) { 01058 This->buf = heap_alloc(BUFFER_SIZE); 01059 if(!This->buf) 01060 return E_OUTOFMEMORY; 01061 }else if(read + This->buf_size > BUFFER_SIZE) { 01062 BYTE *tmp; 01063 01064 tmp = heap_realloc(This->buf, read+This->buf_size); 01065 if(!tmp) 01066 return E_OUTOFMEMORY; 01067 This->buf = tmp; 01068 } 01069 01070 memcpy(This->buf+This->buf_size, buf, read); 01071 This->buf_size += read; 01072 }while(This->buf_size < MIME_TEST_SIZE && hres == S_OK); 01073 01074 if(This->buf_size < MIME_TEST_SIZE && hres != S_FALSE) 01075 return S_OK; 01076 01077 bscf = BSCF_FIRSTDATANOTIFICATION; 01078 if(hres == S_FALSE) 01079 bscf |= BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE; 01080 01081 if(!This->reported_mime) { 01082 BSTR raw_uri; 01083 01084 hres = IUri_GetRawUri(This->uri, &raw_uri); 01085 if(FAILED(hres)) 01086 return hres; 01087 01088 hres = FindMimeFromData(NULL, raw_uri, This->buf, min(This->buf_size, MIME_TEST_SIZE), 01089 This->mime, 0, &mime, 0); 01090 SysFreeString(raw_uri); 01091 if(FAILED(hres)) 01092 return hres; 01093 01094 mime_available(This, mime, TRUE); 01095 CoTaskMemFree(mime); 01096 } 01097 } 01098 01099 if(!This->protocol_sink) 01100 return S_OK; 01101 01102 return IInternetProtocolSink_ReportData(This->protocol_sink, bscf, progress, progress_max); 01103 } 01104 01105 typedef struct { 01106 task_header_t header; 01107 DWORD bscf; 01108 ULONG progress; 01109 ULONG progress_max; 01110 } report_data_task_t; 01111 01112 static void report_data_proc(BindProtocol *This, task_header_t *t) 01113 { 01114 report_data_task_t *task = (report_data_task_t*)t; 01115 01116 report_data(This, task->bscf, task->progress, task->progress_max); 01117 heap_free(task); 01118 } 01119 01120 static HRESULT WINAPI BPInternetProtocolSink_ReportData(IInternetProtocolSink *iface, 01121 DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) 01122 { 01123 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 01124 01125 TRACE("(%p)->(%d %u %u)\n", This, grfBSCF, ulProgress, ulProgressMax); 01126 01127 if(!This->protocol_sink) 01128 return S_OK; 01129 01130 if(!do_direct_notif(This)) { 01131 report_data_task_t *task; 01132 01133 task = heap_alloc(sizeof(report_data_task_t)); 01134 if(!task) 01135 return E_OUTOFMEMORY; 01136 01137 task->bscf = grfBSCF; 01138 task->progress = ulProgress; 01139 task->progress_max = ulProgressMax; 01140 01141 push_task(This, &task->header, report_data_proc); 01142 return S_OK; 01143 } 01144 01145 return report_data(This, grfBSCF, ulProgress, ulProgressMax); 01146 } 01147 01148 typedef struct { 01149 task_header_t header; 01150 01151 HRESULT hres; 01152 DWORD err; 01153 LPWSTR str; 01154 } report_result_task_t; 01155 01156 static void report_result_proc(BindProtocol *This, task_header_t *t) 01157 { 01158 report_result_task_t *task = (report_result_task_t*)t; 01159 01160 if(This->protocol_sink) 01161 IInternetProtocolSink_ReportResult(This->protocol_sink, task->hres, task->err, task->str); 01162 01163 heap_free(task->str); 01164 heap_free(task); 01165 } 01166 01167 static HRESULT WINAPI BPInternetProtocolSink_ReportResult(IInternetProtocolSink *iface, 01168 HRESULT hrResult, DWORD dwError, LPCWSTR szResult) 01169 { 01170 BindProtocol *This = impl_from_IInternetProtocolSink(iface); 01171 01172 TRACE("(%p)->(%08x %d %s)\n", This, hrResult, dwError, debugstr_w(szResult)); 01173 01174 if(!This->protocol_sink) 01175 return E_FAIL; 01176 01177 This->reported_result = TRUE; 01178 01179 if(!do_direct_notif(This)) { 01180 report_result_task_t *task; 01181 01182 task = heap_alloc(sizeof(report_result_task_t)); 01183 if(!task) 01184 return E_OUTOFMEMORY; 01185 01186 task->hres = hrResult; 01187 task->err = dwError; 01188 task->str = heap_strdupW(szResult); 01189 01190 push_task(This, &task->header, report_result_proc); 01191 return S_OK; 01192 } 01193 01194 return IInternetProtocolSink_ReportResult(This->protocol_sink, hrResult, dwError, szResult); 01195 } 01196 01197 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl = { 01198 BPInternetProtocolSink_QueryInterface, 01199 BPInternetProtocolSink_AddRef, 01200 BPInternetProtocolSink_Release, 01201 BPInternetProtocolSink_Switch, 01202 BPInternetProtocolSink_ReportProgress, 01203 BPInternetProtocolSink_ReportData, 01204 BPInternetProtocolSink_ReportResult 01205 }; 01206 01207 static inline BindProtocol *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface) 01208 { 01209 return CONTAINING_RECORD(iface, BindProtocol, IWinInetHttpInfo_iface); 01210 } 01211 01212 static HRESULT WINAPI WinInetHttpInfo_QueryInterface(IWinInetHttpInfo *iface, REFIID riid, void **ppv) 01213 { 01214 BindProtocol *This = impl_from_IWinInetHttpInfo(iface); 01215 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv); 01216 } 01217 01218 static ULONG WINAPI WinInetHttpInfo_AddRef(IWinInetHttpInfo *iface) 01219 { 01220 BindProtocol *This = impl_from_IWinInetHttpInfo(iface); 01221 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 01222 } 01223 01224 static ULONG WINAPI WinInetHttpInfo_Release(IWinInetHttpInfo *iface) 01225 { 01226 BindProtocol *This = impl_from_IWinInetHttpInfo(iface); 01227 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 01228 } 01229 01230 static HRESULT WINAPI WinInetHttpInfo_QueryOption(IWinInetHttpInfo *iface, DWORD dwOption, 01231 void *pBuffer, DWORD *pcbBuffer) 01232 { 01233 BindProtocol *This = impl_from_IWinInetHttpInfo(iface); 01234 FIXME("(%p)->(%x %p %p)\n", This, dwOption, pBuffer, pcbBuffer); 01235 return E_NOTIMPL; 01236 } 01237 01238 static HRESULT WINAPI WinInetHttpInfo_QueryInfo(IWinInetHttpInfo *iface, DWORD dwOption, 01239 void *pBuffer, DWORD *pcbBuffer, DWORD *pdwFlags, DWORD *pdwReserved) 01240 { 01241 BindProtocol *This = impl_from_IWinInetHttpInfo(iface); 01242 FIXME("(%p)->(%x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuffer, pdwFlags, pdwReserved); 01243 return E_NOTIMPL; 01244 } 01245 01246 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl = { 01247 WinInetHttpInfo_QueryInterface, 01248 WinInetHttpInfo_AddRef, 01249 WinInetHttpInfo_Release, 01250 WinInetHttpInfo_QueryOption, 01251 WinInetHttpInfo_QueryInfo 01252 }; 01253 01254 static inline BindProtocol *impl_from_IServiceProvider(IServiceProvider *iface) 01255 { 01256 return CONTAINING_RECORD(iface, BindProtocol, IServiceProvider_iface); 01257 } 01258 01259 static HRESULT WINAPI BPServiceProvider_QueryInterface(IServiceProvider *iface, 01260 REFIID riid, void **ppv) 01261 { 01262 BindProtocol *This = impl_from_IServiceProvider(iface); 01263 return IInternetProtocolEx_QueryInterface(&This->IInternetProtocolEx_iface, riid, ppv); 01264 } 01265 01266 static ULONG WINAPI BPServiceProvider_AddRef(IServiceProvider *iface) 01267 { 01268 BindProtocol *This = impl_from_IServiceProvider(iface); 01269 return IInternetProtocolEx_AddRef(&This->IInternetProtocolEx_iface); 01270 } 01271 01272 static ULONG WINAPI BPServiceProvider_Release(IServiceProvider *iface) 01273 { 01274 BindProtocol *This = impl_from_IServiceProvider(iface); 01275 return IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); 01276 } 01277 01278 static HRESULT WINAPI BPServiceProvider_QueryService(IServiceProvider *iface, 01279 REFGUID guidService, REFIID riid, void **ppv) 01280 { 01281 BindProtocol *This = impl_from_IServiceProvider(iface); 01282 01283 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); 01284 01285 if(!This->service_provider) 01286 return E_NOINTERFACE; 01287 01288 return IServiceProvider_QueryService(This->service_provider, guidService, riid, ppv); 01289 } 01290 01291 static const IServiceProviderVtbl ServiceProviderVtbl = { 01292 BPServiceProvider_QueryInterface, 01293 BPServiceProvider_AddRef, 01294 BPServiceProvider_Release, 01295 BPServiceProvider_QueryService 01296 }; 01297 01298 HRESULT create_binding_protocol(BOOL from_urlmon, BindProtocol **protocol) 01299 { 01300 BindProtocol *ret = heap_alloc_zero(sizeof(BindProtocol)); 01301 01302 ret->IInternetProtocolEx_iface.lpVtbl = &BindProtocolVtbl; 01303 ret->IInternetBindInfo_iface.lpVtbl = &InternetBindInfoVtbl; 01304 ret->IInternetPriority_iface.lpVtbl = &InternetPriorityVtbl; 01305 ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl; 01306 ret->IInternetProtocolSink_iface.lpVtbl = &InternetProtocolSinkVtbl; 01307 ret->IWinInetHttpInfo_iface.lpVtbl = &WinInetHttpInfoVtbl; 01308 01309 ret->default_protocol_handler.IInternetProtocol_iface.lpVtbl = &InternetProtocolHandlerVtbl; 01310 01311 ret->ref = 1; 01312 ret->from_urlmon = from_urlmon; 01313 ret->apartment_thread = GetCurrentThreadId(); 01314 ret->notif_hwnd = get_notif_hwnd(); 01315 ret->protocol_handler = &ret->default_protocol_handler.IInternetProtocol_iface; 01316 InitializeCriticalSection(&ret->section); 01317 01318 URLMON_LockModule(); 01319 01320 *protocol = ret; 01321 return S_OK; 01322 } Generated on Fri May 25 2012 04:24:44 for ReactOS by
1.7.6.1
|