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 BSCBHolder
[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
28 extern IID IID_IBindStatusCallbackHolder
;
31 const IBindStatusCallbackExVtbl
*lpBindStatusCallbackExVtbl
;
32 const IServiceProviderVtbl
*lpServiceProviderVtbl
;
33 const IHttpNegotiate2Vtbl
*lpHttpNegotiate2Vtbl
;
34 const IAuthenticateVtbl
*lpAuthenticateVtbl
;
38 IBindStatusCallback
*callback
;
39 IServiceProvider
*serv_prov
;
42 #define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackExVtbl)
43 #define STATUSCLBEX(x) ((IBindStatusCallbackEx*)&(x)->lpBindStatusCallbackExVtbl)
44 #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
45 #define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl)
46 #define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpAuthenticateVtbl)
48 static void *get_callback_iface(BindStatusCallback
*This
, REFIID riid
)
53 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, (void**)&ret
);
54 if(FAILED(hres
) && This
->serv_prov
)
55 hres
= IServiceProvider_QueryService(This
->serv_prov
, riid
, riid
, &ret
);
57 return SUCCEEDED(hres
) ? ret
: NULL
;
60 #define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallbackEx, iface)
62 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallbackEx
*iface
,
63 REFIID riid
, void **ppv
)
65 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
69 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
70 TRACE("(%p)->(IID_IUnknown, %p)\n", This
, ppv
);
71 *ppv
= STATUSCLB(This
);
72 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
73 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
74 *ppv
= STATUSCLB(This
);
75 }else if(IsEqualGUID(&IID_IBindStatusCallbackEx
, riid
)) {
76 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
77 *ppv
= STATUSCLBEX(This
);
78 }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder
, riid
)) {
79 TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This
, ppv
);
81 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
82 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This
, ppv
);
83 *ppv
= SERVPROV(This
);
84 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
85 TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This
, ppv
);
86 *ppv
= HTTPNEG2(This
);
87 }else if(IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
88 TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This
, ppv
);
89 *ppv
= HTTPNEG2(This
);
90 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
91 TRACE("(%p)->(IID_IAuthenticate, %p)\n", This
, ppv
);
92 *ppv
= AUTHENTICATE(This
);
96 IBindStatusCallback_AddRef((IUnknown
*)*ppv
);
100 TRACE("Unsupported riid = %s\n", debugstr_guid(riid
));
101 return E_NOINTERFACE
;
104 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallbackEx
*iface
)
106 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
107 LONG ref
= InterlockedIncrement(&This
->ref
);
109 TRACE("(%p) ref = %d\n", This
, ref
);
114 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallbackEx
*iface
)
116 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
117 LONG ref
= InterlockedDecrement(&This
->ref
);
119 TRACE("(%p) ref = %d\n", This
, ref
);
123 IServiceProvider_Release(This
->serv_prov
);
124 IBindStatusCallback_Release(This
->callback
);
131 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallbackEx
*iface
,
132 DWORD dwReserved
, IBinding
*pbind
)
134 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
136 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
138 return IBindStatusCallback_OnStartBinding(This
->callback
, 0xff, pbind
);
141 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallbackEx
*iface
, LONG
*pnPriority
)
143 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
145 TRACE("(%p)->(%p)\n", This
, pnPriority
);
147 return IBindStatusCallback_GetPriority(This
->callback
, pnPriority
);
150 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallbackEx
*iface
, DWORD reserved
)
152 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
154 TRACE("(%p)->(%d)\n", This
, reserved
);
156 return IBindStatusCallback_OnLowResource(This
->callback
, reserved
);
159 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallbackEx
*iface
, ULONG ulProgress
,
160 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
162 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
164 TRACE("%p)->(%u %u %u %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
165 debugstr_w(szStatusText
));
167 return IBindStatusCallback_OnProgress(This
->callback
, ulProgress
,
168 ulProgressMax
, ulStatusCode
, szStatusText
);
171 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallbackEx
*iface
,
172 HRESULT hresult
, LPCWSTR szError
)
174 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
176 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
178 return IBindStatusCallback_OnStopBinding(This
->callback
, hresult
, szError
);
181 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallbackEx
*iface
,
182 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
184 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
185 IBindStatusCallbackEx
*bscex
;
188 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
190 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
191 if(SUCCEEDED(hres
)) {
192 DWORD bindf2
= 0, reserv
= 0;
194 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, &bindf2
, &reserv
);
195 IBindStatusCallbackEx_Release(bscex
);
197 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
203 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx
*iface
,
204 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
206 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
208 TRACE("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
210 return IBindStatusCallback_OnDataAvailable(This
->callback
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
213 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx
*iface
,
214 REFIID riid
, IUnknown
*punk
)
216 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
218 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
220 return IBindStatusCallback_OnObjectAvailable(This
->callback
, riid
, punk
);
223 static HRESULT WINAPI
BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx
*iface
, DWORD
*grfBINDF
,
224 BINDINFO
*pbindinfo
, DWORD
*grfBINDF2
, DWORD
*pdwReserved
)
226 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
227 IBindStatusCallbackEx
*bscex
;
230 TRACE("(%p)->(%p %p %p %p)\n", This
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
232 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
233 if(SUCCEEDED(hres
)) {
234 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
235 IBindStatusCallbackEx_Release(bscex
);
237 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
243 #undef STATUSCLB_THIS
245 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl
= {
246 BindStatusCallback_QueryInterface
,
247 BindStatusCallback_AddRef
,
248 BindStatusCallback_Release
,
249 BindStatusCallback_OnStartBinding
,
250 BindStatusCallback_GetPriority
,
251 BindStatusCallback_OnLowResource
,
252 BindStatusCallback_OnProgress
,
253 BindStatusCallback_OnStopBinding
,
254 BindStatusCallback_GetBindInfo
,
255 BindStatusCallback_OnDataAvailable
,
256 BindStatusCallback_OnObjectAvailable
,
257 BindStatusCallback_GetBindInfoEx
260 #define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface)
262 static HRESULT WINAPI
BSCServiceProvider_QueryInterface(IServiceProvider
*iface
,
263 REFIID riid
, void **ppv
)
265 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
266 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
269 static ULONG WINAPI
BSCServiceProvider_AddRef(IServiceProvider
*iface
)
271 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
272 return IBindStatusCallback_AddRef(STATUSCLB(This
));
275 static ULONG WINAPI
BSCServiceProvider_Release(IServiceProvider
*iface
)
277 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
278 return IBindStatusCallback_Release(STATUSCLB(This
));
281 static HRESULT WINAPI
BSCServiceProvider_QueryService(IServiceProvider
*iface
,
282 REFGUID guidService
, REFIID riid
, void **ppv
)
284 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
287 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
)) {
288 TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
289 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
292 if(IsEqualGUID(&IID_IHttpNegotiate2
, guidService
)) {
293 TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This
, debugstr_guid(riid
), ppv
);
294 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
297 if(IsEqualGUID(&IID_IAuthenticate
, guidService
)) {
298 TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
299 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
302 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
304 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, ppv
);
308 if(This
->serv_prov
) {
309 hres
= IServiceProvider_QueryService(This
->serv_prov
, guidService
, riid
, ppv
);
314 return E_NOINTERFACE
;
319 static const IServiceProviderVtbl BSCServiceProviderVtbl
= {
320 BSCServiceProvider_QueryInterface
,
321 BSCServiceProvider_AddRef
,
322 BSCServiceProvider_Release
,
323 BSCServiceProvider_QueryService
326 #define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface)
328 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
,
329 REFIID riid
, void **ppv
)
331 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
332 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
335 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
337 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
338 return IBindStatusCallback_AddRef(STATUSCLB(This
));
341 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate2
*iface
)
343 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
344 return IBindStatusCallback_Release(STATUSCLB(This
));
347 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
,
348 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
350 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
351 IHttpNegotiate
*http_negotiate
;
354 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
), dwReserved
,
355 pszAdditionalHeaders
);
357 *pszAdditionalHeaders
= NULL
;
359 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
361 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, szURL
, szHeaders
,
362 dwReserved
, pszAdditionalHeaders
);
363 IHttpNegotiate_Release(http_negotiate
);
369 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
370 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
371 LPWSTR
*pszAdditionalRequestHeaders
)
373 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
374 LPWSTR additional_headers
= NULL
;
375 IHttpNegotiate
*http_negotiate
;
378 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
379 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
381 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
383 hres
= IHttpNegotiate_OnResponse(http_negotiate
, dwResponseCode
, szResponseHeaders
,
384 szRequestHeaders
, &additional_headers
);
385 IHttpNegotiate_Release(http_negotiate
);
388 if(pszAdditionalRequestHeaders
)
389 *pszAdditionalRequestHeaders
= additional_headers
;
390 else if(additional_headers
)
391 CoTaskMemFree(additional_headers
);
396 static HRESULT WINAPI
BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
397 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
399 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
400 IHttpNegotiate2
*http_negotiate2
;
401 HRESULT hres
= E_FAIL
;
403 TRACE("(%p)->(%p %p %ld)\n", This
, pbSecurityId
, pcbSecurityId
, dwReserved
);
405 http_negotiate2
= get_callback_iface(This
, &IID_IHttpNegotiate2
);
406 if(http_negotiate2
) {
407 hres
= IHttpNegotiate2_GetRootSecurityId(http_negotiate2
, pbSecurityId
,
408 pcbSecurityId
, dwReserved
);
409 IHttpNegotiate2_Release(http_negotiate2
);
417 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl
= {
418 BSCHttpNegotiate_QueryInterface
,
419 BSCHttpNegotiate_AddRef
,
420 BSCHttpNegotiate_Release
,
421 BSCHttpNegotiate_BeginningTransaction
,
422 BSCHttpNegotiate_OnResponse
,
423 BSCHttpNegotiate_GetRootSecurityId
426 #define AUTHENTICATE_THIS(iface) DEFINE_THIS(BindStatusCallback, Authenticate, iface)
428 static HRESULT WINAPI
BSCAuthenticate_QueryInterface(IAuthenticate
*iface
, REFIID riid
, void **ppv
)
430 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
431 return IBindStatusCallback_QueryInterface(AUTHENTICATE(This
), riid
, ppv
);
434 static ULONG WINAPI
BSCAuthenticate_AddRef(IAuthenticate
*iface
)
436 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
437 return IBindStatusCallback_AddRef(STATUSCLB(This
));
440 static ULONG WINAPI
BSCAuthenticate_Release(IAuthenticate
*iface
)
442 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
443 return IBindStatusCallback_Release(STATUSCLB(This
));
446 static HRESULT WINAPI
BSCAuthenticate_Authenticate(IAuthenticate
*iface
,
447 HWND
*phwnd
, LPWSTR
*pszUsername
, LPWSTR
*pszPassword
)
449 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
450 FIXME("(%p)->(%p %p %p)\n", This
, phwnd
, pszUsername
, pszPassword
);
454 #undef AUTHENTICATE_THIS
456 static const IAuthenticateVtbl BSCAuthenticateVtbl
= {
457 BSCAuthenticate_QueryInterface
,
458 BSCAuthenticate_AddRef
,
459 BSCAuthenticate_Release
,
460 BSCAuthenticate_Authenticate
463 static void set_callback(BindStatusCallback
*This
, IBindStatusCallback
*bsc
)
465 IServiceProvider
*serv_prov
;
469 IBindStatusCallback_Release(This
->callback
);
471 IServiceProvider_Release(This
->serv_prov
);
473 IBindStatusCallback_AddRef(bsc
);
474 This
->callback
= bsc
;
476 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IServiceProvider
, (void**)&serv_prov
);
477 This
->serv_prov
= hres
== S_OK
? serv_prov
: NULL
;
480 HRESULT
wrap_callback(IBindStatusCallback
*bsc
, IBindStatusCallback
**ret_iface
)
482 BindStatusCallback
*ret
;
484 ret
= heap_alloc_zero(sizeof(BindStatusCallback
));
486 return E_OUTOFMEMORY
;
488 ret
->lpBindStatusCallbackExVtbl
= &BindStatusCallbackExVtbl
;
489 ret
->lpServiceProviderVtbl
= &BSCServiceProviderVtbl
;
490 ret
->lpHttpNegotiate2Vtbl
= &BSCHttpNegotiateVtbl
;
491 ret
->lpAuthenticateVtbl
= &BSCAuthenticateVtbl
;
494 set_callback(ret
, bsc
);
496 *ret_iface
= STATUSCLB(ret
);
500 /***********************************************************************
501 * RegisterBindStatusCallback (urlmon.@)
503 * Register a bind status callback.
506 * pbc [I] Binding context
507 * pbsc [I] Callback to register
508 * ppbscPrevious [O] Destination for previous callback
509 * dwReserved [I] Reserved, must be 0.
513 * Failure: E_INVALIDARG, if any argument is invalid, or
514 * E_OUTOFMEMORY if memory allocation fails.
516 HRESULT WINAPI
RegisterBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
,
517 IBindStatusCallback
**ppbscPrevious
, DWORD dwReserved
)
519 BindStatusCallback
*holder
;
520 IBindStatusCallback
*bsc
, *prev
= NULL
;
524 TRACE("(%p %p %p %x)\n", pbc
, pbsc
, ppbscPrevious
, dwReserved
);
529 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
530 if(SUCCEEDED(hres
)) {
531 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&bsc
);
532 IUnknown_Release(unk
);
533 if(SUCCEEDED(hres
)) {
534 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
535 if(SUCCEEDED(hres
)) {
537 IBindStatusCallback_AddRef(holder
->callback
);
538 *ppbscPrevious
= holder
->callback
;
541 set_callback(holder
, pbsc
);
543 IBindStatusCallback_Release(bsc
);
544 IBindStatusCallback_Release(STATUSCLB(holder
));
551 IBindCtx_RevokeObjectParam(pbc
, BSCBHolder
);
554 hres
= wrap_callback(pbsc
, &bsc
);
555 if(SUCCEEDED(hres
)) {
556 hres
= IBindCtx_RegisterObjectParam(pbc
, BSCBHolder
, (IUnknown
*)bsc
);
557 IBindStatusCallback_Release(bsc
);
561 IBindStatusCallback_Release(prev
);
566 *ppbscPrevious
= prev
;
570 /***********************************************************************
571 * RevokeBindStatusCallback (URLMON.@)
573 * Unregister a bind status callback.
575 * pbc [I] Binding context
576 * pbsc [I] Callback to unregister
580 * Failure: E_INVALIDARG, if any argument is invalid
582 HRESULT WINAPI
RevokeBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
)
584 BindStatusCallback
*holder
;
585 IBindStatusCallback
*callback
;
587 BOOL dorevoke
= FALSE
;
590 TRACE("(%p %p)\n", pbc
, pbsc
);
595 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
599 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&callback
);
600 IUnknown_Release(unk
);
604 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
605 if(SUCCEEDED(hres
)) {
606 if(pbsc
== holder
->callback
)
608 IBindStatusCallback_Release(STATUSCLB(holder
));
609 }else if(pbsc
== callback
) {
612 IBindStatusCallback_Release(callback
);
615 IBindCtx_RevokeObjectParam(pbc
, BSCBHolder
);
621 const IBindCtxVtbl
*lpBindCtxVtbl
;
628 #define BINDCTX(x) ((IBindCtx*) &(x)->lpBindCtxVtbl)
630 #define BINDCTX_THIS(iface) DEFINE_THIS(AsyncBindCtx, BindCtx, iface)
632 static HRESULT WINAPI
AsyncBindCtx_QueryInterface(IBindCtx
*iface
, REFIID riid
, void **ppv
)
634 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
638 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
639 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
640 *ppv
= BINDCTX(This
);
641 }else if(IsEqualGUID(riid
, &IID_IBindCtx
)) {
642 TRACE("(%p)->(IID_IBindCtx %p)\n", This
, ppv
);
643 *ppv
= BINDCTX(This
);
644 }else if(IsEqualGUID(riid
, &IID_IAsyncBindCtx
)) {
645 TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This
, ppv
);
646 *ppv
= BINDCTX(This
);
650 IUnknown_AddRef((IUnknown
*)*ppv
);
654 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
655 return E_NOINTERFACE
;
658 static ULONG WINAPI
AsyncBindCtx_AddRef(IBindCtx
*iface
)
660 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
661 LONG ref
= InterlockedIncrement(&This
->ref
);
663 TRACE("(%p) ref=%d\n", This
, ref
);
668 static ULONG WINAPI
AsyncBindCtx_Release(IBindCtx
*iface
)
670 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
671 LONG ref
= InterlockedDecrement(&This
->ref
);
673 TRACE("(%p) ref=%d\n", This
, ref
);
676 IBindCtx_Release(This
->bindctx
);
683 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
685 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
687 TRACE("(%p)->(%p)\n", This
, punk
);
689 return IBindCtx_RegisterObjectBound(This
->bindctx
, punk
);
692 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
694 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
696 TRACE("(%p %p)\n", This
, punk
);
698 return IBindCtx_RevokeObjectBound(This
->bindctx
, punk
);
701 static HRESULT WINAPI
AsyncBindCtx_ReleaseBoundObjects(IBindCtx
*iface
)
703 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
705 TRACE("(%p)\n", This
);
707 return IBindCtx_ReleaseBoundObjects(This
->bindctx
);
710 static HRESULT WINAPI
AsyncBindCtx_SetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
712 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
714 TRACE("(%p)->(%p)\n", This
, pbindopts
);
716 return IBindCtx_SetBindOptions(This
->bindctx
, pbindopts
);
719 static HRESULT WINAPI
AsyncBindCtx_GetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
721 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
723 TRACE("(%p)->(%p)\n", This
, pbindopts
);
725 return IBindCtx_GetBindOptions(This
->bindctx
, pbindopts
);
728 static HRESULT WINAPI
AsyncBindCtx_GetRunningObjectTable(IBindCtx
*iface
, IRunningObjectTable
**pprot
)
730 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
732 TRACE("(%p)->(%p)\n", This
, pprot
);
734 return IBindCtx_GetRunningObjectTable(This
->bindctx
, pprot
);
737 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
, IUnknown
*punk
)
739 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
741 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
743 return IBindCtx_RegisterObjectParam(This
->bindctx
, pszkey
, punk
);
746 static HRESULT WINAPI
AsyncBindCtx_GetObjectParam(IBindCtx
* iface
, LPOLESTR pszkey
, IUnknown
**punk
)
748 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
750 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
752 return IBindCtx_GetObjectParam(This
->bindctx
, pszkey
, punk
);
755 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
)
757 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
759 TRACE("(%p)->(%s)\n", This
, debugstr_w(pszkey
));
761 return IBindCtx_RevokeObjectParam(This
->bindctx
, pszkey
);
764 static HRESULT WINAPI
AsyncBindCtx_EnumObjectParam(IBindCtx
*iface
, IEnumString
**pszkey
)
766 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
768 TRACE("(%p)->(%p)\n", This
, pszkey
);
770 return IBindCtx_EnumObjectParam(This
->bindctx
, pszkey
);
775 static const IBindCtxVtbl AsyncBindCtxVtbl
=
777 AsyncBindCtx_QueryInterface
,
779 AsyncBindCtx_Release
,
780 AsyncBindCtx_RegisterObjectBound
,
781 AsyncBindCtx_RevokeObjectBound
,
782 AsyncBindCtx_ReleaseBoundObjects
,
783 AsyncBindCtx_SetBindOptions
,
784 AsyncBindCtx_GetBindOptions
,
785 AsyncBindCtx_GetRunningObjectTable
,
786 AsyncBindCtx_RegisterObjectParam
,
787 AsyncBindCtx_GetObjectParam
,
788 AsyncBindCtx_EnumObjectParam
,
789 AsyncBindCtx_RevokeObjectParam
792 static HRESULT
init_bindctx(IBindCtx
*bindctx
, DWORD options
,
793 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
)
799 FIXME("not supported options %08x\n", options
);
801 FIXME("format is not supported\n");
803 bindopts
.cbStruct
= sizeof(BIND_OPTS
);
804 bindopts
.grfFlags
= BIND_MAYBOTHERUSER
;
805 bindopts
.grfMode
= STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
;
806 bindopts
.dwTickCountDeadline
= 0;
808 hres
= IBindCtx_SetBindOptions(bindctx
, &bindopts
);
813 hres
= RegisterBindStatusCallback(bindctx
, callback
, NULL
, 0);
821 /***********************************************************************
822 * CreateAsyncBindCtx (urlmon.@)
824 HRESULT WINAPI
CreateAsyncBindCtx(DWORD reserved
, IBindStatusCallback
*callback
,
825 IEnumFORMATETC
*format
, IBindCtx
**pbind
)
830 TRACE("(%08x %p %p %p)\n", reserved
, callback
, format
, pbind
);
832 if(!pbind
|| !callback
)
835 hres
= CreateBindCtx(0, &bindctx
);
839 hres
= init_bindctx(bindctx
, 0, callback
, format
);
841 IBindCtx_Release(bindctx
);
849 /***********************************************************************
850 * CreateAsyncBindCtxEx (urlmon.@)
852 * Create an asynchronous bind context.
854 HRESULT WINAPI
CreateAsyncBindCtxEx(IBindCtx
*ibind
, DWORD options
,
855 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
, IBindCtx
** pbind
,
862 TRACE("(%p %08x %p %p %p %d)\n", ibind
, options
, callback
, format
, pbind
, reserved
);
868 WARN("reserved=%d\n", reserved
);
871 IBindCtx_AddRef(ibind
);
874 hres
= CreateBindCtx(0, &bindctx
);
879 ret
= heap_alloc(sizeof(AsyncBindCtx
));
881 ret
->lpBindCtxVtbl
= &AsyncBindCtxVtbl
;
883 ret
->bindctx
= bindctx
;
885 hres
= init_bindctx(BINDCTX(ret
), options
, callback
, format
);
887 IBindCtx_Release(BINDCTX(ret
));
891 *pbind
= BINDCTX(ret
);