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 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 inline BindStatusCallback
*impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx
*iface
)
56 return CONTAINING_RECORD(iface
, BindStatusCallback
, IBindStatusCallbackEx_iface
);
59 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallbackEx
*iface
,
60 REFIID riid
, void **ppv
)
62 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
66 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
67 TRACE("(%p)->(IID_IUnknown, %p)\n", This
, ppv
);
68 *ppv
= &This
->IBindStatusCallbackEx_iface
;
69 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
70 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
71 *ppv
= &This
->IBindStatusCallbackEx_iface
;
72 }else if(IsEqualGUID(&IID_IBindStatusCallbackEx
, riid
)) {
73 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
74 *ppv
= &This
->IBindStatusCallbackEx_iface
;
75 }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder
, riid
)) {
76 TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This
, ppv
);
78 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
79 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This
, ppv
);
80 *ppv
= &This
->IServiceProvider_iface
;
81 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
82 TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This
, ppv
);
83 *ppv
= &This
->IHttpNegotiate2_iface
;
84 }else if(IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
85 TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This
, ppv
);
86 *ppv
= &This
->IHttpNegotiate2_iface
;
87 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
88 TRACE("(%p)->(IID_IAuthenticate, %p)\n", This
, ppv
);
89 *ppv
= &This
->IAuthenticate_iface
;
93 IBindStatusCallback_AddRef((IUnknown
*)*ppv
);
97 TRACE("Unsupported riid = %s\n", debugstr_guid(riid
));
101 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallbackEx
*iface
)
103 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
104 LONG ref
= InterlockedIncrement(&This
->ref
);
106 TRACE("(%p) ref = %d\n", This
, ref
);
111 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallbackEx
*iface
)
113 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
114 LONG ref
= InterlockedDecrement(&This
->ref
);
116 TRACE("(%p) ref = %d\n", This
, ref
);
120 IServiceProvider_Release(This
->serv_prov
);
121 IBindStatusCallback_Release(This
->callback
);
128 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallbackEx
*iface
,
129 DWORD dwReserved
, IBinding
*pbind
)
131 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
133 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
135 return IBindStatusCallback_OnStartBinding(This
->callback
, 0xff, pbind
);
138 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallbackEx
*iface
, LONG
*pnPriority
)
140 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
142 TRACE("(%p)->(%p)\n", This
, pnPriority
);
144 return IBindStatusCallback_GetPriority(This
->callback
, pnPriority
);
147 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallbackEx
*iface
, DWORD reserved
)
149 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
151 TRACE("(%p)->(%d)\n", This
, reserved
);
153 return IBindStatusCallback_OnLowResource(This
->callback
, reserved
);
156 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallbackEx
*iface
, ULONG ulProgress
,
157 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
159 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
161 TRACE("%p)->(%u %u %u %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
162 debugstr_w(szStatusText
));
164 return IBindStatusCallback_OnProgress(This
->callback
, ulProgress
,
165 ulProgressMax
, ulStatusCode
, szStatusText
);
168 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallbackEx
*iface
,
169 HRESULT hresult
, LPCWSTR szError
)
171 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
173 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
175 return IBindStatusCallback_OnStopBinding(This
->callback
, hresult
, szError
);
178 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallbackEx
*iface
,
179 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
181 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
182 IBindStatusCallbackEx
*bscex
;
185 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
187 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
188 if(SUCCEEDED(hres
)) {
189 DWORD bindf2
= 0, reserv
= 0;
191 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, &bindf2
, &reserv
);
192 IBindStatusCallbackEx_Release(bscex
);
194 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
200 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx
*iface
,
201 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
203 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
205 TRACE("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
207 return IBindStatusCallback_OnDataAvailable(This
->callback
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
210 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx
*iface
,
211 REFIID riid
, IUnknown
*punk
)
213 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
215 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
217 return IBindStatusCallback_OnObjectAvailable(This
->callback
, riid
, punk
);
220 static HRESULT WINAPI
BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx
*iface
, DWORD
*grfBINDF
,
221 BINDINFO
*pbindinfo
, DWORD
*grfBINDF2
, DWORD
*pdwReserved
)
223 BindStatusCallback
*This
= impl_from_IBindStatusCallbackEx(iface
);
224 IBindStatusCallbackEx
*bscex
;
227 TRACE("(%p)->(%p %p %p %p)\n", This
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
229 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IBindStatusCallbackEx
, (void**)&bscex
);
230 if(SUCCEEDED(hres
)) {
231 hres
= IBindStatusCallbackEx_GetBindInfoEx(bscex
, grfBINDF
, pbindinfo
, grfBINDF2
, pdwReserved
);
232 IBindStatusCallbackEx_Release(bscex
);
234 hres
= IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
240 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl
= {
241 BindStatusCallback_QueryInterface
,
242 BindStatusCallback_AddRef
,
243 BindStatusCallback_Release
,
244 BindStatusCallback_OnStartBinding
,
245 BindStatusCallback_GetPriority
,
246 BindStatusCallback_OnLowResource
,
247 BindStatusCallback_OnProgress
,
248 BindStatusCallback_OnStopBinding
,
249 BindStatusCallback_GetBindInfo
,
250 BindStatusCallback_OnDataAvailable
,
251 BindStatusCallback_OnObjectAvailable
,
252 BindStatusCallback_GetBindInfoEx
255 static inline BindStatusCallback
*impl_from_IServiceProvider(IServiceProvider
*iface
)
257 return CONTAINING_RECORD(iface
, BindStatusCallback
, IServiceProvider_iface
);
260 static HRESULT WINAPI
BSCServiceProvider_QueryInterface(IServiceProvider
*iface
,
261 REFIID riid
, void **ppv
)
263 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
264 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
267 static ULONG WINAPI
BSCServiceProvider_AddRef(IServiceProvider
*iface
)
269 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
270 return IBindStatusCallback_AddRef(&This
->IBindStatusCallbackEx_iface
);
273 static ULONG WINAPI
BSCServiceProvider_Release(IServiceProvider
*iface
)
275 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
276 return IBindStatusCallback_Release(&This
->IBindStatusCallbackEx_iface
);
279 static HRESULT WINAPI
BSCServiceProvider_QueryService(IServiceProvider
*iface
,
280 REFGUID guidService
, REFIID riid
, void **ppv
)
282 BindStatusCallback
*This
= impl_from_IServiceProvider(iface
);
285 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
)) {
286 TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
287 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
290 if(IsEqualGUID(&IID_IHttpNegotiate2
, guidService
)) {
291 TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This
, debugstr_guid(riid
), ppv
);
292 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
295 if(IsEqualGUID(&IID_IAuthenticate
, guidService
)) {
296 TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
297 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
300 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
302 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, ppv
);
306 if(This
->serv_prov
) {
307 hres
= IServiceProvider_QueryService(This
->serv_prov
, guidService
, riid
, ppv
);
312 return E_NOINTERFACE
;
315 static const IServiceProviderVtbl BSCServiceProviderVtbl
= {
316 BSCServiceProvider_QueryInterface
,
317 BSCServiceProvider_AddRef
,
318 BSCServiceProvider_Release
,
319 BSCServiceProvider_QueryService
322 static inline BindStatusCallback
*impl_from_IHttpNegotiate2(IHttpNegotiate2
*iface
)
324 return CONTAINING_RECORD(iface
, BindStatusCallback
, IHttpNegotiate2_iface
);
327 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
,
328 REFIID riid
, void **ppv
)
330 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
331 return IBindStatusCallback_QueryInterface(&This
->IBindStatusCallbackEx_iface
, riid
, ppv
);
334 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
336 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
337 return IBindStatusCallback_AddRef(&This
->IBindStatusCallbackEx_iface
);
340 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate2
*iface
)
342 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
343 return IBindStatusCallback_Release(&This
->IBindStatusCallbackEx_iface
);
346 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
,
347 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
349 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
350 IHttpNegotiate
*http_negotiate
;
353 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
), dwReserved
,
354 pszAdditionalHeaders
);
356 *pszAdditionalHeaders
= NULL
;
358 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
360 hres
= IHttpNegotiate_BeginningTransaction(http_negotiate
, szURL
, szHeaders
,
361 dwReserved
, pszAdditionalHeaders
);
362 IHttpNegotiate_Release(http_negotiate
);
368 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
369 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
370 LPWSTR
*pszAdditionalRequestHeaders
)
372 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
373 LPWSTR additional_headers
= NULL
;
374 IHttpNegotiate
*http_negotiate
;
377 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
378 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
380 http_negotiate
= get_callback_iface(This
, &IID_IHttpNegotiate
);
382 hres
= IHttpNegotiate_OnResponse(http_negotiate
, dwResponseCode
, szResponseHeaders
,
383 szRequestHeaders
, &additional_headers
);
384 IHttpNegotiate_Release(http_negotiate
);
387 if(pszAdditionalRequestHeaders
)
388 *pszAdditionalRequestHeaders
= additional_headers
;
389 else if(additional_headers
)
390 CoTaskMemFree(additional_headers
);
395 static HRESULT WINAPI
BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
396 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
398 BindStatusCallback
*This
= impl_from_IHttpNegotiate2(iface
);
399 IHttpNegotiate2
*http_negotiate2
;
400 HRESULT hres
= E_FAIL
;
402 TRACE("(%p)->(%p %p %ld)\n", This
, pbSecurityId
, pcbSecurityId
, dwReserved
);
404 http_negotiate2
= get_callback_iface(This
, &IID_IHttpNegotiate2
);
405 if(http_negotiate2
) {
406 hres
= IHttpNegotiate2_GetRootSecurityId(http_negotiate2
, pbSecurityId
,
407 pcbSecurityId
, dwReserved
);
408 IHttpNegotiate2_Release(http_negotiate2
);
414 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl
= {
415 BSCHttpNegotiate_QueryInterface
,
416 BSCHttpNegotiate_AddRef
,
417 BSCHttpNegotiate_Release
,
418 BSCHttpNegotiate_BeginningTransaction
,
419 BSCHttpNegotiate_OnResponse
,
420 BSCHttpNegotiate_GetRootSecurityId
423 static inline BindStatusCallback
*impl_from_IAuthenticate(IAuthenticate
*iface
)
425 return CONTAINING_RECORD(iface
, BindStatusCallback
, IAuthenticate_iface
);
428 static HRESULT WINAPI
BSCAuthenticate_QueryInterface(IAuthenticate
*iface
, REFIID riid
, void **ppv
)
430 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
431 return IBindStatusCallback_QueryInterface(&This
->IAuthenticate_iface
, riid
, ppv
);
434 static ULONG WINAPI
BSCAuthenticate_AddRef(IAuthenticate
*iface
)
436 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
437 return IBindStatusCallback_AddRef(&This
->IBindStatusCallbackEx_iface
);
440 static ULONG WINAPI
BSCAuthenticate_Release(IAuthenticate
*iface
)
442 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
443 return IBindStatusCallback_Release(&This
->IBindStatusCallbackEx_iface
);
446 static HRESULT WINAPI
BSCAuthenticate_Authenticate(IAuthenticate
*iface
,
447 HWND
*phwnd
, LPWSTR
*pszUsername
, LPWSTR
*pszPassword
)
449 BindStatusCallback
*This
= impl_from_IAuthenticate(iface
);
450 FIXME("(%p)->(%p %p %p)\n", This
, phwnd
, pszUsername
, pszPassword
);
454 static const IAuthenticateVtbl BSCAuthenticateVtbl
= {
455 BSCAuthenticate_QueryInterface
,
456 BSCAuthenticate_AddRef
,
457 BSCAuthenticate_Release
,
458 BSCAuthenticate_Authenticate
461 static void set_callback(BindStatusCallback
*This
, IBindStatusCallback
*bsc
)
463 IServiceProvider
*serv_prov
;
467 IBindStatusCallback_Release(This
->callback
);
469 IServiceProvider_Release(This
->serv_prov
);
471 IBindStatusCallback_AddRef(bsc
);
472 This
->callback
= bsc
;
474 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IServiceProvider
, (void**)&serv_prov
);
475 This
->serv_prov
= hres
== S_OK
? serv_prov
: NULL
;
478 HRESULT
wrap_callback(IBindStatusCallback
*bsc
, IBindStatusCallback
**ret_iface
)
480 BindStatusCallback
*ret
;
482 ret
= heap_alloc_zero(sizeof(BindStatusCallback
));
484 return E_OUTOFMEMORY
;
486 ret
->IBindStatusCallbackEx_iface
.lpVtbl
= &BindStatusCallbackExVtbl
;
487 ret
->IServiceProvider_iface
.lpVtbl
= &BSCServiceProviderVtbl
;
488 ret
->IHttpNegotiate2_iface
.lpVtbl
= &BSCHttpNegotiateVtbl
;
489 ret
->IAuthenticate_iface
.lpVtbl
= &BSCAuthenticateVtbl
;
492 set_callback(ret
, bsc
);
494 *ret_iface
= (IBindStatusCallback
*)&ret
->IBindStatusCallbackEx_iface
;
498 /***********************************************************************
499 * RegisterBindStatusCallback (urlmon.@)
501 * Register a bind status callback.
504 * pbc [I] Binding context
505 * pbsc [I] Callback to register
506 * ppbscPrevious [O] Destination for previous callback
507 * dwReserved [I] Reserved, must be 0.
511 * Failure: E_INVALIDARG, if any argument is invalid, or
512 * E_OUTOFMEMORY if memory allocation fails.
514 HRESULT WINAPI
RegisterBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
,
515 IBindStatusCallback
**ppbscPrevious
, DWORD dwReserved
)
517 BindStatusCallback
*holder
;
518 IBindStatusCallback
*bsc
, *prev
= NULL
;
522 TRACE("(%p %p %p %x)\n", pbc
, pbsc
, ppbscPrevious
, dwReserved
);
527 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
528 if(SUCCEEDED(hres
)) {
529 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&bsc
);
530 IUnknown_Release(unk
);
531 if(SUCCEEDED(hres
)) {
532 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
533 if(SUCCEEDED(hres
)) {
535 IBindStatusCallback_AddRef(holder
->callback
);
536 *ppbscPrevious
= holder
->callback
;
539 set_callback(holder
, pbsc
);
541 IBindStatusCallback_Release(bsc
);
542 IBindStatusCallback_Release(&holder
->IBindStatusCallbackEx_iface
);
549 IBindCtx_RevokeObjectParam(pbc
, BSCBHolder
);
552 hres
= wrap_callback(pbsc
, &bsc
);
553 if(SUCCEEDED(hres
)) {
554 hres
= IBindCtx_RegisterObjectParam(pbc
, BSCBHolder
, (IUnknown
*)bsc
);
555 IBindStatusCallback_Release(bsc
);
559 IBindStatusCallback_Release(prev
);
564 *ppbscPrevious
= prev
;
568 /***********************************************************************
569 * RevokeBindStatusCallback (URLMON.@)
571 * Unregister a bind status callback.
573 * pbc [I] Binding context
574 * pbsc [I] Callback to unregister
578 * Failure: E_INVALIDARG, if any argument is invalid
580 HRESULT WINAPI
RevokeBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
)
582 BindStatusCallback
*holder
;
583 IBindStatusCallback
*callback
;
585 BOOL dorevoke
= FALSE
;
588 TRACE("(%p %p)\n", pbc
, pbsc
);
593 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
597 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&callback
);
598 IUnknown_Release(unk
);
602 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
603 if(SUCCEEDED(hres
)) {
604 if(pbsc
== holder
->callback
)
606 IBindStatusCallback_Release(&holder
->IBindStatusCallbackEx_iface
);
607 }else if(pbsc
== callback
) {
610 IBindStatusCallback_Release(callback
);
613 IBindCtx_RevokeObjectParam(pbc
, BSCBHolder
);
619 IBindCtx IBindCtx_iface
;
626 static inline AsyncBindCtx
*impl_from_IBindCtx(IBindCtx
*iface
)
628 return CONTAINING_RECORD(iface
, AsyncBindCtx
, IBindCtx_iface
);
631 static HRESULT WINAPI
AsyncBindCtx_QueryInterface(IBindCtx
*iface
, REFIID riid
, void **ppv
)
633 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
637 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
638 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
639 *ppv
= &This
->IBindCtx_iface
;
640 }else if(IsEqualGUID(riid
, &IID_IBindCtx
)) {
641 TRACE("(%p)->(IID_IBindCtx %p)\n", This
, ppv
);
642 *ppv
= &This
->IBindCtx_iface
;
643 }else if(IsEqualGUID(riid
, &IID_IAsyncBindCtx
)) {
644 TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This
, ppv
);
645 *ppv
= &This
->IBindCtx_iface
;
649 IUnknown_AddRef((IUnknown
*)*ppv
);
653 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
654 return E_NOINTERFACE
;
657 static ULONG WINAPI
AsyncBindCtx_AddRef(IBindCtx
*iface
)
659 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
660 LONG ref
= InterlockedIncrement(&This
->ref
);
662 TRACE("(%p) ref=%d\n", This
, ref
);
667 static ULONG WINAPI
AsyncBindCtx_Release(IBindCtx
*iface
)
669 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
670 LONG ref
= InterlockedDecrement(&This
->ref
);
672 TRACE("(%p) ref=%d\n", This
, ref
);
675 IBindCtx_Release(This
->bindctx
);
682 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
684 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
686 TRACE("(%p)->(%p)\n", This
, punk
);
688 return IBindCtx_RegisterObjectBound(This
->bindctx
, punk
);
691 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
693 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
695 TRACE("(%p %p)\n", This
, punk
);
697 return IBindCtx_RevokeObjectBound(This
->bindctx
, punk
);
700 static HRESULT WINAPI
AsyncBindCtx_ReleaseBoundObjects(IBindCtx
*iface
)
702 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
704 TRACE("(%p)\n", This
);
706 return IBindCtx_ReleaseBoundObjects(This
->bindctx
);
709 static HRESULT WINAPI
AsyncBindCtx_SetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
711 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
713 TRACE("(%p)->(%p)\n", This
, pbindopts
);
715 return IBindCtx_SetBindOptions(This
->bindctx
, pbindopts
);
718 static HRESULT WINAPI
AsyncBindCtx_GetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
720 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
722 TRACE("(%p)->(%p)\n", This
, pbindopts
);
724 return IBindCtx_GetBindOptions(This
->bindctx
, pbindopts
);
727 static HRESULT WINAPI
AsyncBindCtx_GetRunningObjectTable(IBindCtx
*iface
, IRunningObjectTable
**pprot
)
729 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
731 TRACE("(%p)->(%p)\n", This
, pprot
);
733 return IBindCtx_GetRunningObjectTable(This
->bindctx
, pprot
);
736 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
, IUnknown
*punk
)
738 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
740 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
742 return IBindCtx_RegisterObjectParam(This
->bindctx
, pszkey
, punk
);
745 static HRESULT WINAPI
AsyncBindCtx_GetObjectParam(IBindCtx
* iface
, LPOLESTR pszkey
, IUnknown
**punk
)
747 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
749 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
751 return IBindCtx_GetObjectParam(This
->bindctx
, pszkey
, punk
);
754 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
)
756 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
758 TRACE("(%p)->(%s)\n", This
, debugstr_w(pszkey
));
760 return IBindCtx_RevokeObjectParam(This
->bindctx
, pszkey
);
763 static HRESULT WINAPI
AsyncBindCtx_EnumObjectParam(IBindCtx
*iface
, IEnumString
**pszkey
)
765 AsyncBindCtx
*This
= impl_from_IBindCtx(iface
);
767 TRACE("(%p)->(%p)\n", This
, pszkey
);
769 return IBindCtx_EnumObjectParam(This
->bindctx
, pszkey
);
772 static const IBindCtxVtbl AsyncBindCtxVtbl
=
774 AsyncBindCtx_QueryInterface
,
776 AsyncBindCtx_Release
,
777 AsyncBindCtx_RegisterObjectBound
,
778 AsyncBindCtx_RevokeObjectBound
,
779 AsyncBindCtx_ReleaseBoundObjects
,
780 AsyncBindCtx_SetBindOptions
,
781 AsyncBindCtx_GetBindOptions
,
782 AsyncBindCtx_GetRunningObjectTable
,
783 AsyncBindCtx_RegisterObjectParam
,
784 AsyncBindCtx_GetObjectParam
,
785 AsyncBindCtx_EnumObjectParam
,
786 AsyncBindCtx_RevokeObjectParam
789 static HRESULT
init_bindctx(IBindCtx
*bindctx
, DWORD options
,
790 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
)
796 FIXME("not supported options %08x\n", options
);
798 FIXME("format is not supported\n");
800 bindopts
.cbStruct
= sizeof(BIND_OPTS
);
801 bindopts
.grfFlags
= BIND_MAYBOTHERUSER
;
802 bindopts
.grfMode
= STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
;
803 bindopts
.dwTickCountDeadline
= 0;
805 hres
= IBindCtx_SetBindOptions(bindctx
, &bindopts
);
810 hres
= RegisterBindStatusCallback(bindctx
, callback
, NULL
, 0);
818 /***********************************************************************
819 * CreateAsyncBindCtx (urlmon.@)
821 HRESULT WINAPI
CreateAsyncBindCtx(DWORD reserved
, IBindStatusCallback
*callback
,
822 IEnumFORMATETC
*format
, IBindCtx
**pbind
)
827 TRACE("(%08x %p %p %p)\n", reserved
, callback
, format
, pbind
);
829 if(!pbind
|| !callback
)
832 hres
= CreateBindCtx(0, &bindctx
);
836 hres
= init_bindctx(bindctx
, 0, callback
, format
);
838 IBindCtx_Release(bindctx
);
846 /***********************************************************************
847 * CreateAsyncBindCtxEx (urlmon.@)
849 * Create an asynchronous bind context.
851 HRESULT WINAPI
CreateAsyncBindCtxEx(IBindCtx
*ibind
, DWORD options
,
852 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
, IBindCtx
** pbind
,
859 TRACE("(%p %08x %p %p %p %d)\n", ibind
, options
, callback
, format
, pbind
, reserved
);
865 WARN("reserved=%d\n", reserved
);
868 IBindCtx_AddRef(ibind
);
871 hres
= CreateBindCtx(0, &bindctx
);
876 ret
= heap_alloc(sizeof(AsyncBindCtx
));
878 ret
->IBindCtx_iface
.lpVtbl
= &AsyncBindCtxVtbl
;
880 ret
->bindctx
= bindctx
;
882 hres
= init_bindctx(&ret
->IBindCtx_iface
, options
, callback
, format
);
884 IBindCtx_Release(&ret
->IBindCtx_iface
);
888 *pbind
= &ret
->IBindCtx_iface
;