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
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
32 #include "urlmon_main.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(urlmon
);
39 static WCHAR BSCBHolder
[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
41 extern IID IID_IBindStatusCallbackHolder
;
44 const IBindStatusCallbackVtbl
*lpBindStatusCallbackVtbl
;
45 const IServiceProviderVtbl
*lpServiceProviderVtbl
;
46 const IHttpNegotiate2Vtbl
*lpHttpNegotiate2Vtbl
;
47 const IAuthenticateVtbl
*lpAuthenticateVtbl
;
51 IBindStatusCallback
*callback
;
52 IServiceProvider
*serv_prov
;
54 IHttpNegotiate
*http_negotiate
;
55 BOOL init_http_negotiate
;
56 IHttpNegotiate2
*http_negotiate2
;
57 BOOL init_http_negotiate2
;
58 IAuthenticate
*authenticate
;
59 BOOL init_authenticate
;
62 #define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl)
63 #define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl)
64 #define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl)
65 #define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpAuthenticateVtbl)
67 #define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
69 static HRESULT WINAPI
BindStatusCallback_QueryInterface(IBindStatusCallback
*iface
,
70 REFIID riid
, void **ppv
)
72 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
76 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
77 TRACE("(%p)->(IID_IUnknown, %p)\n", This
, ppv
);
78 *ppv
= STATUSCLB(This
);
79 }else if(IsEqualGUID(&IID_IBindStatusCallback
, riid
)) {
80 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This
, ppv
);
81 *ppv
= STATUSCLB(This
);
82 }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder
, riid
)) {
83 TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This
, ppv
);
85 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
86 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This
, ppv
);
87 *ppv
= SERVPROV(This
);
88 }else if(IsEqualGUID(&IID_IHttpNegotiate
, riid
)) {
89 TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This
, ppv
);
90 *ppv
= HTTPNEG2(This
);
91 }else if(IsEqualGUID(&IID_IHttpNegotiate2
, riid
)) {
92 TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This
, ppv
);
93 *ppv
= HTTPNEG2(This
);
94 }else if(IsEqualGUID(&IID_IAuthenticate
, riid
)) {
95 TRACE("(%p)->(IID_IAuthenticate, %p)\n", This
, ppv
);
96 *ppv
= AUTHENTICATE(This
);
100 IBindStatusCallback_AddRef((IUnknown
*)*ppv
);
104 TRACE("Unsupported riid = %s\n", debugstr_guid(riid
));
105 return E_NOINTERFACE
;
108 static ULONG WINAPI
BindStatusCallback_AddRef(IBindStatusCallback
*iface
)
110 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
111 LONG ref
= InterlockedIncrement(&This
->ref
);
113 TRACE("(%p) ref = %d\n", This
, ref
);
118 static ULONG WINAPI
BindStatusCallback_Release(IBindStatusCallback
*iface
)
120 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
121 LONG ref
= InterlockedDecrement(&This
->ref
);
123 TRACE("(%p) ref = %d\n", This
, ref
);
127 IServiceProvider_Release(This
->serv_prov
);
128 if(This
->http_negotiate
)
129 IHttpNegotiate_Release(This
->http_negotiate
);
130 if(This
->http_negotiate2
)
131 IHttpNegotiate2_Release(This
->http_negotiate2
);
132 if(This
->authenticate
)
133 IAuthenticate_Release(This
->authenticate
);
134 IBindStatusCallback_Release(This
->callback
);
141 static HRESULT WINAPI
BindStatusCallback_OnStartBinding(IBindStatusCallback
*iface
,
142 DWORD dwReserved
, IBinding
*pbind
)
144 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
146 TRACE("(%p)->(%d %p)\n", This
, dwReserved
, pbind
);
148 return IBindStatusCallback_OnStartBinding(This
->callback
, 0xff, pbind
);
151 static HRESULT WINAPI
BindStatusCallback_GetPriority(IBindStatusCallback
*iface
, LONG
*pnPriority
)
153 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
155 TRACE("(%p)->(%p)\n", This
, pnPriority
);
157 return IBindStatusCallback_GetPriority(This
->callback
, pnPriority
);
160 static HRESULT WINAPI
BindStatusCallback_OnLowResource(IBindStatusCallback
*iface
, DWORD reserved
)
162 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
164 TRACE("(%p)->(%d)\n", This
, reserved
);
166 return IBindStatusCallback_OnLowResource(This
->callback
, reserved
);
169 static HRESULT WINAPI
BindStatusCallback_OnProgress(IBindStatusCallback
*iface
, ULONG ulProgress
,
170 ULONG ulProgressMax
, ULONG ulStatusCode
, LPCWSTR szStatusText
)
172 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
174 TRACE("%p)->(%u %u %u %s)\n", This
, ulProgress
, ulProgressMax
, ulStatusCode
,
175 debugstr_w(szStatusText
));
177 return IBindStatusCallback_OnProgress(This
->callback
, ulProgress
,
178 ulProgressMax
, ulStatusCode
, szStatusText
);
181 static HRESULT WINAPI
BindStatusCallback_OnStopBinding(IBindStatusCallback
*iface
,
182 HRESULT hresult
, LPCWSTR szError
)
184 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
186 TRACE("(%p)->(%08x %s)\n", This
, hresult
, debugstr_w(szError
));
188 return IBindStatusCallback_OnStopBinding(This
->callback
, hresult
, szError
);
191 static HRESULT WINAPI
BindStatusCallback_GetBindInfo(IBindStatusCallback
*iface
,
192 DWORD
*grfBINDF
, BINDINFO
*pbindinfo
)
194 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
196 TRACE("(%p)->(%p %p)\n", This
, grfBINDF
, pbindinfo
);
198 return IBindStatusCallback_GetBindInfo(This
->callback
, grfBINDF
, pbindinfo
);
201 static HRESULT WINAPI
BindStatusCallback_OnDataAvailable(IBindStatusCallback
*iface
,
202 DWORD grfBSCF
, DWORD dwSize
, FORMATETC
*pformatetc
, STGMEDIUM
*pstgmed
)
204 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
206 TRACE("(%p)->(%08x %d %p %p)\n", This
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
208 return IBindStatusCallback_OnDataAvailable(This
->callback
, grfBSCF
, dwSize
, pformatetc
, pstgmed
);
211 static HRESULT WINAPI
BindStatusCallback_OnObjectAvailable(IBindStatusCallback
*iface
,
212 REFIID riid
, IUnknown
*punk
)
214 BindStatusCallback
*This
= STATUSCLB_THIS(iface
);
216 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), punk
);
218 return IBindStatusCallback_OnObjectAvailable(This
->callback
, riid
, punk
);
221 #undef STATUSCLB_THIS
223 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl
= {
224 BindStatusCallback_QueryInterface
,
225 BindStatusCallback_AddRef
,
226 BindStatusCallback_Release
,
227 BindStatusCallback_OnStartBinding
,
228 BindStatusCallback_GetPriority
,
229 BindStatusCallback_OnLowResource
,
230 BindStatusCallback_OnProgress
,
231 BindStatusCallback_OnStopBinding
,
232 BindStatusCallback_GetBindInfo
,
233 BindStatusCallback_OnDataAvailable
,
234 BindStatusCallback_OnObjectAvailable
237 #define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface)
239 static HRESULT WINAPI
BSCServiceProvider_QueryInterface(IServiceProvider
*iface
,
240 REFIID riid
, void **ppv
)
242 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
243 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
246 static ULONG WINAPI
BSCServiceProvider_AddRef(IServiceProvider
*iface
)
248 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
249 return IBindStatusCallback_AddRef(STATUSCLB(This
));
252 static ULONG WINAPI
BSCServiceProvider_Release(IServiceProvider
*iface
)
254 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
255 return IBindStatusCallback_Release(STATUSCLB(This
));
258 static HRESULT WINAPI
BSCServiceProvider_QueryService(IServiceProvider
*iface
,
259 REFGUID guidService
, REFIID riid
, void **ppv
)
261 BindStatusCallback
*This
= SERVPROV_THIS(iface
);
264 if(IsEqualGUID(&IID_IHttpNegotiate
, guidService
)) {
265 TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
267 if(!This
->init_http_negotiate
) {
268 This
->init_http_negotiate
= TRUE
;
269 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IHttpNegotiate
,
270 (void**)&This
->http_negotiate
);
271 if(FAILED(hres
) && This
->serv_prov
)
272 IServiceProvider_QueryService(This
->serv_prov
, &IID_IHttpNegotiate
,
273 &IID_IHttpNegotiate
, (void**)&This
->http_negotiate
);
276 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
279 if(IsEqualGUID(&IID_IHttpNegotiate2
, guidService
)) {
280 TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This
, debugstr_guid(riid
), ppv
);
282 if(!This
->init_http_negotiate2
) {
283 This
->init_http_negotiate2
= TRUE
;
284 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IHttpNegotiate2
,
285 (void**)&This
->http_negotiate2
);
286 if(FAILED(hres
) && This
->serv_prov
)
287 IServiceProvider_QueryService(This
->serv_prov
, &IID_IHttpNegotiate2
,
288 &IID_IHttpNegotiate2
, (void**)&This
->http_negotiate2
);
291 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
294 if(IsEqualGUID(&IID_IAuthenticate
, guidService
)) {
295 TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This
, debugstr_guid(riid
), ppv
);
297 if(!This
->init_authenticate
) {
298 This
->init_authenticate
= TRUE
;
299 hres
= IBindStatusCallback_QueryInterface(This
->callback
, &IID_IAuthenticate
,
300 (void**)&This
->authenticate
);
301 if(FAILED(hres
) && This
->serv_prov
)
302 IServiceProvider_QueryService(This
->serv_prov
, &IID_IAuthenticate
,
303 &IID_IAuthenticate
, (void**)&This
->authenticate
);
306 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
309 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
311 hres
= IBindStatusCallback_QueryInterface(This
->callback
, riid
, ppv
);
315 if(This
->serv_prov
) {
316 hres
= IServiceProvider_QueryService(This
->serv_prov
, guidService
, riid
, ppv
);
321 return E_NOINTERFACE
;
326 static const IServiceProviderVtbl BSCServiceProviderVtbl
= {
327 BSCServiceProvider_QueryInterface
,
328 BSCServiceProvider_AddRef
,
329 BSCServiceProvider_Release
,
330 BSCServiceProvider_QueryService
333 #define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface)
335 static HRESULT WINAPI
BSCHttpNegotiate_QueryInterface(IHttpNegotiate2
*iface
,
336 REFIID riid
, void **ppv
)
338 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
339 return IBindStatusCallback_QueryInterface(STATUSCLB(This
), riid
, ppv
);
342 static ULONG WINAPI
BSCHttpNegotiate_AddRef(IHttpNegotiate2
*iface
)
344 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
345 return IBindStatusCallback_AddRef(STATUSCLB(This
));
348 static ULONG WINAPI
BSCHttpNegotiate_Release(IHttpNegotiate2
*iface
)
350 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
351 return IBindStatusCallback_Release(STATUSCLB(This
));
354 static HRESULT WINAPI
BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2
*iface
,
355 LPCWSTR szURL
, LPCWSTR szHeaders
, DWORD dwReserved
, LPWSTR
*pszAdditionalHeaders
)
357 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
359 TRACE("(%p)->(%s %s %d %p)\n", This
, debugstr_w(szURL
), debugstr_w(szHeaders
), dwReserved
,
360 pszAdditionalHeaders
);
362 *pszAdditionalHeaders
= NULL
;
364 if(!This
->http_negotiate
)
367 return IHttpNegotiate_BeginningTransaction(This
->http_negotiate
, szURL
, szHeaders
,
368 dwReserved
, pszAdditionalHeaders
);
371 static HRESULT WINAPI
BSCHttpNegotiate_OnResponse(IHttpNegotiate2
*iface
, DWORD dwResponseCode
,
372 LPCWSTR szResponseHeaders
, LPCWSTR szRequestHeaders
,
373 LPWSTR
*pszAdditionalRequestHeaders
)
375 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
376 LPWSTR additional_headers
= NULL
;
379 TRACE("(%p)->(%d %s %s %p)\n", This
, dwResponseCode
, debugstr_w(szResponseHeaders
),
380 debugstr_w(szRequestHeaders
), pszAdditionalRequestHeaders
);
382 if(This
->http_negotiate
)
383 hres
= IHttpNegotiate_OnResponse(This
->http_negotiate
, dwResponseCode
, szResponseHeaders
,
384 szRequestHeaders
, &additional_headers
);
386 if(pszAdditionalRequestHeaders
)
387 *pszAdditionalRequestHeaders
= additional_headers
;
388 else if(additional_headers
)
389 CoTaskMemFree(additional_headers
);
394 static HRESULT WINAPI
BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2
*iface
,
395 BYTE
*pbSecurityId
, DWORD
*pcbSecurityId
, DWORD_PTR dwReserved
)
397 BindStatusCallback
*This
= HTTPNEG2_THIS(iface
);
399 TRACE("(%p)->(%p %p %ld)\n", This
, pbSecurityId
, pcbSecurityId
, dwReserved
);
401 if(!This
->http_negotiate2
)
404 return IHttpNegotiate2_GetRootSecurityId(This
->http_negotiate2
, pbSecurityId
,
405 pcbSecurityId
, dwReserved
);
410 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl
= {
411 BSCHttpNegotiate_QueryInterface
,
412 BSCHttpNegotiate_AddRef
,
413 BSCHttpNegotiate_Release
,
414 BSCHttpNegotiate_BeginningTransaction
,
415 BSCHttpNegotiate_OnResponse
,
416 BSCHttpNegotiate_GetRootSecurityId
419 #define AUTHENTICATE_THIS(iface) DEFINE_THIS(BindStatusCallback, Authenticate, iface)
421 static HRESULT WINAPI
BSCAuthenticate_QueryInterface(IAuthenticate
*iface
, REFIID riid
, void **ppv
)
423 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
424 return IBindStatusCallback_QueryInterface(AUTHENTICATE(This
), riid
, ppv
);
427 static ULONG WINAPI
BSCAuthenticate_AddRef(IAuthenticate
*iface
)
429 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
430 return IBindStatusCallback_AddRef(STATUSCLB(This
));
433 static ULONG WINAPI
BSCAuthenticate_Release(IAuthenticate
*iface
)
435 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
436 return IBindStatusCallback_Release(STATUSCLB(This
));
439 static HRESULT WINAPI
BSCAuthenticate_Authenticate(IAuthenticate
*iface
,
440 HWND
*phwnd
, LPWSTR
*pszUsername
, LPWSTR
*pszPassword
)
442 BindStatusCallback
*This
= AUTHENTICATE_THIS(iface
);
443 FIXME("(%p)->(%p %p %p)\n", This
, phwnd
, pszUsername
, pszPassword
);
447 #undef AUTHENTICATE_THIS
449 static const IAuthenticateVtbl BSCAuthenticateVtbl
= {
450 BSCAuthenticate_QueryInterface
,
451 BSCAuthenticate_AddRef
,
452 BSCAuthenticate_Release
,
453 BSCAuthenticate_Authenticate
456 static IBindStatusCallback
*create_bsc(IBindStatusCallback
*bsc
)
458 BindStatusCallback
*ret
= heap_alloc_zero(sizeof(BindStatusCallback
));
460 ret
->lpBindStatusCallbackVtbl
= &BindStatusCallbackVtbl
;
461 ret
->lpServiceProviderVtbl
= &BSCServiceProviderVtbl
;
462 ret
->lpHttpNegotiate2Vtbl
= &BSCHttpNegotiateVtbl
;
463 ret
->lpAuthenticateVtbl
= &BSCAuthenticateVtbl
;
467 IBindStatusCallback_AddRef(bsc
);
470 IBindStatusCallback_QueryInterface(bsc
, &IID_IServiceProvider
, (void**)&ret
->serv_prov
);
472 return STATUSCLB(ret
);
475 /***********************************************************************
476 * RegisterBindStatusCallback (urlmon.@)
478 * Register a bind status callback.
481 * pbc [I] Binding context
482 * pbsc [I] Callback to register
483 * ppbscPrevious [O] Destination for previous callback
484 * dwReserved [I] Reserved, must be 0.
488 * Failure: E_INVALIDARG, if any argument is invalid, or
489 * E_OUTOFMEMORY if memory allocation fails.
491 HRESULT WINAPI
RegisterBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
,
492 IBindStatusCallback
**ppbscPrevious
, DWORD dwReserved
)
494 BindStatusCallback
*holder
;
495 IBindStatusCallback
*bsc
, *prev
= NULL
;
499 TRACE("(%p %p %p %x)\n", pbc
, pbsc
, ppbscPrevious
, dwReserved
);
504 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
505 if(SUCCEEDED(hres
)) {
506 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&bsc
);
507 if(SUCCEEDED(hres
)) {
508 hres
= IBindStatusCallback_QueryInterface(bsc
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
509 if(SUCCEEDED(hres
)) {
510 prev
= holder
->callback
;
511 IBindStatusCallback_AddRef(prev
);
512 IBindStatusCallback_Release(bsc
);
513 IBindStatusCallback_Release(STATUSCLB(holder
));
519 IUnknown_Release(unk
);
520 IBindCtx_RevokeObjectParam(pbc
, BSCBHolder
);
523 bsc
= create_bsc(pbsc
);
524 hres
= IBindCtx_RegisterObjectParam(pbc
, BSCBHolder
, (IUnknown
*)bsc
);
525 IBindStatusCallback_Release(bsc
);
527 IBindStatusCallback_Release(prev
);
532 *ppbscPrevious
= prev
;
536 /***********************************************************************
537 * RevokeBindStatusCallback (URLMON.@)
539 * Unregister a bind status callback.
541 * pbc [I] Binding context
542 * pbsc [I] Callback to unregister
546 * Failure: E_INVALIDARG, if any argument is invalid
548 HRESULT WINAPI
RevokeBindStatusCallback(IBindCtx
*pbc
, IBindStatusCallback
*pbsc
)
550 BindStatusCallback
*holder
;
551 IBindStatusCallback
*callback
;
553 BOOL dorevoke
= FALSE
;
556 TRACE("(%p %p)\n", pbc
, pbsc
);
561 hres
= IBindCtx_GetObjectParam(pbc
, BSCBHolder
, &unk
);
565 hres
= IUnknown_QueryInterface(unk
, &IID_IBindStatusCallback
, (void**)&callback
);
566 IUnknown_Release(unk
);
570 hres
= IBindStatusCallback_QueryInterface(callback
, &IID_IBindStatusCallbackHolder
, (void**)&holder
);
571 if(SUCCEEDED(hres
)) {
572 if(pbsc
== holder
->callback
)
574 IBindStatusCallback_Release(STATUSCLB(holder
));
575 }else if(pbsc
== callback
) {
578 IBindStatusCallback_Release(callback
);
581 IBindCtx_RevokeObjectParam(pbc
, BSCBHolder
);
587 const IBindCtxVtbl
*lpBindCtxVtbl
;
594 #define BINDCTX(x) ((IBindCtx*) &(x)->lpBindCtxVtbl)
596 #define BINDCTX_THIS(iface) DEFINE_THIS(AsyncBindCtx, BindCtx, iface)
598 static HRESULT WINAPI
AsyncBindCtx_QueryInterface(IBindCtx
*iface
, REFIID riid
, void **ppv
)
600 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
604 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
605 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
606 *ppv
= BINDCTX(This
);
607 }else if(IsEqualGUID(riid
, &IID_IBindCtx
)) {
608 TRACE("(%p)->(IID_IBindCtx %p)\n", This
, ppv
);
609 *ppv
= BINDCTX(This
);
610 }else if(IsEqualGUID(riid
, &IID_IAsyncBindCtx
)) {
611 TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This
, ppv
);
612 *ppv
= BINDCTX(This
);
616 IUnknown_AddRef((IUnknown
*)*ppv
);
620 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
621 return E_NOINTERFACE
;
624 static ULONG WINAPI
AsyncBindCtx_AddRef(IBindCtx
*iface
)
626 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
627 LONG ref
= InterlockedIncrement(&This
->ref
);
629 TRACE("(%p) ref=%d\n", This
, ref
);
634 static ULONG WINAPI
AsyncBindCtx_Release(IBindCtx
*iface
)
636 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
637 LONG ref
= InterlockedDecrement(&This
->ref
);
639 TRACE("(%p) ref=%d\n", This
, ref
);
642 IBindCtx_Release(This
->bindctx
);
649 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
651 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
653 TRACE("(%p)->(%p)\n", This
, punk
);
655 return IBindCtx_RegisterObjectBound(This
->bindctx
, punk
);
658 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectBound(IBindCtx
*iface
, IUnknown
*punk
)
660 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
662 TRACE("(%p %p)\n", This
, punk
);
664 return IBindCtx_RevokeObjectBound(This
->bindctx
, punk
);
667 static HRESULT WINAPI
AsyncBindCtx_ReleaseBoundObjects(IBindCtx
*iface
)
669 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
671 TRACE("(%p)\n", This
);
673 return IBindCtx_ReleaseBoundObjects(This
->bindctx
);
676 static HRESULT WINAPI
AsyncBindCtx_SetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
678 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
680 TRACE("(%p)->(%p)\n", This
, pbindopts
);
682 return IBindCtx_SetBindOptions(This
->bindctx
, pbindopts
);
685 static HRESULT WINAPI
AsyncBindCtx_GetBindOptions(IBindCtx
*iface
, BIND_OPTS
*pbindopts
)
687 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
689 TRACE("(%p)->(%p)\n", This
, pbindopts
);
691 return IBindCtx_GetBindOptions(This
->bindctx
, pbindopts
);
694 static HRESULT WINAPI
AsyncBindCtx_GetRunningObjectTable(IBindCtx
*iface
, IRunningObjectTable
**pprot
)
696 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
698 TRACE("(%p)->(%p)\n", This
, pprot
);
700 return IBindCtx_GetRunningObjectTable(This
->bindctx
, pprot
);
703 static HRESULT WINAPI
AsyncBindCtx_RegisterObjectParam(IBindCtx
*iface
, LPOLESTR pszkey
, IUnknown
*punk
)
705 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
707 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
709 return IBindCtx_RegisterObjectParam(This
->bindctx
, pszkey
, punk
);
712 static HRESULT WINAPI
AsyncBindCtx_GetObjectParam(IBindCtx
* iface
, LPOLESTR pszkey
, IUnknown
**punk
)
714 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
716 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pszkey
), punk
);
718 return IBindCtx_GetObjectParam(This
->bindctx
, pszkey
, punk
);
721 static HRESULT WINAPI
AsyncBindCtx_RevokeObjectParam(IBindCtx
*iface
, LPOLESTR ppenum
)
723 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
725 TRACE("(%p)->(%p)\n", This
, ppenum
);
727 return IBindCtx_RevokeObjectParam(This
->bindctx
, ppenum
);
730 static HRESULT WINAPI
AsyncBindCtx_EnumObjectParam(IBindCtx
*iface
, IEnumString
**pszkey
)
732 AsyncBindCtx
*This
= BINDCTX_THIS(iface
);
734 TRACE("(%p)->(%p)\n", This
, pszkey
);
736 return IBindCtx_EnumObjectParam(This
->bindctx
, pszkey
);
741 static const IBindCtxVtbl AsyncBindCtxVtbl
=
743 AsyncBindCtx_QueryInterface
,
745 AsyncBindCtx_Release
,
746 AsyncBindCtx_RegisterObjectBound
,
747 AsyncBindCtx_RevokeObjectBound
,
748 AsyncBindCtx_ReleaseBoundObjects
,
749 AsyncBindCtx_SetBindOptions
,
750 AsyncBindCtx_GetBindOptions
,
751 AsyncBindCtx_GetRunningObjectTable
,
752 AsyncBindCtx_RegisterObjectParam
,
753 AsyncBindCtx_GetObjectParam
,
754 AsyncBindCtx_EnumObjectParam
,
755 AsyncBindCtx_RevokeObjectParam
758 static HRESULT
init_bindctx(IBindCtx
*bindctx
, DWORD options
,
759 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
)
765 FIXME("not supported options %08x\n", options
);
767 FIXME("format is not supported\n");
769 bindopts
.cbStruct
= sizeof(BIND_OPTS
);
770 bindopts
.grfFlags
= BIND_MAYBOTHERUSER
;
771 bindopts
.grfMode
= STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
;
772 bindopts
.dwTickCountDeadline
= 0;
774 hres
= IBindCtx_SetBindOptions(bindctx
, &bindopts
);
779 hres
= RegisterBindStatusCallback(bindctx
, callback
, NULL
, 0);
787 /***********************************************************************
788 * CreateAsyncBindCtx (urlmon.@)
790 HRESULT WINAPI
CreateAsyncBindCtx(DWORD reserved
, IBindStatusCallback
*callback
,
791 IEnumFORMATETC
*format
, IBindCtx
**pbind
)
796 TRACE("(%08x %p %p %p)\n", reserved
, callback
, format
, pbind
);
798 if(!pbind
|| !callback
)
801 hres
= CreateBindCtx(0, &bindctx
);
805 hres
= init_bindctx(bindctx
, 0, callback
, format
);
807 IBindCtx_Release(bindctx
);
815 /***********************************************************************
816 * CreateAsyncBindCtxEx (urlmon.@)
818 * Create an asynchronous bind context.
820 HRESULT WINAPI
CreateAsyncBindCtxEx(IBindCtx
*ibind
, DWORD options
,
821 IBindStatusCallback
*callback
, IEnumFORMATETC
*format
, IBindCtx
** pbind
,
828 TRACE("(%p %08x %p %p %p %d)\n", ibind
, options
, callback
, format
, pbind
, reserved
);
834 WARN("reserved=%d\n", reserved
);
836 hres
= CreateBindCtx(0, &bindctx
);
840 ret
= heap_alloc(sizeof(AsyncBindCtx
));
842 ret
->lpBindCtxVtbl
= &AsyncBindCtxVtbl
;
844 ret
->bindctx
= bindctx
;
846 hres
= init_bindctx(BINDCTX(ret
), options
, callback
, format
);
848 IBindCtx_Release(BINDCTX(ret
));
852 *pbind
= BINDCTX(ret
);