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;
88 IBindStatusCallbackEx_Release(&holder->IBindStatusCallbackEx_iface);
92 static inline BindStatusCallback *impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx *iface)
94 return CONTAINING_RECORD(iface, BindStatusCallback, IBindStatusCallbackEx_iface);
97 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface,
98 REFIID riid, void **ppv)
100 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
104 if(IsEqualGUID(&IID_IUnknown, riid)) {
105 TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
106 *ppv = &This->IBindStatusCallbackEx_iface;
107 }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
108 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
109 *ppv = &This->IBindStatusCallbackEx_iface;
110 }else if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)) {
111 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
112 *ppv = &This->IBindStatusCallbackEx_iface;
113 }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) {
114 TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv);
116 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
117 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
118 *ppv = &This->IServiceProvider_iface;
119 }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
120 TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv);
121 *ppv = &This->IHttpNegotiate2_iface;
122 }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
123 TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv);
124 *ppv = &This->IHttpNegotiate2_iface;
125 }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
126 TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv);
127 *ppv = &This->IAuthenticate_iface;
131 IUnknown_AddRef((IUnknown*)*ppv);
135 TRACE("Unsupported riid = %s\n", debugstr_guid(riid));
136 return E_NOINTERFACE;
139 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
141 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
142 LONG ref = InterlockedIncrement(&This->ref);
144 TRACE("(%p) ref = %d\n", This, ref);
149 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
151 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
152 LONG ref = InterlockedDecrement(&This->ref);
154 TRACE("(%p) ref = %d\n", This, ref);
158 IServiceProvider_Release(This->serv_prov);
159 IBindStatusCallback_Release(This->callback);
166 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
167 DWORD dwReserved, IBinding *pbind)
169 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
171 TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
173 return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind);
176 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
178 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
180 TRACE("(%p)->(%p)\n", This, pnPriority);
182 return IBindStatusCallback_GetPriority(This->callback, pnPriority);
185 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
187 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
189 TRACE("(%p)->(%d)\n", This, reserved);
191 return IBindStatusCallback_OnLowResource(This->callback, reserved);
194 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
195 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
197 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
199 TRACE("%p)->(%u %u %s %s)\n", This, ulProgress, ulProgressMax, debugstr_bindstatus(ulStatusCode),
200 debugstr_w(szStatusText));
202 return IBindStatusCallback_OnProgress(This->callback, ulProgress,
203 ulProgressMax, ulStatusCode, szStatusText);
206 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface,
207 HRESULT hresult, LPCWSTR szError)
209 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
211 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
213 return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
216 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface,
217 DWORD *grfBINDF, BINDINFO *pbindinfo)
219 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
220 IBindStatusCallbackEx *bscex;
223 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
225 hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
226 if(SUCCEEDED(hres)) {
227 DWORD bindf2 = 0, reserv = 0;
229 hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, &bindf2, &reserv);
230 IBindStatusCallbackEx_Release(bscex);
232 hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
238 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface,
239 DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
241 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
243 TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
245 return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed);
248 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface,
249 REFIID riid, IUnknown *punk)
251 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
253 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
255 return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk);
258 static HRESULT WINAPI BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
259 BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
261 BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
262 IBindStatusCallbackEx *bscex;
265 TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
267 hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
268 if(SUCCEEDED(hres)) {
269 hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
270 IBindStatusCallbackEx_Release(bscex);
272 hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
278 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
279 BindStatusCallback_QueryInterface,
280 BindStatusCallback_AddRef,
281 BindStatusCallback_Release,
282 BindStatusCallback_OnStartBinding,
283 BindStatusCallback_GetPriority,
284 BindStatusCallback_OnLowResource,
285 BindStatusCallback_OnProgress,
286 BindStatusCallback_OnStopBinding,
287 BindStatusCallback_GetBindInfo,
288 BindStatusCallback_OnDataAvailable,
289 BindStatusCallback_OnObjectAvailable,
290 BindStatusCallback_GetBindInfoEx
293 static inline BindStatusCallback *impl_from_IServiceProvider(IServiceProvider *iface)
295 return CONTAINING_RECORD(iface, BindStatusCallback, IServiceProvider_iface);
298 static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface,
299 REFIID riid, void **ppv)
301 BindStatusCallback *This = impl_from_IServiceProvider(iface);
302 return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
305 static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface)
307 BindStatusCallback *This = impl_from_IServiceProvider(iface);
308 return IBindStatusCallbackEx_AddRef(&This->IBindStatusCallbackEx_iface);
311 static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface)
313 BindStatusCallback *This = impl_from_IServiceProvider(iface);
314 return IBindStatusCallbackEx_Release(&This->IBindStatusCallbackEx_iface);
317 static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface,
318 REFGUID guidService, REFIID riid, void **ppv)
320 BindStatusCallback *This = impl_from_IServiceProvider(iface);
323 if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) {
324 TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv);
325 return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
328 if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) {
329 TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv);
330 return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
333 if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
334 TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv);
335 return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
338 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
340 hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv);
344 if(This->serv_prov) {
345 hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv);
350 return E_NOINTERFACE;
353 static const IServiceProviderVtbl BSCServiceProviderVtbl = {
354 BSCServiceProvider_QueryInterface,
355 BSCServiceProvider_AddRef,
356 BSCServiceProvider_Release,
357 BSCServiceProvider_QueryService
360 static inline BindStatusCallback *impl_from_IHttpNegotiate2(IHttpNegotiate2 *iface)
362 return CONTAINING_RECORD(iface, BindStatusCallback, IHttpNegotiate2_iface);
365 static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface,
366 REFIID riid, void **ppv)
368 BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
369 return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
372 static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface)
374 BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
375 return IBindStatusCallbackEx_AddRef(&This->IBindStatusCallbackEx_iface);
378 static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface)
380 BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
381 return IBindStatusCallbackEx_Release(&This->IBindStatusCallbackEx_iface);
384 static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface,
385 LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
387 BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
388 IHttpNegotiate *http_negotiate;
391 TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
392 pszAdditionalHeaders);
394 *pszAdditionalHeaders = NULL;
396 http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
398 hres = IHttpNegotiate_BeginningTransaction(http_negotiate, szURL, szHeaders,
399 dwReserved, pszAdditionalHeaders);
400 IHttpNegotiate_Release(http_negotiate);
406 static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
407 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
408 LPWSTR *pszAdditionalRequestHeaders)
410 BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
411 LPWSTR additional_headers = NULL;
412 IHttpNegotiate *http_negotiate;
415 TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
416 debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
418 http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
420 hres = IHttpNegotiate_OnResponse(http_negotiate, dwResponseCode, szResponseHeaders,
421 szRequestHeaders, &additional_headers);
422 IHttpNegotiate_Release(http_negotiate);
425 if(pszAdditionalRequestHeaders)
426 *pszAdditionalRequestHeaders = additional_headers;
427 else if(additional_headers)
428 CoTaskMemFree(additional_headers);
433 static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
434 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
436 BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
437 IHttpNegotiate2 *http_negotiate2;
438 HRESULT hres = E_FAIL;
440 TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved);
442 http_negotiate2 = get_callback_iface(This, &IID_IHttpNegotiate2);
443 if(http_negotiate2) {
444 hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, pbSecurityId,
445 pcbSecurityId, dwReserved);
446 IHttpNegotiate2_Release(http_negotiate2);
452 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = {
453 BSCHttpNegotiate_QueryInterface,
454 BSCHttpNegotiate_AddRef,
455 BSCHttpNegotiate_Release,
456 BSCHttpNegotiate_BeginningTransaction,
457 BSCHttpNegotiate_OnResponse,
458 BSCHttpNegotiate_GetRootSecurityId
461 static inline BindStatusCallback *impl_from_IAuthenticate(IAuthenticate *iface)
463 return CONTAINING_RECORD(iface, BindStatusCallback, IAuthenticate_iface);
466 static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
468 BindStatusCallback *This = impl_from_IAuthenticate(iface);
469 return IBindStatusCallbackEx_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
472 static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface)
474 BindStatusCallback *This = impl_from_IAuthenticate(iface);
475 return IBindStatusCallbackEx_AddRef(&This->IBindStatusCallbackEx_iface);
478 static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface)
480 BindStatusCallback *This = impl_from_IAuthenticate(iface);
481 return IBindStatusCallbackEx_Release(&This->IBindStatusCallbackEx_iface);
484 static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface,
485 HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
487 BindStatusCallback *This = impl_from_IAuthenticate(iface);
488 FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
492 static const IAuthenticateVtbl BSCAuthenticateVtbl = {
493 BSCAuthenticate_QueryInterface,
494 BSCAuthenticate_AddRef,
495 BSCAuthenticate_Release,
496 BSCAuthenticate_Authenticate
499 static void set_callback(BindStatusCallback *This, IBindStatusCallback *bsc)
501 IServiceProvider *serv_prov;
505 IBindStatusCallback_Release(This->callback);
507 IServiceProvider_Release(This->serv_prov);
509 IBindStatusCallback_AddRef(bsc);
510 This->callback = bsc;
512 hres = IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&serv_prov);
513 This->serv_prov = hres == S_OK ? serv_prov : NULL;
516 HRESULT wrap_callback(IBindStatusCallback *bsc, IBindStatusCallback **ret_iface)
518 BindStatusCallback *ret;
520 ret = heap_alloc_zero(sizeof(BindStatusCallback));
522 return E_OUTOFMEMORY;
524 ret->IBindStatusCallbackEx_iface.lpVtbl = &BindStatusCallbackExVtbl;
525 ret->IServiceProvider_iface.lpVtbl = &BSCServiceProviderVtbl;
526 ret->IHttpNegotiate2_iface.lpVtbl = &BSCHttpNegotiateVtbl;
527 ret->IAuthenticate_iface.lpVtbl = &BSCAuthenticateVtbl;
530 set_callback(ret, bsc);
532 *ret_iface = (IBindStatusCallback*)&ret->IBindStatusCallbackEx_iface;
536 /***********************************************************************
537 * RegisterBindStatusCallback (urlmon.@)
539 * Register a bind status callback.
542 * pbc [I] Binding context
543 * pbsc [I] Callback to register
544 * ppbscPrevious [O] Destination for previous callback
545 * dwReserved [I] Reserved, must be 0.
549 * Failure: E_INVALIDARG, if any argument is invalid, or
550 * E_OUTOFMEMORY if memory allocation fails.
552 HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc,
553 IBindStatusCallback **ppbscPrevious, DWORD dwReserved)
555 BindStatusCallback *holder;
556 IBindStatusCallback *bsc, *prev = NULL;
559 TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved);
564 bsc = bsch_from_bctx(pbc);
566 hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
567 if(SUCCEEDED(hres)) {
569 IBindStatusCallback_AddRef(holder->callback);
570 *ppbscPrevious = holder->callback;
573 set_callback(holder, pbsc);
575 IBindStatusCallback_Release(bsc);
576 IBindStatusCallbackEx_Release(&holder->IBindStatusCallbackEx_iface);
582 IBindCtx_RevokeObjectParam(pbc, bscb_holderW);
585 hres = wrap_callback(pbsc, &bsc);
586 if(SUCCEEDED(hres)) {
587 hres = IBindCtx_RegisterObjectParam(pbc, bscb_holderW, (IUnknown*)bsc);
588 IBindStatusCallback_Release(bsc);
592 IBindStatusCallback_Release(prev);
597 *ppbscPrevious = prev;
601 /***********************************************************************
602 * RevokeBindStatusCallback (URLMON.@)
604 * Unregister a bind status callback.
606 * pbc [I] Binding context
607 * pbsc [I] Callback to unregister
611 * Failure: E_INVALIDARG, if any argument is invalid
613 HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
615 IBindStatusCallback *callback;
617 TRACE("(%p %p)\n", pbc, pbsc);
622 callback = bsc_from_bctx(pbc);
627 IBindCtx_RevokeObjectParam(pbc, bscb_holderW);
629 IBindStatusCallback_Release(callback);
634 IBindCtx IBindCtx_iface;
641 static inline AsyncBindCtx *impl_from_IBindCtx(IBindCtx *iface)
643 return CONTAINING_RECORD(iface, AsyncBindCtx, IBindCtx_iface);
646 static HRESULT WINAPI AsyncBindCtx_QueryInterface(IBindCtx *iface, REFIID riid, void **ppv)
648 AsyncBindCtx *This = impl_from_IBindCtx(iface);
652 if(IsEqualGUID(riid, &IID_IUnknown)) {
653 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
654 *ppv = &This->IBindCtx_iface;
655 }else if(IsEqualGUID(riid, &IID_IBindCtx)) {
656 TRACE("(%p)->(IID_IBindCtx %p)\n", This, ppv);
657 *ppv = &This->IBindCtx_iface;
658 }else if(IsEqualGUID(riid, &IID_IAsyncBindCtx)) {
659 TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This, ppv);
660 *ppv = &This->IBindCtx_iface;
664 IUnknown_AddRef((IUnknown*)*ppv);
668 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
669 return E_NOINTERFACE;
672 static ULONG WINAPI AsyncBindCtx_AddRef(IBindCtx *iface)
674 AsyncBindCtx *This = impl_from_IBindCtx(iface);
675 LONG ref = InterlockedIncrement(&This->ref);
677 TRACE("(%p) ref=%d\n", This, ref);
682 static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface)
684 AsyncBindCtx *This = impl_from_IBindCtx(iface);
685 LONG ref = InterlockedDecrement(&This->ref);
687 TRACE("(%p) ref=%d\n", This, ref);
690 IBindCtx_Release(This->bindctx);
697 static HRESULT WINAPI AsyncBindCtx_RegisterObjectBound(IBindCtx *iface, IUnknown *punk)
699 AsyncBindCtx *This = impl_from_IBindCtx(iface);
701 TRACE("(%p)->(%p)\n", This, punk);
703 return IBindCtx_RegisterObjectBound(This->bindctx, punk);
706 static HRESULT WINAPI AsyncBindCtx_RevokeObjectBound(IBindCtx *iface, IUnknown *punk)
708 AsyncBindCtx *This = impl_from_IBindCtx(iface);
710 TRACE("(%p %p)\n", This, punk);
712 return IBindCtx_RevokeObjectBound(This->bindctx, punk);
715 static HRESULT WINAPI AsyncBindCtx_ReleaseBoundObjects(IBindCtx *iface)
717 AsyncBindCtx *This = impl_from_IBindCtx(iface);
719 TRACE("(%p)\n", This);
721 return IBindCtx_ReleaseBoundObjects(This->bindctx);
724 static HRESULT WINAPI AsyncBindCtx_SetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
726 AsyncBindCtx *This = impl_from_IBindCtx(iface);
728 TRACE("(%p)->(%p)\n", This, pbindopts);
730 return IBindCtx_SetBindOptions(This->bindctx, pbindopts);
733 static HRESULT WINAPI AsyncBindCtx_GetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
735 AsyncBindCtx *This = impl_from_IBindCtx(iface);
737 TRACE("(%p)->(%p)\n", This, pbindopts);
739 return IBindCtx_GetBindOptions(This->bindctx, pbindopts);
742 static HRESULT WINAPI AsyncBindCtx_GetRunningObjectTable(IBindCtx *iface, IRunningObjectTable **pprot)
744 AsyncBindCtx *This = impl_from_IBindCtx(iface);
746 TRACE("(%p)->(%p)\n", This, pprot);
748 return IBindCtx_GetRunningObjectTable(This->bindctx, pprot);
751 static HRESULT WINAPI AsyncBindCtx_RegisterObjectParam(IBindCtx *iface, LPOLESTR pszkey, IUnknown *punk)
753 AsyncBindCtx *This = impl_from_IBindCtx(iface);
755 TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
757 return IBindCtx_RegisterObjectParam(This->bindctx, pszkey, punk);
760 static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszkey, IUnknown **punk)
762 AsyncBindCtx *This = impl_from_IBindCtx(iface);
764 TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
766 return IBindCtx_GetObjectParam(This->bindctx, pszkey, punk);
769 static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR pszkey)
771 AsyncBindCtx *This = impl_from_IBindCtx(iface);
773 TRACE("(%p)->(%s)\n", This, debugstr_w(pszkey));
775 return IBindCtx_RevokeObjectParam(This->bindctx, pszkey);
778 static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey)
780 AsyncBindCtx *This = impl_from_IBindCtx(iface);
782 TRACE("(%p)->(%p)\n", This, pszkey);
784 return IBindCtx_EnumObjectParam(This->bindctx, pszkey);
787 static const IBindCtxVtbl AsyncBindCtxVtbl =
789 AsyncBindCtx_QueryInterface,
791 AsyncBindCtx_Release,
792 AsyncBindCtx_RegisterObjectBound,
793 AsyncBindCtx_RevokeObjectBound,
794 AsyncBindCtx_ReleaseBoundObjects,
795 AsyncBindCtx_SetBindOptions,
796 AsyncBindCtx_GetBindOptions,
797 AsyncBindCtx_GetRunningObjectTable,
798 AsyncBindCtx_RegisterObjectParam,
799 AsyncBindCtx_GetObjectParam,
800 AsyncBindCtx_EnumObjectParam,
801 AsyncBindCtx_RevokeObjectParam
804 static HRESULT init_bindctx(IBindCtx *bindctx, DWORD options,
805 IBindStatusCallback *callback, IEnumFORMATETC *format)
811 FIXME("not supported options %08x\n", options);
813 FIXME("format is not supported\n");
815 bindopts.cbStruct = sizeof(BIND_OPTS);
816 bindopts.grfFlags = BIND_MAYBOTHERUSER;
817 bindopts.grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
818 bindopts.dwTickCountDeadline = 0;
820 hres = IBindCtx_SetBindOptions(bindctx, &bindopts);
825 hres = RegisterBindStatusCallback(bindctx, callback, NULL, 0);
833 /***********************************************************************
834 * CreateAsyncBindCtx (urlmon.@)
836 HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback,
837 IEnumFORMATETC *format, IBindCtx **pbind)
842 TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind);
844 if(!pbind || !callback)
847 hres = CreateBindCtx(0, &bindctx);
851 hres = init_bindctx(bindctx, 0, callback, format);
853 IBindCtx_Release(bindctx);
861 /***********************************************************************
862 * CreateAsyncBindCtxEx (urlmon.@)
864 * Create an asynchronous bind context.
866 HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
867 IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx** pbind,
874 TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved);
880 WARN("reserved=%d\n", reserved);
883 IBindCtx_AddRef(ibind);
886 hres = CreateBindCtx(0, &bindctx);
891 ret = heap_alloc(sizeof(AsyncBindCtx));
893 ret->IBindCtx_iface.lpVtbl = &AsyncBindCtxVtbl;
895 ret->bindctx = bindctx;
897 hres = init_bindctx(&ret->IBindCtx_iface, options, callback, format);
899 IBindCtx_Release(&ret->IBindCtx_iface);
903 *pbind = &ret->IBindCtx_iface;