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"
20 #include "wine/debug.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
24 typedef void (*task_proc_t
)(BindProtocol
*,task_header_t
*);
26 struct _task_header_t
{
31 #define BUFFER_SIZE 2048
32 #define MIME_TEST_SIZE 255
34 #define WM_MK_CONTINUE (WM_USER+101)
35 #define WM_MK_RELEASE (WM_USER+102)
37 static void process_tasks(BindProtocol
*This
)
42 EnterCriticalSection(&This
->section
);
44 task
= This
->task_queue_head
;
46 This
->task_queue_head
= task
->next
;
47 if(!This
->task_queue_head
)
48 This
->task_queue_tail
= NULL
;
51 LeaveCriticalSection(&This
->section
);
56 This
->continue_call
++;
57 task
->proc(This
, task
);
58 This
->continue_call
--;
62 static LRESULT WINAPI
notif_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
65 case WM_MK_CONTINUE
: {
66 BindProtocol
*This
= (BindProtocol
*)lParam
;
70 IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
74 tls_data_t
*data
= get_tls_data();
76 if(!--data
->notif_hwnd_cnt
) {
78 data
->notif_hwnd
= NULL
;
83 return DefWindowProcW(hwnd
, msg
, wParam
, lParam
);
86 static const WCHAR wszURLMonikerNotificationWindow
[] =
87 {'U','R','L',' ','M','o','n','i','k','e','r',' ',
88 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
90 static ATOM notif_wnd_class
;
92 static BOOL WINAPI
register_notif_wnd_class(INIT_ONCE
*once
, void *param
, void **context
)
94 static WNDCLASSEXW wndclass
= {
95 sizeof(wndclass
), 0, notif_wnd_proc
, 0, 0,
96 NULL
, NULL
, NULL
, NULL
, NULL
,
97 wszURLMonikerNotificationWindow
, NULL
100 wndclass
.hInstance
= hProxyDll
;
101 notif_wnd_class
= RegisterClassExW(&wndclass
);
105 void unregister_notif_wnd_class(void)
108 UnregisterClassW(MAKEINTRESOURCEW(notif_wnd_class
), hProxyDll
);
111 HWND
get_notif_hwnd(void)
113 tls_data_t
*tls_data
;
115 static INIT_ONCE init_once
= INIT_ONCE_STATIC_INIT
;
117 tls_data
= get_tls_data();
121 if(tls_data
->notif_hwnd_cnt
) {
122 tls_data
->notif_hwnd_cnt
++;
123 return tls_data
->notif_hwnd
;
126 InitOnceExecuteOnce(&init_once
, register_notif_wnd_class
, NULL
, NULL
);
130 tls_data
->notif_hwnd
= CreateWindowExW(0, MAKEINTRESOURCEW(notif_wnd_class
),
131 wszURLMonikerNotificationWindow
, 0, 0, 0, 0, 0, HWND_MESSAGE
,
132 NULL
, hProxyDll
, NULL
);
133 if(tls_data
->notif_hwnd
)
134 tls_data
->notif_hwnd_cnt
++;
136 TRACE("hwnd = %p\n", tls_data
->notif_hwnd
);
138 return tls_data
->notif_hwnd
;
141 void release_notif_hwnd(HWND hwnd
)
143 tls_data_t
*data
= get_tls_data();
148 if(data
->notif_hwnd
!= hwnd
) {
149 PostMessageW(data
->notif_hwnd
, WM_MK_RELEASE
, 0, 0);
153 if(!--data
->notif_hwnd_cnt
) {
154 DestroyWindow(data
->notif_hwnd
);
155 data
->notif_hwnd
= NULL
;
159 static void push_task(BindProtocol
*This
, task_header_t
*task
, task_proc_t proc
)
161 BOOL do_post
= FALSE
;
166 EnterCriticalSection(&This
->section
);
168 if(This
->task_queue_tail
) {
169 This
->task_queue_tail
->next
= task
;
170 This
->task_queue_tail
= task
;
172 This
->task_queue_tail
= This
->task_queue_head
= task
;
173 do_post
= !This
->continue_call
;
176 LeaveCriticalSection(&This
->section
);
179 IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
180 PostMessageW(This
->notif_hwnd
, WM_MK_CONTINUE
, 0, (LPARAM
)This
);
184 static inline BOOL
is_apartment_thread(BindProtocol
*This
)
186 return This
->apartment_thread
== GetCurrentThreadId();
189 static inline BOOL
do_direct_notif(BindProtocol
*This
)
191 return !(This
->pi
& PI_APARTMENTTHREADED
) || (is_apartment_thread(This
) && !This
->continue_call
);
194 static HRESULT
handle_mime_filter(BindProtocol
*This
, IInternetProtocol
*mime_filter
)
196 PROTOCOLFILTERDATA filter_data
= { sizeof(PROTOCOLFILTERDATA
), NULL
, NULL
, NULL
, 0 };
199 hres
= IInternetProtocol_QueryInterface(mime_filter
, &IID_IInternetProtocolSink
, (void**)&This
->protocol_sink_handler
);
201 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
205 IInternetProtocol_AddRef(mime_filter
);
206 This
->protocol_handler
= mime_filter
;
208 filter_data
.pProtocol
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
209 hres
= IInternetProtocol_Start(mime_filter
, This
->mime
, &This
->default_protocol_handler
.IInternetProtocolSink_iface
,
210 &This
->IInternetBindInfo_iface
, PI_FILTER_MODE
|PI_FORCE_ASYNC
,
211 (HANDLE_PTR
)&filter_data
);
213 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
214 IInternetProtocol_Release(This
->protocol_handler
);
215 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
216 This
->protocol_handler
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
220 /* NOTE: IE9 calls it on the new protocol_sink. It doesn't make sense so it seems to be a bug there. */
221 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_LOADINGMIMEHANDLER
, NULL
);
226 static void mime_available(BindProtocol
*This
, LPCWSTR mime
, BOOL verified
)
228 IInternetProtocol
*mime_filter
;
231 heap_free(This
->mime
);
232 This
->mime
= heap_strdupW(mime
);
234 if(This
->protocol_handler
==&This
->default_protocol_handler
.IInternetProtocol_iface
235 && (mime_filter
= get_mime_filter(mime
))) {
236 TRACE("Got mime filter for %s\n", debugstr_w(mime
));
238 hres
= handle_mime_filter(This
, mime_filter
);
239 IInternetProtocol_Release(mime_filter
);
241 FIXME("MIME filter failed: %08x\n", hres
);
244 if(This
->reported_mime
|| verified
|| !(This
->pi
& PI_MIMEVERIFICATION
)) {
245 This
->reported_mime
= TRUE
;
246 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
250 static inline BindProtocol
*impl_from_IInternetProtocolEx(IInternetProtocolEx
*iface
)
252 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolEx_iface
);
255 static HRESULT WINAPI
BindProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
257 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
260 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
261 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
262 *ppv
= &This
->IInternetProtocolEx_iface
;
263 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
264 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
265 *ppv
= &This
->IInternetProtocolEx_iface
;
266 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
267 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
268 *ppv
= &This
->IInternetProtocolEx_iface
;
269 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
270 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
271 *ppv
= &This
->IInternetProtocolEx_iface
;
272 }else if(IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
273 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This
, ppv
);
274 *ppv
= &This
->IInternetBindInfo_iface
;
275 }else if(IsEqualGUID(&IID_IInternetPriority
, riid
)) {
276 TRACE("(%p)->(IID_IInternetPriority %p)\n", This
, ppv
);
277 *ppv
= &This
->IInternetPriority_iface
;
278 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
279 FIXME("(%p)->(IID_IAuthenticate %p)\n", This
, ppv
);
280 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
281 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
282 *ppv
= &This
->IServiceProvider_iface
;
283 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
284 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
285 *ppv
= &This
->IInternetProtocolSink_iface
;
286 }else if(IsEqualGUID(&IID_IWinInetInfo
, riid
)) {
287 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This
, ppv
);
290 IWinInetInfo
*inet_info
;
293 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetInfo
, (void**)&inet_info
);
294 if(SUCCEEDED(hres
)) {
295 *ppv
= &This
->IWinInetHttpInfo_iface
;
296 IWinInetInfo_Release(inet_info
);
299 }else if(IsEqualGUID(&IID_IWinInetHttpInfo
, riid
)) {
300 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This
, ppv
);
303 IWinInetHttpInfo
*http_info
;
306 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetHttpInfo
, (void**)&http_info
);
307 if(SUCCEEDED(hres
)) {
308 *ppv
= &This
->IWinInetHttpInfo_iface
;
309 IWinInetHttpInfo_Release(http_info
);
313 WARN("not supported interface %s\n", debugstr_guid(riid
));
317 return E_NOINTERFACE
;
319 IUnknown_AddRef((IUnknown
*)*ppv
);
323 static ULONG WINAPI
BindProtocol_AddRef(IInternetProtocolEx
*iface
)
325 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
326 LONG ref
= InterlockedIncrement(&This
->ref
);
327 TRACE("(%p) ref=%d\n", This
, ref
);
331 static ULONG WINAPI
BindProtocol_Release(IInternetProtocolEx
*iface
)
333 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
334 LONG ref
= InterlockedDecrement(&This
->ref
);
336 TRACE("(%p) ref=%d\n", This
, ref
);
339 if(This
->wininet_info
)
340 IWinInetInfo_Release(This
->wininet_info
);
341 if(This
->wininet_http_info
)
342 IWinInetHttpInfo_Release(This
->wininet_http_info
);
344 IInternetProtocol_Release(This
->protocol
);
346 IInternetBindInfo_Release(This
->bind_info
);
347 if(This
->protocol_handler
&& This
->protocol_handler
!= &This
->default_protocol_handler
.IInternetProtocol_iface
)
348 IInternetProtocol_Release(This
->protocol_handler
);
349 if(This
->protocol_sink_handler
&&
350 This
->protocol_sink_handler
!= &This
->default_protocol_handler
.IInternetProtocolSink_iface
)
351 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
353 IUri_Release(This
->uri
);
354 SysFreeString(This
->display_uri
);
356 set_binding_sink(This
, NULL
, NULL
);
359 release_notif_hwnd(This
->notif_hwnd
);
360 This
->section
.DebugInfo
->Spare
[0] = 0;
361 DeleteCriticalSection(&This
->section
);
363 heap_free(This
->mime
);
366 URLMON_UnlockModule();
372 static HRESULT WINAPI
BindProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
373 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
374 DWORD grfPI
, HANDLE_PTR dwReserved
)
376 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
380 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
381 pOIBindInfo
, grfPI
, dwReserved
);
383 hres
= CreateUri(szUrl
, Uri_CREATE_FILE_USE_DOS_PATH
, 0, &uri
);
387 hres
= IInternetProtocolEx_StartEx(&This
->IInternetProtocolEx_iface
, uri
, pOIProtSink
,
388 pOIBindInfo
, grfPI
, (HANDLE
*)dwReserved
);
394 static HRESULT WINAPI
BindProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
396 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
398 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
400 return IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
403 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
406 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
408 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
410 return IInternetProtocol_Abort(This
->protocol_handler
, hrReason
, dwOptions
);
413 static HRESULT WINAPI
BindProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
415 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
417 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
419 return IInternetProtocol_Terminate(This
->protocol_handler
, dwOptions
);
422 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocolEx
*iface
)
424 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
425 FIXME("(%p)\n", This
);
429 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocolEx
*iface
)
431 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
432 FIXME("(%p)\n", This
);
436 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
437 ULONG cb
, ULONG
*pcbRead
)
439 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
441 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
445 return IInternetProtocol_Read(This
->protocol_handler
, pv
, cb
, pcbRead
);
448 static HRESULT WINAPI
BindProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
449 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
451 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
452 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
456 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
458 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
460 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
462 return IInternetProtocol_LockRequest(This
->protocol_handler
, dwOptions
);
465 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
467 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
469 TRACE("(%p)\n", This
);
471 return IInternetProtocol_UnlockRequest(This
->protocol_handler
);
474 static HRESULT WINAPI
BindProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
475 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
476 DWORD grfPI
, HANDLE
*dwReserved
)
478 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
479 IInternetProtocol
*protocol
= NULL
;
480 IInternetProtocolEx
*protocolex
;
481 IInternetPriority
*priority
;
482 IServiceProvider
*service_provider
;
483 BOOL urlmon_protocol
= FALSE
;
484 CLSID clsid
= IID_NULL
;
488 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
490 if(!pUri
|| !pOIProtSink
|| !pOIBindInfo
)
498 hres
= IInternetProtocolSink_QueryInterface(pOIProtSink
, &IID_IServiceProvider
,
499 (void**)&service_provider
);
500 if(SUCCEEDED(hres
)) {
501 /* FIXME: What's protocol CLSID here? */
502 IServiceProvider_QueryService(service_provider
, &IID_IInternetProtocol
,
503 &IID_IInternetProtocol
, (void**)&protocol
);
504 IServiceProvider_Release(service_provider
);
511 hres
= get_protocol_handler(pUri
, &clsid
, &urlmon_protocol
, &cf
);
515 if(This
->from_urlmon
) {
516 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
517 IClassFactory_Release(cf
);
521 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)&This
->IInternetBindInfo_iface
,
522 &IID_IUnknown
, (void**)&unk
);
523 IClassFactory_Release(cf
);
527 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
528 IUnknown_Release(unk
);
534 StringFromCLSID(&clsid
, &clsid_str
);
535 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_PROTOCOLCLASSID
, clsid_str
);
536 CoTaskMemFree(clsid_str
);
538 This
->protocol
= protocol
;
540 if(urlmon_protocol
) {
541 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetInfo
, (void**)&This
->wininet_info
);
542 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetHttpInfo
, (void**)&This
->wininet_http_info
);
545 set_binding_sink(This
, pOIProtSink
, pOIBindInfo
);
547 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
, (void**)&priority
);
548 if(SUCCEEDED(hres
)) {
549 IInternetPriority_SetPriority(priority
, This
->priority
);
550 IInternetPriority_Release(priority
);
553 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetProtocolEx
, (void**)&protocolex
);
554 if(SUCCEEDED(hres
)) {
555 hres
= IInternetProtocolEx_StartEx(protocolex
, pUri
, &This
->IInternetProtocolSink_iface
,
556 &This
->IInternetBindInfo_iface
, 0, NULL
);
557 IInternetProtocolEx_Release(protocolex
);
559 hres
= IUri_GetDisplayUri(pUri
, &This
->display_uri
);
563 hres
= IInternetProtocol_Start(protocol
, This
->display_uri
, &This
->IInternetProtocolSink_iface
,
564 &This
->IInternetBindInfo_iface
, 0, 0);
572 void set_binding_sink(BindProtocol
*This
, IInternetProtocolSink
*sink
, IInternetBindInfo
*bind_info
)
574 IInternetProtocolSink
*prev_sink
;
575 IServiceProvider
*service_provider
= NULL
;
578 IInternetProtocolSink_AddRef(sink
);
579 prev_sink
= InterlockedExchangePointer((void**)&This
->protocol_sink
, sink
);
581 IInternetProtocolSink_Release(prev_sink
);
584 IInternetProtocolSink_QueryInterface(sink
, &IID_IServiceProvider
, (void**)&service_provider
);
585 service_provider
= InterlockedExchangePointer((void**)&This
->service_provider
, service_provider
);
587 IServiceProvider_Release(service_provider
);
590 IInternetBindInfo_AddRef(bind_info
);
591 bind_info
= InterlockedExchangePointer((void**)&This
->bind_info
, bind_info
);
593 IInternetBindInfo_Release(bind_info
);
596 static const IInternetProtocolExVtbl BindProtocolVtbl
= {
597 BindProtocol_QueryInterface
,
599 BindProtocol_Release
,
601 BindProtocol_Continue
,
603 BindProtocol_Terminate
,
604 BindProtocol_Suspend
,
608 BindProtocol_LockRequest
,
609 BindProtocol_UnlockRequest
,
613 static inline BindProtocol
*impl_from_IInternetProtocol(IInternetProtocol
*iface
)
615 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocol_iface
);
618 static HRESULT WINAPI
ProtocolHandler_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
620 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
623 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
624 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
625 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
626 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
627 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
628 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
629 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
630 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
631 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
632 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
633 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
634 *ppv
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
638 IInternetProtocol_AddRef(iface
);
642 WARN("not supported interface %s\n", debugstr_guid(riid
));
643 return E_NOINTERFACE
;
646 static ULONG WINAPI
ProtocolHandler_AddRef(IInternetProtocol
*iface
)
648 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
649 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
652 static ULONG WINAPI
ProtocolHandler_Release(IInternetProtocol
*iface
)
654 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
655 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
658 static HRESULT WINAPI
ProtocolHandler_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
659 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
660 DWORD grfPI
, HANDLE_PTR dwReserved
)
662 ERR("Should not be called\n");
666 static HRESULT WINAPI
ProtocolHandler_Continue(IInternetProtocol
*iface
, PROTOCOLDATA
*pProtocolData
)
668 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
671 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
673 hres
= IInternetProtocol_Continue(This
->protocol
, pProtocolData
);
675 heap_free(pProtocolData
);
679 static HRESULT WINAPI
ProtocolHandler_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
682 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
684 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
686 if(This
->protocol
&& !This
->reported_result
)
687 return IInternetProtocol_Abort(This
->protocol
, hrReason
, dwOptions
);
692 static HRESULT WINAPI
ProtocolHandler_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
694 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
696 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
698 if(!This
->reported_result
)
701 /* This may get released in Terminate call. */
702 IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
704 IInternetProtocol_Terminate(This
->protocol
, 0);
706 set_binding_sink(This
, NULL
, NULL
);
708 if(This
->bind_info
) {
709 IInternetBindInfo_Release(This
->bind_info
);
710 This
->bind_info
= NULL
;
713 IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
717 static HRESULT WINAPI
ProtocolHandler_Suspend(IInternetProtocol
*iface
)
719 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
720 FIXME("(%p)\n", This
);
724 static HRESULT WINAPI
ProtocolHandler_Resume(IInternetProtocol
*iface
)
726 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
727 FIXME("(%p)\n", This
);
731 static HRESULT WINAPI
ProtocolHandler_Read(IInternetProtocol
*iface
, void *pv
,
732 ULONG cb
, ULONG
*pcbRead
)
734 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
738 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
741 read
= min(cb
, This
->buf_size
);
742 memcpy(pv
, This
->buf
, read
);
744 if(read
== This
->buf_size
) {
745 heap_free(This
->buf
);
748 memmove(This
->buf
, This
->buf
+cb
, This
->buf_size
-cb
);
751 This
->buf_size
-= read
;
757 if(is_apartment_thread(This
))
758 This
->continue_call
++;
759 hres
= IInternetProtocol_Read(This
->protocol
, (BYTE
*)pv
+read
, cb
-read
, &cread
);
760 if(is_apartment_thread(This
))
761 This
->continue_call
--;
769 static HRESULT WINAPI
ProtocolHandler_Seek(IInternetProtocol
*iface
, LARGE_INTEGER dlibMove
,
770 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
772 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
773 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
777 static HRESULT WINAPI
ProtocolHandler_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
779 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
781 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
783 return IInternetProtocol_LockRequest(This
->protocol
, dwOptions
);
786 static HRESULT WINAPI
ProtocolHandler_UnlockRequest(IInternetProtocol
*iface
)
788 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
790 TRACE("(%p)\n", This
);
792 return IInternetProtocol_UnlockRequest(This
->protocol
);
795 static const IInternetProtocolVtbl InternetProtocolHandlerVtbl
= {
796 ProtocolHandler_QueryInterface
,
797 ProtocolHandler_AddRef
,
798 ProtocolHandler_Release
,
799 ProtocolHandler_Start
,
800 ProtocolHandler_Continue
,
801 ProtocolHandler_Abort
,
802 ProtocolHandler_Terminate
,
803 ProtocolHandler_Suspend
,
804 ProtocolHandler_Resume
,
805 ProtocolHandler_Read
,
806 ProtocolHandler_Seek
,
807 ProtocolHandler_LockRequest
,
808 ProtocolHandler_UnlockRequest
811 static inline BindProtocol
*impl_from_IInternetProtocolSinkHandler(IInternetProtocolSink
*iface
)
813 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocolSink_iface
);
816 static HRESULT WINAPI
ProtocolSinkHandler_QueryInterface(IInternetProtocolSink
*iface
,
817 REFIID riid
, void **ppvObject
)
819 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
820 return IInternetProtocol_QueryInterface(&This
->default_protocol_handler
.IInternetProtocol_iface
,
824 static ULONG WINAPI
ProtocolSinkHandler_AddRef(IInternetProtocolSink
*iface
)
826 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
827 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
830 static ULONG WINAPI
ProtocolSinkHandler_Release(IInternetProtocolSink
*iface
)
832 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
833 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
836 static HRESULT WINAPI
ProtocolSinkHandler_Switch(IInternetProtocolSink
*iface
,
837 PROTOCOLDATA
*pProtocolData
)
839 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
841 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
843 if(!This
->protocol_sink
) {
844 IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
848 return IInternetProtocolSink_Switch(This
->protocol_sink
, pProtocolData
);
851 static HRESULT WINAPI
ProtocolSinkHandler_ReportProgress(IInternetProtocolSink
*iface
,
852 ULONG status_code
, LPCWSTR status_text
)
854 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
856 TRACE("(%p)->(%s %s)\n", This
, debugstr_bindstatus(status_code
), debugstr_w(status_text
));
858 if(!This
->protocol_sink
)
861 switch(status_code
) {
862 case BINDSTATUS_FINDINGRESOURCE
:
863 case BINDSTATUS_CONNECTING
:
864 case BINDSTATUS_REDIRECTING
:
865 case BINDSTATUS_SENDINGREQUEST
:
866 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
867 case BINDSTATUS_DIRECTBIND
:
868 case BINDSTATUS_ACCEPTRANGES
:
869 case BINDSTATUS_DECODING
:
870 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, status_code
, status_text
);
873 case BINDSTATUS_BEGINDOWNLOADDATA
:
874 IInternetProtocolSink_ReportData(This
->protocol_sink
, This
->bscf
, This
->progress
, This
->progress_max
);
877 case BINDSTATUS_MIMETYPEAVAILABLE
:
878 mime_available(This
, status_text
, FALSE
);
881 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
882 mime_available(This
, status_text
, TRUE
);
886 FIXME("unsupported ulStatusCode %u\n", status_code
);
892 static HRESULT WINAPI
ProtocolSinkHandler_ReportData(IInternetProtocolSink
*iface
,
893 DWORD bscf
, ULONG progress
, ULONG progress_max
)
895 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
897 TRACE("(%p)->(%x %u %u)\n", This
, bscf
, progress
, progress_max
);
900 This
->progress
= progress
;
901 This
->progress_max
= progress_max
;
903 if(!This
->protocol_sink
)
906 if((This
->pi
& PI_MIMEVERIFICATION
) && !This
->reported_mime
) {
907 BYTE buf
[BUFFER_SIZE
];
914 if(is_apartment_thread(This
))
915 This
->continue_call
++;
916 hres
= IInternetProtocol_Read(This
->protocol
, buf
,
917 sizeof(buf
)-This
->buf_size
, &read
);
918 if(is_apartment_thread(This
))
919 This
->continue_call
--;
920 if(FAILED(hres
) && hres
!= E_PENDING
)
924 This
->buf
= heap_alloc(BUFFER_SIZE
);
926 return E_OUTOFMEMORY
;
927 }else if(read
+ This
->buf_size
> BUFFER_SIZE
) {
930 tmp
= heap_realloc(This
->buf
, read
+This
->buf_size
);
932 return E_OUTOFMEMORY
;
936 memcpy(This
->buf
+This
->buf_size
, buf
, read
);
937 This
->buf_size
+= read
;
938 }while(This
->buf_size
< MIME_TEST_SIZE
&& hres
== S_OK
);
940 if(This
->buf_size
< MIME_TEST_SIZE
&& hres
!= S_FALSE
)
943 bscf
= BSCF_FIRSTDATANOTIFICATION
;
945 bscf
|= BSCF_LASTDATANOTIFICATION
|BSCF_DATAFULLYAVAILABLE
;
947 if(!This
->reported_mime
) {
950 hres
= IUri_GetRawUri(This
->uri
, &raw_uri
);
954 hres
= FindMimeFromData(NULL
, raw_uri
, This
->buf
, min(This
->buf_size
, MIME_TEST_SIZE
),
955 This
->mime
, 0, &mime
, 0);
956 SysFreeString(raw_uri
);
960 heap_free(This
->mime
);
961 This
->mime
= heap_strdupW(mime
);
963 This
->reported_mime
= TRUE
;
964 if(This
->protocol_sink
)
965 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, This
->mime
);
969 if(!This
->protocol_sink
)
972 return IInternetProtocolSink_ReportData(This
->protocol_sink
, bscf
, progress
, progress_max
);
975 static HRESULT WINAPI
ProtocolSinkHandler_ReportResult(IInternetProtocolSink
*iface
,
976 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
978 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
980 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
982 if(This
->protocol_sink
)
983 return IInternetProtocolSink_ReportResult(This
->protocol_sink
, hrResult
, dwError
, szResult
);
987 static const IInternetProtocolSinkVtbl InternetProtocolSinkHandlerVtbl
= {
988 ProtocolSinkHandler_QueryInterface
,
989 ProtocolSinkHandler_AddRef
,
990 ProtocolSinkHandler_Release
,
991 ProtocolSinkHandler_Switch
,
992 ProtocolSinkHandler_ReportProgress
,
993 ProtocolSinkHandler_ReportData
,
994 ProtocolSinkHandler_ReportResult
997 static inline BindProtocol
*impl_from_IInternetBindInfo(IInternetBindInfo
*iface
)
999 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetBindInfo_iface
);
1002 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
,
1003 REFIID riid
, void **ppv
)
1005 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1006 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1009 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
1011 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1012 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1015 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
1017 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1018 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1021 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
,
1022 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
1024 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1027 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
1029 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
1031 WARN("GetBindInfo failed: %08x\n", hres
);
1035 *grfBINDF
|= BINDF_FROMURLMON
;
1039 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
,
1040 ULONG ulStringType
, LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
1042 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1044 TRACE("(%p)->(%d %p %d %p)\n", This
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1046 return IInternetBindInfo_GetBindString(This
->bind_info
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1049 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
1050 BindInfo_QueryInterface
,
1053 BindInfo_GetBindInfo
,
1054 BindInfo_GetBindString
1057 static inline BindProtocol
*impl_from_IInternetPriority(IInternetPriority
*iface
)
1059 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetPriority_iface
);
1062 static HRESULT WINAPI
InternetPriority_QueryInterface(IInternetPriority
*iface
,
1063 REFIID riid
, void **ppv
)
1065 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1066 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1069 static ULONG WINAPI
InternetPriority_AddRef(IInternetPriority
*iface
)
1071 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1072 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1075 static ULONG WINAPI
InternetPriority_Release(IInternetPriority
*iface
)
1077 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1078 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1081 static HRESULT WINAPI
InternetPriority_SetPriority(IInternetPriority
*iface
, LONG nPriority
)
1083 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1085 TRACE("(%p)->(%d)\n", This
, nPriority
);
1087 This
->priority
= nPriority
;
1091 static HRESULT WINAPI
InternetPriority_GetPriority(IInternetPriority
*iface
, LONG
*pnPriority
)
1093 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1095 TRACE("(%p)->(%p)\n", This
, pnPriority
);
1097 *pnPriority
= This
->priority
;
1101 static const IInternetPriorityVtbl InternetPriorityVtbl
= {
1102 InternetPriority_QueryInterface
,
1103 InternetPriority_AddRef
,
1104 InternetPriority_Release
,
1105 InternetPriority_SetPriority
,
1106 InternetPriority_GetPriority
1110 static inline BindProtocol
*impl_from_IInternetProtocolSink(IInternetProtocolSink
*iface
)
1112 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolSink_iface
);
1115 static HRESULT WINAPI
BPInternetProtocolSink_QueryInterface(IInternetProtocolSink
*iface
,
1116 REFIID riid
, void **ppv
)
1118 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1119 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1122 static ULONG WINAPI
BPInternetProtocolSink_AddRef(IInternetProtocolSink
*iface
)
1124 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1125 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1128 static ULONG WINAPI
BPInternetProtocolSink_Release(IInternetProtocolSink
*iface
)
1130 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1131 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1135 task_header_t header
;
1139 static void switch_proc(BindProtocol
*bind
, task_header_t
*t
)
1141 switch_task_t
*task
= (switch_task_t
*)t
;
1143 IInternetProtocol_Continue(bind
->protocol_handler
, task
->data
);
1148 static HRESULT WINAPI
BPInternetProtocolSink_Switch(IInternetProtocolSink
*iface
,
1149 PROTOCOLDATA
*pProtocolData
)
1151 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1154 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
1156 TRACE("flags %x state %x data %p cb %u\n", pProtocolData
->grfFlags
, pProtocolData
->dwState
,
1157 pProtocolData
->pData
, pProtocolData
->cbData
);
1159 data
= heap_alloc(sizeof(PROTOCOLDATA
));
1161 return E_OUTOFMEMORY
;
1162 memcpy(data
, pProtocolData
, sizeof(PROTOCOLDATA
));
1164 if((This
->pi
&PI_APARTMENTTHREADED
&& pProtocolData
->grfFlags
&PI_FORCE_ASYNC
)
1165 || !do_direct_notif(This
)) {
1166 switch_task_t
*task
;
1168 task
= heap_alloc(sizeof(switch_task_t
));
1172 return E_OUTOFMEMORY
;
1177 push_task(This
, &task
->header
, switch_proc
);
1181 return IInternetProtocolSink_Switch(This
->protocol_sink_handler
, data
);
1185 task_header_t header
;
1189 } on_progress_task_t
;
1191 static void on_progress_proc(BindProtocol
*This
, task_header_t
*t
)
1193 on_progress_task_t
*task
= (on_progress_task_t
*)t
;
1195 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, task
->status_code
, task
->status_text
);
1197 heap_free(task
->status_text
);
1201 static HRESULT WINAPI
BPInternetProtocolSink_ReportProgress(IInternetProtocolSink
*iface
,
1202 ULONG ulStatusCode
, LPCWSTR szStatusText
)
1204 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1206 TRACE("(%p)->(%u %s)\n", This
, ulStatusCode
, debugstr_w(szStatusText
));
1208 if(do_direct_notif(This
)) {
1209 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, ulStatusCode
, szStatusText
);
1211 on_progress_task_t
*task
;
1213 task
= heap_alloc(sizeof(on_progress_task_t
));
1215 task
->status_code
= ulStatusCode
;
1216 task
->status_text
= heap_strdupW(szStatusText
);
1218 push_task(This
, &task
->header
, on_progress_proc
);
1225 task_header_t header
;
1229 } report_data_task_t
;
1231 static void report_data_proc(BindProtocol
*This
, task_header_t
*t
)
1233 report_data_task_t
*task
= (report_data_task_t
*)t
;
1235 IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1236 task
->bscf
, task
->progress
, task
->progress_max
);
1241 static HRESULT WINAPI
BPInternetProtocolSink_ReportData(IInternetProtocolSink
*iface
,
1242 DWORD grfBSCF
, ULONG ulProgress
, ULONG ulProgressMax
)
1244 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1246 TRACE("(%p)->(%x %u %u)\n", This
, grfBSCF
, ulProgress
, ulProgressMax
);
1248 if(!This
->protocol_sink
)
1251 if(!do_direct_notif(This
)) {
1252 report_data_task_t
*task
;
1254 task
= heap_alloc(sizeof(report_data_task_t
));
1256 return E_OUTOFMEMORY
;
1258 task
->bscf
= grfBSCF
;
1259 task
->progress
= ulProgress
;
1260 task
->progress_max
= ulProgressMax
;
1262 push_task(This
, &task
->header
, report_data_proc
);
1266 return IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1267 grfBSCF
, ulProgress
, ulProgressMax
);
1271 task_header_t header
;
1276 } report_result_task_t
;
1278 static void report_result_proc(BindProtocol
*This
, task_header_t
*t
)
1280 report_result_task_t
*task
= (report_result_task_t
*)t
;
1282 IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, task
->hres
, task
->err
, task
->str
);
1284 heap_free(task
->str
);
1288 static HRESULT WINAPI
BPInternetProtocolSink_ReportResult(IInternetProtocolSink
*iface
,
1289 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
1291 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1293 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
1295 if(!This
->protocol_sink
)
1297 This
->reported_result
= TRUE
;
1299 if(!do_direct_notif(This
)) {
1300 report_result_task_t
*task
;
1302 task
= heap_alloc(sizeof(report_result_task_t
));
1304 return E_OUTOFMEMORY
;
1306 task
->hres
= hrResult
;
1307 task
->err
= dwError
;
1308 task
->str
= heap_strdupW(szResult
);
1310 push_task(This
, &task
->header
, report_result_proc
);
1314 return IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, hrResult
, dwError
, szResult
);
1317 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
= {
1318 BPInternetProtocolSink_QueryInterface
,
1319 BPInternetProtocolSink_AddRef
,
1320 BPInternetProtocolSink_Release
,
1321 BPInternetProtocolSink_Switch
,
1322 BPInternetProtocolSink_ReportProgress
,
1323 BPInternetProtocolSink_ReportData
,
1324 BPInternetProtocolSink_ReportResult
1327 static inline BindProtocol
*impl_from_IWinInetHttpInfo(IWinInetHttpInfo
*iface
)
1329 return CONTAINING_RECORD(iface
, BindProtocol
, IWinInetHttpInfo_iface
);
1332 static HRESULT WINAPI
WinInetHttpInfo_QueryInterface(IWinInetHttpInfo
*iface
, REFIID riid
, void **ppv
)
1334 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1335 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1338 static ULONG WINAPI
WinInetHttpInfo_AddRef(IWinInetHttpInfo
*iface
)
1340 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1341 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1344 static ULONG WINAPI
WinInetHttpInfo_Release(IWinInetHttpInfo
*iface
)
1346 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1347 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1350 static HRESULT WINAPI
WinInetHttpInfo_QueryOption(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1351 void *pBuffer
, DWORD
*pcbBuffer
)
1353 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1354 FIXME("(%p)->(%x %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
);
1358 static HRESULT WINAPI
WinInetHttpInfo_QueryInfo(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1359 void *pBuffer
, DWORD
*pcbBuffer
, DWORD
*pdwFlags
, DWORD
*pdwReserved
)
1361 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1362 FIXME("(%p)->(%x %p %p %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
, pdwFlags
, pdwReserved
);
1366 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl
= {
1367 WinInetHttpInfo_QueryInterface
,
1368 WinInetHttpInfo_AddRef
,
1369 WinInetHttpInfo_Release
,
1370 WinInetHttpInfo_QueryOption
,
1371 WinInetHttpInfo_QueryInfo
1374 static inline BindProtocol
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1376 return CONTAINING_RECORD(iface
, BindProtocol
, IServiceProvider_iface
);
1379 static HRESULT WINAPI
BPServiceProvider_QueryInterface(IServiceProvider
*iface
,
1380 REFIID riid
, void **ppv
)
1382 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1383 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1386 static ULONG WINAPI
BPServiceProvider_AddRef(IServiceProvider
*iface
)
1388 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1389 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1392 static ULONG WINAPI
BPServiceProvider_Release(IServiceProvider
*iface
)
1394 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1395 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1398 static HRESULT WINAPI
BPServiceProvider_QueryService(IServiceProvider
*iface
,
1399 REFGUID guidService
, REFIID riid
, void **ppv
)
1401 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1403 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1405 if(!This
->service_provider
)
1406 return E_NOINTERFACE
;
1408 return IServiceProvider_QueryService(This
->service_provider
, guidService
, riid
, ppv
);
1411 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1412 BPServiceProvider_QueryInterface
,
1413 BPServiceProvider_AddRef
,
1414 BPServiceProvider_Release
,
1415 BPServiceProvider_QueryService
1418 HRESULT
create_binding_protocol(BOOL from_urlmon
, BindProtocol
**protocol
)
1420 BindProtocol
*ret
= heap_alloc_zero(sizeof(BindProtocol
));
1422 ret
->IInternetProtocolEx_iface
.lpVtbl
= &BindProtocolVtbl
;
1423 ret
->IInternetBindInfo_iface
.lpVtbl
= &InternetBindInfoVtbl
;
1424 ret
->IInternetPriority_iface
.lpVtbl
= &InternetPriorityVtbl
;
1425 ret
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
1426 ret
->IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkVtbl
;
1427 ret
->IWinInetHttpInfo_iface
.lpVtbl
= &WinInetHttpInfoVtbl
;
1429 ret
->default_protocol_handler
.IInternetProtocol_iface
.lpVtbl
= &InternetProtocolHandlerVtbl
;
1430 ret
->default_protocol_handler
.IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkHandlerVtbl
;
1433 ret
->from_urlmon
= from_urlmon
;
1434 ret
->apartment_thread
= GetCurrentThreadId();
1435 ret
->notif_hwnd
= get_notif_hwnd();
1436 ret
->protocol_handler
= &ret
->default_protocol_handler
.IInternetProtocol_iface
;
1437 ret
->protocol_sink_handler
= &ret
->default_protocol_handler
.IInternetProtocolSink_iface
;
1438 InitializeCriticalSection(&ret
->section
);
1439 ret
->section
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BindProtocol.section");
1441 URLMON_LockModule();