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 LRESULT WINAPI
notif_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
40 case WM_MK_CONTINUE
: {
41 BindProtocol
*This
= (BindProtocol
*)lParam
;
45 EnterCriticalSection(&This
->section
);
47 task
= This
->task_queue_head
;
49 This
->task_queue_head
= task
->next
;
50 if(!This
->task_queue_head
)
51 This
->task_queue_tail
= NULL
;
54 LeaveCriticalSection(&This
->section
);
59 This
->continue_call
++;
60 task
->proc(This
, task
);
61 This
->continue_call
--;
64 IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
68 tls_data_t
*data
= get_tls_data();
70 if(!--data
->notif_hwnd_cnt
) {
72 data
->notif_hwnd
= NULL
;
77 return DefWindowProcW(hwnd
, msg
, wParam
, lParam
);
80 HWND
get_notif_hwnd(void)
82 static ATOM wnd_class
= 0;
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 tls_data
= get_tls_data();
93 if(tls_data
->notif_hwnd_cnt
) {
94 tls_data
->notif_hwnd_cnt
++;
95 return tls_data
->notif_hwnd
;
99 static WNDCLASSEXW wndclass
= {
101 notif_wnd_proc
, 0, 0,
102 NULL
, NULL
, NULL
, NULL
, NULL
,
103 wszURLMonikerNotificationWindow
,
107 wndclass
.hInstance
= hProxyDll
;
109 wnd_class
= RegisterClassExW(&wndclass
);
110 if (!wnd_class
&& GetLastError() == ERROR_CLASS_ALREADY_EXISTS
)
114 tls_data
->notif_hwnd
= CreateWindowExW(0, wszURLMonikerNotificationWindow
,
115 wszURLMonikerNotificationWindow
, 0, 0, 0, 0, 0, HWND_MESSAGE
,
116 NULL
, hProxyDll
, NULL
);
117 if(tls_data
->notif_hwnd
)
118 tls_data
->notif_hwnd_cnt
++;
120 TRACE("hwnd = %p\n", tls_data
->notif_hwnd
);
122 return tls_data
->notif_hwnd
;
125 void release_notif_hwnd(HWND hwnd
)
127 tls_data_t
*data
= get_tls_data();
132 if(data
->notif_hwnd
!= hwnd
) {
133 PostMessageW(data
->notif_hwnd
, WM_MK_RELEASE
, 0, 0);
137 if(!--data
->notif_hwnd_cnt
) {
138 DestroyWindow(data
->notif_hwnd
);
139 data
->notif_hwnd
= NULL
;
143 static void push_task(BindProtocol
*This
, task_header_t
*task
, task_proc_t proc
)
145 BOOL do_post
= FALSE
;
150 EnterCriticalSection(&This
->section
);
152 if(This
->task_queue_tail
) {
153 This
->task_queue_tail
->next
= task
;
154 This
->task_queue_tail
= task
;
156 This
->task_queue_tail
= This
->task_queue_head
= task
;
157 do_post
= !This
->continue_call
;
160 LeaveCriticalSection(&This
->section
);
163 IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
164 PostMessageW(This
->notif_hwnd
, WM_MK_CONTINUE
, 0, (LPARAM
)This
);
168 static inline BOOL
do_direct_notif(BindProtocol
*This
)
170 return !(This
->pi
& PI_APARTMENTTHREADED
) || (This
->apartment_thread
== GetCurrentThreadId() && !This
->continue_call
);
173 static HRESULT
handle_mime_filter(BindProtocol
*This
, IInternetProtocol
*mime_filter
)
175 PROTOCOLFILTERDATA filter_data
= { sizeof(PROTOCOLFILTERDATA
), NULL
, NULL
, NULL
, 0 };
178 hres
= IInternetProtocol_QueryInterface(mime_filter
, &IID_IInternetProtocolSink
, (void**)&This
->protocol_sink_handler
);
180 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
184 IInternetProtocol_AddRef(mime_filter
);
185 This
->protocol_handler
= mime_filter
;
187 filter_data
.pProtocol
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
188 hres
= IInternetProtocol_Start(mime_filter
, This
->mime
, &This
->default_protocol_handler
.IInternetProtocolSink_iface
,
189 &This
->IInternetBindInfo_iface
, PI_FILTER_MODE
|PI_FORCE_ASYNC
,
190 (HANDLE_PTR
)&filter_data
);
192 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
193 IInternetProtocol_Release(This
->protocol_handler
);
194 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
195 This
->protocol_handler
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
199 /* NOTE: IE9 calls it on the new protocol_sink. It doesn't make sense to is seems to be a bug there. */
200 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_LOADINGMIMEHANDLER
, NULL
);
205 static void mime_available(BindProtocol
*This
, LPCWSTR mime
, BOOL verified
)
207 IInternetProtocol
*mime_filter
;
210 heap_free(This
->mime
);
211 This
->mime
= heap_strdupW(mime
);
213 if(This
->protocol_handler
==&This
->default_protocol_handler
.IInternetProtocol_iface
214 && (mime_filter
= get_mime_filter(mime
))) {
215 TRACE("Got mime filter for %s\n", debugstr_w(mime
));
217 hres
= handle_mime_filter(This
, mime_filter
);
218 IInternetProtocol_Release(mime_filter
);
220 FIXME("MIME filter failed: %08x\n", hres
);
223 if(This
->reported_mime
|| verified
|| !(This
->pi
& PI_MIMEVERIFICATION
)) {
224 This
->reported_mime
= TRUE
;
225 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
229 static inline BindProtocol
*impl_from_IInternetProtocolEx(IInternetProtocolEx
*iface
)
231 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolEx_iface
);
234 static HRESULT WINAPI
BindProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
236 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
239 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
240 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
241 *ppv
= &This
->IInternetProtocolEx_iface
;
242 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
243 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
244 *ppv
= &This
->IInternetProtocolEx_iface
;
245 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
246 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
247 *ppv
= &This
->IInternetProtocolEx_iface
;
248 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
249 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
250 *ppv
= &This
->IInternetProtocolEx_iface
;
251 }else if(IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
252 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This
, ppv
);
253 *ppv
= &This
->IInternetBindInfo_iface
;
254 }else if(IsEqualGUID(&IID_IInternetPriority
, riid
)) {
255 TRACE("(%p)->(IID_IInternetPriority %p)\n", This
, ppv
);
256 *ppv
= &This
->IInternetPriority_iface
;
257 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
258 FIXME("(%p)->(IID_IAuthenticate %p)\n", This
, ppv
);
259 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
260 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
261 *ppv
= &This
->IServiceProvider_iface
;
262 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
263 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
264 *ppv
= &This
->IInternetProtocolSink_iface
;
265 }else if(IsEqualGUID(&IID_IWinInetInfo
, riid
)) {
266 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This
, ppv
);
269 IWinInetInfo
*inet_info
;
272 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetInfo
, (void**)&inet_info
);
273 if(SUCCEEDED(hres
)) {
274 *ppv
= &This
->IWinInetHttpInfo_iface
;
275 IWinInetInfo_Release(inet_info
);
278 }else if(IsEqualGUID(&IID_IWinInetHttpInfo
, riid
)) {
279 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This
, ppv
);
282 IWinInetHttpInfo
*http_info
;
285 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetHttpInfo
, (void**)&http_info
);
286 if(SUCCEEDED(hres
)) {
287 *ppv
= &This
->IWinInetHttpInfo_iface
;
288 IWinInetHttpInfo_Release(http_info
);
292 WARN("not supported interface %s\n", debugstr_guid(riid
));
296 return E_NOINTERFACE
;
298 IUnknown_AddRef((IUnknown
*)*ppv
);
302 static ULONG WINAPI
BindProtocol_AddRef(IInternetProtocolEx
*iface
)
304 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
305 LONG ref
= InterlockedIncrement(&This
->ref
);
306 TRACE("(%p) ref=%d\n", This
, ref
);
310 static ULONG WINAPI
BindProtocol_Release(IInternetProtocolEx
*iface
)
312 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
313 LONG ref
= InterlockedDecrement(&This
->ref
);
315 TRACE("(%p) ref=%d\n", This
, ref
);
318 if(This
->wininet_info
)
319 IWinInetInfo_Release(This
->wininet_info
);
320 if(This
->wininet_http_info
)
321 IWinInetHttpInfo_Release(This
->wininet_http_info
);
323 IInternetProtocol_Release(This
->protocol
);
325 IInternetBindInfo_Release(This
->bind_info
);
326 if(This
->protocol_handler
&& This
->protocol_handler
!= &This
->default_protocol_handler
.IInternetProtocol_iface
)
327 IInternetProtocol_Release(This
->protocol_handler
);
328 if(This
->protocol_sink_handler
&&
329 This
->protocol_sink_handler
!= &This
->default_protocol_handler
.IInternetProtocolSink_iface
)
330 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
332 IUri_Release(This
->uri
);
333 SysFreeString(This
->display_uri
);
335 set_binding_sink(This
, NULL
, NULL
);
338 release_notif_hwnd(This
->notif_hwnd
);
339 This
->section
.DebugInfo
->Spare
[0] = 0;
340 DeleteCriticalSection(&This
->section
);
342 heap_free(This
->mime
);
345 URLMON_UnlockModule();
351 static HRESULT WINAPI
BindProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
352 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
353 DWORD grfPI
, HANDLE_PTR dwReserved
)
355 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
359 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
360 pOIBindInfo
, grfPI
, dwReserved
);
362 hres
= CreateUri(szUrl
, Uri_CREATE_FILE_USE_DOS_PATH
, 0, &uri
);
366 hres
= IInternetProtocolEx_StartEx(&This
->IInternetProtocolEx_iface
, uri
, pOIProtSink
,
367 pOIBindInfo
, grfPI
, (HANDLE
*)dwReserved
);
373 static HRESULT WINAPI
BindProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
375 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
377 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
379 return IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
382 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
385 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
387 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
389 return IInternetProtocol_Abort(This
->protocol_handler
, hrReason
, dwOptions
);
392 static HRESULT WINAPI
BindProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
394 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
396 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
398 return IInternetProtocol_Terminate(This
->protocol_handler
, dwOptions
);
401 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocolEx
*iface
)
403 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
404 FIXME("(%p)\n", This
);
408 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocolEx
*iface
)
410 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
411 FIXME("(%p)\n", This
);
415 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
416 ULONG cb
, ULONG
*pcbRead
)
418 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
420 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
424 return IInternetProtocol_Read(This
->protocol_handler
, pv
, cb
, pcbRead
);
427 static HRESULT WINAPI
BindProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
428 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
430 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
431 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
435 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
437 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
439 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
441 return IInternetProtocol_LockRequest(This
->protocol_handler
, dwOptions
);
444 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
446 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
448 TRACE("(%p)\n", This
);
450 return IInternetProtocol_UnlockRequest(This
->protocol_handler
);
453 static HRESULT WINAPI
BindProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
454 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
455 DWORD grfPI
, HANDLE
*dwReserved
)
457 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
458 IInternetProtocol
*protocol
= NULL
;
459 IInternetProtocolEx
*protocolex
;
460 IInternetPriority
*priority
;
461 IServiceProvider
*service_provider
;
462 BOOL urlmon_protocol
= FALSE
;
463 CLSID clsid
= IID_NULL
;
467 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
469 if(!pUri
|| !pOIProtSink
|| !pOIBindInfo
)
477 hres
= IInternetProtocolSink_QueryInterface(pOIProtSink
, &IID_IServiceProvider
,
478 (void**)&service_provider
);
479 if(SUCCEEDED(hres
)) {
480 /* FIXME: What's protocol CLSID here? */
481 IServiceProvider_QueryService(service_provider
, &IID_IInternetProtocol
,
482 &IID_IInternetProtocol
, (void**)&protocol
);
483 IServiceProvider_Release(service_provider
);
490 hres
= get_protocol_handler(pUri
, &clsid
, &urlmon_protocol
, &cf
);
494 if(This
->from_urlmon
) {
495 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
496 IClassFactory_Release(cf
);
500 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)&This
->IInternetBindInfo_iface
,
501 &IID_IUnknown
, (void**)&unk
);
502 IClassFactory_Release(cf
);
506 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
507 IUnknown_Release(unk
);
513 StringFromCLSID(&clsid
, &clsid_str
);
514 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_PROTOCOLCLASSID
, clsid_str
);
515 CoTaskMemFree(clsid_str
);
517 This
->protocol
= protocol
;
519 if(urlmon_protocol
) {
520 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetInfo
, (void**)&This
->wininet_info
);
521 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetHttpInfo
, (void**)&This
->wininet_http_info
);
524 set_binding_sink(This
, pOIProtSink
, pOIBindInfo
);
526 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
, (void**)&priority
);
527 if(SUCCEEDED(hres
)) {
528 IInternetPriority_SetPriority(priority
, This
->priority
);
529 IInternetPriority_Release(priority
);
532 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetProtocolEx
, (void**)&protocolex
);
533 if(SUCCEEDED(hres
)) {
534 hres
= IInternetProtocolEx_StartEx(protocolex
, pUri
, &This
->IInternetProtocolSink_iface
,
535 &This
->IInternetBindInfo_iface
, 0, NULL
);
536 IInternetProtocolEx_Release(protocolex
);
538 hres
= IUri_GetDisplayUri(pUri
, &This
->display_uri
);
542 hres
= IInternetProtocol_Start(protocol
, This
->display_uri
, &This
->IInternetProtocolSink_iface
,
543 &This
->IInternetBindInfo_iface
, 0, 0);
549 void set_binding_sink(BindProtocol
*This
, IInternetProtocolSink
*sink
, IInternetBindInfo
*bind_info
)
551 IInternetProtocolSink
*prev_sink
;
552 IServiceProvider
*service_provider
= NULL
;
555 IInternetProtocolSink_AddRef(sink
);
556 prev_sink
= InterlockedExchangePointer((void**)&This
->protocol_sink
, sink
);
558 IInternetProtocolSink_Release(prev_sink
);
561 IInternetProtocolSink_QueryInterface(sink
, &IID_IServiceProvider
, (void**)&service_provider
);
562 service_provider
= InterlockedExchangePointer((void**)&This
->service_provider
, service_provider
);
564 IServiceProvider_Release(service_provider
);
567 IInternetBindInfo_AddRef(bind_info
);
568 bind_info
= InterlockedExchangePointer((void**)&This
->bind_info
, bind_info
);
570 IInternetBindInfo_Release(bind_info
);
573 static const IInternetProtocolExVtbl BindProtocolVtbl
= {
574 BindProtocol_QueryInterface
,
576 BindProtocol_Release
,
578 BindProtocol_Continue
,
580 BindProtocol_Terminate
,
581 BindProtocol_Suspend
,
585 BindProtocol_LockRequest
,
586 BindProtocol_UnlockRequest
,
590 static inline BindProtocol
*impl_from_IInternetProtocol(IInternetProtocol
*iface
)
592 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocol_iface
);
595 static HRESULT WINAPI
ProtocolHandler_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
597 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
600 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
601 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
602 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
603 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
604 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
605 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
606 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
607 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
608 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
609 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
610 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
611 *ppv
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
615 IInternetProtocol_AddRef(iface
);
619 WARN("not supported interface %s\n", debugstr_guid(riid
));
620 return E_NOINTERFACE
;
623 static ULONG WINAPI
ProtocolHandler_AddRef(IInternetProtocol
*iface
)
625 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
626 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
629 static ULONG WINAPI
ProtocolHandler_Release(IInternetProtocol
*iface
)
631 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
632 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
635 static HRESULT WINAPI
ProtocolHandler_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
636 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
637 DWORD grfPI
, HANDLE_PTR dwReserved
)
639 ERR("Should not be called\n");
643 static HRESULT WINAPI
ProtocolHandler_Continue(IInternetProtocol
*iface
, PROTOCOLDATA
*pProtocolData
)
645 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
648 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
650 hres
= IInternetProtocol_Continue(This
->protocol
, pProtocolData
);
652 heap_free(pProtocolData
);
656 static HRESULT WINAPI
ProtocolHandler_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
659 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
661 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
663 if(This
->protocol
&& !This
->reported_result
)
664 return IInternetProtocol_Abort(This
->protocol
, hrReason
, dwOptions
);
669 static HRESULT WINAPI
ProtocolHandler_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
671 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
673 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
675 if(!This
->reported_result
)
678 IInternetProtocol_Terminate(This
->protocol
, 0);
680 set_binding_sink(This
, NULL
, NULL
);
682 if(This
->bind_info
) {
683 IInternetBindInfo_Release(This
->bind_info
);
684 This
->bind_info
= NULL
;
690 static HRESULT WINAPI
ProtocolHandler_Suspend(IInternetProtocol
*iface
)
692 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
693 FIXME("(%p)\n", This
);
697 static HRESULT WINAPI
ProtocolHandler_Resume(IInternetProtocol
*iface
)
699 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
700 FIXME("(%p)\n", This
);
704 static HRESULT WINAPI
ProtocolHandler_Read(IInternetProtocol
*iface
, void *pv
,
705 ULONG cb
, ULONG
*pcbRead
)
707 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
711 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
714 read
= min(cb
, This
->buf_size
);
715 memcpy(pv
, This
->buf
, read
);
717 if(read
== This
->buf_size
) {
718 heap_free(This
->buf
);
721 memmove(This
->buf
, This
->buf
+cb
, This
->buf_size
-cb
);
724 This
->buf_size
-= read
;
730 hres
= IInternetProtocol_Read(This
->protocol
, (BYTE
*)pv
+read
, cb
-read
, &cread
);
738 static HRESULT WINAPI
ProtocolHandler_Seek(IInternetProtocol
*iface
, LARGE_INTEGER dlibMove
,
739 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
741 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
742 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
746 static HRESULT WINAPI
ProtocolHandler_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
748 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
750 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
752 return IInternetProtocol_LockRequest(This
->protocol
, dwOptions
);
755 static HRESULT WINAPI
ProtocolHandler_UnlockRequest(IInternetProtocol
*iface
)
757 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
759 TRACE("(%p)\n", This
);
761 return IInternetProtocol_UnlockRequest(This
->protocol
);
764 static const IInternetProtocolVtbl InternetProtocolHandlerVtbl
= {
765 ProtocolHandler_QueryInterface
,
766 ProtocolHandler_AddRef
,
767 ProtocolHandler_Release
,
768 ProtocolHandler_Start
,
769 ProtocolHandler_Continue
,
770 ProtocolHandler_Abort
,
771 ProtocolHandler_Terminate
,
772 ProtocolHandler_Suspend
,
773 ProtocolHandler_Resume
,
774 ProtocolHandler_Read
,
775 ProtocolHandler_Seek
,
776 ProtocolHandler_LockRequest
,
777 ProtocolHandler_UnlockRequest
780 static inline BindProtocol
*impl_from_IInternetProtocolSinkHandler(IInternetProtocolSink
*iface
)
782 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocolSink_iface
);
785 static HRESULT WINAPI
ProtocolSinkHandler_QueryInterface(IInternetProtocolSink
*iface
,
786 REFIID riid
, void **ppvObject
)
788 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
789 return IInternetProtocol_QueryInterface(&This
->default_protocol_handler
.IInternetProtocol_iface
,
793 static ULONG WINAPI
ProtocolSinkHandler_AddRef(IInternetProtocolSink
*iface
)
795 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
796 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
799 static ULONG WINAPI
ProtocolSinkHandler_Release(IInternetProtocolSink
*iface
)
801 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
802 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
805 static HRESULT WINAPI
ProtocolSinkHandler_Switch(IInternetProtocolSink
*iface
,
806 PROTOCOLDATA
*pProtocolData
)
808 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
810 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
812 if(!This
->protocol_sink
) {
813 IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
817 return IInternetProtocolSink_Switch(This
->protocol_sink
, pProtocolData
);
820 static HRESULT WINAPI
ProtocolSinkHandler_ReportProgress(IInternetProtocolSink
*iface
,
821 ULONG status_code
, LPCWSTR status_text
)
823 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
825 TRACE("(%p)->(%u %s)\n", This
, status_code
, debugstr_w(status_text
));
827 if(!This
->protocol_sink
)
830 switch(status_code
) {
831 case BINDSTATUS_FINDINGRESOURCE
:
832 case BINDSTATUS_CONNECTING
:
833 case BINDSTATUS_REDIRECTING
:
834 case BINDSTATUS_SENDINGREQUEST
:
835 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
836 case BINDSTATUS_DIRECTBIND
:
837 case BINDSTATUS_ACCEPTRANGES
:
838 case BINDSTATUS_DECODING
:
839 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, status_code
, status_text
);
842 case BINDSTATUS_BEGINDOWNLOADDATA
:
843 IInternetProtocolSink_ReportData(This
->protocol_sink
, This
->bscf
, This
->progress
, This
->progress_max
);
846 case BINDSTATUS_MIMETYPEAVAILABLE
:
847 mime_available(This
, status_text
, FALSE
);
850 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
851 mime_available(This
, status_text
, TRUE
);
855 FIXME("unsupported ulStatusCode %u\n", status_code
);
861 static HRESULT WINAPI
ProtocolSinkHandler_ReportData(IInternetProtocolSink
*iface
,
862 DWORD bscf
, ULONG progress
, ULONG progress_max
)
864 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
866 TRACE("(%p)->(%x %u %u)\n", This
, bscf
, progress
, progress_max
);
869 This
->progress
= progress
;
870 This
->progress_max
= progress_max
;
872 if(!This
->protocol_sink
)
875 if((This
->pi
& PI_MIMEVERIFICATION
) && !This
->reported_mime
) {
876 BYTE buf
[BUFFER_SIZE
];
883 hres
= IInternetProtocol_Read(This
->protocol
, buf
,
884 sizeof(buf
)-This
->buf_size
, &read
);
885 if(FAILED(hres
) && hres
!= E_PENDING
)
889 This
->buf
= heap_alloc(BUFFER_SIZE
);
891 return E_OUTOFMEMORY
;
892 }else if(read
+ This
->buf_size
> BUFFER_SIZE
) {
895 tmp
= heap_realloc(This
->buf
, read
+This
->buf_size
);
897 return E_OUTOFMEMORY
;
901 memcpy(This
->buf
+This
->buf_size
, buf
, read
);
902 This
->buf_size
+= read
;
903 }while(This
->buf_size
< MIME_TEST_SIZE
&& hres
== S_OK
);
905 if(This
->buf_size
< MIME_TEST_SIZE
&& hres
!= S_FALSE
)
908 bscf
= BSCF_FIRSTDATANOTIFICATION
;
910 bscf
|= BSCF_LASTDATANOTIFICATION
|BSCF_DATAFULLYAVAILABLE
;
912 if(!This
->reported_mime
) {
915 hres
= IUri_GetRawUri(This
->uri
, &raw_uri
);
919 hres
= FindMimeFromData(NULL
, raw_uri
, This
->buf
, min(This
->buf_size
, MIME_TEST_SIZE
),
920 This
->mime
, 0, &mime
, 0);
921 SysFreeString(raw_uri
);
925 heap_free(This
->mime
);
926 This
->mime
= heap_strdupW(mime
);
928 This
->reported_mime
= TRUE
;
929 if(This
->protocol_sink
)
930 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, This
->mime
);
934 if(!This
->protocol_sink
)
937 return IInternetProtocolSink_ReportData(This
->protocol_sink
, bscf
, progress
, progress_max
);
940 static HRESULT WINAPI
ProtocolSinkHandler_ReportResult(IInternetProtocolSink
*iface
,
941 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
943 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
945 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
947 if(This
->protocol_sink
)
948 return IInternetProtocolSink_ReportResult(This
->protocol_sink
, hrResult
, dwError
, szResult
);
952 static const IInternetProtocolSinkVtbl InternetProtocolSinkHandlerVtbl
= {
953 ProtocolSinkHandler_QueryInterface
,
954 ProtocolSinkHandler_AddRef
,
955 ProtocolSinkHandler_Release
,
956 ProtocolSinkHandler_Switch
,
957 ProtocolSinkHandler_ReportProgress
,
958 ProtocolSinkHandler_ReportData
,
959 ProtocolSinkHandler_ReportResult
962 static inline BindProtocol
*impl_from_IInternetBindInfo(IInternetBindInfo
*iface
)
964 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetBindInfo_iface
);
967 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
,
968 REFIID riid
, void **ppv
)
970 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
971 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
974 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
976 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
977 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
980 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
982 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
983 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
986 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
,
987 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
989 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
992 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
994 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
996 WARN("GetBindInfo failed: %08x\n", hres
);
1000 *grfBINDF
|= BINDF_FROMURLMON
;
1004 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
,
1005 ULONG ulStringType
, LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
1007 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1009 TRACE("(%p)->(%d %p %d %p)\n", This
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1011 return IInternetBindInfo_GetBindString(This
->bind_info
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1014 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
1015 BindInfo_QueryInterface
,
1018 BindInfo_GetBindInfo
,
1019 BindInfo_GetBindString
1022 static inline BindProtocol
*impl_from_IInternetPriority(IInternetPriority
*iface
)
1024 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetPriority_iface
);
1027 static HRESULT WINAPI
InternetPriority_QueryInterface(IInternetPriority
*iface
,
1028 REFIID riid
, void **ppv
)
1030 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1031 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1034 static ULONG WINAPI
InternetPriority_AddRef(IInternetPriority
*iface
)
1036 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1037 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1040 static ULONG WINAPI
InternetPriority_Release(IInternetPriority
*iface
)
1042 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1043 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1046 static HRESULT WINAPI
InternetPriority_SetPriority(IInternetPriority
*iface
, LONG nPriority
)
1048 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1050 TRACE("(%p)->(%d)\n", This
, nPriority
);
1052 This
->priority
= nPriority
;
1056 static HRESULT WINAPI
InternetPriority_GetPriority(IInternetPriority
*iface
, LONG
*pnPriority
)
1058 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1060 TRACE("(%p)->(%p)\n", This
, pnPriority
);
1062 *pnPriority
= This
->priority
;
1066 static const IInternetPriorityVtbl InternetPriorityVtbl
= {
1067 InternetPriority_QueryInterface
,
1068 InternetPriority_AddRef
,
1069 InternetPriority_Release
,
1070 InternetPriority_SetPriority
,
1071 InternetPriority_GetPriority
1075 static inline BindProtocol
*impl_from_IInternetProtocolSink(IInternetProtocolSink
*iface
)
1077 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolSink_iface
);
1080 static HRESULT WINAPI
BPInternetProtocolSink_QueryInterface(IInternetProtocolSink
*iface
,
1081 REFIID riid
, void **ppv
)
1083 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1084 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1087 static ULONG WINAPI
BPInternetProtocolSink_AddRef(IInternetProtocolSink
*iface
)
1089 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1090 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1093 static ULONG WINAPI
BPInternetProtocolSink_Release(IInternetProtocolSink
*iface
)
1095 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1096 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1100 task_header_t header
;
1104 static void switch_proc(BindProtocol
*bind
, task_header_t
*t
)
1106 switch_task_t
*task
= (switch_task_t
*)t
;
1108 IInternetProtocol_Continue(bind
->protocol_handler
, task
->data
);
1113 static HRESULT WINAPI
BPInternetProtocolSink_Switch(IInternetProtocolSink
*iface
,
1114 PROTOCOLDATA
*pProtocolData
)
1116 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1119 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
1121 TRACE("flags %x state %x data %p cb %u\n", pProtocolData
->grfFlags
, pProtocolData
->dwState
,
1122 pProtocolData
->pData
, pProtocolData
->cbData
);
1124 data
= heap_alloc(sizeof(PROTOCOLDATA
));
1126 return E_OUTOFMEMORY
;
1127 memcpy(data
, pProtocolData
, sizeof(PROTOCOLDATA
));
1129 if((This
->pi
&PI_APARTMENTTHREADED
&& pProtocolData
->grfFlags
&PI_FORCE_ASYNC
)
1130 || !do_direct_notif(This
)) {
1131 switch_task_t
*task
;
1133 task
= heap_alloc(sizeof(switch_task_t
));
1135 return E_OUTOFMEMORY
;
1139 push_task(This
, &task
->header
, switch_proc
);
1143 return IInternetProtocolSink_Switch(This
->protocol_sink_handler
, data
);
1147 task_header_t header
;
1151 } on_progress_task_t
;
1153 static void on_progress_proc(BindProtocol
*This
, task_header_t
*t
)
1155 on_progress_task_t
*task
= (on_progress_task_t
*)t
;
1157 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, task
->status_code
, task
->status_text
);
1159 heap_free(task
->status_text
);
1163 static HRESULT WINAPI
BPInternetProtocolSink_ReportProgress(IInternetProtocolSink
*iface
,
1164 ULONG ulStatusCode
, LPCWSTR szStatusText
)
1166 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1168 TRACE("(%p)->(%u %s)\n", This
, ulStatusCode
, debugstr_w(szStatusText
));
1170 if(do_direct_notif(This
)) {
1171 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, ulStatusCode
, szStatusText
);
1173 on_progress_task_t
*task
;
1175 task
= heap_alloc(sizeof(on_progress_task_t
));
1177 task
->status_code
= ulStatusCode
;
1178 task
->status_text
= heap_strdupW(szStatusText
);
1180 push_task(This
, &task
->header
, on_progress_proc
);
1187 task_header_t header
;
1191 } report_data_task_t
;
1193 static void report_data_proc(BindProtocol
*This
, task_header_t
*t
)
1195 report_data_task_t
*task
= (report_data_task_t
*)t
;
1197 IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1198 task
->bscf
, task
->progress
, task
->progress_max
);
1203 static HRESULT WINAPI
BPInternetProtocolSink_ReportData(IInternetProtocolSink
*iface
,
1204 DWORD grfBSCF
, ULONG ulProgress
, ULONG ulProgressMax
)
1206 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1208 TRACE("(%p)->(%x %u %u)\n", This
, grfBSCF
, ulProgress
, ulProgressMax
);
1210 if(!This
->protocol_sink
)
1213 if(!do_direct_notif(This
)) {
1214 report_data_task_t
*task
;
1216 task
= heap_alloc(sizeof(report_data_task_t
));
1218 return E_OUTOFMEMORY
;
1220 task
->bscf
= grfBSCF
;
1221 task
->progress
= ulProgress
;
1222 task
->progress_max
= ulProgressMax
;
1224 push_task(This
, &task
->header
, report_data_proc
);
1228 return IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1229 grfBSCF
, ulProgress
, ulProgressMax
);
1233 task_header_t header
;
1238 } report_result_task_t
;
1240 static void report_result_proc(BindProtocol
*This
, task_header_t
*t
)
1242 report_result_task_t
*task
= (report_result_task_t
*)t
;
1244 IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, task
->hres
, task
->err
, task
->str
);
1246 heap_free(task
->str
);
1250 static HRESULT WINAPI
BPInternetProtocolSink_ReportResult(IInternetProtocolSink
*iface
,
1251 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
1253 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1255 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
1257 if(!This
->protocol_sink
)
1259 This
->reported_result
= TRUE
;
1261 if(!do_direct_notif(This
)) {
1262 report_result_task_t
*task
;
1264 task
= heap_alloc(sizeof(report_result_task_t
));
1266 return E_OUTOFMEMORY
;
1268 task
->hres
= hrResult
;
1269 task
->err
= dwError
;
1270 task
->str
= heap_strdupW(szResult
);
1272 push_task(This
, &task
->header
, report_result_proc
);
1276 return IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, hrResult
, dwError
, szResult
);
1279 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
= {
1280 BPInternetProtocolSink_QueryInterface
,
1281 BPInternetProtocolSink_AddRef
,
1282 BPInternetProtocolSink_Release
,
1283 BPInternetProtocolSink_Switch
,
1284 BPInternetProtocolSink_ReportProgress
,
1285 BPInternetProtocolSink_ReportData
,
1286 BPInternetProtocolSink_ReportResult
1289 static inline BindProtocol
*impl_from_IWinInetHttpInfo(IWinInetHttpInfo
*iface
)
1291 return CONTAINING_RECORD(iface
, BindProtocol
, IWinInetHttpInfo_iface
);
1294 static HRESULT WINAPI
WinInetHttpInfo_QueryInterface(IWinInetHttpInfo
*iface
, REFIID riid
, void **ppv
)
1296 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1297 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1300 static ULONG WINAPI
WinInetHttpInfo_AddRef(IWinInetHttpInfo
*iface
)
1302 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1303 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1306 static ULONG WINAPI
WinInetHttpInfo_Release(IWinInetHttpInfo
*iface
)
1308 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1309 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1312 static HRESULT WINAPI
WinInetHttpInfo_QueryOption(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1313 void *pBuffer
, DWORD
*pcbBuffer
)
1315 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1316 FIXME("(%p)->(%x %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
);
1320 static HRESULT WINAPI
WinInetHttpInfo_QueryInfo(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1321 void *pBuffer
, DWORD
*pcbBuffer
, DWORD
*pdwFlags
, DWORD
*pdwReserved
)
1323 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1324 FIXME("(%p)->(%x %p %p %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
, pdwFlags
, pdwReserved
);
1328 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl
= {
1329 WinInetHttpInfo_QueryInterface
,
1330 WinInetHttpInfo_AddRef
,
1331 WinInetHttpInfo_Release
,
1332 WinInetHttpInfo_QueryOption
,
1333 WinInetHttpInfo_QueryInfo
1336 static inline BindProtocol
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1338 return CONTAINING_RECORD(iface
, BindProtocol
, IServiceProvider_iface
);
1341 static HRESULT WINAPI
BPServiceProvider_QueryInterface(IServiceProvider
*iface
,
1342 REFIID riid
, void **ppv
)
1344 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1345 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1348 static ULONG WINAPI
BPServiceProvider_AddRef(IServiceProvider
*iface
)
1350 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1351 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1354 static ULONG WINAPI
BPServiceProvider_Release(IServiceProvider
*iface
)
1356 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1357 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1360 static HRESULT WINAPI
BPServiceProvider_QueryService(IServiceProvider
*iface
,
1361 REFGUID guidService
, REFIID riid
, void **ppv
)
1363 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1365 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1367 if(!This
->service_provider
)
1368 return E_NOINTERFACE
;
1370 return IServiceProvider_QueryService(This
->service_provider
, guidService
, riid
, ppv
);
1373 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1374 BPServiceProvider_QueryInterface
,
1375 BPServiceProvider_AddRef
,
1376 BPServiceProvider_Release
,
1377 BPServiceProvider_QueryService
1380 HRESULT
create_binding_protocol(BOOL from_urlmon
, BindProtocol
**protocol
)
1382 BindProtocol
*ret
= heap_alloc_zero(sizeof(BindProtocol
));
1384 ret
->IInternetProtocolEx_iface
.lpVtbl
= &BindProtocolVtbl
;
1385 ret
->IInternetBindInfo_iface
.lpVtbl
= &InternetBindInfoVtbl
;
1386 ret
->IInternetPriority_iface
.lpVtbl
= &InternetPriorityVtbl
;
1387 ret
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
1388 ret
->IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkVtbl
;
1389 ret
->IWinInetHttpInfo_iface
.lpVtbl
= &WinInetHttpInfoVtbl
;
1391 ret
->default_protocol_handler
.IInternetProtocol_iface
.lpVtbl
= &InternetProtocolHandlerVtbl
;
1392 ret
->default_protocol_handler
.IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkHandlerVtbl
;
1395 ret
->from_urlmon
= from_urlmon
;
1396 ret
->apartment_thread
= GetCurrentThreadId();
1397 ret
->notif_hwnd
= get_notif_hwnd();
1398 ret
->protocol_handler
= &ret
->default_protocol_handler
.IInternetProtocol_iface
;
1399 ret
->protocol_sink_handler
= &ret
->default_protocol_handler
.IInternetProtocolSink_iface
;
1400 InitializeCriticalSection(&ret
->section
);
1401 ret
->section
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BindProtocol.section");
1403 URLMON_LockModule();