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 IServiceProvider IServiceProvider_iface
;
33 IHttpNegotiate2 IHttpNegotiate2_iface
;
34 IAuthenticate IAuthenticate_iface
;
38 IBindStatusCallback
*callback
;
39 IServiceProvider
*serv_prov
;
42 static void *get_callback_iface(BindStatusCallback
*This
, REFIID riid
)
47 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, (void**)&ret
);
48 if(FAILED(hres
) && This
->serv_prov
)
49 hres
= IServiceProvider_QueryService(This
->serv_prov
, riid
, riid
, &ret
);
51 return SUCCEEDED(hres
) ? ret
: NULL
;
54 static IBindStatusCallback
*bsch_from_bctx(IBindCtx
*bctx
)
56 IBindStatusCallback
*bsc
;
60 hres
= IBindCtx_GetObjectParam(bctx
, bscb_holderW
, &unk
);
64 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&bsc
);
65 IUnknown_Release(unk
);
66 return SUCCEEDED(hres
) ? bsc
: NULL
;
69 IBindStatusCallback
*bsc_from_bctx(IBindCtx
*bctx
)
71 BindStatusCallback
*holder
;
72 IBindStatusCallback
*bsc
;
75 bsc
= bsch_from_bctx(bctx
);
79 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
83 if(holder
->callback
) {
84 IBindStatusCallback_Release(bsc
);
85 bsc
= holder
->callback
;
86 IBindStatusCallback_AddRef(bsc
);
89 IBindStatusCallbackEx_Release(&holder
->IBindStatusCallbackEx_iface
);
93 static inline BindStatusCallback
*impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx
*iface
)
95 return CONTAINING_RECORD(iface
, BindStatusCallback
, IBindStatusCallbackEx_iface
);
98 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallbackEx
*iface
,
99 REFIID riid
, void **ppv
)
101 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
105 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
106 TRACE("(%p)->(IID_IUnknown, %p)\n", This
, ppv
);
107 *ppv
= &This
->IBindStatusCallbackEx_iface
;
108 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
109 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
110 *ppv
= &This
->IBindStatusCallbackEx_iface
;
111 }else if(IsEqualGUID(&IID_IBindStatusCallbackEx
, riid
)) {
112 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
113 *ppv
= &This
->IBindStatusCallbackEx_iface
;
114 }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder
, riid
)) {
115 TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This
, ppv
);
117 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
118 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This
, ppv
);
119 *ppv
= &This
->IServiceProvider_iface
;
120 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
121 TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This
, ppv
);
122 *ppv
= &This
->IHttpNegotiate2_iface
;
123 }else if(IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
124 TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This
, ppv
);
125 *ppv
= &This
->IHttpNegotiate2_iface
;
126 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
127 TRACE("(%p)->(IID_IAuthenticate, %p)\n", This
, ppv
);
128 *ppv
= &This
->IAuthenticate_iface
;
132 IUnknown_AddRef((IUnknown
*)*ppv
);
136 TRACE("Unsupported riid = %s\n", debugstr_guid(riid
));
137 return E_NOINTERFACE
;
140 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallbackEx
*iface
)
142 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
143 LONG ref
= InterlockedIncrement(&This
->ref
);
145 TRACE("(%p) ref = %d\n", This
, ref
);
150 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallbackEx
*iface
)
152 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
153 LONG ref
= InterlockedDecrement(&This
->ref
);
155 TRACE("(%p) ref = %d\n", This
, ref
);
159 IServiceProvider_Release(This
->serv_prov
);
160 IBindStatusCallback_Release(This
->callback
);
167 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallbackEx
*iface
,
168 DWORD dwReserved
, IBinding
*pbind
)
170 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
172 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
174 return IBindStatusCallback_OnStartBinding(This
->callback
, 0xff, pbind
);
177 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallbackEx
*iface
, LONG
*pnPriority
)
179 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
181 TRACE("(%p)->(%p)\n", This
, pnPriority
);
183 return IBindStatusCallback_GetPriority(This
->callback
, pnPriority
);
186 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallbackEx
*iface
, DWORD reserved
)
188 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
190 TRACE("(%p)->(%d)\n", This
, reserved
);
192 return IBindStatusCallback_OnLowResource(This
->callback
, reserved
);
195 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallbackEx
*iface
, ULONG ulProgress
,
196 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
198 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
200 TRACE("%p)->(%u %u %s %s)\n", This
, ulProgress
, ulProgressMax
, debugstr_bindstatus(ulStatusCode
),
201 debugstr_w(szStatusText
));
203 return IBindStatusCallback_OnProgress(This
->callback
, ulProgress
,
204 ulProgressMax
, ulStatusCode
, szStatusText
);
207 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallbackEx
*iface
,
208 HRESULT hresult
, LPCWSTR szError
)
210 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
212 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
214 return IBindStatusCallback_OnStopBinding(This
->callback
, hresult
, szError
);
217 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallbackEx
*iface
,
218 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
220 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
221 IBindStatusCallbackEx
*bscex
;
224 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
226 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
227 if(SUCCEEDED(hres
)) {
228 DWORD bindf2
= 0, reserv
= 0;
230 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, &bindf2
, &reserv
);
231 IBindStatusCallbackEx_Release(bscex
);
233 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
239 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx
*iface
,
240 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
242 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
244 TRACE("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
246 return IBindStatusCallback_OnDataAvailable(This
->callback
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
249 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx
*iface
,
250 REFIID riid
, IUnknown
*punk
)
252 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
254 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
256 return IBindStatusCallback_OnObjectAvailable(This
->callback
, riid
, punk
);
259 static HRESULT WINAPI
BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx
*iface
, DWORD
*grfBINDF
,
260 BINDINFO
*pbindinfo
, DWORD
*grfBINDF2
, DWORD
*pdwReserved
)
262 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
263 IBindStatusCallbackEx
*bscex
;
266 TRACE("(%p)->(%p %p %p %p)\n", This
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
268 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
269 if(SUCCEEDED(hres
)) {
270 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
271 IBindStatusCallbackEx_Release(bscex
);
273 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
279 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl
= {
280 BindStatusCallback_QueryInterface
,
281 BindStatusCallback_AddRef
,
282 BindStatusCallback_Release
,
283 BindStatusCallback_OnStartBinding
,
284 BindStatusCallback_GetPriority
,
285 BindStatusCallback_OnLowResource
,
286 BindStatusCallback_OnProgress
,
287 BindStatusCallback_OnStopBinding
,
288 BindStatusCallback_GetBindInfo
,
289 BindStatusCallback_OnDataAvailable
,
290 BindStatusCallback_OnObjectAvailable
,
291 BindStatusCallback_GetBindInfoEx
294 static inline BindStatusCallback
*impl_from_IServiceProvider(IServiceProvider
*iface
)
296 return CONTAINING_RECORD(iface
, BindStatusCallback
, IServiceProvider_iface
);
299 static HRESULT WINAPI
BSCServiceProvider_QueryInterface(IServiceProvider
*iface
,
300 REFIID riid
, void **ppv
)
302 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
303 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
306 static ULONG WINAPI
BSCServiceProvider_AddRef(IServiceProvider
*iface
)
308 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
309 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
312 static ULONG WINAPI
BSCServiceProvider_Release(IServiceProvider
*iface
)
314 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
315 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
318 static HRESULT WINAPI
BSCServiceProvider_QueryService(IServiceProvider
*iface
,
319 REFGUID guidService
, REFIID riid
, void **ppv
)
321 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
324 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
)) {
325 TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
326 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
329 if(IsEqualGUID(&IID_IHttpNegotiate2
, guidService
)) {
330 TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This
, debugstr_guid(riid
), ppv
);
331 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
334 if(IsEqualGUID(&IID_IAuthenticate
, guidService
)) {
335 TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
336 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
339 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
341 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, ppv
);
345 if(This
->serv_prov
) {
346 hres
= IServiceProvider_QueryService(This
->serv_prov
, guidService
, riid
, ppv
);
351 return E_NOINTERFACE
;
354 static const IServiceProviderVtbl BSCServiceProviderVtbl
= {
355 BSCServiceProvider_QueryInterface
,
356 BSCServiceProvider_AddRef
,
357 BSCServiceProvider_Release
,
358 BSCServiceProvider_QueryService
361 static inline BindStatusCallback
*impl_from_IHttpNegotiate2(IHttpNegotiate2
*iface
)
363 return CONTAINING_RECORD(iface
, BindStatusCallback
, IHttpNegotiate2_iface
);
366 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
,
367 REFIID riid
, void **ppv
)
369 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
370 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
373 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
375 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
376 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
379 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate2
*iface
)
381 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
382 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
385 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
,
386 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
388 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
389 IHttpNegotiate
*http_negotiate
;
392 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
), dwReserved
,
393 pszAdditionalHeaders
);
395 *pszAdditionalHeaders
= NULL
;
397 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
399 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, szURL
, szHeaders
,
400 dwReserved
, pszAdditionalHeaders
);
401 IHttpNegotiate_Release(http_negotiate
);
407 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
408 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
409 LPWSTR
*pszAdditionalRequestHeaders
)
411 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
412 LPWSTR additional_headers
= NULL
;
413 IHttpNegotiate
*http_negotiate
;
416 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
417 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
419 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
421 hres
= IHttpNegotiate_OnResponse(http_negotiate
, dwResponseCode
, szResponseHeaders
,
422 szRequestHeaders
, &additional_headers
);
423 IHttpNegotiate_Release(http_negotiate
);
426 if(pszAdditionalRequestHeaders
)
427 *pszAdditionalRequestHeaders
= additional_headers
;
428 else if(additional_headers
)
429 CoTaskMemFree(additional_headers
);
434 static HRESULT WINAPI
BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
435 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
437 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
438 IHttpNegotiate2
*http_negotiate2
;
439 HRESULT hres
= E_FAIL
;
441 TRACE("(%p)->(%p %p %ld)\n", This
, pbSecurityId
, pcbSecurityId
, dwReserved
);
443 http_negotiate2
= get_callback_iface(This
, &IID_IHttpNegotiate2
);
444 if(http_negotiate2
) {
445 hres
= IHttpNegotiate2_GetRootSecurityId(http_negotiate2
, pbSecurityId
,
446 pcbSecurityId
, dwReserved
);
447 IHttpNegotiate2_Release(http_negotiate2
);
453 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl
= {
454 BSCHttpNegotiate_QueryInterface
,
455 BSCHttpNegotiate_AddRef
,
456 BSCHttpNegotiate_Release
,
457 BSCHttpNegotiate_BeginningTransaction
,
458 BSCHttpNegotiate_OnResponse
,
459 BSCHttpNegotiate_GetRootSecurityId
462 static inline BindStatusCallback
*impl_from_IAuthenticate(IAuthenticate
*iface
)
464 return CONTAINING_RECORD(iface
, BindStatusCallback
, IAuthenticate_iface
);
467 static HRESULT WINAPI
BSCAuthenticate_QueryInterface(IAuthenticate
*iface
, REFIID riid
, void **ppv
)
469 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
470 return IBindStatusCallbackEx_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
473 static ULONG WINAPI
BSCAuthenticate_AddRef(IAuthenticate
*iface
)
475 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
476 return IBindStatusCallbackEx_AddRef(&This
->IBindStatusCallbackEx_iface
);
479 static ULONG WINAPI
BSCAuthenticate_Release(IAuthenticate
*iface
)
481 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
482 return IBindStatusCallbackEx_Release(&This
->IBindStatusCallbackEx_iface
);
485 static HRESULT WINAPI
BSCAuthenticate_Authenticate(IAuthenticate
*iface
,
486 HWND
*phwnd
, LPWSTR
*pszUsername
, LPWSTR
*pszPassword
)
488 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
489 FIXME("(%p)->(%p %p %p)\n", This
, phwnd
, pszUsername
, pszPassword
);
493 static const IAuthenticateVtbl BSCAuthenticateVtbl
= {
494 BSCAuthenticate_QueryInterface
,
495 BSCAuthenticate_AddRef
,
496 BSCAuthenticate_Release
,
497 BSCAuthenticate_Authenticate
500 static void set_callback(BindStatusCallback
*This
, IBindStatusCallback
*bsc
)
502 IServiceProvider
*serv_prov
;
506 IBindStatusCallback_Release(This
->callback
);
508 IServiceProvider_Release(This
->serv_prov
);
510 IBindStatusCallback_AddRef(bsc
);
511 This
->callback
= bsc
;
513 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IServiceProvider
, (void**)&serv_prov
);
514 This
->serv_prov
= hres
== S_OK
? serv_prov
: NULL
;
517 HRESULT
wrap_callback(IBindStatusCallback
*bsc
, IBindStatusCallback
**ret_iface
)
519 BindStatusCallback
*ret
;
521 ret
= heap_alloc_zero(sizeof(BindStatusCallback
));
523 return E_OUTOFMEMORY
;
525 ret
->IBindStatusCallbackEx_iface
.lpVtbl
= &BindStatusCallbackExVtbl
;
526 ret
->IServiceProvider_iface
.lpVtbl
= &BSCServiceProviderVtbl
;
527 ret
->IHttpNegotiate2_iface
.lpVtbl
= &BSCHttpNegotiateVtbl
;
528 ret
->IAuthenticate_iface
.lpVtbl
= &BSCAuthenticateVtbl
;
531 set_callback(ret
, bsc
);
533 *ret_iface
= (IBindStatusCallback
*)&ret
->IBindStatusCallbackEx_iface
;
537 /***********************************************************************
538 * RegisterBindStatusCallback (urlmon.@)
540 * Register a bind status callback.
543 * pbc [I] Binding context
544 * pbsc [I] Callback to register
545 * ppbscPrevious [O] Destination for previous callback
546 * dwReserved [I] Reserved, must be 0.
550 * Failure: E_INVALIDARG, if any argument is invalid, or
551 * E_OUTOFMEMORY if memory allocation fails.
553 HRESULT WINAPI
RegisterBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
,
554 IBindStatusCallback
**ppbscPrevious
, DWORD dwReserved
)
556 BindStatusCallback
*holder
;
557 IBindStatusCallback
*bsc
, *prev
= NULL
;
560 TRACE("(%p %p %p %x)\n", pbc
, pbsc
, ppbscPrevious
, dwReserved
);
565 bsc
= bsch_from_bctx(pbc
);
567 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
568 if(SUCCEEDED(hres
)) {
570 IBindStatusCallback_AddRef(holder
->callback
);
571 *ppbscPrevious
= holder
->callback
;
574 set_callback(holder
, pbsc
);
576 IBindStatusCallback_Release(bsc
);
577 IBindStatusCallbackEx_Release(&holder
->IBindStatusCallbackEx_iface
);
583 IBindCtx_RevokeObjectParam(pbc
, bscb_holderW
);
586 hres
= wrap_callback(pbsc
, &bsc
);
587 if(SUCCEEDED(hres
)) {
588 hres
= IBindCtx_RegisterObjectParam(pbc
, bscb_holderW
, (IUnknown
*)bsc
);
589 IBindStatusCallback_Release(bsc
);
593 IBindStatusCallback_Release(prev
);
598 *ppbscPrevious
= prev
;
602 /***********************************************************************
603 * RevokeBindStatusCallback (URLMON.@)
605 * Unregister a bind status callback.
607 * pbc [I] Binding context
608 * pbsc [I] Callback to unregister
612 * Failure: E_INVALIDARG, if any argument is invalid
614 HRESULT WINAPI
RevokeBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
)
616 IBindStatusCallback
*callback
;
618 TRACE("(%p %p)\n", pbc
, pbsc
);
623 callback
= bsc_from_bctx(pbc
);
628 IBindCtx_RevokeObjectParam(pbc
, bscb_holderW
);
630 IBindStatusCallback_Release(callback
);
635 IBindCtx IBindCtx_iface
;
642 static inline AsyncBindCtx
*impl_from_IBindCtx(IBindCtx
*iface
)
644 return CONTAINING_RECORD(iface
, AsyncBindCtx
, IBindCtx_iface
);
647 static HRESULT WINAPI
AsyncBindCtx_QueryInterface(IBindCtx
*iface
, REFIID riid
, void **ppv
)
649 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
653 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
654 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
655 *ppv
= &This
->IBindCtx_iface
;
656 }else if(IsEqualGUID(riid
, &IID_IBindCtx
)) {
657 TRACE("(%p)->(IID_IBindCtx %p)\n", This
, ppv
);
658 *ppv
= &This
->IBindCtx_iface
;
659 }else if(IsEqualGUID(riid
, &IID_IAsyncBindCtx
)) {
660 TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This
, ppv
);
661 *ppv
= &This
->IBindCtx_iface
;
665 IUnknown_AddRef((IUnknown
*)*ppv
);
669 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
670 return E_NOINTERFACE
;
673 static ULONG WINAPI
AsyncBindCtx_AddRef(IBindCtx
*iface
)
675 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
676 LONG ref
= InterlockedIncrement(&This
->ref
);
678 TRACE("(%p) ref=%d\n", This
, ref
);
683 static ULONG WINAPI
AsyncBindCtx_Release(IBindCtx
*iface
)
685 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
686 LONG ref
= InterlockedDecrement(&This
->ref
);
688 TRACE("(%p) ref=%d\n", This
, ref
);
691 IBindCtx_Release(This
->bindctx
);
698 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
700 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
702 TRACE("(%p)->(%p)\n", This
, punk
);
704 return IBindCtx_RegisterObjectBound(This
->bindctx
, punk
);
707 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
709 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
711 TRACE("(%p %p)\n", This
, punk
);
713 return IBindCtx_RevokeObjectBound(This
->bindctx
, punk
);
716 static HRESULT WINAPI
AsyncBindCtx_ReleaseBoundObjects(IBindCtx
*iface
)
718 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
720 TRACE("(%p)\n", This
);
722 return IBindCtx_ReleaseBoundObjects(This
->bindctx
);
725 static HRESULT WINAPI
AsyncBindCtx_SetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
727 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
729 TRACE("(%p)->(%p)\n", This
, pbindopts
);
731 return IBindCtx_SetBindOptions(This
->bindctx
, pbindopts
);
734 static HRESULT WINAPI
AsyncBindCtx_GetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
736 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
738 TRACE("(%p)->(%p)\n", This
, pbindopts
);
740 return IBindCtx_GetBindOptions(This
->bindctx
, pbindopts
);
743 static HRESULT WINAPI
AsyncBindCtx_GetRunningObjectTable(IBindCtx
*iface
, IRunningObjectTable
**pprot
)
745 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
747 TRACE("(%p)->(%p)\n", This
, pprot
);
749 return IBindCtx_GetRunningObjectTable(This
->bindctx
, pprot
);
752 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
, IUnknown
*punk
)
754 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
756 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
758 return IBindCtx_RegisterObjectParam(This
->bindctx
, pszkey
, punk
);
761 static HRESULT WINAPI
AsyncBindCtx_GetObjectParam(IBindCtx
* iface
, LPOLESTR pszkey
, IUnknown
**punk
)
763 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
765 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
767 return IBindCtx_GetObjectParam(This
->bindctx
, pszkey
, punk
);
770 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
)
772 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
774 TRACE("(%p)->(%s)\n", This
, debugstr_w(pszkey
));
776 return IBindCtx_RevokeObjectParam(This
->bindctx
, pszkey
);
779 static HRESULT WINAPI
AsyncBindCtx_EnumObjectParam(IBindCtx
*iface
, IEnumString
**pszkey
)
781 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
783 TRACE("(%p)->(%p)\n", This
, pszkey
);
785 return IBindCtx_EnumObjectParam(This
->bindctx
, pszkey
);
788 static const IBindCtxVtbl AsyncBindCtxVtbl
=
790 AsyncBindCtx_QueryInterface
,
792 AsyncBindCtx_Release
,
793 AsyncBindCtx_RegisterObjectBound
,
794 AsyncBindCtx_RevokeObjectBound
,
795 AsyncBindCtx_ReleaseBoundObjects
,
796 AsyncBindCtx_SetBindOptions
,
797 AsyncBindCtx_GetBindOptions
,
798 AsyncBindCtx_GetRunningObjectTable
,
799 AsyncBindCtx_RegisterObjectParam
,
800 AsyncBindCtx_GetObjectParam
,
801 AsyncBindCtx_EnumObjectParam
,
802 AsyncBindCtx_RevokeObjectParam
805 static HRESULT
init_bindctx(IBindCtx
*bindctx
, DWORD options
,
806 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
)
812 FIXME("not supported options %08x\n", options
);
814 FIXME("format is not supported\n");
816 bindopts
.cbStruct
= sizeof(BIND_OPTS
);
817 bindopts
.grfFlags
= BIND_MAYBOTHERUSER
;
818 bindopts
.grfMode
= STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
;
819 bindopts
.dwTickCountDeadline
= 0;
821 hres
= IBindCtx_SetBindOptions(bindctx
, &bindopts
);
826 hres
= RegisterBindStatusCallback(bindctx
, callback
, NULL
, 0);
834 /***********************************************************************
835 * CreateAsyncBindCtx (urlmon.@)
837 HRESULT WINAPI
CreateAsyncBindCtx(DWORD reserved
, IBindStatusCallback
*callback
,
838 IEnumFORMATETC
*format
, IBindCtx
**pbind
)
843 TRACE("(%08x %p %p %p)\n", reserved
, callback
, format
, pbind
);
845 if(!pbind
|| !callback
)
848 hres
= CreateBindCtx(0, &bindctx
);
852 hres
= init_bindctx(bindctx
, 0, callback
, format
);
854 IBindCtx_Release(bindctx
);
862 /***********************************************************************
863 * CreateAsyncBindCtxEx (urlmon.@)
865 * Create an asynchronous bind context.
867 HRESULT WINAPI
CreateAsyncBindCtxEx(IBindCtx
*ibind
, DWORD options
,
868 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
, IBindCtx
** pbind
,
875 TRACE("(%p %08x %p %p %p %d)\n", ibind
, options
, callback
, format
, pbind
, reserved
);
881 WARN("reserved=%d\n", reserved
);
884 IBindCtx_AddRef(ibind
);
887 hres
= CreateBindCtx(0, &bindctx
);
892 ret
= heap_alloc(sizeof(AsyncBindCtx
));
894 ret
->IBindCtx_iface
.lpVtbl
= &AsyncBindCtxVtbl
;
896 ret
->bindctx
= bindctx
;
898 hres
= init_bindctx(&ret
->IBindCtx_iface
, options
, callback
, format
);
900 IBindCtx_Release(&ret
->IBindCtx_iface
);
904 *pbind
= &ret
->IBindCtx_iface
;