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 struct BindProtocol BindProtocol
;
26 struct _task_header_t
;
28 typedef void (*task_proc_t
)(BindProtocol
*,struct _task_header_t
*);
30 typedef struct _task_header_t
{
32 struct _task_header_t
*next
;
36 const IInternetProtocolExVtbl
*lpIInternetProtocolExVtbl
;
37 const IInternetBindInfoVtbl
*lpInternetBindInfoVtbl
;
38 const IInternetPriorityVtbl
*lpInternetPriorityVtbl
;
39 const IServiceProviderVtbl
*lpServiceProviderVtbl
;
40 const IInternetProtocolSinkVtbl
*lpIInternetProtocolSinkVtbl
;
41 const IWinInetHttpInfoVtbl
*lpIWinInetHttpInfoVtbl
;
43 const IInternetProtocolExVtbl
*lpIInternetProtocolHandlerVtbl
;
47 IInternetProtocol
*protocol
;
48 IInternetProtocol
*protocol_handler
;
49 IInternetBindInfo
*bind_info
;
50 IInternetProtocolSink
*protocol_sink
;
51 IServiceProvider
*service_provider
;
52 IWinInetInfo
*wininet_info
;
61 DWORD apartment_thread
;
65 CRITICAL_SECTION section
;
66 task_header_t
*task_queue_head
, *task_queue_tail
;
72 ProtocolProxy
*filter_proxy
;
75 #define BINDINFO(x) ((IInternetBindInfo*) &(x)->lpInternetBindInfoVtbl)
76 #define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
77 #define HTTPINFO(x) ((IWinInetHttpInfo*) &(x)->lpIWinInetHttpInfoVtbl)
78 #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
79 #define PROTOCOLEX(x) ((IInternetProtocolEx*) &(x)->lpIInternetProtocolExVtbl)
81 #define PROTOCOLHANDLER(x) ((IInternetProtocolEx*) &(x)->lpIInternetProtocolHandlerVtbl)
83 #define BUFFER_SIZE 2048
84 #define MIME_TEST_SIZE 255
86 #define WM_MK_CONTINUE (WM_USER+101)
87 #define WM_MK_RELEASE (WM_USER+102)
89 static LRESULT WINAPI
notif_wnd_proc(HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
92 case WM_MK_CONTINUE
: {
93 BindProtocol
*This
= (BindProtocol
*)lParam
;
97 EnterCriticalSection(&This
->section
);
99 task
= This
->task_queue_head
;
101 This
->task_queue_head
= task
->next
;
102 if(!This
->task_queue_head
)
103 This
->task_queue_tail
= NULL
;
106 LeaveCriticalSection(&This
->section
);
111 This
->continue_call
++;
112 task
->proc(This
, task
);
113 This
->continue_call
--;
116 IInternetProtocolEx_Release(PROTOCOLEX(This
));
119 case WM_MK_RELEASE
: {
120 tls_data_t
*data
= get_tls_data();
122 if(!--data
->notif_hwnd_cnt
) {
124 data
->notif_hwnd
= NULL
;
129 return DefWindowProcW(hwnd
, msg
, wParam
, lParam
);
132 HWND
get_notif_hwnd(void)
134 static ATOM wnd_class
= 0;
135 tls_data_t
*tls_data
;
137 static const WCHAR wszURLMonikerNotificationWindow
[] =
138 {'U','R','L',' ','M','o','n','i','k','e','r',' ',
139 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
141 tls_data
= get_tls_data();
145 if(tls_data
->notif_hwnd_cnt
) {
146 tls_data
->notif_hwnd_cnt
++;
147 return tls_data
->notif_hwnd
;
151 static WNDCLASSEXW wndclass
= {
153 notif_wnd_proc
, 0, 0,
154 NULL
, NULL
, NULL
, NULL
, NULL
,
155 wszURLMonikerNotificationWindow
,
159 wndclass
.hInstance
= hProxyDll
;
161 wnd_class
= RegisterClassExW(&wndclass
);
162 if (!wnd_class
&& GetLastError() == ERROR_CLASS_ALREADY_EXISTS
)
166 tls_data
->notif_hwnd
= CreateWindowExW(0, wszURLMonikerNotificationWindow
,
167 wszURLMonikerNotificationWindow
, 0, 0, 0, 0, 0, HWND_MESSAGE
,
168 NULL
, hProxyDll
, NULL
);
169 if(tls_data
->notif_hwnd
)
170 tls_data
->notif_hwnd_cnt
++;
172 TRACE("hwnd = %p\n", tls_data
->notif_hwnd
);
174 return tls_data
->notif_hwnd
;
177 void release_notif_hwnd(HWND hwnd
)
179 tls_data_t
*data
= get_tls_data();
184 if(data
->notif_hwnd
!= hwnd
) {
185 PostMessageW(data
->notif_hwnd
, WM_MK_RELEASE
, 0, 0);
189 if(!--data
->notif_hwnd_cnt
) {
190 DestroyWindow(data
->notif_hwnd
);
191 data
->notif_hwnd
= NULL
;
195 static void push_task(BindProtocol
*This
, task_header_t
*task
, task_proc_t proc
)
197 BOOL do_post
= FALSE
;
202 EnterCriticalSection(&This
->section
);
204 if(This
->task_queue_tail
) {
205 This
->task_queue_tail
->next
= task
;
206 This
->task_queue_tail
= task
;
208 This
->task_queue_tail
= This
->task_queue_head
= task
;
209 do_post
= !This
->continue_call
;
212 LeaveCriticalSection(&This
->section
);
215 IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
216 PostMessageW(This
->notif_hwnd
, WM_MK_CONTINUE
, 0, (LPARAM
)This
);
220 static inline BOOL
do_direct_notif(BindProtocol
*This
)
222 return !(This
->pi
& PI_APARTMENTTHREADED
) || (This
->apartment_thread
== GetCurrentThreadId() && !This
->continue_call
);
225 static HRESULT
handle_mime_filter(BindProtocol
*This
, IInternetProtocol
*mime_filter
, LPCWSTR mime
)
227 PROTOCOLFILTERDATA filter_data
= { sizeof(PROTOCOLFILTERDATA
), NULL
, NULL
, NULL
, 0 };
228 IInternetProtocolSink
*protocol_sink
, *old_sink
;
229 ProtocolProxy
*filter_proxy
;
232 hres
= IInternetProtocol_QueryInterface(mime_filter
, &IID_IInternetProtocolSink
, (void**)&protocol_sink
);
236 hres
= create_protocol_proxy((IInternetProtocol
*)PROTOCOLHANDLER(This
), This
->protocol_sink
, &filter_proxy
);
238 IInternetProtocolSink_Release(protocol_sink
);
242 old_sink
= This
->protocol_sink
;
243 This
->protocol_sink
= protocol_sink
;
244 This
->filter_proxy
= filter_proxy
;
246 IInternetProtocol_AddRef(mime_filter
);
247 This
->protocol_handler
= mime_filter
;
249 filter_data
.pProtocol
= PROTOCOL(filter_proxy
);
250 hres
= IInternetProtocol_Start(mime_filter
, mime
, PROTSINK(filter_proxy
), BINDINFO(This
),
251 PI_FILTER_MODE
|PI_FORCE_ASYNC
, (HANDLE_PTR
)&filter_data
);
253 IInternetProtocolSink_Release(old_sink
);
257 IInternetProtocolSink_ReportProgress(old_sink
, BINDSTATUS_LOADINGMIMEHANDLER
, NULL
);
258 IInternetProtocolSink_Release(old_sink
);
260 This
->pi
&= ~PI_MIMEVERIFICATION
; /* FIXME: more tests */
264 static void mime_available(BindProtocol
*This
, LPCWSTR mime
, BOOL verified
)
266 IInternetProtocol
*mime_filter
;
269 heap_free(This
->mime
);
272 mime_filter
= get_mime_filter(mime
);
274 TRACE("Got mime filter for %s\n", debugstr_w(mime
));
276 hres
= handle_mime_filter(This
, mime_filter
, mime
);
277 IInternetProtocol_Release(mime_filter
);
279 FIXME("MIME filter failed: %08x\n", hres
);
281 This
->mime
= heap_strdupW(mime
);
283 if(verified
|| !(This
->pi
& PI_MIMEVERIFICATION
)) {
284 This
->reported_mime
= TRUE
;
286 if(This
->protocol_sink
)
287 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
292 #define PROTOCOL_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolEx, iface)
294 static HRESULT WINAPI
BindProtocol_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
296 BindProtocol
*This
= PROTOCOL_THIS(iface
);
299 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
300 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
301 *ppv
= PROTOCOLEX(This
);
302 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
303 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This
, ppv
);
304 *ppv
= PROTOCOLEX(This
);
305 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
306 TRACE("(%p)->(IID_IInternetProtocol %p)\n", This
, ppv
);
307 *ppv
= PROTOCOLEX(This
);
308 }else if(IsEqualGUID(&IID_IInternetProtocolEx
, riid
)) {
309 TRACE("(%p)->(IID_IInternetProtocolEx %p)\n", This
, ppv
);
310 *ppv
= PROTOCOLEX(This
);
311 }else if(IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
312 TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This
, ppv
);
313 *ppv
= BINDINFO(This
);
314 }else if(IsEqualGUID(&IID_IInternetPriority
, riid
)) {
315 TRACE("(%p)->(IID_IInternetPriority %p)\n", This
, ppv
);
316 *ppv
= PRIORITY(This
);
317 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
318 FIXME("(%p)->(IID_IAuthenticate %p)\n", This
, ppv
);
319 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
320 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
321 *ppv
= SERVPROV(This
);
322 }else if(IsEqualGUID(&IID_IInternetProtocolSink
, riid
)) {
323 TRACE("(%p)->(IID_IInternetProtocolSink %p)\n", This
, ppv
);
324 *ppv
= PROTSINK(This
);
325 }else if(IsEqualGUID(&IID_IWinInetInfo
, riid
)) {
326 TRACE("(%p)->(IID_IWinInetInfo %p)\n", This
, ppv
);
329 IWinInetInfo
*inet_info
;
332 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetInfo
, (void**)&inet_info
);
333 if(SUCCEEDED(hres
)) {
334 *ppv
= HTTPINFO(This
);
335 IWinInetInfo_Release(inet_info
);
338 }else if(IsEqualGUID(&IID_IWinInetHttpInfo
, riid
)) {
339 TRACE("(%p)->(IID_IWinInetHttpInfo %p)\n", This
, ppv
);
342 IWinInetHttpInfo
*http_info
;
345 hres
= IInternetProtocol_QueryInterface(This
->protocol
, &IID_IWinInetHttpInfo
, (void**)&http_info
);
346 if(SUCCEEDED(hres
)) {
347 *ppv
= HTTPINFO(This
);
348 IWinInetHttpInfo_Release(http_info
);
352 WARN("not supported interface %s\n", debugstr_guid(riid
));
356 return E_NOINTERFACE
;
358 IUnknown_AddRef((IUnknown
*)*ppv
);
362 static ULONG WINAPI
BindProtocol_AddRef(IInternetProtocolEx
*iface
)
364 BindProtocol
*This
= PROTOCOL_THIS(iface
);
365 LONG ref
= InterlockedIncrement(&This
->ref
);
366 TRACE("(%p) ref=%d\n", This
, ref
);
370 static ULONG WINAPI
BindProtocol_Release(IInternetProtocolEx
*iface
)
372 BindProtocol
*This
= PROTOCOL_THIS(iface
);
373 LONG ref
= InterlockedDecrement(&This
->ref
);
375 TRACE("(%p) ref=%d\n", This
, ref
);
378 if(This
->wininet_info
)
379 IWinInetInfo_Release(This
->wininet_info
);
381 IInternetProtocol_Release(This
->protocol
);
383 IInternetBindInfo_Release(This
->bind_info
);
384 if(This
->protocol_handler
&& This
->protocol_handler
!= (IInternetProtocol
*)PROTOCOLHANDLER(This
))
385 IInternetProtocol_Release(This
->protocol_handler
);
386 if(This
->filter_proxy
)
387 IInternetProtocol_Release(PROTOCOL(This
->filter_proxy
));
389 IUri_Release(This
->uri
);
391 set_binding_sink((IInternetProtocol
*)PROTOCOLEX(This
), NULL
, NULL
);
394 release_notif_hwnd(This
->notif_hwnd
);
395 DeleteCriticalSection(&This
->section
);
397 heap_free(This
->mime
);
400 URLMON_UnlockModule();
406 static HRESULT WINAPI
BindProtocol_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
407 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
408 DWORD grfPI
, HANDLE_PTR dwReserved
)
410 BindProtocol
*This
= PROTOCOL_THIS(iface
);
412 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
413 pOIBindInfo
, grfPI
, dwReserved
);
415 if(This
->protocol_handler
!= (IInternetProtocol
*)PROTOCOLHANDLER(This
)) {
416 FIXME("This->protocol_handler != PROTOCOLHANDLER(This)\n");
420 return IInternetProtocolEx_Start(PROTOCOLHANDLER(This
), szUrl
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
423 static HRESULT WINAPI
BindProtocol_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
425 BindProtocol
*This
= PROTOCOL_THIS(iface
);
427 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
429 return IInternetProtocol_Continue(This
->protocol_handler
, pProtocolData
);
432 static HRESULT WINAPI
BindProtocol_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
435 BindProtocol
*This
= PROTOCOL_THIS(iface
);
437 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
439 return IInternetProtocol_Abort(This
->protocol_handler
, hrReason
, dwOptions
);
442 static HRESULT WINAPI
BindProtocol_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
444 BindProtocol
*This
= PROTOCOL_THIS(iface
);
446 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
448 return IInternetProtocol_Terminate(This
->protocol_handler
, dwOptions
);
451 static HRESULT WINAPI
BindProtocol_Suspend(IInternetProtocolEx
*iface
)
453 BindProtocol
*This
= PROTOCOL_THIS(iface
);
454 FIXME("(%p)\n", This
);
458 static HRESULT WINAPI
BindProtocol_Resume(IInternetProtocolEx
*iface
)
460 BindProtocol
*This
= PROTOCOL_THIS(iface
);
461 FIXME("(%p)\n", This
);
465 static HRESULT WINAPI
BindProtocol_Read(IInternetProtocolEx
*iface
, void *pv
,
466 ULONG cb
, ULONG
*pcbRead
)
468 BindProtocol
*This
= PROTOCOL_THIS(iface
);
470 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
474 return IInternetProtocol_Read(This
->protocol_handler
, pv
, cb
, pcbRead
);
477 static HRESULT WINAPI
BindProtocol_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
478 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
480 BindProtocol
*This
= PROTOCOL_THIS(iface
);
481 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
485 static HRESULT WINAPI
BindProtocol_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
487 BindProtocol
*This
= PROTOCOL_THIS(iface
);
489 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
491 return IInternetProtocol_LockRequest(This
->protocol_handler
, dwOptions
);
494 static HRESULT WINAPI
BindProtocol_UnlockRequest(IInternetProtocolEx
*iface
)
496 BindProtocol
*This
= PROTOCOL_THIS(iface
);
498 TRACE("(%p)\n", This
);
500 return IInternetProtocol_UnlockRequest(This
->protocol_handler
);
503 static HRESULT WINAPI
BindProtocol_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
504 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
505 DWORD grfPI
, HANDLE
*dwReserved
)
507 BindProtocol
*This
= PROTOCOL_THIS(iface
);
509 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
511 if(This
->protocol_handler
!= (IInternetProtocol
*)PROTOCOLHANDLER(This
)) {
512 FIXME("This->protocol_handler != PROTOCOLHANDLER(This)\n");
516 return IInternetProtocolEx_StartEx(PROTOCOLHANDLER(This
), pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
519 void set_binding_sink(IInternetProtocol
*bind_protocol
, IInternetProtocolSink
*sink
, IInternetBindInfo
*bind_info
)
521 BindProtocol
*This
= PROTOCOL_THIS(bind_protocol
);
522 IInternetProtocolSink
*prev_sink
;
523 IServiceProvider
*service_provider
= NULL
;
526 IInternetProtocolSink_AddRef(sink
);
527 prev_sink
= InterlockedExchangePointer((void**)&This
->protocol_sink
, sink
);
529 IInternetProtocolSink_Release(prev_sink
);
532 IInternetProtocolSink_QueryInterface(sink
, &IID_IServiceProvider
, (void**)&service_provider
);
533 service_provider
= InterlockedExchangePointer((void**)&This
->service_provider
, service_provider
);
535 IServiceProvider_Release(service_provider
);
538 IInternetBindInfo_AddRef(bind_info
);
539 bind_info
= InterlockedExchangePointer((void**)&This
->bind_info
, bind_info
);
541 IInternetBindInfo_Release(bind_info
);
544 IWinInetInfo
*get_wininet_info(IInternetProtocol
*bind_protocol
)
546 BindProtocol
*This
= PROTOCOL_THIS(bind_protocol
);
548 return This
->wininet_info
;
553 static const IInternetProtocolExVtbl BindProtocolVtbl
= {
554 BindProtocol_QueryInterface
,
556 BindProtocol_Release
,
558 BindProtocol_Continue
,
560 BindProtocol_Terminate
,
561 BindProtocol_Suspend
,
565 BindProtocol_LockRequest
,
566 BindProtocol_UnlockRequest
,
570 #define PROTOCOLHANDLER_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolHandler, iface)
572 static HRESULT WINAPI
ProtocolHandler_QueryInterface(IInternetProtocolEx
*iface
, REFIID riid
, void **ppv
)
574 ERR("should not be called\n");
575 return E_NOINTERFACE
;
578 static ULONG WINAPI
ProtocolHandler_AddRef(IInternetProtocolEx
*iface
)
580 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
581 return IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
584 static ULONG WINAPI
ProtocolHandler_Release(IInternetProtocolEx
*iface
)
586 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
587 return IInternetProtocolEx_Release(PROTOCOLEX(This
));
590 static HRESULT WINAPI
ProtocolHandler_Start(IInternetProtocolEx
*iface
, LPCWSTR szUrl
,
591 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
592 DWORD grfPI
, HANDLE_PTR dwReserved
)
594 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
598 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
599 pOIBindInfo
, grfPI
, dwReserved
);
601 hres
= CreateUri(szUrl
, Uri_CREATE_FILE_USE_DOS_PATH
, 0, &uri
);
605 hres
= IInternetProtocolEx_StartEx(PROTOCOLHANDLER(This
), uri
, pOIProtSink
, pOIBindInfo
,
606 grfPI
, (HANDLE
*)dwReserved
);
612 static HRESULT WINAPI
ProtocolHandler_Continue(IInternetProtocolEx
*iface
, PROTOCOLDATA
*pProtocolData
)
614 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
617 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
619 hres
= IInternetProtocol_Continue(This
->protocol
, pProtocolData
);
621 heap_free(pProtocolData
);
625 static HRESULT WINAPI
ProtocolHandler_Abort(IInternetProtocolEx
*iface
, HRESULT hrReason
,
628 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
630 TRACE("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
632 if(This
->protocol
&& !This
->reported_result
)
633 return IInternetProtocol_Abort(This
->protocol
, hrReason
, dwOptions
);
638 static HRESULT WINAPI
ProtocolHandler_Terminate(IInternetProtocolEx
*iface
, DWORD dwOptions
)
640 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
642 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
644 if(!This
->reported_result
)
647 IInternetProtocol_Terminate(This
->protocol
, 0);
649 if(This
->filter_proxy
) {
650 IInternetProtocol_Release(PROTOCOL(This
->filter_proxy
));
651 This
->filter_proxy
= NULL
;
654 set_binding_sink((IInternetProtocol
*)PROTOCOLEX(This
), NULL
, NULL
);
656 if(This
->bind_info
) {
657 IInternetBindInfo_Release(This
->bind_info
);
658 This
->bind_info
= NULL
;
664 static HRESULT WINAPI
ProtocolHandler_Suspend(IInternetProtocolEx
*iface
)
666 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
667 FIXME("(%p)\n", This
);
671 static HRESULT WINAPI
ProtocolHandler_Resume(IInternetProtocolEx
*iface
)
673 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
674 FIXME("(%p)\n", This
);
678 static HRESULT WINAPI
ProtocolHandler_Read(IInternetProtocolEx
*iface
, void *pv
,
679 ULONG cb
, ULONG
*pcbRead
)
681 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
685 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
688 read
= min(cb
, This
->buf_size
);
689 memcpy(pv
, This
->buf
, read
);
691 if(read
== This
->buf_size
) {
692 heap_free(This
->buf
);
695 memmove(This
->buf
, This
->buf
+cb
, This
->buf_size
-cb
);
698 This
->buf_size
-= read
;
704 hres
= IInternetProtocol_Read(This
->protocol
, (BYTE
*)pv
+read
, cb
-read
, &cread
);
712 static HRESULT WINAPI
ProtocolHandler_Seek(IInternetProtocolEx
*iface
, LARGE_INTEGER dlibMove
,
713 DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
)
715 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
716 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
720 static HRESULT WINAPI
ProtocolHandler_LockRequest(IInternetProtocolEx
*iface
, DWORD dwOptions
)
722 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
724 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
726 return IInternetProtocol_LockRequest(This
->protocol
, dwOptions
);
729 static HRESULT WINAPI
ProtocolHandler_UnlockRequest(IInternetProtocolEx
*iface
)
731 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
733 TRACE("(%p)\n", This
);
735 return IInternetProtocol_UnlockRequest(This
->protocol
);
738 static HRESULT WINAPI
ProtocolHandler_StartEx(IInternetProtocolEx
*iface
, IUri
*pUri
,
739 IInternetProtocolSink
*pOIProtSink
, IInternetBindInfo
*pOIBindInfo
,
740 DWORD grfPI
, HANDLE
*dwReserved
)
742 BindProtocol
*This
= PROTOCOLHANDLER_THIS(iface
);
743 IInternetProtocol
*protocol
= NULL
;
744 IInternetProtocolEx
*protocolex
;
745 IInternetPriority
*priority
;
746 IServiceProvider
*service_provider
;
747 BOOL urlmon_protocol
= FALSE
;
748 CLSID clsid
= IID_NULL
;
752 TRACE("(%p)->(%p %p %p %08x %p)\n", This
, pUri
, pOIProtSink
, pOIBindInfo
, grfPI
, dwReserved
);
754 if(!pUri
|| !pOIProtSink
|| !pOIBindInfo
)
762 hres
= IInternetProtocolSink_QueryInterface(pOIProtSink
, &IID_IServiceProvider
,
763 (void**)&service_provider
);
764 if(SUCCEEDED(hres
)) {
765 /* FIXME: What's protocol CLSID here? */
766 IServiceProvider_QueryService(service_provider
, &IID_IInternetProtocol
,
767 &IID_IInternetProtocol
, (void**)&protocol
);
768 IServiceProvider_Release(service_provider
);
776 /* FIXME: Avoid GetRawUri here */
777 hres
= IUri_GetRawUri(pUri
, &raw_uri
);
781 hres
= get_protocol_handler(raw_uri
, &clsid
, &urlmon_protocol
, &cf
);
782 SysFreeString(raw_uri
);
786 if(This
->from_urlmon
) {
787 hres
= IClassFactory_CreateInstance(cf
, NULL
, &IID_IInternetProtocol
, (void**)&protocol
);
788 IClassFactory_Release(cf
);
792 hres
= IClassFactory_CreateInstance(cf
, (IUnknown
*)BINDINFO(This
),
793 &IID_IUnknown
, (void**)&unk
);
794 IClassFactory_Release(cf
);
798 hres
= IUnknown_QueryInterface(unk
, &IID_IInternetProtocol
, (void**)&protocol
);
799 IUnknown_Release(unk
);
805 StringFromCLSID(&clsid
, &clsid_str
);
806 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_PROTOCOLCLASSID
, clsid_str
);
807 CoTaskMemFree(clsid_str
);
809 This
->protocol
= protocol
;
812 IInternetProtocol_QueryInterface(protocol
, &IID_IWinInetInfo
, (void**)&This
->wininet_info
);
814 set_binding_sink((IInternetProtocol
*)PROTOCOLEX(This
), pOIProtSink
, pOIBindInfo
);
816 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetPriority
, (void**)&priority
);
817 if(SUCCEEDED(hres
)) {
818 IInternetPriority_SetPriority(priority
, This
->priority
);
819 IInternetPriority_Release(priority
);
822 hres
= IInternetProtocol_QueryInterface(protocol
, &IID_IInternetProtocolEx
, (void**)&protocolex
);
823 if(SUCCEEDED(hres
)) {
824 hres
= IInternetProtocolEx_StartEx(protocolex
, pUri
, PROTSINK(This
), BINDINFO(This
), 0, NULL
);
825 IInternetProtocolEx_Release(protocolex
);
829 hres
= IUri_GetDisplayUri(pUri
, &display_uri
);
833 hres
= IInternetProtocol_Start(protocol
, display_uri
, PROTSINK(This
), BINDINFO(This
), 0, 0);
834 SysFreeString(display_uri
);
842 static const IInternetProtocolExVtbl InternetProtocolHandlerVtbl
= {
843 ProtocolHandler_QueryInterface
,
844 ProtocolHandler_AddRef
,
845 ProtocolHandler_Release
,
846 ProtocolHandler_Start
,
847 ProtocolHandler_Continue
,
848 ProtocolHandler_Abort
,
849 ProtocolHandler_Terminate
,
850 ProtocolHandler_Suspend
,
851 ProtocolHandler_Resume
,
852 ProtocolHandler_Read
,
853 ProtocolHandler_Seek
,
854 ProtocolHandler_LockRequest
,
855 ProtocolHandler_UnlockRequest
,
856 ProtocolHandler_StartEx
859 #define BINDINFO_THIS(iface) DEFINE_THIS(BindProtocol, InternetBindInfo, iface)
861 static HRESULT WINAPI
BindInfo_QueryInterface(IInternetBindInfo
*iface
,
862 REFIID riid
, void **ppv
)
864 BindProtocol
*This
= BINDINFO_THIS(iface
);
865 return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This
), riid
, ppv
);
868 static ULONG WINAPI
BindInfo_AddRef(IInternetBindInfo
*iface
)
870 BindProtocol
*This
= BINDINFO_THIS(iface
);
871 return IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
874 static ULONG WINAPI
BindInfo_Release(IInternetBindInfo
*iface
)
876 BindProtocol
*This
= BINDINFO_THIS(iface
);
877 return IInternetProtocolEx_Release(PROTOCOLEX(This
));
880 static HRESULT WINAPI
BindInfo_GetBindInfo(IInternetBindInfo
*iface
,
881 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
883 BindProtocol
*This
= BINDINFO_THIS(iface
);
886 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
888 hres
= IInternetBindInfo_GetBindInfo(This
->bind_info
, grfBINDF
, pbindinfo
);
890 WARN("GetBindInfo failed: %08x\n", hres
);
894 *grfBINDF
|= BINDF_FROMURLMON
;
898 static HRESULT WINAPI
BindInfo_GetBindString(IInternetBindInfo
*iface
,
899 ULONG ulStringType
, LPOLESTR
*ppwzStr
, ULONG cEl
, ULONG
*pcElFetched
)
901 BindProtocol
*This
= BINDINFO_THIS(iface
);
903 TRACE("(%p)->(%d %p %d %p)\n", This
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
905 return IInternetBindInfo_GetBindString(This
->bind_info
, ulStringType
, ppwzStr
, cEl
, pcElFetched
);
910 static const IInternetBindInfoVtbl InternetBindInfoVtbl
= {
911 BindInfo_QueryInterface
,
914 BindInfo_GetBindInfo
,
915 BindInfo_GetBindString
918 #define PRIORITY_THIS(iface) DEFINE_THIS(BindProtocol, InternetPriority, iface)
920 static HRESULT WINAPI
InternetPriority_QueryInterface(IInternetPriority
*iface
,
921 REFIID riid
, void **ppv
)
923 BindProtocol
*This
= PRIORITY_THIS(iface
);
924 return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This
), riid
, ppv
);
927 static ULONG WINAPI
InternetPriority_AddRef(IInternetPriority
*iface
)
929 BindProtocol
*This
= PRIORITY_THIS(iface
);
930 return IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
933 static ULONG WINAPI
InternetPriority_Release(IInternetPriority
*iface
)
935 BindProtocol
*This
= PRIORITY_THIS(iface
);
936 return IInternetProtocolEx_Release(PROTOCOLEX(This
));
939 static HRESULT WINAPI
InternetPriority_SetPriority(IInternetPriority
*iface
, LONG nPriority
)
941 BindProtocol
*This
= PRIORITY_THIS(iface
);
943 TRACE("(%p)->(%d)\n", This
, nPriority
);
945 This
->priority
= nPriority
;
949 static HRESULT WINAPI
InternetPriority_GetPriority(IInternetPriority
*iface
, LONG
*pnPriority
)
951 BindProtocol
*This
= PRIORITY_THIS(iface
);
953 TRACE("(%p)->(%p)\n", This
, pnPriority
);
955 *pnPriority
= This
->priority
;
961 static const IInternetPriorityVtbl InternetPriorityVtbl
= {
962 InternetPriority_QueryInterface
,
963 InternetPriority_AddRef
,
964 InternetPriority_Release
,
965 InternetPriority_SetPriority
,
966 InternetPriority_GetPriority
970 #define PROTSINK_THIS(iface) DEFINE_THIS(BindProtocol, IInternetProtocolSink, iface)
972 static HRESULT WINAPI
BPInternetProtocolSink_QueryInterface(IInternetProtocolSink
*iface
,
973 REFIID riid
, void **ppv
)
975 BindProtocol
*This
= PROTSINK_THIS(iface
);
976 return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This
), riid
, ppv
);
979 static ULONG WINAPI
BPInternetProtocolSink_AddRef(IInternetProtocolSink
*iface
)
981 BindProtocol
*This
= PROTSINK_THIS(iface
);
982 return IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
985 static ULONG WINAPI
BPInternetProtocolSink_Release(IInternetProtocolSink
*iface
)
987 BindProtocol
*This
= PROTSINK_THIS(iface
);
988 return IInternetProtocolEx_Release(PROTOCOLEX(This
));
992 task_header_t header
;
996 static void switch_proc(BindProtocol
*bind
, task_header_t
*t
)
998 switch_task_t
*task
= (switch_task_t
*)t
;
1000 IInternetProtocol_Continue(bind
->protocol_handler
, task
->data
);
1005 static HRESULT WINAPI
BPInternetProtocolSink_Switch(IInternetProtocolSink
*iface
,
1006 PROTOCOLDATA
*pProtocolData
)
1008 BindProtocol
*This
= PROTSINK_THIS(iface
);
1011 TRACE("(%p)->(%p)\n", This
, pProtocolData
);
1013 TRACE("flags %x state %x data %p cb %u\n", pProtocolData
->grfFlags
, pProtocolData
->dwState
,
1014 pProtocolData
->pData
, pProtocolData
->cbData
);
1016 data
= heap_alloc(sizeof(PROTOCOLDATA
));
1018 return E_OUTOFMEMORY
;
1019 memcpy(data
, pProtocolData
, sizeof(PROTOCOLDATA
));
1021 if(!do_direct_notif(This
)) {
1022 switch_task_t
*task
;
1024 task
= heap_alloc(sizeof(switch_task_t
));
1026 return E_OUTOFMEMORY
;
1030 push_task(This
, &task
->header
, switch_proc
);
1034 if(!This
->protocol_sink
) {
1035 IInternetProtocol_Continue(This
->protocol_handler
, data
);
1039 return IInternetProtocolSink_Switch(This
->protocol_sink
, data
);
1042 static void report_progress(BindProtocol
*This
, ULONG status_code
, LPCWSTR status_text
)
1044 switch(status_code
) {
1045 case BINDSTATUS_FINDINGRESOURCE
:
1046 case BINDSTATUS_CONNECTING
:
1047 case BINDSTATUS_REDIRECTING
:
1048 case BINDSTATUS_BEGINDOWNLOADDATA
:
1049 case BINDSTATUS_SENDINGREQUEST
:
1050 case BINDSTATUS_CACHEFILENAMEAVAILABLE
:
1051 case BINDSTATUS_DIRECTBIND
:
1052 case BINDSTATUS_ACCEPTRANGES
:
1053 if(This
->protocol_sink
)
1054 IInternetProtocolSink_ReportProgress(This
->protocol_sink
, status_code
, status_text
);
1057 case BINDSTATUS_MIMETYPEAVAILABLE
:
1058 mime_available(This
, status_text
, FALSE
);
1061 case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE
:
1062 mime_available(This
, status_text
, TRUE
);
1066 FIXME("unsupported ulStatusCode %u\n", status_code
);
1071 task_header_t header
;
1075 } on_progress_task_t
;
1077 static void on_progress_proc(BindProtocol
*This
, task_header_t
*t
)
1079 on_progress_task_t
*task
= (on_progress_task_t
*)t
;
1081 report_progress(This
, task
->status_code
, task
->status_text
);
1083 heap_free(task
->status_text
);
1087 static HRESULT WINAPI
BPInternetProtocolSink_ReportProgress(IInternetProtocolSink
*iface
,
1088 ULONG ulStatusCode
, LPCWSTR szStatusText
)
1090 BindProtocol
*This
= PROTSINK_THIS(iface
);
1092 TRACE("(%p)->(%u %s)\n", This
, ulStatusCode
, debugstr_w(szStatusText
));
1094 if(do_direct_notif(This
)) {
1095 report_progress(This
, ulStatusCode
, szStatusText
);
1097 on_progress_task_t
*task
;
1099 task
= heap_alloc(sizeof(on_progress_task_t
));
1101 task
->status_code
= ulStatusCode
;
1102 task
->status_text
= heap_strdupW(szStatusText
);
1104 push_task(This
, &task
->header
, on_progress_proc
);
1110 static HRESULT
report_data(BindProtocol
*This
, DWORD bscf
, ULONG progress
, ULONG progress_max
)
1112 if(!This
->protocol_sink
)
1115 if((This
->pi
& PI_MIMEVERIFICATION
) && !This
->reported_mime
) {
1116 BYTE buf
[BUFFER_SIZE
];
1123 hres
= IInternetProtocol_Read(This
->protocol
, buf
,
1124 sizeof(buf
)-This
->buf_size
, &read
);
1125 if(FAILED(hres
) && hres
!= E_PENDING
)
1129 This
->buf
= heap_alloc(BUFFER_SIZE
);
1131 return E_OUTOFMEMORY
;
1132 }else if(read
+ This
->buf_size
> BUFFER_SIZE
) {
1135 tmp
= heap_realloc(This
->buf
, read
+This
->buf_size
);
1137 return E_OUTOFMEMORY
;
1141 memcpy(This
->buf
+This
->buf_size
, buf
, read
);
1142 This
->buf_size
+= read
;
1143 }while(This
->buf_size
< MIME_TEST_SIZE
&& hres
== S_OK
);
1145 if(This
->buf_size
< MIME_TEST_SIZE
&& hres
!= S_FALSE
)
1148 bscf
= BSCF_FIRSTDATANOTIFICATION
;
1150 bscf
|= BSCF_LASTDATANOTIFICATION
|BSCF_DATAFULLYAVAILABLE
;
1152 if(!This
->reported_mime
) {
1155 hres
= IUri_GetRawUri(This
->uri
, &raw_uri
);
1159 hres
= FindMimeFromData(NULL
, raw_uri
, This
->buf
, min(This
->buf_size
, MIME_TEST_SIZE
),
1160 This
->mime
, 0, &mime
, 0);
1161 SysFreeString(raw_uri
);
1165 mime_available(This
, mime
, TRUE
);
1166 CoTaskMemFree(mime
);
1170 if(!This
->protocol_sink
)
1173 return IInternetProtocolSink_ReportData(This
->protocol_sink
, bscf
, progress
, progress_max
);
1177 task_header_t header
;
1181 } report_data_task_t
;
1183 static void report_data_proc(BindProtocol
*This
, task_header_t
*t
)
1185 report_data_task_t
*task
= (report_data_task_t
*)t
;
1187 report_data(This
, task
->bscf
, task
->progress
, task
->progress_max
);
1191 static HRESULT WINAPI
BPInternetProtocolSink_ReportData(IInternetProtocolSink
*iface
,
1192 DWORD grfBSCF
, ULONG ulProgress
, ULONG ulProgressMax
)
1194 BindProtocol
*This
= PROTSINK_THIS(iface
);
1196 TRACE("(%p)->(%d %u %u)\n", This
, grfBSCF
, ulProgress
, ulProgressMax
);
1198 if(!This
->protocol_sink
)
1201 if(!do_direct_notif(This
)) {
1202 report_data_task_t
*task
;
1204 task
= heap_alloc(sizeof(report_data_task_t
));
1206 return E_OUTOFMEMORY
;
1208 task
->bscf
= grfBSCF
;
1209 task
->progress
= ulProgress
;
1210 task
->progress_max
= ulProgressMax
;
1212 push_task(This
, &task
->header
, report_data_proc
);
1216 return report_data(This
, grfBSCF
, ulProgress
, ulProgressMax
);
1220 task_header_t header
;
1225 } report_result_task_t
;
1227 static void report_result_proc(BindProtocol
*This
, task_header_t
*t
)
1229 report_result_task_t
*task
= (report_result_task_t
*)t
;
1231 if(This
->protocol_sink
)
1232 IInternetProtocolSink_ReportResult(This
->protocol_sink
, task
->hres
, task
->err
, task
->str
);
1234 heap_free(task
->str
);
1238 static HRESULT WINAPI
BPInternetProtocolSink_ReportResult(IInternetProtocolSink
*iface
,
1239 HRESULT hrResult
, DWORD dwError
, LPCWSTR szResult
)
1241 BindProtocol
*This
= PROTSINK_THIS(iface
);
1243 TRACE("(%p)->(%08x %d %s)\n", This
, hrResult
, dwError
, debugstr_w(szResult
));
1245 if(!This
->protocol_sink
)
1248 This
->reported_result
= TRUE
;
1250 if(!do_direct_notif(This
)) {
1251 report_result_task_t
*task
;
1253 task
= heap_alloc(sizeof(report_result_task_t
));
1255 return E_OUTOFMEMORY
;
1257 task
->hres
= hrResult
;
1258 task
->err
= dwError
;
1259 task
->str
= heap_strdupW(szResult
);
1261 push_task(This
, &task
->header
, report_result_proc
);
1265 return IInternetProtocolSink_ReportResult(This
->protocol_sink
, hrResult
, dwError
, szResult
);
1268 #undef PROTSINK_THIS
1270 static const IInternetProtocolSinkVtbl InternetProtocolSinkVtbl
= {
1271 BPInternetProtocolSink_QueryInterface
,
1272 BPInternetProtocolSink_AddRef
,
1273 BPInternetProtocolSink_Release
,
1274 BPInternetProtocolSink_Switch
,
1275 BPInternetProtocolSink_ReportProgress
,
1276 BPInternetProtocolSink_ReportData
,
1277 BPInternetProtocolSink_ReportResult
1280 #define INETINFO_THIS(iface) DEFINE_THIS(BindProtocol, IWinInetHttpInfo, iface)
1282 static HRESULT WINAPI
WinInetHttpInfo_QueryInterface(IWinInetHttpInfo
*iface
, REFIID riid
, void **ppv
)
1284 BindProtocol
*This
= INETINFO_THIS(iface
);
1285 return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This
), riid
, ppv
);
1288 static ULONG WINAPI
WinInetHttpInfo_AddRef(IWinInetHttpInfo
*iface
)
1290 BindProtocol
*This
= INETINFO_THIS(iface
);
1291 return IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
1294 static ULONG WINAPI
WinInetHttpInfo_Release(IWinInetHttpInfo
*iface
)
1296 BindProtocol
*This
= INETINFO_THIS(iface
);
1297 return IInternetProtocolEx_Release(PROTOCOLEX(This
));
1300 static HRESULT WINAPI
WinInetHttpInfo_QueryOption(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1301 void *pBuffer
, DWORD
*pcbBuffer
)
1303 BindProtocol
*This
= INETINFO_THIS(iface
);
1304 FIXME("(%p)->(%x %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
);
1308 static HRESULT WINAPI
WinInetHttpInfo_QueryInfo(IWinInetHttpInfo
*iface
, DWORD dwOption
,
1309 void *pBuffer
, DWORD
*pcbBuffer
, DWORD
*pdwFlags
, DWORD
*pdwReserved
)
1311 BindProtocol
*This
= INETINFO_THIS(iface
);
1312 FIXME("(%p)->(%x %p %p %p %p)\n", This
, dwOption
, pBuffer
, pcbBuffer
, pdwFlags
, pdwReserved
);
1316 #undef INETINFO_THIS
1318 static const IWinInetHttpInfoVtbl WinInetHttpInfoVtbl
= {
1319 WinInetHttpInfo_QueryInterface
,
1320 WinInetHttpInfo_AddRef
,
1321 WinInetHttpInfo_Release
,
1322 WinInetHttpInfo_QueryOption
,
1323 WinInetHttpInfo_QueryInfo
1326 #define SERVPROV_THIS(iface) DEFINE_THIS(BindProtocol, ServiceProvider, iface)
1328 static HRESULT WINAPI
BPServiceProvider_QueryInterface(IServiceProvider
*iface
,
1329 REFIID riid
, void **ppv
)
1331 BindProtocol
*This
= SERVPROV_THIS(iface
);
1332 return IInternetProtocolEx_QueryInterface(PROTOCOLEX(This
), riid
, ppv
);
1335 static ULONG WINAPI
BPServiceProvider_AddRef(IServiceProvider
*iface
)
1337 BindProtocol
*This
= SERVPROV_THIS(iface
);
1338 return IInternetProtocolEx_AddRef(PROTOCOLEX(This
));
1341 static ULONG WINAPI
BPServiceProvider_Release(IServiceProvider
*iface
)
1343 BindProtocol
*This
= SERVPROV_THIS(iface
);
1344 return IInternetProtocolEx_Release(PROTOCOLEX(This
));
1347 static HRESULT WINAPI
BPServiceProvider_QueryService(IServiceProvider
*iface
,
1348 REFGUID guidService
, REFIID riid
, void **ppv
)
1350 BindProtocol
*This
= SERVPROV_THIS(iface
);
1352 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1354 if(!This
->service_provider
)
1355 return E_NOINTERFACE
;
1357 return IServiceProvider_QueryService(This
->service_provider
, guidService
, riid
, ppv
);
1360 #undef SERVPROV_THIS
1362 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1363 BPServiceProvider_QueryInterface
,
1364 BPServiceProvider_AddRef
,
1365 BPServiceProvider_Release
,
1366 BPServiceProvider_QueryService
1369 HRESULT
create_binding_protocol(LPCWSTR url
, BOOL from_urlmon
, IInternetProtocol
**protocol
)
1371 BindProtocol
*ret
= heap_alloc_zero(sizeof(BindProtocol
));
1373 ret
->lpIInternetProtocolExVtbl
= &BindProtocolVtbl
;
1374 ret
->lpInternetBindInfoVtbl
= &InternetBindInfoVtbl
;
1375 ret
->lpInternetPriorityVtbl
= &InternetPriorityVtbl
;
1376 ret
->lpServiceProviderVtbl
= &ServiceProviderVtbl
;
1377 ret
->lpIInternetProtocolSinkVtbl
= &InternetProtocolSinkVtbl
;
1378 ret
->lpIInternetProtocolHandlerVtbl
= &InternetProtocolHandlerVtbl
;
1379 ret
->lpIWinInetHttpInfoVtbl
= &WinInetHttpInfoVtbl
;
1382 ret
->from_urlmon
= from_urlmon
;
1383 ret
->apartment_thread
= GetCurrentThreadId();
1384 ret
->notif_hwnd
= get_notif_hwnd();
1385 ret
->protocol_handler
= (IInternetProtocol
*)PROTOCOLHANDLER(ret
);
1386 InitializeCriticalSection(&ret
->section
);
1388 URLMON_LockModule();
1390 *protocol
= (IInternetProtocol
*)PROTOCOLEX(ret
);