Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbindctx.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
1.7.6.1
|