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
);
83 HWND
get_notif_hwnd(void)
85 static ATOM wnd_class
= 0;
88 static const WCHAR wszURLMonikerNotificationWindow
[] =
89 {'U','R','L',' ','M','o','n','i','k','e','r',' ',
90 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
92 tls_data
= get_tls_data();
96 if(tls_data
->notif_hwnd_cnt
) {
97 tls_data
->notif_hwnd_cnt
++;
98 return tls_data
->notif_hwnd
;
102 static WNDCLASSEXW wndclass
= {
104 notif_wnd_proc
, 0, 0,
105 NULL
, NULL
, NULL
, NULL
, NULL
,
106 wszURLMonikerNotificationWindow
,
110 wndclass
.hInstance
= hProxyDll
;
112 wnd_class
= RegisterClassExW(&wndclass
);
113 if (!wnd_class
&& GetLastError() == ERROR_CLASS_ALREADY_EXISTS
)
117 tls_data
->notif_hwnd
= CreateWindowExW(0, wszURLMonikerNotificationWindow
,
118 wszURLMonikerNotificationWindow
, 0, 0, 0, 0, 0, HWND_MESSAGE
,
119 NULL
, hProxyDll
, NULL
);
120 if(tls_data
->notif_hwnd
)
121 tls_data
->notif_hwnd_cnt
++;
123 TRACE("hwnd = %p\n", tls_data
->notif_hwnd
);
125 return tls_data
->notif_hwnd
;
128 void release_notif_hwnd(HWND hwnd
)
130 tls_data_t
*data
= get_tls_data();
135 if(data
->notif_hwnd
!= hwnd
) {
136 PostMessageW(data
->notif_hwnd
, WM_MK_RELEASE
, 0, 0);
140 if(!--data
->notif_hwnd_cnt
) {
141 DestroyWindow(data
->notif_hwnd
);
142 data
->notif_hwnd
= NULL
;
146 static void push_task(BindProtocol
*This
, task_header_t
*task
, task_proc_t proc
)
148 BOOL do_post
= FALSE
;
153 EnterCriticalSection(&This
->section
);
155 if(This
->task_queue_tail
) {
156 This
->task_queue_tail
->next
= task
;
157 This
->task_queue_tail
= task
;
159 This
->task_queue_tail
= This
->task_queue_head
= task
;
160 do_post
= !This
->continue_call
;
163 LeaveCriticalSection(&This
->section
);
166 IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
167 PostMessageW(This
->notif_hwnd
, WM_MK_CONTINUE
, 0, (LPARAM
)This
);
171 static inline BOOL
is_apartment_thread(BindProtocol
*This
)
173 return This
->apartment_thread
== GetCurrentThreadId();
176 static inline BOOL
do_direct_notif(BindProtocol
*This
)
178 return !(This
->pi
& PI_APARTMENTTHREADED
) || (is_apartment_thread(This
) && !This
->continue_call
);
181 static HRESULT
handle_mime_filter(BindProtocol
*This
, IInternetProtocol
*mime_filter
)
183 PROTOCOLFILTERDATA filter_data
= { sizeof(PROTOCOLFILTERDATA
), NULL
, NULL
, NULL
, 0 };
186 hres
= IInternetProtocol_QueryInterface(mime_filter
, &IID_IInternetProtocolSink
, (void**)&This
->protocol_sink_handler
);
188 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
192 IInternetProtocol_AddRef(mime_filter
);
193 This
->protocol_handler
= mime_filter
;
195 filter_data
.pProtocol
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
196 hres
= IInternetProtocol_Start(mime_filter
, This
->mime
, &This
->default_protocol_handler
.IInternetProtocolSink_iface
,
197 &This
->IInternetBindInfo_iface
, PI_FILTER_MODE
|PI_FORCE_ASYNC
,
198 (HANDLE_PTR
)&filter_data
);
200 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
201 IInternetProtocol_Release(This
->protocol_handler
);
202 This
->protocol_sink_handler
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
203 This
->protocol_handler
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
207 /* NOTE: IE9 calls it on the new protocol_sink. It doesn't make sense to is seems to be a bug there. */
208 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_LOADINGMIMEHANDLER
, NULL
);
213 static void mime_available(BindProtocol
*This
, LPCWSTR mime
, BOOL verified
)
215 IInternetProtocol
*mime_filter
;
218 heap_free(This
->mime
);
219 This
->mime
= heap_strdupW(mime
);
221 if(This
->protocol_handler
==&This
->default_protocol_handler
.IInternetProtocol_iface
222 && (mime_filter
= get_mime_filter(mime
))) {
223 TRACE("Got mime filter for %s\n", debugstr_w(mime
));
225 hres
= handle_mime_filter(This
, mime_filter
);
226 IInternetProtocol_Release(mime_filter
);
228 FIXME("MIME filter failed: %08x\n", hres
);
231 if(This
->reported_mime
|| verified
|| !(This
->pi
& PI_MIMEVERIFICATION
)) {
232 This
->reported_mime
= TRUE
;
233 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
237 static inline BindProtocol
*impl_from_IInternetProtocolEx(IInternetProtocolEx
*iface
)
239 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolEx_iface
);
242 static HRESULT WINAPI
BindProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
244 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
247 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
248 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
249 *ppv
= &This
->IInternetProtocolEx_iface
;
250 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
251 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
252 *ppv
= &This
->IInternetProtocolEx_iface
;
253 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
254 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
255 *ppv
= &This
->IInternetProtocolEx_iface
;
256 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
257 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
258 *ppv
= &This
->IInternetProtocolEx_iface
;
259 }else if(IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
260 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This
, ppv
);
261 *ppv
= &This
->IInternetBindInfo_iface
;
262 }else if(IsEqualGUID(&IID_IInternetPriority
, riid
)) {
263 TRACE("(%p)->(IID_IInternetPriority %p)\n", This
, ppv
);
264 *ppv
= &This
->IInternetPriority_iface
;
265 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
266 FIXME("(%p)->(IID_IAuthenticate %p)\n", This
, ppv
);
267 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
268 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
269 *ppv
= &This
->IServiceProvider_iface
;
270 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
271 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
272 *ppv
= &This
->IInternetProtocolSink_iface
;
273 }else if(IsEqualGUID(&IID_IWinInetInfo
, riid
)) {
274 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This
, ppv
);
277 IWinInetInfo
*inet_info
;
280 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetInfo
, (void**)&inet_info
);
281 if(SUCCEEDED(hres
)) {
282 *ppv
= &This
->IWinInetHttpInfo_iface
;
283 IWinInetInfo_Release(inet_info
);
286 }else if(IsEqualGUID(&IID_IWinInetHttpInfo
, riid
)) {
287 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This
, ppv
);
290 IWinInetHttpInfo
*http_info
;
293 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetHttpInfo
, (void**)&http_info
);
294 if(SUCCEEDED(hres
)) {
295 *ppv
= &This
->IWinInetHttpInfo_iface
;
296 IWinInetHttpInfo_Release(http_info
);
300 WARN("not supported interface %s\n", debugstr_guid(riid
));
304 return E_NOINTERFACE
;
306 IUnknown_AddRef((IUnknown
*)*ppv
);
310 static ULONG WINAPI
BindProtocol_AddRef(IInternetProtocolEx
*iface
)
312 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
313 LONG ref
= InterlockedIncrement(&This
->ref
);
314 TRACE("(%p) ref=%d\n", This
, ref
);
318 static ULONG WINAPI
BindProtocol_Release(IInternetProtocolEx
*iface
)
320 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
321 LONG ref
= InterlockedDecrement(&This
->ref
);
323 TRACE("(%p) ref=%d\n", This
, ref
);
326 if(This
->wininet_info
)
327 IWinInetInfo_Release(This
->wininet_info
);
328 if(This
->wininet_http_info
)
329 IWinInetHttpInfo_Release(This
->wininet_http_info
);
331 IInternetProtocol_Release(This
->protocol
);
333 IInternetBindInfo_Release(This
->bind_info
);
334 if(This
->protocol_handler
&& This
->protocol_handler
!= &This
->default_protocol_handler
.IInternetProtocol_iface
)
335 IInternetProtocol_Release(This
->protocol_handler
);
336 if(This
->protocol_sink_handler
&&
337 This
->protocol_sink_handler
!= &This
->default_protocol_handler
.IInternetProtocolSink_iface
)
338 IInternetProtocolSink_Release(This
->protocol_sink_handler
);
340 IUri_Release(This
->uri
);
341 SysFreeString(This
->display_uri
);
343 set_binding_sink(This
, NULL
, NULL
);
346 release_notif_hwnd(This
->notif_hwnd
);
347 This
->section
.DebugInfo
->Spare
[0] = 0;
348 DeleteCriticalSection(&This
->section
);
350 heap_free(This
->mime
);
353 URLMON_UnlockModule();
359 static HRESULT WINAPI
BindProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
360 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
361 DWORD grfPI
, HANDLE_PTR dwReserved
)
363 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
367 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
368 pOIBindInfo
, grfPI
, dwReserved
);
370 hres
= CreateUri(szUrl
, Uri_CREATE_FILE_USE_DOS_PATH
, 0, &uri
);
374 hres
= IInternetProtocolEx_StartEx(&This
->IInternetProtocolEx_iface
, uri
, pOIProtSink
,
375 pOIBindInfo
, grfPI
, (HANDLE
*)dwReserved
);
381 static HRESULT WINAPI
BindProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
383 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
385 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
387 return IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
390 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
393 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
395 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
397 return IInternetProtocol_Abort(This
->protocol_handler
, hrReason
, dwOptions
);
400 static HRESULT WINAPI
BindProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
402 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
404 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
406 return IInternetProtocol_Terminate(This
->protocol_handler
, dwOptions
);
409 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocolEx
*iface
)
411 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
412 FIXME("(%p)\n", This
);
416 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocolEx
*iface
)
418 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
419 FIXME("(%p)\n", This
);
423 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
424 ULONG cb
, ULONG
*pcbRead
)
426 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
428 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
432 return IInternetProtocol_Read(This
->protocol_handler
, pv
, cb
, pcbRead
);
435 static HRESULT WINAPI
BindProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
436 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
438 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
439 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
443 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
445 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
447 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
449 return IInternetProtocol_LockRequest(This
->protocol_handler
, dwOptions
);
452 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
454 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
456 TRACE("(%p)\n", This
);
458 return IInternetProtocol_UnlockRequest(This
->protocol_handler
);
461 static HRESULT WINAPI
BindProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
462 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
463 DWORD grfPI
, HANDLE
*dwReserved
)
465 BindProtocol
*This
= impl_from_IInternetProtocolEx(iface
);
466 IInternetProtocol
*protocol
= NULL
;
467 IInternetProtocolEx
*protocolex
;
468 IInternetPriority
*priority
;
469 IServiceProvider
*service_provider
;
470 BOOL urlmon_protocol
= FALSE
;
471 CLSID clsid
= IID_NULL
;
475 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
477 if(!pUri
|| !pOIProtSink
|| !pOIBindInfo
)
485 hres
= IInternetProtocolSink_QueryInterface(pOIProtSink
, &IID_IServiceProvider
,
486 (void**)&service_provider
);
487 if(SUCCEEDED(hres
)) {
488 /* FIXME: What's protocol CLSID here? */
489 IServiceProvider_QueryService(service_provider
, &IID_IInternetProtocol
,
490 &IID_IInternetProtocol
, (void**)&protocol
);
491 IServiceProvider_Release(service_provider
);
498 hres
= get_protocol_handler(pUri
, &clsid
, &urlmon_protocol
, &cf
);
502 if(This
->from_urlmon
) {
503 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
504 IClassFactory_Release(cf
);
508 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)&This
->IInternetBindInfo_iface
,
509 &IID_IUnknown
, (void**)&unk
);
510 IClassFactory_Release(cf
);
514 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
515 IUnknown_Release(unk
);
521 StringFromCLSID(&clsid
, &clsid_str
);
522 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_PROTOCOLCLASSID
, clsid_str
);
523 CoTaskMemFree(clsid_str
);
525 This
->protocol
= protocol
;
527 if(urlmon_protocol
) {
528 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetInfo
, (void**)&This
->wininet_info
);
529 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetHttpInfo
, (void**)&This
->wininet_http_info
);
532 set_binding_sink(This
, pOIProtSink
, pOIBindInfo
);
534 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
, (void**)&priority
);
535 if(SUCCEEDED(hres
)) {
536 IInternetPriority_SetPriority(priority
, This
->priority
);
537 IInternetPriority_Release(priority
);
540 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetProtocolEx
, (void**)&protocolex
);
541 if(SUCCEEDED(hres
)) {
542 hres
= IInternetProtocolEx_StartEx(protocolex
, pUri
, &This
->IInternetProtocolSink_iface
,
543 &This
->IInternetBindInfo_iface
, 0, NULL
);
544 IInternetProtocolEx_Release(protocolex
);
546 hres
= IUri_GetDisplayUri(pUri
, &This
->display_uri
);
550 hres
= IInternetProtocol_Start(protocol
, This
->display_uri
, &This
->IInternetProtocolSink_iface
,
551 &This
->IInternetBindInfo_iface
, 0, 0);
559 void set_binding_sink(BindProtocol
*This
, IInternetProtocolSink
*sink
, IInternetBindInfo
*bind_info
)
561 IInternetProtocolSink
*prev_sink
;
562 IServiceProvider
*service_provider
= NULL
;
565 IInternetProtocolSink_AddRef(sink
);
566 prev_sink
= InterlockedExchangePointer((void**)&This
->protocol_sink
, sink
);
568 IInternetProtocolSink_Release(prev_sink
);
571 IInternetProtocolSink_QueryInterface(sink
, &IID_IServiceProvider
, (void**)&service_provider
);
572 service_provider
= InterlockedExchangePointer((void**)&This
->service_provider
, service_provider
);
574 IServiceProvider_Release(service_provider
);
577 IInternetBindInfo_AddRef(bind_info
);
578 bind_info
= InterlockedExchangePointer((void**)&This
->bind_info
, bind_info
);
580 IInternetBindInfo_Release(bind_info
);
583 static const IInternetProtocolExVtbl BindProtocolVtbl
= {
584 BindProtocol_QueryInterface
,
586 BindProtocol_Release
,
588 BindProtocol_Continue
,
590 BindProtocol_Terminate
,
591 BindProtocol_Suspend
,
595 BindProtocol_LockRequest
,
596 BindProtocol_UnlockRequest
,
600 static inline BindProtocol
*impl_from_IInternetProtocol(IInternetProtocol
*iface
)
602 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocol_iface
);
605 static HRESULT WINAPI
ProtocolHandler_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
607 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
610 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
611 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
612 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
613 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
614 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
615 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
616 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
617 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
618 *ppv
= &This
->default_protocol_handler
.IInternetProtocol_iface
;
619 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
620 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
621 *ppv
= &This
->default_protocol_handler
.IInternetProtocolSink_iface
;
625 IInternetProtocol_AddRef(iface
);
629 WARN("not supported interface %s\n", debugstr_guid(riid
));
630 return E_NOINTERFACE
;
633 static ULONG WINAPI
ProtocolHandler_AddRef(IInternetProtocol
*iface
)
635 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
636 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
639 static ULONG WINAPI
ProtocolHandler_Release(IInternetProtocol
*iface
)
641 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
642 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
645 static HRESULT WINAPI
ProtocolHandler_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
646 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
647 DWORD grfPI
, HANDLE_PTR dwReserved
)
649 ERR("Should not be called\n");
653 static HRESULT WINAPI
ProtocolHandler_Continue(IInternetProtocol
*iface
, PROTOCOLDATA
*pProtocolData
)
655 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
658 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
660 hres
= IInternetProtocol_Continue(This
->protocol
, pProtocolData
);
662 heap_free(pProtocolData
);
666 static HRESULT WINAPI
ProtocolHandler_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
669 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
671 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
673 if(This
->protocol
&& !This
->reported_result
)
674 return IInternetProtocol_Abort(This
->protocol
, hrReason
, dwOptions
);
679 static HRESULT WINAPI
ProtocolHandler_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
681 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
683 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
685 if(!This
->reported_result
)
688 IInternetProtocol_Terminate(This
->protocol
, 0);
690 set_binding_sink(This
, NULL
, NULL
);
692 if(This
->bind_info
) {
693 IInternetBindInfo_Release(This
->bind_info
);
694 This
->bind_info
= NULL
;
700 static HRESULT WINAPI
ProtocolHandler_Suspend(IInternetProtocol
*iface
)
702 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
703 FIXME("(%p)\n", This
);
707 static HRESULT WINAPI
ProtocolHandler_Resume(IInternetProtocol
*iface
)
709 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
710 FIXME("(%p)\n", This
);
714 static HRESULT WINAPI
ProtocolHandler_Read(IInternetProtocol
*iface
, void *pv
,
715 ULONG cb
, ULONG
*pcbRead
)
717 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
721 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
724 read
= min(cb
, This
->buf_size
);
725 memcpy(pv
, This
->buf
, read
);
727 if(read
== This
->buf_size
) {
728 heap_free(This
->buf
);
731 memmove(This
->buf
, This
->buf
+cb
, This
->buf_size
-cb
);
734 This
->buf_size
-= read
;
740 if(is_apartment_thread(This
))
741 This
->continue_call
++;
742 hres
= IInternetProtocol_Read(This
->protocol
, (BYTE
*)pv
+read
, cb
-read
, &cread
);
743 if(is_apartment_thread(This
))
744 This
->continue_call
--;
752 static HRESULT WINAPI
ProtocolHandler_Seek(IInternetProtocol
*iface
, LARGE_INTEGER dlibMove
,
753 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
755 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
756 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
760 static HRESULT WINAPI
ProtocolHandler_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
762 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
764 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
766 return IInternetProtocol_LockRequest(This
->protocol
, dwOptions
);
769 static HRESULT WINAPI
ProtocolHandler_UnlockRequest(IInternetProtocol
*iface
)
771 BindProtocol
*This
= impl_from_IInternetProtocol(iface
);
773 TRACE("(%p)\n", This
);
775 return IInternetProtocol_UnlockRequest(This
->protocol
);
778 static const IInternetProtocolVtbl InternetProtocolHandlerVtbl
= {
779 ProtocolHandler_QueryInterface
,
780 ProtocolHandler_AddRef
,
781 ProtocolHandler_Release
,
782 ProtocolHandler_Start
,
783 ProtocolHandler_Continue
,
784 ProtocolHandler_Abort
,
785 ProtocolHandler_Terminate
,
786 ProtocolHandler_Suspend
,
787 ProtocolHandler_Resume
,
788 ProtocolHandler_Read
,
789 ProtocolHandler_Seek
,
790 ProtocolHandler_LockRequest
,
791 ProtocolHandler_UnlockRequest
794 static inline BindProtocol
*impl_from_IInternetProtocolSinkHandler(IInternetProtocolSink
*iface
)
796 return CONTAINING_RECORD(iface
, BindProtocol
, default_protocol_handler
.IInternetProtocolSink_iface
);
799 static HRESULT WINAPI
ProtocolSinkHandler_QueryInterface(IInternetProtocolSink
*iface
,
800 REFIID riid
, void **ppvObject
)
802 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
803 return IInternetProtocol_QueryInterface(&This
->default_protocol_handler
.IInternetProtocol_iface
,
807 static ULONG WINAPI
ProtocolSinkHandler_AddRef(IInternetProtocolSink
*iface
)
809 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
810 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
813 static ULONG WINAPI
ProtocolSinkHandler_Release(IInternetProtocolSink
*iface
)
815 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
816 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
819 static HRESULT WINAPI
ProtocolSinkHandler_Switch(IInternetProtocolSink
*iface
,
820 PROTOCOLDATA
*pProtocolData
)
822 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
824 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
826 if(!This
->protocol_sink
) {
827 IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
831 return IInternetProtocolSink_Switch(This
->protocol_sink
, pProtocolData
);
834 static HRESULT WINAPI
ProtocolSinkHandler_ReportProgress(IInternetProtocolSink
*iface
,
835 ULONG status_code
, LPCWSTR status_text
)
837 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
839 TRACE("(%p)->(%s %s)\n", This
, debugstr_bindstatus(status_code
), debugstr_w(status_text
));
841 if(!This
->protocol_sink
)
844 switch(status_code
) {
845 case BINDSTATUS_FINDINGRESOURCE
:
846 case BINDSTATUS_CONNECTING
:
847 case BINDSTATUS_REDIRECTING
:
848 case BINDSTATUS_SENDINGREQUEST
:
849 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
850 case BINDSTATUS_DIRECTBIND
:
851 case BINDSTATUS_ACCEPTRANGES
:
852 case BINDSTATUS_DECODING
:
853 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, status_code
, status_text
);
856 case BINDSTATUS_BEGINDOWNLOADDATA
:
857 IInternetProtocolSink_ReportData(This
->protocol_sink
, This
->bscf
, This
->progress
, This
->progress_max
);
860 case BINDSTATUS_MIMETYPEAVAILABLE
:
861 mime_available(This
, status_text
, FALSE
);
864 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
865 mime_available(This
, status_text
, TRUE
);
869 FIXME("unsupported ulStatusCode %u\n", status_code
);
875 static HRESULT WINAPI
ProtocolSinkHandler_ReportData(IInternetProtocolSink
*iface
,
876 DWORD bscf
, ULONG progress
, ULONG progress_max
)
878 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
880 TRACE("(%p)->(%x %u %u)\n", This
, bscf
, progress
, progress_max
);
883 This
->progress
= progress
;
884 This
->progress_max
= progress_max
;
886 if(!This
->protocol_sink
)
889 if((This
->pi
& PI_MIMEVERIFICATION
) && !This
->reported_mime
) {
890 BYTE buf
[BUFFER_SIZE
];
897 if(is_apartment_thread(This
))
898 This
->continue_call
++;
899 hres
= IInternetProtocol_Read(This
->protocol
, buf
,
900 sizeof(buf
)-This
->buf_size
, &read
);
901 if(is_apartment_thread(This
))
902 This
->continue_call
--;
903 if(FAILED(hres
) && hres
!= E_PENDING
)
907 This
->buf
= heap_alloc(BUFFER_SIZE
);
909 return E_OUTOFMEMORY
;
910 }else if(read
+ This
->buf_size
> BUFFER_SIZE
) {
913 tmp
= heap_realloc(This
->buf
, read
+This
->buf_size
);
915 return E_OUTOFMEMORY
;
919 memcpy(This
->buf
+This
->buf_size
, buf
, read
);
920 This
->buf_size
+= read
;
921 }while(This
->buf_size
< MIME_TEST_SIZE
&& hres
== S_OK
);
923 if(This
->buf_size
< MIME_TEST_SIZE
&& hres
!= S_FALSE
)
926 bscf
= BSCF_FIRSTDATANOTIFICATION
;
928 bscf
|= BSCF_LASTDATANOTIFICATION
|BSCF_DATAFULLYAVAILABLE
;
930 if(!This
->reported_mime
) {
933 hres
= IUri_GetRawUri(This
->uri
, &raw_uri
);
937 hres
= FindMimeFromData(NULL
, raw_uri
, This
->buf
, min(This
->buf_size
, MIME_TEST_SIZE
),
938 This
->mime
, 0, &mime
, 0);
939 SysFreeString(raw_uri
);
943 heap_free(This
->mime
);
944 This
->mime
= heap_strdupW(mime
);
946 This
->reported_mime
= TRUE
;
947 if(This
->protocol_sink
)
948 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, This
->mime
);
952 if(!This
->protocol_sink
)
955 return IInternetProtocolSink_ReportData(This
->protocol_sink
, bscf
, progress
, progress_max
);
958 static HRESULT WINAPI
ProtocolSinkHandler_ReportResult(IInternetProtocolSink
*iface
,
959 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
961 BindProtocol
*This
= impl_from_IInternetProtocolSinkHandler(iface
);
963 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
965 if(This
->protocol_sink
)
966 return IInternetProtocolSink_ReportResult(This
->protocol_sink
, hrResult
, dwError
, szResult
);
970 static const IInternetProtocolSinkVtbl InternetProtocolSinkHandlerVtbl
= {
971 ProtocolSinkHandler_QueryInterface
,
972 ProtocolSinkHandler_AddRef
,
973 ProtocolSinkHandler_Release
,
974 ProtocolSinkHandler_Switch
,
975 ProtocolSinkHandler_ReportProgress
,
976 ProtocolSinkHandler_ReportData
,
977 ProtocolSinkHandler_ReportResult
980 static inline BindProtocol
*impl_from_IInternetBindInfo(IInternetBindInfo
*iface
)
982 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetBindInfo_iface
);
985 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
,
986 REFIID riid
, void **ppv
)
988 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
989 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
992 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
994 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
995 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
998 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
1000 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1001 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1004 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
,
1005 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
1007 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1010 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
1012 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
1014 WARN("GetBindInfo failed: %08x\n", hres
);
1018 *grfBINDF
|= BINDF_FROMURLMON
;
1022 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
,
1023 ULONG ulStringType
, LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
1025 BindProtocol
*This
= impl_from_IInternetBindInfo(iface
);
1027 TRACE("(%p)->(%d %p %d %p)\n", This
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1029 return IInternetBindInfo_GetBindString(This
->bind_info
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
1032 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
1033 BindInfo_QueryInterface
,
1036 BindInfo_GetBindInfo
,
1037 BindInfo_GetBindString
1040 static inline BindProtocol
*impl_from_IInternetPriority(IInternetPriority
*iface
)
1042 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetPriority_iface
);
1045 static HRESULT WINAPI
InternetPriority_QueryInterface(IInternetPriority
*iface
,
1046 REFIID riid
, void **ppv
)
1048 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1049 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1052 static ULONG WINAPI
InternetPriority_AddRef(IInternetPriority
*iface
)
1054 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1055 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1058 static ULONG WINAPI
InternetPriority_Release(IInternetPriority
*iface
)
1060 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1061 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1064 static HRESULT WINAPI
InternetPriority_SetPriority(IInternetPriority
*iface
, LONG nPriority
)
1066 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1068 TRACE("(%p)->(%d)\n", This
, nPriority
);
1070 This
->priority
= nPriority
;
1074 static HRESULT WINAPI
InternetPriority_GetPriority(IInternetPriority
*iface
, LONG
*pnPriority
)
1076 BindProtocol
*This
= impl_from_IInternetPriority(iface
);
1078 TRACE("(%p)->(%p)\n", This
, pnPriority
);
1080 *pnPriority
= This
->priority
;
1084 static const IInternetPriorityVtbl InternetPriorityVtbl
= {
1085 InternetPriority_QueryInterface
,
1086 InternetPriority_AddRef
,
1087 InternetPriority_Release
,
1088 InternetPriority_SetPriority
,
1089 InternetPriority_GetPriority
1093 static inline BindProtocol
*impl_from_IInternetProtocolSink(IInternetProtocolSink
*iface
)
1095 return CONTAINING_RECORD(iface
, BindProtocol
, IInternetProtocolSink_iface
);
1098 static HRESULT WINAPI
BPInternetProtocolSink_QueryInterface(IInternetProtocolSink
*iface
,
1099 REFIID riid
, void **ppv
)
1101 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1102 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1105 static ULONG WINAPI
BPInternetProtocolSink_AddRef(IInternetProtocolSink
*iface
)
1107 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1108 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1111 static ULONG WINAPI
BPInternetProtocolSink_Release(IInternetProtocolSink
*iface
)
1113 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1114 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1118 task_header_t header
;
1122 static void switch_proc(BindProtocol
*bind
, task_header_t
*t
)
1124 switch_task_t
*task
= (switch_task_t
*)t
;
1126 IInternetProtocol_Continue(bind
->protocol_handler
, task
->data
);
1131 static HRESULT WINAPI
BPInternetProtocolSink_Switch(IInternetProtocolSink
*iface
,
1132 PROTOCOLDATA
*pProtocolData
)
1134 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1137 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
1139 TRACE("flags %x state %x data %p cb %u\n", pProtocolData
->grfFlags
, pProtocolData
->dwState
,
1140 pProtocolData
->pData
, pProtocolData
->cbData
);
1142 data
= heap_alloc(sizeof(PROTOCOLDATA
));
1144 return E_OUTOFMEMORY
;
1145 memcpy(data
, pProtocolData
, sizeof(PROTOCOLDATA
));
1147 if((This
->pi
&PI_APARTMENTTHREADED
&& pProtocolData
->grfFlags
&PI_FORCE_ASYNC
)
1148 || !do_direct_notif(This
)) {
1149 switch_task_t
*task
;
1151 task
= heap_alloc(sizeof(switch_task_t
));
1155 return E_OUTOFMEMORY
;
1160 push_task(This
, &task
->header
, switch_proc
);
1164 return IInternetProtocolSink_Switch(This
->protocol_sink_handler
, data
);
1168 task_header_t header
;
1172 } on_progress_task_t
;
1174 static void on_progress_proc(BindProtocol
*This
, task_header_t
*t
)
1176 on_progress_task_t
*task
= (on_progress_task_t
*)t
;
1178 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, task
->status_code
, task
->status_text
);
1180 heap_free(task
->status_text
);
1184 static HRESULT WINAPI
BPInternetProtocolSink_ReportProgress(IInternetProtocolSink
*iface
,
1185 ULONG ulStatusCode
, LPCWSTR szStatusText
)
1187 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1189 TRACE("(%p)->(%u %s)\n", This
, ulStatusCode
, debugstr_w(szStatusText
));
1191 if(do_direct_notif(This
)) {
1192 IInternetProtocolSink_ReportProgress(This
->protocol_sink_handler
, ulStatusCode
, szStatusText
);
1194 on_progress_task_t
*task
;
1196 task
= heap_alloc(sizeof(on_progress_task_t
));
1198 task
->status_code
= ulStatusCode
;
1199 task
->status_text
= heap_strdupW(szStatusText
);
1201 push_task(This
, &task
->header
, on_progress_proc
);
1208 task_header_t header
;
1212 } report_data_task_t
;
1214 static void report_data_proc(BindProtocol
*This
, task_header_t
*t
)
1216 report_data_task_t
*task
= (report_data_task_t
*)t
;
1218 IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1219 task
->bscf
, task
->progress
, task
->progress_max
);
1224 static HRESULT WINAPI
BPInternetProtocolSink_ReportData(IInternetProtocolSink
*iface
,
1225 DWORD grfBSCF
, ULONG ulProgress
, ULONG ulProgressMax
)
1227 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1229 TRACE("(%p)->(%x %u %u)\n", This
, grfBSCF
, ulProgress
, ulProgressMax
);
1231 if(!This
->protocol_sink
)
1234 if(!do_direct_notif(This
)) {
1235 report_data_task_t
*task
;
1237 task
= heap_alloc(sizeof(report_data_task_t
));
1239 return E_OUTOFMEMORY
;
1241 task
->bscf
= grfBSCF
;
1242 task
->progress
= ulProgress
;
1243 task
->progress_max
= ulProgressMax
;
1245 push_task(This
, &task
->header
, report_data_proc
);
1249 return IInternetProtocolSink_ReportData(This
->protocol_sink_handler
,
1250 grfBSCF
, ulProgress
, ulProgressMax
);
1254 task_header_t header
;
1259 } report_result_task_t
;
1261 static void report_result_proc(BindProtocol
*This
, task_header_t
*t
)
1263 report_result_task_t
*task
= (report_result_task_t
*)t
;
1265 IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, task
->hres
, task
->err
, task
->str
);
1267 heap_free(task
->str
);
1271 static HRESULT WINAPI
BPInternetProtocolSink_ReportResult(IInternetProtocolSink
*iface
,
1272 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
1274 BindProtocol
*This
= impl_from_IInternetProtocolSink(iface
);
1276 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
1278 if(!This
->protocol_sink
)
1280 This
->reported_result
= TRUE
;
1282 if(!do_direct_notif(This
)) {
1283 report_result_task_t
*task
;
1285 task
= heap_alloc(sizeof(report_result_task_t
));
1287 return E_OUTOFMEMORY
;
1289 task
->hres
= hrResult
;
1290 task
->err
= dwError
;
1291 task
->str
= heap_strdupW(szResult
);
1293 push_task(This
, &task
->header
, report_result_proc
);
1297 return IInternetProtocolSink_ReportResult(This
->protocol_sink_handler
, hrResult
, dwError
, szResult
);
1300 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
= {
1301 BPInternetProtocolSink_QueryInterface
,
1302 BPInternetProtocolSink_AddRef
,
1303 BPInternetProtocolSink_Release
,
1304 BPInternetProtocolSink_Switch
,
1305 BPInternetProtocolSink_ReportProgress
,
1306 BPInternetProtocolSink_ReportData
,
1307 BPInternetProtocolSink_ReportResult
1310 static inline BindProtocol
*impl_from_IWinInetHttpInfo(IWinInetHttpInfo
*iface
)
1312 return CONTAINING_RECORD(iface
, BindProtocol
, IWinInetHttpInfo_iface
);
1315 static HRESULT WINAPI
WinInetHttpInfo_QueryInterface(IWinInetHttpInfo
*iface
, REFIID riid
, void **ppv
)
1317 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1318 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1321 static ULONG WINAPI
WinInetHttpInfo_AddRef(IWinInetHttpInfo
*iface
)
1323 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1324 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1327 static ULONG WINAPI
WinInetHttpInfo_Release(IWinInetHttpInfo
*iface
)
1329 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1330 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1333 static HRESULT WINAPI
WinInetHttpInfo_QueryOption(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1334 void *pBuffer
, DWORD
*pcbBuffer
)
1336 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1337 FIXME("(%p)->(%x %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
);
1341 static HRESULT WINAPI
WinInetHttpInfo_QueryInfo(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1342 void *pBuffer
, DWORD
*pcbBuffer
, DWORD
*pdwFlags
, DWORD
*pdwReserved
)
1344 BindProtocol
*This
= impl_from_IWinInetHttpInfo(iface
);
1345 FIXME("(%p)->(%x %p %p %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
, pdwFlags
, pdwReserved
);
1349 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl
= {
1350 WinInetHttpInfo_QueryInterface
,
1351 WinInetHttpInfo_AddRef
,
1352 WinInetHttpInfo_Release
,
1353 WinInetHttpInfo_QueryOption
,
1354 WinInetHttpInfo_QueryInfo
1357 static inline BindProtocol
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1359 return CONTAINING_RECORD(iface
, BindProtocol
, IServiceProvider_iface
);
1362 static HRESULT WINAPI
BPServiceProvider_QueryInterface(IServiceProvider
*iface
,
1363 REFIID riid
, void **ppv
)
1365 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1366 return IInternetProtocolEx_QueryInterface(&This
->IInternetProtocolEx_iface
, riid
, ppv
);
1369 static ULONG WINAPI
BPServiceProvider_AddRef(IServiceProvider
*iface
)
1371 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1372 return IInternetProtocolEx_AddRef(&This
->IInternetProtocolEx_iface
);
1375 static ULONG WINAPI
BPServiceProvider_Release(IServiceProvider
*iface
)
1377 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1378 return IInternetProtocolEx_Release(&This
->IInternetProtocolEx_iface
);
1381 static HRESULT WINAPI
BPServiceProvider_QueryService(IServiceProvider
*iface
,
1382 REFGUID guidService
, REFIID riid
, void **ppv
)
1384 BindProtocol
*This
= impl_from_IServiceProvider(iface
);
1386 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1388 if(!This
->service_provider
)
1389 return E_NOINTERFACE
;
1391 return IServiceProvider_QueryService(This
->service_provider
, guidService
, riid
, ppv
);
1394 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1395 BPServiceProvider_QueryInterface
,
1396 BPServiceProvider_AddRef
,
1397 BPServiceProvider_Release
,
1398 BPServiceProvider_QueryService
1401 HRESULT
create_binding_protocol(BOOL from_urlmon
, BindProtocol
**protocol
)
1403 BindProtocol
*ret
= heap_alloc_zero(sizeof(BindProtocol
));
1405 ret
->IInternetProtocolEx_iface
.lpVtbl
= &BindProtocolVtbl
;
1406 ret
->IInternetBindInfo_iface
.lpVtbl
= &InternetBindInfoVtbl
;
1407 ret
->IInternetPriority_iface
.lpVtbl
= &InternetPriorityVtbl
;
1408 ret
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
1409 ret
->IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkVtbl
;
1410 ret
->IWinInetHttpInfo_iface
.lpVtbl
= &WinInetHttpInfoVtbl
;
1412 ret
->default_protocol_handler
.IInternetProtocol_iface
.lpVtbl
= &InternetProtocolHandlerVtbl
;
1413 ret
->default_protocol_handler
.IInternetProtocolSink_iface
.lpVtbl
= &InternetProtocolSinkHandlerVtbl
;
1416 ret
->from_urlmon
= from_urlmon
;
1417 ret
->apartment_thread
= GetCurrentThreadId();
1418 ret
->notif_hwnd
= get_notif_hwnd();
1419 ret
->protocol_handler
= &ret
->default_protocol_handler
.IInternetProtocol_iface
;
1420 ret
->protocol_sink_handler
= &ret
->default_protocol_handler
.IInternetProtocolSink_iface
;
1421 InitializeCriticalSection(&ret
->section
);
1422 ret
->section
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BindProtocol.section");
1424 URLMON_LockModule();