2 * Copyright 2007 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
21 #include "urlmon_main.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
26 static WCHAR bscb_holderW
[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
28 extern IID IID_IBindStatusCallbackHolder
;
31 IBindStatusCallbackEx IBindStatusCallbackEx_iface
;
32 IInternetBindInfo IInternetBindInfo_iface
;
33 IServiceProvider IServiceProvider_iface
;
34 IHttpNegotiate2 IHttpNegotiate2_iface
;
35 IAuthenticate IAuthenticate_iface
;
39 IBindStatusCallback
*callback
;
40 IServiceProvider
*serv_prov
;
43 static void *get_callback_iface(BindStatusCallback
*This
, REFIID riid
)
48 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, (void**)&ret
);
49 if(FAILED(hres
) && This
->serv_prov
)
50 hres
= IServiceProvider_QueryService(This
->serv_prov
, riid
, riid
, &ret
);
52 return SUCCEEDED(hres
) ? ret
: NULL
;
55 static IBindStatusCallback
*bsch_from_bctx(IBindCtx
*bctx
)
57 IBindStatusCallback
*bsc
;
61 hres
= IBindCtx_GetObjectParam(bctx
, bscb_holderW
, &unk
);
65 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&bsc
);
66 IUnknown_Release(unk
);
67 return SUCCEEDED(hres
) ? bsc
: NULL
;
70 IBindStatusCallback
*bsc_from_bctx(IBindCtx
*bctx
)
72 BindStatusCallback
*holder
;
73 IBindStatusCallback
*bsc
;
76 bsc
= bsch_from_bctx(bctx
);
80 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
84 if(holder
->callback
) {
85 IBindStatusCallback_Release(bsc
);
86 bsc
= holder
->callback
;
87 IBindStatusCallback_AddRef(bsc
);
90 IBindStatusCallbackEx_Release(&holder
->IBindStatusCallbackEx_iface
);
94 static inline BindStatusCallback
*impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx
*iface
)
96 return CONTAINING_RECORD(iface
, BindStatusCallback
, IBindStatusCallbackEx_iface
);
99 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallbackEx
*iface
,
100 REFIID riid
, void **ppv
)
102 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
106 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
107 TRACE("(%p)->(IID_IUnknown, %p)\n", This
, ppv
);
108 *ppv
= &This
->IBindStatusCallbackEx_iface
;
109 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
110 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
111 *ppv
= &This
->IBindStatusCallbackEx_iface
;
112 }else if(IsEqualGUID(&IID_IBindStatusCallbackEx
, riid
)) {
113 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
114 *ppv
= &This
->IBindStatusCallbackEx_iface
;
115 }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder
, riid
)) {
116 TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This
, ppv
);
118 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
119 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This
, ppv
);
120 *ppv
= &This
->IServiceProvider_iface
;
121 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
122 TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This
, ppv
);
123 *ppv
= &This
->IHttpNegotiate2_iface
;
124 }else if(IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
125 TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This
, ppv
);
126 *ppv
= &This
->IHttpNegotiate2_iface
;
127 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
128 TRACE("(%p)->(IID_IAuthenticate, %p)\n", This
, ppv
);
129 *ppv
= &This
->IAuthenticate_iface
;
130 }else if(IsEqualGUID(&IID_IInternetBindInfo
, riid
)) {
131 TRACE("(%p)->(IID_IInternetBindInfo, %p)\n", This
, ppv
);
132 *ppv
= &This
->IInternetBindInfo_iface
;
136 IUnknown_AddRef((IUnknown
*)*ppv
);
140 TRACE("Unsupported riid = %s\n", debugstr_guid(riid
));
141 return E_NOINTERFACE
;
144 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallbackEx
*iface
)
146 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
147 LONG ref
= InterlockedIncrement(&This
->ref
);
149 TRACE("(%p) ref = %d\n", This
, ref
);
154 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallbackEx
*iface
)
156 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
157 LONG ref
= InterlockedDecrement(&This
->ref
);
159 TRACE("(%p) ref = %d\n", This
, ref
);
163 IServiceProvider_Release(This
->serv_prov
);
164 IBindStatusCallback_Release(This
->callback
);
171 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallbackEx
*iface
,
172 DWORD dwReserved
, IBinding
*pbind
)
174 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
176 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
178 return IBindStatusCallback_OnStartBinding(This
->callback
, 0xff, pbind
);
181 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallbackEx
*iface
, LONG
*pnPriority
)
183 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
185 TRACE("(%p)->(%p)\n", This
, pnPriority
);
187 return IBindStatusCallback_GetPriority(This
->callback
, pnPriority
);
190 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallbackEx
*iface
, DWORD reserved
)
192 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
194 TRACE("(%p)->(%d)\n", This
, reserved
);
196 return IBindStatusCallback_OnLowResource(This
->callback
, reserved
);
199 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallbackEx
*iface
, ULONG ulProgress
,
200 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
202 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
204 TRACE("%p)->(%u %u %s %s)\n", This
, ulProgress
, ulProgressMax
, debugstr_bindstatus(ulStatusCode
),
205 debugstr_w(szStatusText
));
207 return IBindStatusCallback_OnProgress(This
->callback
, ulProgress
,
208 ulProgressMax
, ulStatusCode
, szStatusText
);
211 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallbackEx
*iface
,
212 HRESULT hresult
, LPCWSTR szError
)
214 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
216 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
218 return IBindStatusCallback_OnStopBinding(This
->callback
, hresult
, szError
);
221 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallbackEx
*iface
,
222 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
224 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
225 IBindStatusCallbackEx
*bscex
;
228 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
230 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
231 if(SUCCEEDED(hres
)) {
232 DWORD bindf2
= 0, reserv
= 0;
234 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, &bindf2
, &reserv
);
235 IBindStatusCallbackEx_Release(bscex
);
237 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
243 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx
*iface
,
244 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
246 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
248 TRACE("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
250 return IBindStatusCallback_OnDataAvailable(This
->callback
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
253 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx
*iface
,
254 REFIID riid
, IUnknown
*punk
)
256 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
258 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
260 return IBindStatusCallback_OnObjectAvailable(This
->callback
, riid
, punk
);
263 static HRESULT WINAPI
BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx
*iface
, DWORD
*grfBINDF
,
264 BINDINFO
*pbindinfo
, DWORD
*grfBINDF2
, DWORD
*pdwReserved
)
266 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
267 IBindStatusCallbackEx
*bscex
;
270 TRACE("(%p)->(%p %p %p %p)\n", This
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
272 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
273 if(SUCCEEDED(hres
)) {
274 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
275 IBindStatusCallbackEx_Release(bscex
);
277 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
283 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl
= {
284 BindStatusCallback_QueryInterface
,
285 BindStatusCallback_AddRef
,
286 BindStatusCallback_Release
,
287 BindStatusCallback_OnStartBinding
,
288 BindStatusCallback_GetPriority
,
289 BindStatusCallback_OnLowResource
,
290 BindStatusCallback_OnProgress
,
291 BindStatusCallback_OnStopBinding
,
292 BindStatusCallback_GetBindInfo
,
293 BindStatusCallback_OnDataAvailable
,
294 BindStatusCallback_OnObjectAvailable
,
295 BindStatusCallback_GetBindInfoEx
298 static inline BindStatusCallback
*impl_from_IServiceProvider(IServiceProvider
*iface
)
300 return CONTAINING_RECORD(iface
, BindStatusCallback
, IServiceProvider_iface
);
303 static HRESULT WINAPI
BSCServiceProvider_QueryInterface(IServiceProvider
*iface
,
304 REFIID riid
, void **ppv
)
306 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
307 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
310 static ULONG WINAPI
BSCServiceProvider_AddRef(IServiceProvider
*iface
)
312 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
313 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
316 static ULONG WINAPI
BSCServiceProvider_Release(IServiceProvider
*iface
)
318 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
319 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
322 static HRESULT WINAPI
BSCServiceProvider_QueryService(IServiceProvider
*iface
,
323 REFGUID guidService
, REFIID riid
, void **ppv
)
325 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
328 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
)) {
329 TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
330 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
333 if(IsEqualGUID(&IID_IHttpNegotiate2
, guidService
)) {
334 TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This
, debugstr_guid(riid
), ppv
);
335 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
338 if(IsEqualGUID(&IID_IAuthenticate
, guidService
)) {
339 TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
340 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
343 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
345 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, ppv
);
349 if(This
->serv_prov
) {
350 hres
= IServiceProvider_QueryService(This
->serv_prov
, guidService
, riid
, ppv
);
355 return E_NOINTERFACE
;
358 static const IServiceProviderVtbl BSCServiceProviderVtbl
= {
359 BSCServiceProvider_QueryInterface
,
360 BSCServiceProvider_AddRef
,
361 BSCServiceProvider_Release
,
362 BSCServiceProvider_QueryService
365 static inline BindStatusCallback
*impl_from_IHttpNegotiate2(IHttpNegotiate2
*iface
)
367 return CONTAINING_RECORD(iface
, BindStatusCallback
, IHttpNegotiate2_iface
);
370 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
,
371 REFIID riid
, void **ppv
)
373 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
374 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
377 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
379 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
380 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
383 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate2
*iface
)
385 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
386 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
389 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
,
390 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
392 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
393 IHttpNegotiate
*http_negotiate
;
396 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
), dwReserved
,
397 pszAdditionalHeaders
);
399 *pszAdditionalHeaders
= NULL
;
401 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
403 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, szURL
, szHeaders
,
404 dwReserved
, pszAdditionalHeaders
);
405 IHttpNegotiate_Release(http_negotiate
);
411 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
412 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
413 LPWSTR
*pszAdditionalRequestHeaders
)
415 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
416 LPWSTR additional_headers
= NULL
;
417 IHttpNegotiate
*http_negotiate
;
420 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
421 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
423 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
425 hres
= IHttpNegotiate_OnResponse(http_negotiate
, dwResponseCode
, szResponseHeaders
,
426 szRequestHeaders
, &additional_headers
);
427 IHttpNegotiate_Release(http_negotiate
);
430 if(pszAdditionalRequestHeaders
)
431 *pszAdditionalRequestHeaders
= additional_headers
;
433 CoTaskMemFree(additional_headers
);
438 static HRESULT WINAPI
BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
439 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
441 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
442 IHttpNegotiate2
*http_negotiate2
;
443 HRESULT hres
= E_FAIL
;
445 TRACE("(%p)->(%p %p %ld)\n", This
, pbSecurityId
, pcbSecurityId
, dwReserved
);
447 http_negotiate2
= get_callback_iface(This
, &IID_IHttpNegotiate2
);
448 if(http_negotiate2
) {
449 hres
= IHttpNegotiate2_GetRootSecurityId(http_negotiate2
, pbSecurityId
,
450 pcbSecurityId
, dwReserved
);
451 IHttpNegotiate2_Release(http_negotiate2
);
457 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl
= {
458 BSCHttpNegotiate_QueryInterface
,
459 BSCHttpNegotiate_AddRef
,
460 BSCHttpNegotiate_Release
,
461 BSCHttpNegotiate_BeginningTransaction
,
462 BSCHttpNegotiate_OnResponse
,
463 BSCHttpNegotiate_GetRootSecurityId
466 static inline BindStatusCallback
*impl_from_IAuthenticate(IAuthenticate
*iface
)
468 return CONTAINING_RECORD(iface
, BindStatusCallback
, IAuthenticate_iface
);
471 static HRESULT WINAPI
BSCAuthenticate_QueryInterface(IAuthenticate
*iface
, REFIID riid
, void **ppv
)
473 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
474 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
477 static ULONG WINAPI
BSCAuthenticate_AddRef(IAuthenticate
*iface
)
479 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
480 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
483 static ULONG WINAPI
BSCAuthenticate_Release(IAuthenticate
*iface
)
485 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
486 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
489 static HRESULT WINAPI
BSCAuthenticate_Authenticate(IAuthenticate
*iface
,
490 HWND
*phwnd
, LPWSTR
*pszUsername
, LPWSTR
*pszPassword
)
492 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
493 FIXME("(%p)->(%p %p %p)\n", This
, phwnd
, pszUsername
, pszPassword
);
497 static const IAuthenticateVtbl BSCAuthenticateVtbl
= {
498 BSCAuthenticate_QueryInterface
,
499 BSCAuthenticate_AddRef
,
500 BSCAuthenticate_Release
,
501 BSCAuthenticate_Authenticate
504 static inline BindStatusCallback
*impl_from_IInternetBindInfo(IInternetBindInfo
*iface
)
506 return CONTAINING_RECORD(iface
, BindStatusCallback
, IInternetBindInfo_iface
);
509 static HRESULT WINAPI
BSCInternetBindInfo_QueryInterface(IInternetBindInfo
*iface
, REFIID riid
, void **ppv
)
511 BindStatusCallback
*This
= impl_from_IInternetBindInfo(iface
);
512 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
515 static ULONG WINAPI
BSCInternetBindInfo_AddRef(IInternetBindInfo
*iface
)
517 BindStatusCallback
*This
= impl_from_IInternetBindInfo(iface
);
518 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
521 static ULONG WINAPI
BSCInternetBindInfo_Release(IInternetBindInfo
*iface
)
523 BindStatusCallback
*This
= impl_from_IInternetBindInfo(iface
);
524 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
527 static HRESULT WINAPI
BSCInternetBindInfo_GetBindInfo(IInternetBindInfo
*iface
, DWORD
*bindf
, BINDINFO
*bindinfo
)
529 BindStatusCallback
*This
= impl_from_IInternetBindInfo(iface
);
530 FIXME("(%p)->(%p %p)\n", This
, bindf
, bindinfo
);
534 static HRESULT WINAPI
BSCInternetBindInfo_GetBindString(IInternetBindInfo
*iface
, ULONG string_type
,
535 WCHAR
**strs
, ULONG cnt
, ULONG
*fetched
)
537 BindStatusCallback
*This
= impl_from_IInternetBindInfo(iface
);
538 IInternetBindInfo
*bind_info
;
541 TRACE("(%p)->(%d %p %d %p)\n", This
, string_type
, strs
, cnt
, fetched
);
543 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IInternetBindInfo
, (void**)&bind_info
);
547 hres
= IInternetBindInfo_GetBindString(bind_info
, string_type
, strs
, cnt
, fetched
);
549 IInternetBindInfo_Release(bind_info
);
553 static IInternetBindInfoVtbl BSCInternetBindInfoVtbl
= {
554 BSCInternetBindInfo_QueryInterface
,
555 BSCInternetBindInfo_AddRef
,
556 BSCInternetBindInfo_Release
,
557 BSCInternetBindInfo_GetBindInfo
,
558 BSCInternetBindInfo_GetBindString
561 static void set_callback(BindStatusCallback
*This
, IBindStatusCallback
*bsc
)
563 IServiceProvider
*serv_prov
;
567 IBindStatusCallback_Release(This
->callback
);
569 IServiceProvider_Release(This
->serv_prov
);
571 IBindStatusCallback_AddRef(bsc
);
572 This
->callback
= bsc
;
574 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IServiceProvider
, (void**)&serv_prov
);
575 This
->serv_prov
= hres
== S_OK
? serv_prov
: NULL
;
578 HRESULT
wrap_callback(IBindStatusCallback
*bsc
, IBindStatusCallback
**ret_iface
)
580 BindStatusCallback
*ret
;
582 ret
= heap_alloc_zero(sizeof(BindStatusCallback
));
584 return E_OUTOFMEMORY
;
586 ret
->IBindStatusCallbackEx_iface
.lpVtbl
= &BindStatusCallbackExVtbl
;
587 ret
->IInternetBindInfo_iface
.lpVtbl
= &BSCInternetBindInfoVtbl
;
588 ret
->IServiceProvider_iface
.lpVtbl
= &BSCServiceProviderVtbl
;
589 ret
->IHttpNegotiate2_iface
.lpVtbl
= &BSCHttpNegotiateVtbl
;
590 ret
->IAuthenticate_iface
.lpVtbl
= &BSCAuthenticateVtbl
;
593 set_callback(ret
, bsc
);
595 *ret_iface
= (IBindStatusCallback
*)&ret
->IBindStatusCallbackEx_iface
;
599 /***********************************************************************
600 * RegisterBindStatusCallback (urlmon.@)
602 * Register a bind status callback.
605 * pbc [I] Binding context
606 * pbsc [I] Callback to register
607 * ppbscPrevious [O] Destination for previous callback
608 * dwReserved [I] Reserved, must be 0.
612 * Failure: E_INVALIDARG, if any argument is invalid, or
613 * E_OUTOFMEMORY if memory allocation fails.
615 HRESULT WINAPI
RegisterBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
,
616 IBindStatusCallback
**ppbscPrevious
, DWORD dwReserved
)
618 BindStatusCallback
*holder
;
619 IBindStatusCallback
*bsc
, *prev
= NULL
;
622 TRACE("(%p %p %p %x)\n", pbc
, pbsc
, ppbscPrevious
, dwReserved
);
627 bsc
= bsch_from_bctx(pbc
);
629 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
630 if(SUCCEEDED(hres
)) {
632 IBindStatusCallback_AddRef(holder
->callback
);
633 *ppbscPrevious
= holder
->callback
;
636 set_callback(holder
, pbsc
);
638 IBindStatusCallback_Release(bsc
);
639 IBindStatusCallbackEx_Release(&holder
->IBindStatusCallbackEx_iface
);
645 IBindCtx_RevokeObjectParam(pbc
, bscb_holderW
);
648 hres
= wrap_callback(pbsc
, &bsc
);
649 if(SUCCEEDED(hres
)) {
650 hres
= IBindCtx_RegisterObjectParam(pbc
, bscb_holderW
, (IUnknown
*)bsc
);
651 IBindStatusCallback_Release(bsc
);
655 IBindStatusCallback_Release(prev
);
660 *ppbscPrevious
= prev
;
664 /***********************************************************************
665 * RevokeBindStatusCallback (URLMON.@)
667 * Unregister a bind status callback.
669 * pbc [I] Binding context
670 * pbsc [I] Callback to unregister
674 * Failure: E_INVALIDARG, if any argument is invalid
676 HRESULT WINAPI
RevokeBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
)
678 IBindStatusCallback
*callback
;
680 TRACE("(%p %p)\n", pbc
, pbsc
);
685 callback
= bsc_from_bctx(pbc
);
690 IBindCtx_RevokeObjectParam(pbc
, bscb_holderW
);
692 IBindStatusCallback_Release(callback
);
697 IBindCtx IBindCtx_iface
;
704 static inline AsyncBindCtx
*impl_from_IBindCtx(IBindCtx
*iface
)
706 return CONTAINING_RECORD(iface
, AsyncBindCtx
, IBindCtx_iface
);
709 static HRESULT WINAPI
AsyncBindCtx_QueryInterface(IBindCtx
*iface
, REFIID riid
, void **ppv
)
711 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
715 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
716 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
717 *ppv
= &This
->IBindCtx_iface
;
718 }else if(IsEqualGUID(riid
, &IID_IBindCtx
)) {
719 TRACE("(%p)->(IID_IBindCtx %p)\n", This
, ppv
);
720 *ppv
= &This
->IBindCtx_iface
;
721 }else if(IsEqualGUID(riid
, &IID_IAsyncBindCtx
)) {
722 TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This
, ppv
);
723 *ppv
= &This
->IBindCtx_iface
;
727 IUnknown_AddRef((IUnknown
*)*ppv
);
731 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
732 return E_NOINTERFACE
;
735 static ULONG WINAPI
AsyncBindCtx_AddRef(IBindCtx
*iface
)
737 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
738 LONG ref
= InterlockedIncrement(&This
->ref
);
740 TRACE("(%p) ref=%d\n", This
, ref
);
745 static ULONG WINAPI
AsyncBindCtx_Release(IBindCtx
*iface
)
747 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
748 LONG ref
= InterlockedDecrement(&This
->ref
);
750 TRACE("(%p) ref=%d\n", This
, ref
);
753 IBindCtx_Release(This
->bindctx
);
760 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
762 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
764 TRACE("(%p)->(%p)\n", This
, punk
);
766 return IBindCtx_RegisterObjectBound(This
->bindctx
, punk
);
769 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
771 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
773 TRACE("(%p %p)\n", This
, punk
);
775 return IBindCtx_RevokeObjectBound(This
->bindctx
, punk
);
778 static HRESULT WINAPI
AsyncBindCtx_ReleaseBoundObjects(IBindCtx
*iface
)
780 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
782 TRACE("(%p)\n", This
);
784 return IBindCtx_ReleaseBoundObjects(This
->bindctx
);
787 static HRESULT WINAPI
AsyncBindCtx_SetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
789 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
791 TRACE("(%p)->(%p)\n", This
, pbindopts
);
793 return IBindCtx_SetBindOptions(This
->bindctx
, pbindopts
);
796 static HRESULT WINAPI
AsyncBindCtx_GetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
798 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
800 TRACE("(%p)->(%p)\n", This
, pbindopts
);
802 return IBindCtx_GetBindOptions(This
->bindctx
, pbindopts
);
805 static HRESULT WINAPI
AsyncBindCtx_GetRunningObjectTable(IBindCtx
*iface
, IRunningObjectTable
**pprot
)
807 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
809 TRACE("(%p)->(%p)\n", This
, pprot
);
811 return IBindCtx_GetRunningObjectTable(This
->bindctx
, pprot
);
814 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
, IUnknown
*punk
)
816 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
818 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
820 return IBindCtx_RegisterObjectParam(This
->bindctx
, pszkey
, punk
);
823 static HRESULT WINAPI
AsyncBindCtx_GetObjectParam(IBindCtx
* iface
, LPOLESTR pszkey
, IUnknown
**punk
)
825 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
827 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
829 return IBindCtx_GetObjectParam(This
->bindctx
, pszkey
, punk
);
832 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
)
834 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
836 TRACE("(%p)->(%s)\n", This
, debugstr_w(pszkey
));
838 return IBindCtx_RevokeObjectParam(This
->bindctx
, pszkey
);
841 static HRESULT WINAPI
AsyncBindCtx_EnumObjectParam(IBindCtx
*iface
, IEnumString
**pszkey
)
843 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
845 TRACE("(%p)->(%p)\n", This
, pszkey
);
847 return IBindCtx_EnumObjectParam(This
->bindctx
, pszkey
);
850 static const IBindCtxVtbl AsyncBindCtxVtbl
=
852 AsyncBindCtx_QueryInterface
,
854 AsyncBindCtx_Release
,
855 AsyncBindCtx_RegisterObjectBound
,
856 AsyncBindCtx_RevokeObjectBound
,
857 AsyncBindCtx_ReleaseBoundObjects
,
858 AsyncBindCtx_SetBindOptions
,
859 AsyncBindCtx_GetBindOptions
,
860 AsyncBindCtx_GetRunningObjectTable
,
861 AsyncBindCtx_RegisterObjectParam
,
862 AsyncBindCtx_GetObjectParam
,
863 AsyncBindCtx_EnumObjectParam
,
864 AsyncBindCtx_RevokeObjectParam
867 static HRESULT
init_bindctx(IBindCtx
*bindctx
, DWORD options
,
868 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
)
874 FIXME("not supported options %08x\n", options
);
876 FIXME("format is not supported\n");
878 bindopts
.cbStruct
= sizeof(BIND_OPTS
);
879 bindopts
.grfFlags
= BIND_MAYBOTHERUSER
;
880 bindopts
.grfMode
= STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
;
881 bindopts
.dwTickCountDeadline
= 0;
883 hres
= IBindCtx_SetBindOptions(bindctx
, &bindopts
);
888 hres
= RegisterBindStatusCallback(bindctx
, callback
, NULL
, 0);
896 /***********************************************************************
897 * CreateAsyncBindCtx (urlmon.@)
899 HRESULT WINAPI
CreateAsyncBindCtx(DWORD reserved
, IBindStatusCallback
*callback
,
900 IEnumFORMATETC
*format
, IBindCtx
**pbind
)
905 TRACE("(%08x %p %p %p)\n", reserved
, callback
, format
, pbind
);
907 if(!pbind
|| !callback
)
910 hres
= CreateBindCtx(0, &bindctx
);
914 hres
= init_bindctx(bindctx
, 0, callback
, format
);
916 IBindCtx_Release(bindctx
);
924 /***********************************************************************
925 * CreateAsyncBindCtxEx (urlmon.@)
927 * Create an asynchronous bind context.
929 HRESULT WINAPI
CreateAsyncBindCtxEx(IBindCtx
*ibind
, DWORD options
,
930 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
, IBindCtx
** pbind
,
937 TRACE("(%p %08x %p %p %p %d)\n", ibind
, options
, callback
, format
, pbind
, reserved
);
943 WARN("reserved=%d\n", reserved
);
946 IBindCtx_AddRef(ibind
);
949 hres
= CreateBindCtx(0, &bindctx
);
954 ret
= heap_alloc(sizeof(AsyncBindCtx
));
956 ret
->IBindCtx_iface
.lpVtbl
= &AsyncBindCtxVtbl
;
958 ret
->bindctx
= bindctx
;
960 hres
= init_bindctx(&ret
->IBindCtx_iface
, options
, callback
, format
);
962 IBindCtx_Release(&ret
->IBindCtx_iface
);
966 *pbind
= &ret
->IBindCtx_iface
;