ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bindctx.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2007 Jacek Caban for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include <stdio.h>
00020 
00021 #include "urlmon_main.h"
00022 #include "wine/debug.h"
00023 
00024 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
00025 
00026 static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
00027 
00028 extern IID IID_IBindStatusCallbackHolder;
00029 
00030 typedef struct {
00031     IBindStatusCallbackEx IBindStatusCallbackEx_iface;
00032     IServiceProvider      IServiceProvider_iface;
00033     IHttpNegotiate2       IHttpNegotiate2_iface;
00034     IAuthenticate         IAuthenticate_iface;
00035 
00036     LONG ref;
00037 
00038     IBindStatusCallback *callback;
00039     IServiceProvider *serv_prov;
00040 } BindStatusCallback;
00041 
00042 static void *get_callback_iface(BindStatusCallback *This, REFIID riid)
00043 {
00044     void *ret;
00045     HRESULT hres;
00046 
00047     hres = IBindStatusCallback_QueryInterface(This->callback, riid, (void**)&ret);
00048     if(FAILED(hres) && This->serv_prov)
00049         hres = IServiceProvider_QueryService(This->serv_prov, riid, riid, &ret);
00050 
00051     return SUCCEEDED(hres) ? ret : NULL;
00052 }
00053 
00054 static inline BindStatusCallback *impl_from_IBindStatusCallbackEx(IBindStatusCallbackEx *iface)
00055 {
00056     return CONTAINING_RECORD(iface, BindStatusCallback, IBindStatusCallbackEx_iface);
00057 }
00058 
00059 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallbackEx *iface,
00060         REFIID riid, void **ppv)
00061 {
00062     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00063 
00064     *ppv = NULL;
00065 
00066     if(IsEqualGUID(&IID_IUnknown, riid)) {
00067         TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
00068         *ppv = &This->IBindStatusCallbackEx_iface;
00069     }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
00070         TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
00071         *ppv = &This->IBindStatusCallbackEx_iface;
00072     }else if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid)) {
00073         TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
00074         *ppv = &This->IBindStatusCallbackEx_iface;
00075     }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) {
00076         TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv);
00077         *ppv = This;
00078     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
00079         TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
00080         *ppv = &This->IServiceProvider_iface;
00081     }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
00082         TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv);
00083         *ppv = &This->IHttpNegotiate2_iface;
00084     }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
00085         TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv);
00086         *ppv = &This->IHttpNegotiate2_iface;
00087     }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
00088         TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv);
00089         *ppv = &This->IAuthenticate_iface;
00090     }
00091 
00092     if(*ppv) {
00093         IBindStatusCallback_AddRef((IUnknown*)*ppv);
00094         return S_OK;
00095     }
00096 
00097     TRACE("Unsupported riid = %s\n", debugstr_guid(riid));
00098     return E_NOINTERFACE;
00099 }
00100 
00101 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallbackEx *iface)
00102 {
00103     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00104     LONG ref = InterlockedIncrement(&This->ref);
00105 
00106     TRACE("(%p) ref = %d\n", This, ref);
00107 
00108     return ref;
00109 }
00110 
00111 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallbackEx *iface)
00112 {
00113     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00114     LONG ref = InterlockedDecrement(&This->ref);
00115 
00116     TRACE("(%p) ref = %d\n", This, ref);
00117 
00118     if(!ref) {
00119         if(This->serv_prov)
00120             IServiceProvider_Release(This->serv_prov);
00121         IBindStatusCallback_Release(This->callback);
00122         heap_free(This);
00123     }
00124 
00125     return ref;
00126 }
00127 
00128 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallbackEx *iface,
00129         DWORD dwReserved, IBinding *pbind)
00130 {
00131     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00132 
00133     TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind);
00134 
00135     return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind);
00136 }
00137 
00138 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
00139 {
00140     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00141 
00142     TRACE("(%p)->(%p)\n", This, pnPriority);
00143 
00144     return IBindStatusCallback_GetPriority(This->callback, pnPriority);
00145 }
00146 
00147 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
00148 {
00149     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00150 
00151     TRACE("(%p)->(%d)\n", This, reserved);
00152 
00153     return IBindStatusCallback_OnLowResource(This->callback, reserved);
00154 }
00155 
00156 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
00157         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
00158 {
00159     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00160 
00161     TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
00162             debugstr_w(szStatusText));
00163 
00164     return IBindStatusCallback_OnProgress(This->callback, ulProgress,
00165             ulProgressMax, ulStatusCode, szStatusText);
00166 }
00167 
00168 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallbackEx *iface,
00169         HRESULT hresult, LPCWSTR szError)
00170 {
00171     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00172 
00173     TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
00174 
00175     return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError);
00176 }
00177 
00178 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallbackEx *iface,
00179         DWORD *grfBINDF, BINDINFO *pbindinfo)
00180 {
00181     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00182     IBindStatusCallbackEx *bscex;
00183     HRESULT hres;
00184 
00185     TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
00186 
00187     hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
00188     if(SUCCEEDED(hres)) {
00189         DWORD bindf2 = 0, reserv = 0;
00190 
00191         hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, &bindf2, &reserv);
00192         IBindStatusCallbackEx_Release(bscex);
00193     }else {
00194         hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
00195     }
00196 
00197     return hres;
00198 }
00199 
00200 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallbackEx *iface,
00201         DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
00202 {
00203     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00204 
00205     TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
00206 
00207     return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed);
00208 }
00209 
00210 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallbackEx *iface,
00211         REFIID riid, IUnknown *punk)
00212 {
00213     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00214 
00215     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
00216 
00217     return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk);
00218 }
00219 
00220 static HRESULT WINAPI BindStatusCallback_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF,
00221         BINDINFO *pbindinfo, DWORD *grfBINDF2, DWORD *pdwReserved)
00222 {
00223     BindStatusCallback *This = impl_from_IBindStatusCallbackEx(iface);
00224     IBindStatusCallbackEx *bscex;
00225     HRESULT hres;
00226 
00227     TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
00228 
00229     hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IBindStatusCallbackEx, (void**)&bscex);
00230     if(SUCCEEDED(hres)) {
00231         hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, grfBINDF, pbindinfo, grfBINDF2, pdwReserved);
00232         IBindStatusCallbackEx_Release(bscex);
00233     }else {
00234         hres = IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo);
00235     }
00236 
00237     return hres;
00238 }
00239 
00240 static const IBindStatusCallbackExVtbl BindStatusCallbackExVtbl = {
00241     BindStatusCallback_QueryInterface,
00242     BindStatusCallback_AddRef,
00243     BindStatusCallback_Release,
00244     BindStatusCallback_OnStartBinding,
00245     BindStatusCallback_GetPriority,
00246     BindStatusCallback_OnLowResource,
00247     BindStatusCallback_OnProgress,
00248     BindStatusCallback_OnStopBinding,
00249     BindStatusCallback_GetBindInfo,
00250     BindStatusCallback_OnDataAvailable,
00251     BindStatusCallback_OnObjectAvailable,
00252     BindStatusCallback_GetBindInfoEx
00253 };
00254 
00255 static inline BindStatusCallback *impl_from_IServiceProvider(IServiceProvider *iface)
00256 {
00257     return CONTAINING_RECORD(iface, BindStatusCallback, IServiceProvider_iface);
00258 }
00259 
00260 static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface,
00261         REFIID riid, void **ppv)
00262 {
00263     BindStatusCallback *This = impl_from_IServiceProvider(iface);
00264     return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
00265 }
00266 
00267 static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface)
00268 {
00269     BindStatusCallback *This = impl_from_IServiceProvider(iface);
00270     return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
00271 }
00272 
00273 static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface)
00274 {
00275     BindStatusCallback *This = impl_from_IServiceProvider(iface);
00276     return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
00277 }
00278 
00279 static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface,
00280         REFGUID guidService, REFIID riid, void **ppv)
00281 {
00282     BindStatusCallback *This = impl_from_IServiceProvider(iface);
00283     HRESULT hres;
00284 
00285     if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) {
00286         TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv);
00287         return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
00288     }
00289 
00290     if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) {
00291         TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv);
00292         return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
00293     }
00294 
00295     if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
00296         TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv);
00297         return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
00298     }
00299 
00300     TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
00301 
00302     hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv);
00303     if(SUCCEEDED(hres))
00304         return S_OK;
00305 
00306     if(This->serv_prov) {
00307         hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv);
00308         if(SUCCEEDED(hres))
00309             return S_OK;
00310     }
00311 
00312     return E_NOINTERFACE;
00313 }
00314 
00315 static const IServiceProviderVtbl BSCServiceProviderVtbl = {
00316     BSCServiceProvider_QueryInterface,
00317     BSCServiceProvider_AddRef,
00318     BSCServiceProvider_Release,
00319     BSCServiceProvider_QueryService
00320 };
00321 
00322 static inline BindStatusCallback *impl_from_IHttpNegotiate2(IHttpNegotiate2 *iface)
00323 {
00324     return CONTAINING_RECORD(iface, BindStatusCallback, IHttpNegotiate2_iface);
00325 }
00326 
00327 static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface,
00328         REFIID riid, void **ppv)
00329 {
00330     BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
00331     return IBindStatusCallback_QueryInterface(&This->IBindStatusCallbackEx_iface, riid, ppv);
00332 }
00333 
00334 static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface)
00335 {
00336     BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
00337     return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
00338 }
00339 
00340 static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface)
00341 {
00342     BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
00343     return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
00344 }
00345 
00346 static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface,
00347         LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
00348 {
00349     BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
00350     IHttpNegotiate *http_negotiate;
00351     HRESULT hres = S_OK;
00352 
00353     TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
00354           pszAdditionalHeaders);
00355 
00356     *pszAdditionalHeaders = NULL;
00357 
00358     http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
00359     if(http_negotiate) {
00360         hres = IHttpNegotiate_BeginningTransaction(http_negotiate, szURL, szHeaders,
00361                 dwReserved, pszAdditionalHeaders);
00362         IHttpNegotiate_Release(http_negotiate);
00363     }
00364 
00365     return hres;
00366 }
00367 
00368 static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
00369         LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,
00370         LPWSTR *pszAdditionalRequestHeaders)
00371 {
00372     BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
00373     LPWSTR additional_headers = NULL;
00374     IHttpNegotiate *http_negotiate;
00375     HRESULT hres = S_OK;
00376 
00377     TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
00378           debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
00379 
00380     http_negotiate = get_callback_iface(This, &IID_IHttpNegotiate);
00381     if(http_negotiate) {
00382         hres = IHttpNegotiate_OnResponse(http_negotiate, dwResponseCode, szResponseHeaders,
00383                 szRequestHeaders, &additional_headers);
00384         IHttpNegotiate_Release(http_negotiate);
00385     }
00386 
00387     if(pszAdditionalRequestHeaders)
00388         *pszAdditionalRequestHeaders = additional_headers;
00389     else if(additional_headers)
00390         CoTaskMemFree(additional_headers);
00391 
00392     return hres;
00393 }
00394 
00395 static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
00396         BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
00397 {
00398     BindStatusCallback *This = impl_from_IHttpNegotiate2(iface);
00399     IHttpNegotiate2 *http_negotiate2;
00400     HRESULT hres = E_FAIL;
00401 
00402     TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved);
00403 
00404     http_negotiate2 = get_callback_iface(This, &IID_IHttpNegotiate2);
00405     if(http_negotiate2) {
00406         hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, pbSecurityId,
00407                 pcbSecurityId, dwReserved);
00408         IHttpNegotiate2_Release(http_negotiate2);
00409     }
00410 
00411     return hres;
00412 }
00413 
00414 static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = {
00415     BSCHttpNegotiate_QueryInterface,
00416     BSCHttpNegotiate_AddRef,
00417     BSCHttpNegotiate_Release,
00418     BSCHttpNegotiate_BeginningTransaction,
00419     BSCHttpNegotiate_OnResponse,
00420     BSCHttpNegotiate_GetRootSecurityId
00421 };
00422 
00423 static inline BindStatusCallback *impl_from_IAuthenticate(IAuthenticate *iface)
00424 {
00425     return CONTAINING_RECORD(iface, BindStatusCallback, IAuthenticate_iface);
00426 }
00427 
00428 static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
00429 {
00430     BindStatusCallback *This = impl_from_IAuthenticate(iface);
00431     return IBindStatusCallback_QueryInterface(&This->IAuthenticate_iface, riid, ppv);
00432 }
00433 
00434 static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface)
00435 {
00436     BindStatusCallback *This = impl_from_IAuthenticate(iface);
00437     return IBindStatusCallback_AddRef(&This->IBindStatusCallbackEx_iface);
00438 }
00439 
00440 static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface)
00441 {
00442     BindStatusCallback *This = impl_from_IAuthenticate(iface);
00443     return IBindStatusCallback_Release(&This->IBindStatusCallbackEx_iface);
00444 }
00445 
00446 static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface,
00447         HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
00448 {
00449     BindStatusCallback *This = impl_from_IAuthenticate(iface);
00450     FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
00451     return E_NOTIMPL;
00452 }
00453 
00454 static const IAuthenticateVtbl BSCAuthenticateVtbl = {
00455     BSCAuthenticate_QueryInterface,
00456     BSCAuthenticate_AddRef,
00457     BSCAuthenticate_Release,
00458     BSCAuthenticate_Authenticate
00459 };
00460 
00461 static void set_callback(BindStatusCallback *This, IBindStatusCallback *bsc)
00462 {
00463     IServiceProvider *serv_prov;
00464     HRESULT hres;
00465 
00466     if(This->callback)
00467         IBindStatusCallback_Release(This->callback);
00468     if(This->serv_prov)
00469         IServiceProvider_Release(This->serv_prov);
00470 
00471     IBindStatusCallback_AddRef(bsc);
00472     This->callback = bsc;
00473 
00474     hres = IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&serv_prov);
00475     This->serv_prov = hres == S_OK ? serv_prov : NULL;
00476 }
00477 
00478 HRESULT wrap_callback(IBindStatusCallback *bsc, IBindStatusCallback **ret_iface)
00479 {
00480     BindStatusCallback *ret;
00481 
00482     ret = heap_alloc_zero(sizeof(BindStatusCallback));
00483     if(!ret)
00484         return E_OUTOFMEMORY;
00485 
00486     ret->IBindStatusCallbackEx_iface.lpVtbl = &BindStatusCallbackExVtbl;
00487     ret->IServiceProvider_iface.lpVtbl = &BSCServiceProviderVtbl;
00488     ret->IHttpNegotiate2_iface.lpVtbl = &BSCHttpNegotiateVtbl;
00489     ret->IAuthenticate_iface.lpVtbl = &BSCAuthenticateVtbl;
00490 
00491     ret->ref = 1;
00492     set_callback(ret, bsc);
00493 
00494     *ret_iface = (IBindStatusCallback*)&ret->IBindStatusCallbackEx_iface;
00495     return S_OK;
00496 }
00497 
00498 /***********************************************************************
00499  *           RegisterBindStatusCallback (urlmon.@)
00500  *
00501  * Register a bind status callback.
00502  *
00503  * PARAMS
00504  *  pbc           [I] Binding context
00505  *  pbsc          [I] Callback to register
00506  *  ppbscPrevious [O] Destination for previous callback
00507  *  dwReserved    [I] Reserved, must be 0.
00508  *
00509  * RETURNS
00510  *    Success: S_OK.
00511  *    Failure: E_INVALIDARG, if any argument is invalid, or
00512  *             E_OUTOFMEMORY if memory allocation fails.
00513  */
00514 HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc,
00515         IBindStatusCallback **ppbscPrevious, DWORD dwReserved)
00516 {
00517     BindStatusCallback *holder;
00518     IBindStatusCallback *bsc, *prev = NULL;
00519     IUnknown *unk;
00520     HRESULT hres;
00521 
00522     TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved);
00523 
00524     if (!pbc || !pbsc)
00525         return E_INVALIDARG;
00526 
00527     hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
00528     if(SUCCEEDED(hres)) {
00529         hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc);
00530         IUnknown_Release(unk);
00531         if(SUCCEEDED(hres)) {
00532             hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
00533             if(SUCCEEDED(hres)) {
00534                 if(ppbscPrevious) {
00535                     IBindStatusCallback_AddRef(holder->callback);
00536                     *ppbscPrevious = holder->callback;
00537                 }
00538 
00539                 set_callback(holder, pbsc);
00540 
00541                 IBindStatusCallback_Release(bsc);
00542                 IBindStatusCallback_Release(&holder->IBindStatusCallbackEx_iface);
00543                 return S_OK;
00544             }else {
00545                 prev = bsc;
00546             }
00547         }
00548 
00549         IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
00550     }
00551 
00552     hres = wrap_callback(pbsc, &bsc);
00553     if(SUCCEEDED(hres)) {
00554         hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc);
00555         IBindStatusCallback_Release(bsc);
00556     }
00557     if(FAILED(hres)) {
00558         if(prev)
00559             IBindStatusCallback_Release(prev);
00560         return hres;
00561     }
00562 
00563     if(ppbscPrevious)
00564         *ppbscPrevious = prev;
00565     return S_OK;
00566 }
00567 
00568 /***********************************************************************
00569  *           RevokeBindStatusCallback (URLMON.@)
00570  *
00571  * Unregister a bind status callback.
00572  *
00573  *  pbc           [I] Binding context
00574  *  pbsc          [I] Callback to unregister
00575  *
00576  * RETURNS
00577  *    Success: S_OK.
00578  *    Failure: E_INVALIDARG, if any argument is invalid
00579  */
00580 HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
00581 {
00582     BindStatusCallback *holder;
00583     IBindStatusCallback *callback;
00584     IUnknown *unk;
00585     BOOL dorevoke = FALSE;
00586     HRESULT hres;
00587 
00588     TRACE("(%p %p)\n", pbc, pbsc);
00589 
00590     if (!pbc || !pbsc)
00591         return E_INVALIDARG;
00592 
00593     hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
00594     if(FAILED(hres))
00595         return S_OK;
00596 
00597     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback);
00598     IUnknown_Release(unk);
00599     if(FAILED(hres))
00600         return S_OK;
00601 
00602     hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder);
00603     if(SUCCEEDED(hres)) {
00604         if(pbsc == holder->callback)
00605             dorevoke = TRUE;
00606         IBindStatusCallback_Release(&holder->IBindStatusCallbackEx_iface);
00607     }else if(pbsc == callback) {
00608         dorevoke = TRUE;
00609     }
00610     IBindStatusCallback_Release(callback);
00611 
00612     if(dorevoke)
00613         IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
00614 
00615     return S_OK;
00616 }
00617 
00618 typedef struct {
00619     IBindCtx IBindCtx_iface;
00620 
00621     LONG ref;
00622 
00623     IBindCtx *bindctx;
00624 } AsyncBindCtx;
00625 
00626 static inline AsyncBindCtx *impl_from_IBindCtx(IBindCtx *iface)
00627 {
00628     return CONTAINING_RECORD(iface, AsyncBindCtx, IBindCtx_iface);
00629 }
00630 
00631 static HRESULT WINAPI AsyncBindCtx_QueryInterface(IBindCtx *iface, REFIID riid, void **ppv)
00632 {
00633     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00634 
00635     *ppv = NULL;
00636 
00637     if(IsEqualGUID(riid, &IID_IUnknown)) {
00638         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
00639         *ppv = &This->IBindCtx_iface;
00640     }else if(IsEqualGUID(riid, &IID_IBindCtx)) {
00641         TRACE("(%p)->(IID_IBindCtx %p)\n", This, ppv);
00642         *ppv = &This->IBindCtx_iface;
00643     }else if(IsEqualGUID(riid, &IID_IAsyncBindCtx)) {
00644         TRACE("(%p)->(IID_IAsyncBindCtx %p)\n", This, ppv);
00645         *ppv = &This->IBindCtx_iface;
00646     }
00647 
00648     if(*ppv) {
00649         IUnknown_AddRef((IUnknown*)*ppv);
00650         return S_OK;
00651     }
00652 
00653     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
00654     return E_NOINTERFACE;
00655 }
00656 
00657 static ULONG WINAPI AsyncBindCtx_AddRef(IBindCtx *iface)
00658 {
00659     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00660     LONG ref = InterlockedIncrement(&This->ref);
00661 
00662     TRACE("(%p) ref=%d\n", This, ref);
00663 
00664     return ref;
00665 }
00666 
00667 static ULONG WINAPI AsyncBindCtx_Release(IBindCtx *iface)
00668 {
00669     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00670     LONG ref = InterlockedDecrement(&This->ref);
00671 
00672     TRACE("(%p) ref=%d\n", This, ref);
00673 
00674     if(!ref) {
00675         IBindCtx_Release(This->bindctx);
00676         heap_free(This);
00677     }
00678 
00679     return ref;
00680 }
00681 
00682 static HRESULT WINAPI AsyncBindCtx_RegisterObjectBound(IBindCtx *iface, IUnknown *punk)
00683 {
00684     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00685 
00686     TRACE("(%p)->(%p)\n", This, punk);
00687 
00688     return IBindCtx_RegisterObjectBound(This->bindctx, punk);
00689 }
00690 
00691 static HRESULT WINAPI AsyncBindCtx_RevokeObjectBound(IBindCtx *iface, IUnknown *punk)
00692 {
00693     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00694 
00695     TRACE("(%p %p)\n", This, punk);
00696 
00697     return IBindCtx_RevokeObjectBound(This->bindctx, punk);
00698 }
00699 
00700 static HRESULT WINAPI AsyncBindCtx_ReleaseBoundObjects(IBindCtx *iface)
00701 {
00702     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00703 
00704     TRACE("(%p)\n", This);
00705 
00706     return IBindCtx_ReleaseBoundObjects(This->bindctx);
00707 }
00708 
00709 static HRESULT WINAPI AsyncBindCtx_SetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
00710 {
00711     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00712 
00713     TRACE("(%p)->(%p)\n", This, pbindopts);
00714 
00715     return IBindCtx_SetBindOptions(This->bindctx, pbindopts);
00716 }
00717 
00718 static HRESULT WINAPI AsyncBindCtx_GetBindOptions(IBindCtx *iface, BIND_OPTS *pbindopts)
00719 {
00720     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00721 
00722     TRACE("(%p)->(%p)\n", This, pbindopts);
00723 
00724     return IBindCtx_GetBindOptions(This->bindctx, pbindopts);
00725 }
00726 
00727 static HRESULT WINAPI AsyncBindCtx_GetRunningObjectTable(IBindCtx *iface, IRunningObjectTable **pprot)
00728 {
00729     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00730 
00731     TRACE("(%p)->(%p)\n", This, pprot);
00732 
00733     return IBindCtx_GetRunningObjectTable(This->bindctx, pprot);
00734 }
00735 
00736 static HRESULT WINAPI AsyncBindCtx_RegisterObjectParam(IBindCtx *iface, LPOLESTR pszkey, IUnknown *punk)
00737 {
00738     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00739 
00740     TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
00741 
00742     return IBindCtx_RegisterObjectParam(This->bindctx, pszkey, punk);
00743 }
00744 
00745 static HRESULT WINAPI AsyncBindCtx_GetObjectParam(IBindCtx* iface, LPOLESTR pszkey, IUnknown **punk)
00746 {
00747     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00748 
00749     TRACE("(%p)->(%s %p)\n", This, debugstr_w(pszkey), punk);
00750 
00751     return IBindCtx_GetObjectParam(This->bindctx, pszkey, punk);
00752 }
00753 
00754 static HRESULT WINAPI AsyncBindCtx_RevokeObjectParam(IBindCtx *iface, LPOLESTR pszkey)
00755 {
00756     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00757 
00758     TRACE("(%p)->(%s)\n", This, debugstr_w(pszkey));
00759 
00760     return IBindCtx_RevokeObjectParam(This->bindctx, pszkey);
00761 }
00762 
00763 static HRESULT WINAPI AsyncBindCtx_EnumObjectParam(IBindCtx *iface, IEnumString **pszkey)
00764 {
00765     AsyncBindCtx *This = impl_from_IBindCtx(iface);
00766 
00767     TRACE("(%p)->(%p)\n", This, pszkey);
00768 
00769     return IBindCtx_EnumObjectParam(This->bindctx, pszkey);
00770 }
00771 
00772 static const IBindCtxVtbl AsyncBindCtxVtbl =
00773 {
00774     AsyncBindCtx_QueryInterface,
00775     AsyncBindCtx_AddRef,
00776     AsyncBindCtx_Release,
00777     AsyncBindCtx_RegisterObjectBound,
00778     AsyncBindCtx_RevokeObjectBound,
00779     AsyncBindCtx_ReleaseBoundObjects,
00780     AsyncBindCtx_SetBindOptions,
00781     AsyncBindCtx_GetBindOptions,
00782     AsyncBindCtx_GetRunningObjectTable,
00783     AsyncBindCtx_RegisterObjectParam,
00784     AsyncBindCtx_GetObjectParam,
00785     AsyncBindCtx_EnumObjectParam,
00786     AsyncBindCtx_RevokeObjectParam
00787 };
00788 
00789 static HRESULT init_bindctx(IBindCtx *bindctx, DWORD options,
00790        IBindStatusCallback *callback, IEnumFORMATETC *format)
00791 {
00792     BIND_OPTS bindopts;
00793     HRESULT hres;
00794 
00795     if(options)
00796         FIXME("not supported options %08x\n", options);
00797     if(format)
00798         FIXME("format is not supported\n");
00799 
00800     bindopts.cbStruct = sizeof(BIND_OPTS);
00801     bindopts.grfFlags = BIND_MAYBOTHERUSER;
00802     bindopts.grfMode = STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
00803     bindopts.dwTickCountDeadline = 0;
00804 
00805     hres = IBindCtx_SetBindOptions(bindctx, &bindopts);
00806     if(FAILED(hres))
00807        return hres;
00808 
00809     if(callback) {
00810         hres = RegisterBindStatusCallback(bindctx, callback, NULL, 0);
00811         if(FAILED(hres))
00812             return hres;
00813     }
00814 
00815     return S_OK;
00816 }
00817 
00818 /***********************************************************************
00819  *           CreateAsyncBindCtx (urlmon.@)
00820  */
00821 HRESULT WINAPI CreateAsyncBindCtx(DWORD reserved, IBindStatusCallback *callback,
00822         IEnumFORMATETC *format, IBindCtx **pbind)
00823 {
00824     IBindCtx *bindctx;
00825     HRESULT hres;
00826 
00827     TRACE("(%08x %p %p %p)\n", reserved, callback, format, pbind);
00828 
00829     if(!pbind || !callback)
00830         return E_INVALIDARG;
00831 
00832     hres = CreateBindCtx(0, &bindctx);
00833     if(FAILED(hres))
00834         return hres;
00835 
00836     hres = init_bindctx(bindctx, 0, callback, format);
00837     if(FAILED(hres)) {
00838         IBindCtx_Release(bindctx);
00839         return hres;
00840     }
00841 
00842     *pbind = bindctx;
00843     return S_OK;
00844 }
00845 
00846 /***********************************************************************
00847  *           CreateAsyncBindCtxEx (urlmon.@)
00848  *
00849  * Create an asynchronous bind context.
00850  */
00851 HRESULT WINAPI CreateAsyncBindCtxEx(IBindCtx *ibind, DWORD options,
00852         IBindStatusCallback *callback, IEnumFORMATETC *format, IBindCtx** pbind,
00853         DWORD reserved)
00854 {
00855     AsyncBindCtx *ret;
00856     IBindCtx *bindctx;
00857     HRESULT hres;
00858 
00859     TRACE("(%p %08x %p %p %p %d)\n", ibind, options, callback, format, pbind, reserved);
00860 
00861     if(!pbind)
00862         return E_INVALIDARG;
00863 
00864     if(reserved)
00865         WARN("reserved=%d\n", reserved);
00866 
00867     if(ibind) {
00868         IBindCtx_AddRef(ibind);
00869         bindctx = ibind;
00870     }else {
00871         hres = CreateBindCtx(0, &bindctx);
00872         if(FAILED(hres))
00873             return hres;
00874     }
00875 
00876     ret = heap_alloc(sizeof(AsyncBindCtx));
00877 
00878     ret->IBindCtx_iface.lpVtbl = &AsyncBindCtxVtbl;
00879     ret->ref = 1;
00880     ret->bindctx = bindctx;
00881 
00882     hres = init_bindctx(&ret->IBindCtx_iface, options, callback, format);
00883     if(FAILED(hres)) {
00884         IBindCtx_Release(&ret->IBindCtx_iface);
00885         return hres;
00886     }
00887 
00888     *pbind = &ret->IBindCtx_iface;
00889     return S_OK;
00890 }

Generated on Sat May 26 2012 04:24:04 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.