~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/urlmon/bindctx.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright 2007 Jacek Caban for CodeWeavers
  3  *
  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.
  8  *
  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.
 13  *
 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
 17  */
 18 
 19 #include <stdio.h>
 20 
 21 #include "urlmon_main.h"
 22 #include "wine/debug.h"
 23 
 24 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
 25 
 26 static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
 27 
 28 extern IID IID_IBindStatusCallbackHolder;
 29 
 30 typedef struct {
 31     const IBindStatusCallbackExVtbl  *lpBindStatusCallbackExVtbl;
 32     const IServiceProviderVtbl       *lpServiceProviderVtbl;
 33     const IHttpNegotiate2Vtbl        *lpHttpNegotiate2Vtbl;
 34     const IAuthenticateVtbl          *lpAuthenticateVtbl;
 35 
 36     LONG ref;
 37 
 38     IBindStatusCallback *callback;
 39     IServiceProvider *serv_prov;
 40 } BindStatusCallback;
 41 
 42 #define STATUSCLB(x)     ((IBindStatusCallback*)  &(x)->lpBindStatusCallbackExVtbl)
 43 #define STATUSCLBEX(x)   ((IBindStatusCallbackEx*)&(x)->lpBindStatusCallbackExVtbl)
 44 #define SERVPROV(x)      ((IServiceProvider*)     &(x)->lpServiceProviderVtbl)
 45 #define HTTPNEG2(x)      ((IHttpNegotiate2*)      &(x)->lpHttpNegotiate2Vtbl)
 46 #define AUTHENTICATE(x)  ((IAuthenticate*)        &(x)->lpAuthenticateVtbl)
 47 
 48 static void *get_callback_iface(BindStatusCallback *This, REFIID riid)
 49 {
 50     void *ret;
 51     HRESULT hres;
 52 
 53     hres = IBindStatusCallback_QueryInterface(This->callback, riid, (void**)&ret);
 54     if(FAILED(hres) && This->serv_prov)
 55         hres = IServiceProvider_QueryService(This->serv_prov, riid, riid, &ret);
 56 
 57     return SUCCEEDED(hres) ? ret : NULL;
 58 }
 59 
 60 #define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallbackEx, iface)
 61 
 62 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface,
 63         REFIID riid, void **ppv)
 64 {
 65     BindStatusCallback *This = STATUSCLB_THIS(iface);
 66 
 67     *ppv = NULL;
 68 
 69     if(IsEqualGUID(&IID_IUnknown, riid)) {
 70         TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
 71         *ppv = STATUSCLB(This);
 72     }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
 73         TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
 74         *ppv = STATUSCLB(This);
 75     }else if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)) {
 76         TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
 77         *ppv = STATUSCLBEX(This);
 78     }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) {
 79         TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv);
 80         *ppv = This;
 81     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
 82         TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
 83         *ppv = SERVPROV(This);
 84     }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
 85         TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv);
 86         *ppv = HTTPNEG2(This);
 87     }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
 88         TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv);
 89         *ppv = HTTPNEG2(This);
 90     }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
 91         TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv);
 92         *ppv = AUTHENTICATE(This);
 93     }
 94 
 95     if(*ppv) {
 96         IBindStatusCallback_AddRef((IUnknown*)*ppv);
 97         return S_OK;
 98     }
 99 
100     TRACE("Unsupported riid = %s\n", debugstr_guid(riid));
101     return E_NOINTERFACE;
102 }
103 
104 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
105 {
106     BindStatusCallback *This = STATUSCLB_THIS(iface);
107     LONG ref = InterlockedIncrement(&This->ref);
108 
109     TRACE("(%p) ref = %d\n", This, ref);
110 
111     return ref;
112 }
113 
114 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
115 {
116     BindStatusCallback *This = STATUSCLB_THIS(iface);
117     LONG ref = InterlockedDecrement(&This->ref);
118 
119     TRACE("(%p) ref = %d\n", This, ref);
120 
121     if(!ref) {
122         if(This->serv_prov)
123             IServiceProvider_Release(This->serv_prov);
124         IBindStatusCallback_Release(This->callback);
125         heap_free(This);
126     }
127 
128     return ref;
129 }
130 
131 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
132         DWORD dwReserved, IBinding *pbind)
133 {
134     BindStatusCallback *This = STATUSCLB_THIS(iface);
135 
136     TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
137 
138     return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind);
139 }
140 
141 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
142 {
143     BindStatusCallback *This = STATUSCLB_THIS(iface);
144 
145     TRACE("(%p)->(%p)\n", This, pnPriority);
146 
147     return IBindStatusCallback_GetPriority(This->callback, pnPriority);
148 }
149 
150 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
151 {
152     BindStatusCallback *This = STATUSCLB_THIS(iface);
153 
154     TRACE("(%p)->(%d)\n", This, reserved);
155 
156     return IBindStatusCallback_OnLowResource(This->callback, reserved);
157 }
158 
159 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
160         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
161 {
162     BindStatusCallback *This = STATUSCLB_THIS(iface);
163 
164     TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
165             debugstr_w(szStatusText));
166 
167     return IBindStatusCallback_OnProgress(This->callback, ulProgress,
168             ulProgressMax, ulStatusCode, szStatusText);
169 }
170 
171 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface,
172         HRESULT hresult, LPCWSTR szError)
173 {
174     BindStatusCallback *This = STATUSCLB_THIS(iface);
175 
176     TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
177 
178     return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
179 }
180 
181 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface,
182         DWORD *grfBINDF, BINDINFO *pbindinfo)
183 {
184     BindStatusCallback *This = STATUSCLB_THIS(iface);
185     IBindStatusCallbackEx *bscex;
186     HRESULT hres;
187 
188     TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
189 
190     hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
191     if(SUCCEEDED(hres)) {
192         DWORD bindf2 = 0, reserv = 0;
193 
194         hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, &bindf2, &reserv);
195         IBindStatusCallbackEx_Release(bscex);
196     }else {
197         hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
198     }
199 
200     return hres;
201 }
202 
203 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface,
204         DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
205 {
206     BindStatusCallback *This = STATUSCLB_THIS(iface);
207 
208     TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
209 
210     return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed);
211 }
212 
213 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface,
214         REFIID riid, IUnknown *punk)
215 {
216     BindStatusCallback *This = STATUSCLB_THIS(iface);
217 
218     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
219 
220     return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk);
221 }
222 
223 static HRESULT WINAPI BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
224         BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
225 {
226     BindStatusCallback *This = STATUSCLB_THIS(iface);
227     IBindStatusCallbackEx *bscex;
228     HRESULT hres;
229 
230     TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
231 
232     hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
233     if(SUCCEEDED(hres)) {
234         hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
235         IBindStatusCallbackEx_Release(bscex);
236     }else {
237         hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
238     }
239 
240     return hres;
241 }
242 
243 #undef STATUSCLB_THIS
244 
245 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
246     BindStatusCallback_QueryInterface,
247     BindStatusCallback_AddRef,
248     BindStatusCallback_Release,
249     BindStatusCallback_OnStartBinding,
250     BindStatusCallback_GetPriority,
251     BindStatusCallback_OnLowResource,
252     BindStatusCallback_OnProgress,
253     BindStatusCallback_OnStopBinding,
254     BindStatusCallback_GetBindInfo,
255     BindStatusCallback_OnDataAvailable,
256     BindStatusCallback_OnObjectAvailable,
257     BindStatusCallback_GetBindInfoEx
258 };
259 
260 #define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface)
261 
262 static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface,
263         REFIID riid, void **ppv)
264 {
265     BindStatusCallback *This = SERVPROV_THIS(iface);
266     return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
267 }
268 
269 static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface)
270 {
271     BindStatusCallback *This = SERVPROV_THIS(iface);
272     return IBindStatusCallback_AddRef(STATUSCLB(This));
273 }
274 
275 static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface)
276 {
277     BindStatusCallback *This = SERVPROV_THIS(iface);
278     return IBindStatusCallback_Release(STATUSCLB(This));
279 }
280 
281 static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface,
282         REFGUID guidService, REFIID riid, void **ppv)
283 {
284     BindStatusCallback *This = SERVPROV_THIS(iface);
285     HRESULT hres;
286 
287     if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) {
288         TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv);
289         return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
290     }
291 
292     if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) {
293         TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv);
294         return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
295     }
296 
297     if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
298         TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv);
299         return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
300     }
301 
302     TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
303 
304     hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv);
305     if(SUCCEEDED(hres))
306         return S_OK;
307 
308     if(This->serv_prov) {
309         hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv);
310         if(SUCCEEDED(hres))
311             return S_OK;
312     }
313 
314     return E_NOINTERFACE;
315 }
316 
317 #undef SERVPROV_THIS
318 
319 static const IServiceProviderVtbl BSCServiceProviderVtbl = {
320     BSCServiceProvider_QueryInterface,
321     BSCServiceProvider_AddRef,
322     BSCServiceProvider_Release,
323     BSCServiceProvider_QueryService
324 };
325 
326 #define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface)
327 
328 static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface,
329         REFIID riid, void **ppv)
330 {
331     BindStatusCallback *This = HTTPNEG2_THIS(iface);
332     return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv);
333 }
334 
335 static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface)
336 {
337     BindStatusCallback *This = HTTPNEG2_THIS(iface);
338     return IBindStatusCallback_AddRef(STATUSCLB(This));
339 }
340 
341 static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface)
342 {
343     BindStatusCallback *This = HTTPNEG2_THIS(iface);
344     return IBindStatusCallback_Release(STATUSCLB(This));
345 }
346 
347 static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface,
348         LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
349 {
350     BindStatusCallback *This = HTTPNEG2_THIS(iface);
351     IHttpNegotiate *http_negotiate;
352     HRESULT hres = S_OK;
353 
354     TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
355           pszAdditionalHeaders);
356 
357     *pszAdditionalHeaders = NULL;
358 
359     http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
360     if(http_negotiate) {
361         hres = IHttpNegotiate_BeginningTransaction(http_negotiate, szURL, szHeaders,
362                 dwReserved, pszAdditionalHeaders);
363         IHttpNegotiate_Release(http_negotiate);
364     }
365 
366     return hres;
367 }
368 
369 static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
370         LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
371         LPWSTR *pszAdditionalRequestHeaders)
372 {
373     BindStatusCallback *This = HTTPNEG2_THIS(iface);
374     LPWSTR additional_headers = NULL;
375     IHttpNegotiate *http_negotiate;
376     HRESULT hres = S_OK;
377 
378     TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
379           debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
380 
381     http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
382     if(http_negotiate) {
383         hres = IHttpNegotiate_OnResponse(http_negotiate, dwResponseCode, szResponseHeaders,
384                 szRequestHeaders, &additional_headers);
385         IHttpNegotiate_Release(http_negotiate);
386     }
387 
388     if(pszAdditionalRequestHeaders)
389         *pszAdditionalRequestHeaders = additional_headers;
390     else if(additional_headers)
391         CoTaskMemFree(additional_headers);
392 
393     return hres;
394 }
395 
396 static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
397         BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
398 {
399     BindStatusCallback *This = HTTPNEG2_THIS(iface);
400     IHttpNegotiate2 *http_negotiate2;
401     HRESULT hres = E_FAIL;
402 
403     TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved);
404 
405     http_negotiate2 = get_callback_iface(This, &IID_IHttpNegotiate2);
406     if(http_negotiate2) {
407         hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, pbSecurityId,
408                 pcbSecurityId, dwReserved);
409         IHttpNegotiate2_Release(http_negotiate2);
410     }
411 
412     return hres;
413 }
414 
415 #undef HTTPNEG2_THIS
416 
417 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = {
418     BSCHttpNegotiate_QueryInterface,
419     BSCHttpNegotiate_AddRef,
420     BSCHttpNegotiate_Release,
421     BSCHttpNegotiate_BeginningTransaction,
422     BSCHttpNegotiate_OnResponse,
423     BSCHttpNegotiate_GetRootSecurityId
424 };
425 
426 #define AUTHENTICATE_THIS(iface)  DEFINE_THIS(BindStatusCallback, Authenticate, iface)
427 
428 static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
429 {
430     BindStatusCallback *This = AUTHENTICATE_THIS(iface);
431     return IBindStatusCallback_QueryInterface(AUTHENTICATE(This), riid, ppv);
432 }
433 
434 static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface)
435 {
436     BindStatusCallback *This = AUTHENTICATE_THIS(iface);
437     return IBindStatusCallback_AddRef(STATUSCLB(This));
438 }
439 
440 static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface)
441 {
442     BindStatusCallback *This = AUTHENTICATE_THIS(iface);
443     return IBindStatusCallback_Release(STATUSCLB(This));
444 }
445 
446 static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface,
447         HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
448 {
449     BindStatusCallback *This = AUTHENTICATE_THIS(iface);
450     FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
451     return E_NOTIMPL;
452 }
453 
454 #undef AUTHENTICATE_THIS
455 
456 static const IAuthenticateVtbl BSCAuthenticateVtbl = {
457     BSCAuthenticate_QueryInterface,
458     BSCAuthenticate_AddRef,
459     BSCAuthenticate_Release,
460     BSCAuthenticate_Authenticate
461 };
462 
463 static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc)
464 {
465     BindStatusCallback *ret = heap_alloc_zero(sizeof(BindStatusCallback));
466 
467     ret->lpBindStatusCallbackExVtbl = &BindStatusCallbackExVtbl;
468     ret->lpServiceProviderVtbl    = &BSCServiceProviderVtbl;
469     ret->lpHttpNegotiate2Vtbl     = &BSCHttpNegotiateVtbl;
470     ret->lpAuthenticateVtbl       = &BSCAuthenticateVtbl;
471 
472     ret->ref = 1;
473 
474     IBindStatusCallback_AddRef(bsc);
475     ret->callback = bsc;
476 
477     IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&ret->serv_prov);
478 
479     return STATUSCLB(ret);
480 }
481 
482 /***********************************************************************
483  *           RegisterBindStatusCallback (urlmon.@)
484  *
485  * Register a bind status callback.
486  *
487  * PARAMS
488  *  pbc           [I] Binding context
489  *  pbsc          [I] Callback to register
490  *  ppbscPrevious [O] Destination for previous callback
491  *  dwReserved    [I] Reserved, must be 0.
492  *
493  * RETURNS
494  *    Success: S_OK.
495  *    Failure: E_INVALIDARG, if any argument is invalid, or
496  *             E_OUTOFMEMORY if memory allocation fails.
497  */
498 HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc,
499         IBindStatusCallback **ppbscPrevious, DWORD dwReserved)
500 {
501     BindStatusCallback *holder;
502     IBindStatusCallback *bsc, *prev = NULL;
503     IUnknown *unk;
504     HRESULT hres;
505 
506     TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved);
507 
508     if (!pbc || !pbsc)
509         return E_INVALIDARG;
510 
511     hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
512     if(SUCCEEDED(hres)) {
513         hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc);
514         if(SUCCEEDED(hres)) {
515             hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
516             if(SUCCEEDED(hres)) {
517                 prev = holder->callback;
518                 IBindStatusCallback_AddRef(prev);
519                 IBindStatusCallback_Release(bsc);
520                 IBindStatusCallback_Release(STATUSCLB(holder));
521             }else {
522                 prev = bsc;
523             }
524         }
525 
526         IUnknown_Release(unk);
527         IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
528     }
529 
530     bsc = create_bsc(pbsc);
531     hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc);
532     IBindStatusCallback_Release(bsc);
533     if(FAILED(hres)) {
534         if(prev)
535             IBindStatusCallback_Release(prev);
536         return hres;
537     }
538 
539     if(ppbscPrevious)
540         *ppbscPrevious = prev;
541     return S_OK;
542 }
543 
544 /***********************************************************************
545  *           RevokeBindStatusCallback (URLMON.@)
546  *
547  * Unregister a bind status callback.
548  *
549  *  pbc           [I] Binding context
550  *  pbsc          [I] Callback to unregister
551  *
552  * RETURNS
553  *    Success: S_OK.
554  *    Failure: E_INVALIDARG, if any argument is invalid
555  */
556 HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
557 {
558     BindStatusCallback *holder;
559     IBindStatusCallback *callback;
560     IUnknown *unk;
561     BOOL dorevoke = FALSE;
562     HRESULT hres;
563 
564     TRACE("(%p %p)\n", pbc, pbsc);
565 
566     if (!pbc || !pbsc)
567         return E_INVALIDARG;
568 
569     hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
570     if(FAILED(hres))
571         return S_OK;
572 
573     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback);
574     IUnknown_Release(unk);
575     if(FAILED(hres))
576         return S_OK;
577 
578     hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder);
579     if(SUCCEEDED(hres)) {
580         if(pbsc == holder->callback)
581             dorevoke = TRUE;
582         IBindStatusCallback_Release(STATUSCLB(holder));
583     }else if(pbsc == callback) {
584         dorevoke = TRUE;
585     }
586     IBindStatusCallback_Release(callback);
587 
588     if(dorevoke)
589         IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
590 
591     return S_OK;
592 }
593 
594 typedef struct {
595     const IBindCtxVtbl *lpBindCtxVtbl;
596 
597     LONG ref;
598 
599     IBindCtx *bindctx;
600 } AsyncBindCtx;
601 
602 #define BINDCTX(x)  ((IBindCtx*)  &(x)->lpBindCtxVtbl)
603 
604 #define BINDCTX_THIS(iface) DEFINE_THIS(AsyncBindCtx, BindCtx, iface)
605 
606 static HRESULT WINAPI AsyncBindCtx_QueryInterface(IBindCtx *iface, REFIID riid, void **ppv)
607 {
608     AsyncBindCtx *This = BINDCTX_THIS(iface);
609 
610     *ppv = NULL;
611 
612     if(IsEqualGUID(riid, &IID_IUnknown)) {
613         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
614         *ppv = BINDCTX(This);
615     }else if(IsEqualGUID(riid, &IID_IBindCtx)) {
616         TRACE("(%p)->(IID_IBindCtx %p)\n", This, ppv);
617         *ppv = BINDCTX(This);
618     }else if(IsEqualGUID(riid, &IID_IAsyncBindCtx)) {
619         TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This, ppv);
620         *ppv = BINDCTX(This);
621     }
622 
623     if(*ppv) {
624         IUnknown_AddRef((IUnknown*)*ppv);
625         return S_OK;
626     }
627 
628     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
629     return E_NOINTERFACE;
630 }
631 
632 static ULONG WINAPI AsyncBindCtx_AddRef(IBindCtx *iface)
633 {
634     AsyncBindCtx *This = BINDCTX_THIS(iface);
635     LONG ref = InterlockedIncrement(&This->ref);
636 
637     TRACE("(%p) ref=%d\n", This, ref);
638 
639     return ref;
640 }
641 
642 static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface)
643 {
644     AsyncBindCtx *This = BINDCTX_THIS(iface);
645     LONG ref = InterlockedDecrement(&This->ref);
646 
647     TRACE("(%p) ref=%d\n", This, ref);
648 
649     if(!ref) {
650         IBindCtx_Release(This->bindctx);
651         heap_free(This);
652     }
653 
654     return ref;
655 }
656 
657 static HRESULT WINAPI AsyncBindCtx_RegisterObjectBound(IBindCtx *iface, IUnknown *punk)
658 {
659     AsyncBindCtx *This = BINDCTX_THIS(iface);
660 
661     TRACE("(%p)->(%p)\n", This, punk);
662 
663     return IBindCtx_RegisterObjectBound(This->bindctx, punk);
664 }
665 
666 static HRESULT WINAPI AsyncBindCtx_RevokeObjectBound(IBindCtx *iface, IUnknown *punk)
667 {
668     AsyncBindCtx *This = BINDCTX_THIS(iface);
669 
670     TRACE("(%p %p)\n", This, punk);
671 
672     return IBindCtx_RevokeObjectBound(This->bindctx, punk);
673 }
674 
675 static HRESULT WINAPI AsyncBindCtx_ReleaseBoundObjects(IBindCtx *iface)
676 {
677     AsyncBindCtx *This = BINDCTX_THIS(iface);
678 
679     TRACE("(%p)\n", This);
680 
681     return IBindCtx_ReleaseBoundObjects(This->bindctx);
682 }
683 
684 static HRESULT WINAPI AsyncBindCtx_SetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
685 {
686     AsyncBindCtx *This = BINDCTX_THIS(iface);
687 
688     TRACE("(%p)->(%p)\n", This, pbindopts);
689 
690     return IBindCtx_SetBindOptions(This->bindctx, pbindopts);
691 }
692 
693 static HRESULT WINAPI AsyncBindCtx_GetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
694 {
695     AsyncBindCtx *This = BINDCTX_THIS(iface);
696 
697     TRACE("(%p)->(%p)\n", This, pbindopts);
698 
699     return IBindCtx_GetBindOptions(This->bindctx, pbindopts);
700 }
701 
702 static HRESULT WINAPI AsyncBindCtx_GetRunningObjectTable(IBindCtx *iface, IRunningObjectTable **pprot)
703 {
704     AsyncBindCtx *This = BINDCTX_THIS(iface);
705 
706     TRACE("(%p)->(%p)\n", This, pprot);
707 
708     return IBindCtx_GetRunningObjectTable(This->bindctx, pprot);
709 }
710 
711 static HRESULT WINAPI AsyncBindCtx_RegisterObjectParam(IBindCtx *iface, LPOLESTR pszkey, IUnknown *punk)
712 {
713     AsyncBindCtx *This = BINDCTX_THIS(iface);
714 
715     TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
716 
717     return IBindCtx_RegisterObjectParam(This->bindctx, pszkey, punk);
718 }
719 
720 static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszkey, IUnknown **punk)
721 {
722     AsyncBindCtx *This = BINDCTX_THIS(iface);
723 
724     TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
725 
726     return IBindCtx_GetObjectParam(This->bindctx, pszkey, punk);
727 }
728 
729 static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR pszkey)
730 {
731     AsyncBindCtx *This = BINDCTX_THIS(iface);
732 
733     TRACE("(%p)->(%s)\n", This, debugstr_w(pszkey));
734 
735     return IBindCtx_RevokeObjectParam(This->bindctx, pszkey);
736 }
737 
738 static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey)
739 {
740     AsyncBindCtx *This = BINDCTX_THIS(iface);
741 
742     TRACE("(%p)->(%p)\n", This, pszkey);
743 
744     return IBindCtx_EnumObjectParam(This->bindctx, pszkey);
745 }
746 
747 #undef BINDCTX_THIS
748 
749 static const IBindCtxVtbl AsyncBindCtxVtbl =
750 {
751     AsyncBindCtx_QueryInterface,
752     AsyncBindCtx_AddRef,
753     AsyncBindCtx_Release,
754     AsyncBindCtx_RegisterObjectBound,
755     AsyncBindCtx_RevokeObjectBound,
756     AsyncBindCtx_ReleaseBoundObjects,
757     AsyncBindCtx_SetBindOptions,
758     AsyncBindCtx_GetBindOptions,
759     AsyncBindCtx_GetRunningObjectTable,
760     AsyncBindCtx_RegisterObjectParam,
761     AsyncBindCtx_GetObjectParam,
762     AsyncBindCtx_EnumObjectParam,
763     AsyncBindCtx_RevokeObjectParam
764 };
765 
766 static HRESULT init_bindctx(IBindCtx *bindctx, DWORD options,
767        IBindStatusCallback *callback, IEnumFORMATETC *format)
768 {
769     BIND_OPTS bindopts;
770     HRESULT hres;
771 
772     if(options)
773         FIXME("not supported options %08x\n", options);
774     if(format)
775         FIXME("format is not supported\n");
776 
777     bindopts.cbStruct = sizeof(BIND_OPTS);
778     bindopts.grfFlags = BIND_MAYBOTHERUSER;
779     bindopts.grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
780     bindopts.dwTickCountDeadline = 0;
781 
782     hres = IBindCtx_SetBindOptions(bindctx, &bindopts);
783     if(FAILED(hres))
784        return hres;
785 
786     if(callback) {
787         hres = RegisterBindStatusCallback(bindctx, callback, NULL, 0);
788         if(FAILED(hres))
789             return hres;
790     }
791 
792     return S_OK;
793 }
794 
795 /***********************************************************************
796  *           CreateAsyncBindCtx (urlmon.@)
797  */
798 HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback,
799         IEnumFORMATETC *format, IBindCtx **pbind)
800 {
801     IBindCtx *bindctx;
802     HRESULT hres;
803 
804     TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind);
805 
806     if(!pbind || !callback)
807         return E_INVALIDARG;
808 
809     hres = CreateBindCtx(0, &bindctx);
810     if(FAILED(hres))
811         return hres;
812 
813     hres = init_bindctx(bindctx, 0, callback, format);
814     if(FAILED(hres)) {
815         IBindCtx_Release(bindctx);
816         return hres;
817     }
818 
819     *pbind = bindctx;
820     return S_OK;
821 }
822 
823 /***********************************************************************
824  *           CreateAsyncBindCtxEx (urlmon.@)
825  *
826  * Create an asynchronous bind context.
827  */
828 HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
829         IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx** pbind,
830         DWORD reserved)
831 {
832     AsyncBindCtx *ret;
833     IBindCtx *bindctx;
834     HRESULT hres;
835 
836     TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved);
837 
838     if(!pbind)
839         return E_INVALIDARG;
840 
841     if(reserved)
842         WARN("reserved=%d\n", reserved);
843 
844     if(ibind) {
845         IBindCtx_AddRef(ibind);
846         bindctx = ibind;
847     }else {
848         hres = CreateBindCtx(0, &bindctx);
849         if(FAILED(hres))
850             return hres;
851     }
852 
853     ret = heap_alloc(sizeof(AsyncBindCtx));
854 
855     ret->lpBindCtxVtbl = &AsyncBindCtxVtbl;
856     ret->ref = 1;
857     ret->bindctx = bindctx;
858 
859     hres = init_bindctx(BINDCTX(ret), options, callback, format);
860     if(FAILED(hres)) {
861         IBindCtx_Release(BINDCTX(ret));
862         return hres;
863     }
864 
865     *pbind = BINDCTX(ret);
866     return S_OK;
867 }
868 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.