2 * Copyright 2007-2009 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "urlmon_main.h"
21 typedef void (*task_proc_t
)(BindProtocol
*,task_header_t
*);
23 struct _task_header_t
{
28 #define BUFFER_SIZE 2048
29 #define MIME_TEST_SIZE 255
31 #define WM_MK_CONTINUE (WM_USER+101)
32 #define WM_MK_RELEASE (WM_USER+102)
34 static void process_tasks(BindProtocol
*This
)
39 EnterCriticalSection(&This
->section
);
41 task
= This
->task_queue_head
;
43 This
->task_queue_head
= task
->next
;
44 if(!This
->task_queue_head
)
45 This
->task_queue_tail
= NULL
;
48 LeaveCriticalSection(&This
->section
);
53 This
->continue_call
++;
54 task
->proc(This
, task
);
55 This
->continue_call
--;
59 static LRESULT WINAPI
notif_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
62 case WM_MK_CONTINUE
: {
63 BindProtocol
*This
= (BindProtocol
*)lParam
;
67 IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
71 tls_data_t
*data
= get_tls_data();
73 if(!--data
->notif_hwnd_cnt
) {
75 data
->notif_hwnd
= NULL
;
80 return DefWindowProcW(hwnd
, msg
, wParam
, lParam
);
85 static const WCHAR wszURLMonikerNotificationWindow
[] =
86 {'U','R','L',' ','M','o','n','i','k','e','r',' ',
87 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
89 static ATOM notif_wnd_class
;
91 static BOOL WINAPI
register_notif_wnd_class(INIT_ONCE
*once
, void *param
, void **context
)
93 static WNDCLASSEXW wndclass
= {
94 sizeof(wndclass
), 0, notif_wnd_proc
, 0, 0,
95 NULL
, NULL
, NULL
, NULL
, NULL
,
96 wszURLMonikerNotificationWindow
, NULL
99 wndclass
.hInstance
= hProxyDll
;
100 notif_wnd_class
= RegisterClassExW(&wndclass
);
104 void unregister_notif_wnd_class(void)
107 UnregisterClassW(MAKEINTRESOURCEW(notif_wnd_class
), hProxyDll
);
110 #endif /* !__REACTOS__ */
112 HWND
get_notif_hwnd(void)
115 static ATOM wnd_class
= 0;
117 tls_data_t
*tls_data
;
120 static const WCHAR wszURLMonikerNotificationWindow
[] =
121 {'U','R','L',' ','M','o','n','i','k','e','r',' ',
122 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
124 static INIT_ONCE init_once
= INIT_ONCE_STATIC_INIT
;
127 tls_data
= get_tls_data();
131 if(tls_data
->notif_hwnd_cnt
) {
132 tls_data
->notif_hwnd_cnt
++;
133 return tls_data
->notif_hwnd
;
137 InitOnceExecuteOnce(&init_once
, register_notif_wnd_class
, NULL
, NULL
);
142 static WNDCLASSEXW wndclass
= {
144 notif_wnd_proc
, 0, 0,
145 NULL
, NULL
, NULL
, NULL
, NULL
,
146 wszURLMonikerNotificationWindow
,
150 wndclass
.hInstance
= hProxyDll
;
152 wnd_class
= RegisterClassExW(&wndclass
);
153 if (!wnd_class
&& GetLastError() == ERROR_CLASS_ALREADY_EXISTS
)
159 tls_data
->notif_hwnd
= CreateWindowExW(0, MAKEINTRESOURCEW(notif_wnd_class
),
161 tls_data
->notif_hwnd
= CreateWindowExW(0, wszURLMonikerNotificationWindow
,
163 wszURLMonikerNotificationWindow
, 0, 0, 0, 0, 0, HWND_MESSAGE
,
164 NULL
, hProxyDll
, NULL
);
165 if(tls_data
->notif_hwnd
)
166 tls_data
->notif_hwnd_cnt
++;
168 TRACE("hwnd = %p\n", tls_data
->notif_hwnd
);
170 return tls_data
->notif_hwnd
;
173 void release_notif_hwnd(HWND hwnd
)
175 tls_data_t
*data
= get_tls_data();
180 if(data
->notif_hwnd
!= hwnd
) {
181 PostMessageW(data
->notif_hwnd
, WM_MK_RELEASE
, 0, 0);
185 if(!--data
->notif_hwnd_cnt
) {
186 DestroyWindow(data
->notif_hwnd
);
187 data
->notif_hwnd
= NULL
;
191 static void push_task(BindProtocol
*This
, task_header_t
*task
, task_proc_t proc
)
193 BOOL do_post
= FALSE
;
198 EnterCriticalSection(&This
->section
);
200 if(This
->task_queue_tail
) {
201 This
->task_queue_tail
->next
= task
;
202 This
->task_queue_tail
= task
;
204 This
->task_queue_tail
= This
->task_queue_head
= task
;
205 do_post
= !This
->continue_call
;
208 LeaveCriticalSection(&This
->section
);
211 IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
212 PostMessageW(This
->notif_hwnd
, WM_MK_CONTINUE
, 0, (LPARAM
)This
);
216 static inline BOOL
is_apartment_thread(BindProtocol
*This
)
218 return This
->apartment_thread
== GetCurrentThreadId();
221 static inline BOOL
do_direct_notif(BindProtocol
*This
)
223 return !(This
->pi
& PI_APARTMENTTHREADED
) || (is_apartment_thread(This
) && !This
->continue_call
);
226 static HRESULT
handle_mime_filter(BindProtocol
*This
, IInternetProtocol
*mime_filter
)
228 PROTOCOLFILTERDATA filter_data
= { sizeof(PROTOCOLFILTERDATA
), NULL
, NULL
, NULL
, 0 };
231 hres
= IInternetProtocol_QueryInterface(mime_filter
, &IID_IInternetProtocolSink
, (void**)&This
->protocol_sink_handler
);
233 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
237 IInternetProtocol_AddRef(mime_filter
);
238 This
->protocol_handler
= mime_filter
;
240 filter_data
.pProtocol
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
241 hres
= IInternetProtocol_Start(mime_filter
, This
->mime
, &This
->default_protocol_handler
.IInternetProtocolSink_iface
,
242 &This
->IInternetBindInfo_iface
, PI_FILTER_MODE
|PI_FORCE_ASYNC
,
243 (HANDLE_PTR
)&filter_data
);
245 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
246 IInternetProtocol_Release(This
->protocol_handler
);
247 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
248 This
->protocol_handler
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
252 /* NOTE: IE9 calls it on the new protocol_sink. It doesn't make sense so it seems to be a bug there. */
253 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_LOADINGMIMEHANDLER
, NULL
);
258 static void mime_available(BindProtocol
*This
, LPCWSTR mime
, BOOL verified
)
260 IInternetProtocol
*mime_filter
;
263 heap_free(This
->mime
);
264 This
->mime
= heap_strdupW(mime
);
266 if(This
->protocol_handler
==&This
->default_protocol_handler
.IInternetProtocol_iface
267 && (mime_filter
= get_mime_filter(mime
))) {
268 TRACE("Got mime filter for %s\n", debugstr_w(mime
));
270 hres
= handle_mime_filter(This
, mime_filter
);
271 IInternetProtocol_Release(mime_filter
);
273 FIXME("MIME filter failed: %08x\n", hres
);
276 if(This
->reported_mime
|| verified
|| !(This
->pi
& PI_MIMEVERIFICATION
)) {
277 This
->reported_mime
= TRUE
;
278 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
282 static inline BindProtocol
*impl_from_IInternetProtocolEx(IInternetProtocolEx
*iface
)
284 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolEx_iface
);
287 static HRESULT WINAPI
BindProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
289 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
292 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
293 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
294 *ppv
= &This
->IInternetProtocolEx_iface
;
295 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
296 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
297 *ppv
= &This
->IInternetProtocolEx_iface
;
298 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
299 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
300 *ppv
= &This
->IInternetProtocolEx_iface
;
301 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
302 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
303 *ppv
= &This
->IInternetProtocolEx_iface
;
304 }else if(IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
305 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This
, ppv
);
306 *ppv
= &This
->IInternetBindInfo_iface
;
307 }else if(IsEqualGUID(&IID_IInternetPriority
, riid
)) {
308 TRACE("(%p)->(IID_IInternetPriority %p)\n", This
, ppv
);
309 *ppv
= &This
->IInternetPriority_iface
;
310 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
311 FIXME("(%p)->(IID_IAuthenticate %p)\n", This
, ppv
);
312 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
313 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
314 *ppv
= &This
->IServiceProvider_iface
;
315 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
316 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
317 *ppv
= &This
->IInternetProtocolSink_iface
;
318 }else if(IsEqualGUID(&IID_IWinInetInfo
, riid
)) {
319 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This
, ppv
);
322 IWinInetInfo
*inet_info
;
325 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetInfo
, (void**)&inet_info
);
326 if(SUCCEEDED(hres
)) {
327 *ppv
= &This
->IWinInetHttpInfo_iface
;
328 IWinInetInfo_Release(inet_info
);
331 }else if(IsEqualGUID(&IID_IWinInetHttpInfo
, riid
)) {
332 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This
, ppv
);
335 IWinInetHttpInfo
*http_info
;
338 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetHttpInfo
, (void**)&http_info
);
339 if(SUCCEEDED(hres
)) {
340 *ppv
= &This
->IWinInetHttpInfo_iface
;
341 IWinInetHttpInfo_Release(http_info
);
345 WARN("not supported interface %s\n", debugstr_guid(riid
));
349 return E_NOINTERFACE
;
351 IUnknown_AddRef((IUnknown
*)*ppv
);
355 static ULONG WINAPI
BindProtocol_AddRef(IInternetProtocolEx
*iface
)
357 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
358 LONG ref
= InterlockedIncrement(&This
->ref
);
359 TRACE("(%p) ref=%d\n", This
, ref
);
363 static ULONG WINAPI
BindProtocol_Release(IInternetProtocolEx
*iface
)
365 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
366 LONG ref
= InterlockedDecrement(&This
->ref
);
368 TRACE("(%p) ref=%d\n", This
, ref
);
371 if(This
->wininet_info
)
372 IWinInetInfo_Release(This
->wininet_info
);
373 if(This
->wininet_http_info
)
374 IWinInetHttpInfo_Release(This
->wininet_http_info
);
376 IInternetProtocol_Release(This
->protocol
);
378 IInternetBindInfo_Release(This
->bind_info
);
379 if(This
->protocol_handler
&& This
->protocol_handler
!= &This
->default_protocol_handler
.IInternetProtocol_iface
)
380 IInternetProtocol_Release(This
->protocol_handler
);
381 if(This
->protocol_sink_handler
&&
382 This
->protocol_sink_handler
!= &This
->default_protocol_handler
.IInternetProtocolSink_iface
)
383 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
385 IUri_Release(This
->uri
);
386 SysFreeString(This
->display_uri
);
388 set_binding_sink(This
, NULL
, NULL
);
391 release_notif_hwnd(This
->notif_hwnd
);
392 This
->section
.DebugInfo
->Spare
[0] = 0;
393 DeleteCriticalSection(&This
->section
);
395 heap_free(This
->mime
);
398 URLMON_UnlockModule();
404 static HRESULT WINAPI
BindProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
405 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
406 DWORD grfPI
, HANDLE_PTR dwReserved
)
408 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
412 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
413 pOIBindInfo
, grfPI
, dwReserved
);
415 hres
= CreateUri(szUrl
, Uri_CREATE_FILE_USE_DOS_PATH
, 0, &uri
);
419 hres
= IInternetProtocolEx_StartEx(&This
->IInternetProtocolEx_iface
, uri
, pOIProtSink
,
420 pOIBindInfo
, grfPI
, (HANDLE
*)dwReserved
);
426 static HRESULT WINAPI
BindProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
428 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
430 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
432 return IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
435 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
438 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
440 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
442 return IInternetProtocol_Abort(This
->protocol_handler
, hrReason
, dwOptions
);
445 static HRESULT WINAPI
BindProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
447 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
449 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
451 return IInternetProtocol_Terminate(This
->protocol_handler
, dwOptions
);
454 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocolEx
*iface
)
456 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
457 FIXME("(%p)\n", This
);
461 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocolEx
*iface
)
463 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
464 FIXME("(%p)\n", This
);
468 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
469 ULONG cb
, ULONG
*pcbRead
)
471 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
473 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
477 return IInternetProtocol_Read(This
->protocol_handler
, pv
, cb
, pcbRead
);
480 static HRESULT WINAPI
BindProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
481 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
483 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
484 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
488 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
490 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
492 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
494 return IInternetProtocol_LockRequest(This
->protocol_handler
, dwOptions
);
497 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
499 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
501 TRACE("(%p)\n", This
);
503 return IInternetProtocol_UnlockRequest(This
->protocol_handler
);
506 static HRESULT WINAPI
BindProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
507 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
508 DWORD grfPI
, HANDLE
*dwReserved
)
510 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
511 IInternetProtocol
*protocol
= NULL
;
512 IInternetProtocolEx
*protocolex
;
513 IInternetPriority
*priority
;
514 IServiceProvider
*service_provider
;
515 BOOL urlmon_protocol
= FALSE
;
516 CLSID clsid
= IID_NULL
;
520 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
522 if(!pUri
|| !pOIProtSink
|| !pOIBindInfo
)
530 hres
= IInternetProtocolSink_QueryInterface(pOIProtSink
, &IID_IServiceProvider
,
531 (void**)&service_provider
);
532 if(SUCCEEDED(hres
)) {
533 /* FIXME: What's protocol CLSID here? */
534 IServiceProvider_QueryService(service_provider
, &IID_IInternetProtocol
,
535 &IID_IInternetProtocol
, (void**)&protocol
);
536 IServiceProvider_Release(service_provider
);
543 hres
= get_protocol_handler(pUri
, &clsid
, &urlmon_protocol
, &cf
);
547 if(This
->from_urlmon
) {
548 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
549 IClassFactory_Release(cf
);
553 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)&This
->IInternetBindInfo_iface
,
554 &IID_IUnknown
, (void**)&unk
);
555 IClassFactory_Release(cf
);
559 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
560 IUnknown_Release(unk
);
566 StringFromCLSID(&clsid
, &clsid_str
);
567 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_PROTOCOLCLASSID
, clsid_str
);
568 CoTaskMemFree(clsid_str
);
570 This
->protocol
= protocol
;
572 if(urlmon_protocol
) {
573 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetInfo
, (void**)&This
->wininet_info
);
574 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetHttpInfo
, (void**)&This
->wininet_http_info
);
577 set_binding_sink(This
, pOIProtSink
, pOIBindInfo
);
579 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
, (void**)&priority
);
580 if(SUCCEEDED(hres
)) {
581 IInternetPriority_SetPriority(priority
, This
->priority
);
582 IInternetPriority_Release(priority
);
585 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetProtocolEx
, (void**)&protocolex
);
586 if(SUCCEEDED(hres
)) {
587 hres
= IInternetProtocolEx_StartEx(protocolex
, pUri
, &This
->IInternetProtocolSink_iface
,
588 &This
->IInternetBindInfo_iface
, 0, NULL
);
589 IInternetProtocolEx_Release(protocolex
);
591 hres
= IUri_GetDisplayUri(pUri
, &This
->display_uri
);
595 hres
= IInternetProtocol_Start(protocol
, This
->display_uri
, &This
->IInternetProtocolSink_iface
,
596 &This
->IInternetBindInfo_iface
, 0, 0);
604 void set_binding_sink(BindProtocol
*This
, IInternetProtocolSink
*sink
, IInternetBindInfo
*bind_info
)
606 IInternetProtocolSink
*prev_sink
;
607 IServiceProvider
*service_provider
= NULL
;
610 IInternetProtocolSink_AddRef(sink
);
611 prev_sink
= InterlockedExchangePointer((void**)&This
->protocol_sink
, sink
);
613 IInternetProtocolSink_Release(prev_sink
);
616 IInternetProtocolSink_QueryInterface(sink
, &IID_IServiceProvider
, (void**)&service_provider
);
617 service_provider
= InterlockedExchangePointer((void**)&This
->service_provider
, service_provider
);
619 IServiceProvider_Release(service_provider
);
622 IInternetBindInfo_AddRef(bind_info
);
623 bind_info
= InterlockedExchangePointer((void**)&This
->bind_info
, bind_info
);
625 IInternetBindInfo_Release(bind_info
);
628 static const IInternetProtocolExVtbl BindProtocolVtbl
= {
629 BindProtocol_QueryInterface
,
631 BindProtocol_Release
,
633 BindProtocol_Continue
,
635 BindProtocol_Terminate
,
636 BindProtocol_Suspend
,
640 BindProtocol_LockRequest
,
641 BindProtocol_UnlockRequest
,
645 static inline BindProtocol
*impl_from_IInternetProtocol(IInternetProtocol
*iface
)
647 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocol_iface
);
650 static HRESULT WINAPI
ProtocolHandler_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
652 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
655 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
656 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
657 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
658 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
659 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
660 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
661 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
662 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
663 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
664 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
665 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
666 *ppv
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
670 IInternetProtocol_AddRef(iface
);
674 WARN("not supported interface %s\n", debugstr_guid(riid
));
675 return E_NOINTERFACE
;
678 static ULONG WINAPI
ProtocolHandler_AddRef(IInternetProtocol
*iface
)
680 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
681 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
684 static ULONG WINAPI
ProtocolHandler_Release(IInternetProtocol
*iface
)
686 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
687 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
690 static HRESULT WINAPI
ProtocolHandler_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
691 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
692 DWORD grfPI
, HANDLE_PTR dwReserved
)
694 ERR("Should not be called\n");
698 static HRESULT WINAPI
ProtocolHandler_Continue(IInternetProtocol
*iface
, PROTOCOLDATA
*pProtocolData
)
700 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
703 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
705 hres
= IInternetProtocol_Continue(This
->protocol
, pProtocolData
);
707 heap_free(pProtocolData
);
711 static HRESULT WINAPI
ProtocolHandler_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
714 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
716 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
718 if(This
->protocol
&& !This
->reported_result
)
719 return IInternetProtocol_Abort(This
->protocol
, hrReason
, dwOptions
);
724 static HRESULT WINAPI
ProtocolHandler_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
726 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
728 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
730 if(!This
->reported_result
)
733 /* This may get released in Terminate call. */
734 IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
736 IInternetProtocol_Terminate(This
->protocol
, 0);
738 set_binding_sink(This
, NULL
, NULL
);
740 if(This
->bind_info
) {
741 IInternetBindInfo_Release(This
->bind_info
);
742 This
->bind_info
= NULL
;
745 IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
749 static HRESULT WINAPI
ProtocolHandler_Suspend(IInternetProtocol
*iface
)
751 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
752 FIXME("(%p)\n", This
);
756 static HRESULT WINAPI
ProtocolHandler_Resume(IInternetProtocol
*iface
)
758 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
759 FIXME("(%p)\n", This
);
763 static HRESULT WINAPI
ProtocolHandler_Read(IInternetProtocol
*iface
, void *pv
,
764 ULONG cb
, ULONG
*pcbRead
)
766 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
770 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
773 read
= min(cb
, This
->buf_size
);
774 memcpy(pv
, This
->buf
, read
);
776 if(read
== This
->buf_size
) {
777 heap_free(This
->buf
);
780 memmove(This
->buf
, This
->buf
+cb
, This
->buf_size
-cb
);
783 This
->buf_size
-= read
;
789 if(is_apartment_thread(This
))
790 This
->continue_call
++;
791 hres
= IInternetProtocol_Read(This
->protocol
, (BYTE
*)pv
+read
, cb
-read
, &cread
);
792 if(is_apartment_thread(This
))
793 This
->continue_call
--;
801 static HRESULT WINAPI
ProtocolHandler_Seek(IInternetProtocol
*iface
, LARGE_INTEGER dlibMove
,
802 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
804 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
805 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
809 static HRESULT WINAPI
ProtocolHandler_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
811 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
813 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
815 return IInternetProtocol_LockRequest(This
->protocol
, dwOptions
);
818 static HRESULT WINAPI
ProtocolHandler_UnlockRequest(IInternetProtocol
*iface
)
820 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
822 TRACE("(%p)\n", This
);
824 return IInternetProtocol_UnlockRequest(This
->protocol
);
827 static const IInternetProtocolVtbl InternetProtocolHandlerVtbl
= {
828 ProtocolHandler_QueryInterface
,
829 ProtocolHandler_AddRef
,
830 ProtocolHandler_Release
,
831 ProtocolHandler_Start
,
832 ProtocolHandler_Continue
,
833 ProtocolHandler_Abort
,
834 ProtocolHandler_Terminate
,
835 ProtocolHandler_Suspend
,
836 ProtocolHandler_Resume
,
837 ProtocolHandler_Read
,
838 ProtocolHandler_Seek
,
839 ProtocolHandler_LockRequest
,
840 ProtocolHandler_UnlockRequest
843 static inline BindProtocol
*impl_from_IInternetProtocolSinkHandler(IInternetProtocolSink
*iface
)
845 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocolSink_iface
);
848 static HRESULT WINAPI
ProtocolSinkHandler_QueryInterface(IInternetProtocolSink
*iface
,
849 REFIID riid
, void **ppvObject
)
851 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
852 return IInternetProtocol_QueryInterface(&This
->default_protocol_handler
.IInternetProtocol_iface
,
856 static ULONG WINAPI
ProtocolSinkHandler_AddRef(IInternetProtocolSink
*iface
)
858 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
859 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
862 static ULONG WINAPI
ProtocolSinkHandler_Release(IInternetProtocolSink
*iface
)
864 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
865 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
868 static HRESULT WINAPI
ProtocolSinkHandler_Switch(IInternetProtocolSink
*iface
,
869 PROTOCOLDATA
*pProtocolData
)
871 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
873 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
875 if(!This
->protocol_sink
) {
876 IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
880 return IInternetProtocolSink_Switch(This
->protocol_sink
, pProtocolData
);
883 static HRESULT WINAPI
ProtocolSinkHandler_ReportProgress(IInternetProtocolSink
*iface
,
884 ULONG status_code
, LPCWSTR status_text
)
886 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
888 TRACE("(%p)->(%s %s)\n", This
, debugstr_bindstatus(status_code
), debugstr_w(status_text
));
890 if(!This
->protocol_sink
)
893 switch(status_code
) {
894 case BINDSTATUS_FINDINGRESOURCE
:
895 case BINDSTATUS_CONNECTING
:
896 case BINDSTATUS_REDIRECTING
:
897 case BINDSTATUS_SENDINGREQUEST
:
898 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
899 case BINDSTATUS_DIRECTBIND
:
900 case BINDSTATUS_ACCEPTRANGES
:
901 case BINDSTATUS_DECODING
:
902 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, status_code
, status_text
);
905 case BINDSTATUS_BEGINDOWNLOADDATA
:
906 IInternetProtocolSink_ReportData(This
->protocol_sink
, This
->bscf
, This
->progress
, This
->progress_max
);
909 case BINDSTATUS_MIMETYPEAVAILABLE
:
910 mime_available(This
, status_text
, FALSE
);
913 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
914 mime_available(This
, status_text
, TRUE
);
918 FIXME("unsupported ulStatusCode %u\n", status_code
);
924 static HRESULT WINAPI
ProtocolSinkHandler_ReportData(IInternetProtocolSink
*iface
,
925 DWORD bscf
, ULONG progress
, ULONG progress_max
)
927 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
929 TRACE("(%p)->(%x %u %u)\n", This
, bscf
, progress
, progress_max
);
932 This
->progress
= progress
;
933 This
->progress_max
= progress_max
;
935 if(!This
->protocol_sink
)
938 if((This
->pi
& PI_MIMEVERIFICATION
) && !This
->reported_mime
) {
939 BYTE buf
[BUFFER_SIZE
];
946 if(is_apartment_thread(This
))
947 This
->continue_call
++;
948 hres
= IInternetProtocol_Read(This
->protocol
, buf
,
949 sizeof(buf
)-This
->buf_size
, &read
);
950 if(is_apartment_thread(This
))
951 This
->continue_call
--;
952 if(FAILED(hres
) && hres
!= E_PENDING
)
956 This
->buf
= heap_alloc(BUFFER_SIZE
);
958 return E_OUTOFMEMORY
;
959 }else if(read
+ This
->buf_size
> BUFFER_SIZE
) {
962 tmp
= heap_realloc(This
->buf
, read
+This
->buf_size
);
964 return E_OUTOFMEMORY
;
968 memcpy(This
->buf
+This
->buf_size
, buf
, read
);
969 This
->buf_size
+= read
;
970 }while(This
->buf_size
< MIME_TEST_SIZE
&& hres
== S_OK
);
972 if(This
->buf_size
< MIME_TEST_SIZE
&& hres
!= S_FALSE
)
975 bscf
= BSCF_FIRSTDATANOTIFICATION
;
977 bscf
|= BSCF_LASTDATANOTIFICATION
|BSCF_DATAFULLYAVAILABLE
;
979 if(!This
->reported_mime
) {
982 hres
= IUri_GetRawUri(This
->uri
, &raw_uri
);
986 hres
= FindMimeFromData(NULL
, raw_uri
, This
->buf
, min(This
->buf_size
, MIME_TEST_SIZE
),
987 This
->mime
, 0, &mime
, 0);
988 SysFreeString(raw_uri
);
992 heap_free(This
->mime
);
993 This
->mime
= heap_strdupW(mime
);
995 This
->reported_mime
= TRUE
;
996 if(This
->protocol_sink
)
997 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, This
->mime
);
1001 if(!This
->protocol_sink
)
1004 return IInternetProtocolSink_ReportData(This
->protocol_sink
, bscf
, progress
, progress_max
);
1007 static HRESULT WINAPI
ProtocolSinkHandler_ReportResult(IInternetProtocolSink
*iface
,
1008 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
1010 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
1012 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
1014 if(This
->protocol_sink
)
1015 return IInternetProtocolSink_ReportResult(This
->protocol_sink
, hrResult
, dwError
, szResult
);
1019 static const IInternetProtocolSinkVtbl InternetProtocolSinkHandlerVtbl
= {
1020 ProtocolSinkHandler_QueryInterface
,
1021 ProtocolSinkHandler_AddRef
,
1022 ProtocolSinkHandler_Release
,
1023 ProtocolSinkHandler_Switch
,
1024 ProtocolSinkHandler_ReportProgress
,
1025 ProtocolSinkHandler_ReportData
,
1026 ProtocolSinkHandler_ReportResult
1029 static inline BindProtocol
*impl_from_IInternetBindInfo(IInternetBindInfo
*iface
)
1031 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetBindInfo_iface
);
1034 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
,
1035 REFIID riid
, void **ppv
)
1037 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1038 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1041 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
1043 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1044 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1047 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
1049 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1050 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1053 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
,
1054 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
1056 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1059 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
1061 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
1063 WARN("GetBindInfo failed: %08x\n", hres
);
1067 *grfBINDF
|= BINDF_FROMURLMON
;
1071 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
,
1072 ULONG ulStringType
, LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
1074 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1076 TRACE("(%p)->(%d %p %d %p)\n", This
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1078 return IInternetBindInfo_GetBindString(This
->bind_info
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1081 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
1082 BindInfo_QueryInterface
,
1085 BindInfo_GetBindInfo
,
1086 BindInfo_GetBindString
1089 static inline BindProtocol
*impl_from_IInternetPriority(IInternetPriority
*iface
)
1091 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetPriority_iface
);
1094 static HRESULT WINAPI
InternetPriority_QueryInterface(IInternetPriority
*iface
,
1095 REFIID riid
, void **ppv
)
1097 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1098 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1101 static ULONG WINAPI
InternetPriority_AddRef(IInternetPriority
*iface
)
1103 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1104 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1107 static ULONG WINAPI
InternetPriority_Release(IInternetPriority
*iface
)
1109 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1110 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1113 static HRESULT WINAPI
InternetPriority_SetPriority(IInternetPriority
*iface
, LONG nPriority
)
1115 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1117 TRACE("(%p)->(%d)\n", This
, nPriority
);
1119 This
->priority
= nPriority
;
1123 static HRESULT WINAPI
InternetPriority_GetPriority(IInternetPriority
*iface
, LONG
*pnPriority
)
1125 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1127 TRACE("(%p)->(%p)\n", This
, pnPriority
);
1129 *pnPriority
= This
->priority
;
1133 static const IInternetPriorityVtbl InternetPriorityVtbl
= {
1134 InternetPriority_QueryInterface
,
1135 InternetPriority_AddRef
,
1136 InternetPriority_Release
,
1137 InternetPriority_SetPriority
,
1138 InternetPriority_GetPriority
1142 static inline BindProtocol
*impl_from_IInternetProtocolSink(IInternetProtocolSink
*iface
)
1144 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolSink_iface
);
1147 static HRESULT WINAPI
BPInternetProtocolSink_QueryInterface(IInternetProtocolSink
*iface
,
1148 REFIID riid
, void **ppv
)
1150 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1151 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1154 static ULONG WINAPI
BPInternetProtocolSink_AddRef(IInternetProtocolSink
*iface
)
1156 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1157 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1160 static ULONG WINAPI
BPInternetProtocolSink_Release(IInternetProtocolSink
*iface
)
1162 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1163 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1167 task_header_t header
;
1171 static void switch_proc(BindProtocol
*bind
, task_header_t
*t
)
1173 switch_task_t
*task
= (switch_task_t
*)t
;
1175 IInternetProtocol_Continue(bind
->protocol_handler
, task
->data
);
1180 static HRESULT WINAPI
BPInternetProtocolSink_Switch(IInternetProtocolSink
*iface
,
1181 PROTOCOLDATA
*pProtocolData
)
1183 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1186 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
1188 TRACE("flags %x state %x data %p cb %u\n", pProtocolData
->grfFlags
, pProtocolData
->dwState
,
1189 pProtocolData
->pData
, pProtocolData
->cbData
);
1191 data
= heap_alloc(sizeof(PROTOCOLDATA
));
1193 return E_OUTOFMEMORY
;
1194 memcpy(data
, pProtocolData
, sizeof(PROTOCOLDATA
));
1196 if((This
->pi
&PI_APARTMENTTHREADED
&& pProtocolData
->grfFlags
&PI_FORCE_ASYNC
)
1197 || !do_direct_notif(This
)) {
1198 switch_task_t
*task
;
1200 task
= heap_alloc(sizeof(switch_task_t
));
1204 return E_OUTOFMEMORY
;
1209 push_task(This
, &task
->header
, switch_proc
);
1213 return IInternetProtocolSink_Switch(This
->protocol_sink_handler
, data
);
1217 task_header_t header
;
1221 } on_progress_task_t
;
1223 static void on_progress_proc(BindProtocol
*This
, task_header_t
*t
)
1225 on_progress_task_t
*task
= (on_progress_task_t
*)t
;
1227 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, task
->status_code
, task
->status_text
);
1229 heap_free(task
->status_text
);
1233 static HRESULT WINAPI
BPInternetProtocolSink_ReportProgress(IInternetProtocolSink
*iface
,
1234 ULONG ulStatusCode
, LPCWSTR szStatusText
)
1236 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1238 TRACE("(%p)->(%u %s)\n", This
, ulStatusCode
, debugstr_w(szStatusText
));
1240 if(do_direct_notif(This
)) {
1241 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, ulStatusCode
, szStatusText
);
1243 on_progress_task_t
*task
;
1245 task
= heap_alloc(sizeof(on_progress_task_t
));
1247 task
->status_code
= ulStatusCode
;
1248 task
->status_text
= heap_strdupW(szStatusText
);
1250 push_task(This
, &task
->header
, on_progress_proc
);
1257 task_header_t header
;
1261 } report_data_task_t
;
1263 static void report_data_proc(BindProtocol
*This
, task_header_t
*t
)
1265 report_data_task_t
*task
= (report_data_task_t
*)t
;
1267 IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1268 task
->bscf
, task
->progress
, task
->progress_max
);
1273 static HRESULT WINAPI
BPInternetProtocolSink_ReportData(IInternetProtocolSink
*iface
,
1274 DWORD grfBSCF
, ULONG ulProgress
, ULONG ulProgressMax
)
1276 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1278 TRACE("(%p)->(%x %u %u)\n", This
, grfBSCF
, ulProgress
, ulProgressMax
);
1280 if(!This
->protocol_sink
)
1283 if(!do_direct_notif(This
)) {
1284 report_data_task_t
*task
;
1286 task
= heap_alloc(sizeof(report_data_task_t
));
1288 return E_OUTOFMEMORY
;
1290 task
->bscf
= grfBSCF
;
1291 task
->progress
= ulProgress
;
1292 task
->progress_max
= ulProgressMax
;
1294 push_task(This
, &task
->header
, report_data_proc
);
1298 return IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1299 grfBSCF
, ulProgress
, ulProgressMax
);
1303 task_header_t header
;
1308 } report_result_task_t
;
1310 static void report_result_proc(BindProtocol
*This
, task_header_t
*t
)
1312 report_result_task_t
*task
= (report_result_task_t
*)t
;
1314 IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, task
->hres
, task
->err
, task
->str
);
1316 heap_free(task
->str
);
1320 static HRESULT WINAPI
BPInternetProtocolSink_ReportResult(IInternetProtocolSink
*iface
,
1321 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
1323 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1325 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
1327 if(!This
->protocol_sink
)
1329 This
->reported_result
= TRUE
;
1331 if(!do_direct_notif(This
)) {
1332 report_result_task_t
*task
;
1334 task
= heap_alloc(sizeof(report_result_task_t
));
1336 return E_OUTOFMEMORY
;
1338 task
->hres
= hrResult
;
1339 task
->err
= dwError
;
1340 task
->str
= heap_strdupW(szResult
);
1342 push_task(This
, &task
->header
, report_result_proc
);
1346 return IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, hrResult
, dwError
, szResult
);
1349 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
= {
1350 BPInternetProtocolSink_QueryInterface
,
1351 BPInternetProtocolSink_AddRef
,
1352 BPInternetProtocolSink_Release
,
1353 BPInternetProtocolSink_Switch
,
1354 BPInternetProtocolSink_ReportProgress
,
1355 BPInternetProtocolSink_ReportData
,
1356 BPInternetProtocolSink_ReportResult
1359 static inline BindProtocol
*impl_from_IWinInetHttpInfo(IWinInetHttpInfo
*iface
)
1361 return CONTAINING_RECORD(iface
, BindProtocol
, IWinInetHttpInfo_iface
);
1364 static HRESULT WINAPI
WinInetHttpInfo_QueryInterface(IWinInetHttpInfo
*iface
, REFIID riid
, void **ppv
)
1366 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1367 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1370 static ULONG WINAPI
WinInetHttpInfo_AddRef(IWinInetHttpInfo
*iface
)
1372 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1373 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1376 static ULONG WINAPI
WinInetHttpInfo_Release(IWinInetHttpInfo
*iface
)
1378 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1379 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1382 static HRESULT WINAPI
WinInetHttpInfo_QueryOption(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1383 void *pBuffer
, DWORD
*pcbBuffer
)
1385 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1386 FIXME("(%p)->(%x %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
);
1390 static HRESULT WINAPI
WinInetHttpInfo_QueryInfo(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1391 void *pBuffer
, DWORD
*pcbBuffer
, DWORD
*pdwFlags
, DWORD
*pdwReserved
)
1393 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1394 FIXME("(%p)->(%x %p %p %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
, pdwFlags
, pdwReserved
);
1398 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl
= {
1399 WinInetHttpInfo_QueryInterface
,
1400 WinInetHttpInfo_AddRef
,
1401 WinInetHttpInfo_Release
,
1402 WinInetHttpInfo_QueryOption
,
1403 WinInetHttpInfo_QueryInfo
1406 static inline BindProtocol
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1408 return CONTAINING_RECORD(iface
, BindProtocol
, IServiceProvider_iface
);
1411 static HRESULT WINAPI
BPServiceProvider_QueryInterface(IServiceProvider
*iface
,
1412 REFIID riid
, void **ppv
)
1414 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1415 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1418 static ULONG WINAPI
BPServiceProvider_AddRef(IServiceProvider
*iface
)
1420 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1421 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1424 static ULONG WINAPI
BPServiceProvider_Release(IServiceProvider
*iface
)
1426 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1427 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1430 static HRESULT WINAPI
BPServiceProvider_QueryService(IServiceProvider
*iface
,
1431 REFGUID guidService
, REFIID riid
, void **ppv
)
1433 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1435 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1437 if(!This
->service_provider
)
1438 return E_NOINTERFACE
;
1440 return IServiceProvider_QueryService(This
->service_provider
, guidService
, riid
, ppv
);
1443 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1444 BPServiceProvider_QueryInterface
,
1445 BPServiceProvider_AddRef
,
1446 BPServiceProvider_Release
,
1447 BPServiceProvider_QueryService
1450 HRESULT
create_binding_protocol(BOOL from_urlmon
, BindProtocol
**protocol
)
1452 BindProtocol
*ret
= heap_alloc_zero(sizeof(BindProtocol
));
1454 ret
->IInternetProtocolEx_iface
.lpVtbl
= &BindProtocolVtbl
;
1455 ret
->IInternetBindInfo_iface
.lpVtbl
= &InternetBindInfoVtbl
;
1456 ret
->IInternetPriority_iface
.lpVtbl
= &InternetPriorityVtbl
;
1457 ret
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
1458 ret
->IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkVtbl
;
1459 ret
->IWinInetHttpInfo_iface
.lpVtbl
= &WinInetHttpInfoVtbl
;
1461 ret
->default_protocol_handler
.IInternetProtocol_iface
.lpVtbl
= &InternetProtocolHandlerVtbl
;
1462 ret
->default_protocol_handler
.IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkHandlerVtbl
;
1465 ret
->from_urlmon
= from_urlmon
;
1466 ret
->apartment_thread
= GetCurrentThreadId();
1467 ret
->notif_hwnd
= get_notif_hwnd();
1468 ret
->protocol_handler
= &ret
->default_protocol_handler
.IInternetProtocol_iface
;
1469 ret
->protocol_sink_handler
= &ret
->default_protocol_handler
.IInternetProtocolSink_iface
;
1470 InitializeCriticalSection(&ret
->section
);
1471 ret
->section
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BindProtocol.section");
1473 URLMON_LockModule();