push 97f44e0adb27fff75ba63d8fb97c65db9edfbe82
[wine/hacks.git] / dlls / urlmon / bindctx.c
blob13dd9876ea5a3020030a845765965336dd4c76a0
1 /*
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
19 #include <stdarg.h>
20 #include <stdio.h>
22 #define COBJMACROS
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
26 #include "windef.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "urlmon.h"
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;
43 typedef struct {
44 const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl;
45 const IServiceProviderVtbl *lpServiceProviderVtbl;
46 const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl;
47 const IAuthenticateVtbl *lpAuthenticateVtbl;
49 LONG ref;
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;
60 } BindStatusCallback;
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);
74 *ppv = NULL;
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);
84 *ppv = This;
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);
99 if(*ppv) {
100 IBindStatusCallback_AddRef((IUnknown*)*ppv);
101 return S_OK;
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);
115 return 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);
125 if(!ref) {
126 if(This->serv_prov)
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);
135 HeapFree(GetProcessHeap(), 0, This);
138 return ref;
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);
262 HRESULT hres;
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);
312 if(SUCCEEDED(hres))
313 return S_OK;
315 if(This->serv_prov) {
316 hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv);
317 if(SUCCEEDED(hres))
318 return S_OK;
321 return E_NOINTERFACE;
324 #undef SERVPROV_THIS
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)
365 return S_OK;
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;
377 HRESULT hres = S_OK;
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);
391 return hres;
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)
402 return E_FAIL;
404 return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId,
405 pcbSecurityId, dwReserved);
408 #undef HTTPNEG2_THIS
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);
444 return E_NOTIMPL;
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 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BindStatusCallback));
460 ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl;
461 ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl;
462 ret->lpHttpNegotiate2Vtbl = &BSCHttpNegotiateVtbl;
463 ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl;
465 ret->ref = 1;
467 IBindStatusCallback_AddRef(bsc);
468 ret->callback = 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.
480 * PARAMS
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.
486 * RETURNS
487 * Success: S_OK.
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;
496 IUnknown *unk;
497 HRESULT hres;
499 TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved);
501 if (!pbc || !pbsc)
502 return E_INVALIDARG;
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));
514 }else {
515 prev = bsc;
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);
526 if(FAILED(hres)) {
527 IBindStatusCallback_Release(prev);
528 return hres;
531 if(ppbscPrevious)
532 *ppbscPrevious = prev;
533 return S_OK;
536 /***********************************************************************
537 * RevokeBindStatusCallback (URLMON.@)
539 * Unregister a bind status callback.
541 * pbc [I] Binding context
542 * pbsc [I] Callback to unregister
544 * RETURNS
545 * Success: S_OK.
546 * Failure: E_INVALIDARG, if any argument is invalid
548 HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
550 BindStatusCallback *holder;
551 IBindStatusCallback *callback;
552 IUnknown *unk;
553 BOOL dorevoke = FALSE;
554 HRESULT hres;
556 TRACE("(%p %p)\n", pbc, pbsc);
558 if (!pbc || !pbsc)
559 return E_INVALIDARG;
561 hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
562 if(FAILED(hres))
563 return S_OK;
565 hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback);
566 IUnknown_Release(unk);
567 if(FAILED(hres))
568 return S_OK;
570 hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder);
571 if(SUCCEEDED(hres)) {
572 if(pbsc == holder->callback)
573 dorevoke = TRUE;
574 IBindStatusCallback_Release(STATUSCLB(holder));
575 }else if(pbsc == callback) {
576 dorevoke = TRUE;
578 IBindStatusCallback_Release(callback);
580 if(dorevoke)
581 IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
583 return S_OK;
586 typedef struct {
587 const IBindCtxVtbl *lpBindCtxVtbl;
589 LONG ref;
591 IBindCtx *bindctx;
592 } AsyncBindCtx;
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);
602 *ppv = NULL;
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);
615 if(*ppv) {
616 IUnknown_AddRef((IUnknown*)*ppv);
617 return S_OK;
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);
631 return 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);
641 if(!ref) {
642 IBindCtx_Release(This->bindctx);
643 HeapFree(GetProcessHeap(), 0, This);
646 return ref;
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);
739 #undef BINDCTX_THIS
741 static const IBindCtxVtbl AsyncBindCtxVtbl =
743 AsyncBindCtx_QueryInterface,
744 AsyncBindCtx_AddRef,
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)
761 BIND_OPTS bindopts;
762 HRESULT hres;
764 if(options)
765 FIXME("not supported options %08x\n", options);
766 if(format)
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);
775 if(FAILED(hres))
776 return hres;
778 if(callback) {
779 hres = RegisterBindStatusCallback(bindctx, callback, NULL, 0);
780 if(FAILED(hres))
781 return hres;
784 return S_OK;
787 /***********************************************************************
788 * CreateAsyncBindCtx (urlmon.@)
790 HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback,
791 IEnumFORMATETC *format, IBindCtx **pbind)
793 IBindCtx *bindctx;
794 HRESULT hres;
796 TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind);
798 if(!pbind || !callback)
799 return E_INVALIDARG;
801 hres = CreateBindCtx(0, &bindctx);
802 if(FAILED(hres))
803 return hres;
805 hres = init_bindctx(bindctx, 0, callback, format);
806 if(FAILED(hres)) {
807 IBindCtx_Release(bindctx);
808 return hres;
811 *pbind = bindctx;
812 return S_OK;
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,
822 DWORD reserved)
824 AsyncBindCtx *ret;
825 IBindCtx *bindctx;
826 HRESULT hres;
828 TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved);
830 if(!pbind)
831 return E_INVALIDARG;
833 if(reserved)
834 WARN("reserved=%d\n", reserved);
836 hres = CreateBindCtx(0, &bindctx);
837 if(FAILED(hres))
838 return hres;
840 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(AsyncBindCtx));
842 ret->lpBindCtxVtbl = &AsyncBindCtxVtbl;
843 ret->ref = 1;
844 ret->bindctx = bindctx;
846 hres = init_bindctx(BINDCTX(ret), options, callback, format);
847 if(FAILED(hres)) {
848 IBindCtx_Release(BINDCTX(ret));
849 return hres;
852 *pbind = BINDCTX(ret);
853 return S_OK;