Jacek Caban : urlmon: Use existing callback holder in RegisterBindStatusCallback if already exists .
Alexandre Julliard
julliard at winehq.org
Thu Oct 7 11:24:24 CDT 2010
Module: wine
Branch: master
Commit: 428c1bbac6d9da0d5b09b3b13db0c07a34a63fb5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=428c1bbac6d9da0d5b09b3b13db0c07a34a63fb5
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Oct 6 21:36:03 2010 +0200
urlmon: Use existing callback holder in RegisterBindStatusCallback if already exists.
---
dlls/urlmon/bindctx.c | 54 ++++++++++++++++++++++++++++++++++++------------
1 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/dlls/urlmon/bindctx.c b/dlls/urlmon/bindctx.c
index 0b3efa6..67391a4 100644
--- a/dlls/urlmon/bindctx.c
+++ b/dlls/urlmon/bindctx.c
@@ -460,9 +460,30 @@ static const IAuthenticateVtbl BSCAuthenticateVtbl = {
BSCAuthenticate_Authenticate
};
-static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc)
+static void set_callback(BindStatusCallback *This, IBindStatusCallback *bsc)
{
- BindStatusCallback *ret = heap_alloc_zero(sizeof(BindStatusCallback));
+ IServiceProvider *serv_prov;
+ HRESULT hres;
+
+ if(This->callback)
+ IBindStatusCallback_Release(This->callback);
+ if(This->serv_prov)
+ IServiceProvider_Release(This->serv_prov);
+
+ IBindStatusCallback_AddRef(bsc);
+ This->callback = bsc;
+
+ hres = IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&serv_prov);
+ This->serv_prov = hres == S_OK ? serv_prov : NULL;
+}
+
+static HRESULT wrap_callback(IBindStatusCallback *bsc, IBindStatusCallback **ret_iface)
+{
+ BindStatusCallback *ret;
+
+ ret = heap_alloc_zero(sizeof(BindStatusCallback));
+ if(!ret)
+ return E_OUTOFMEMORY;
ret->lpBindStatusCallbackExVtbl = &BindStatusCallbackExVtbl;
ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl;
@@ -470,13 +491,10 @@ static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc)
ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl;
ret->ref = 1;
+ set_callback(ret, bsc);
- IBindStatusCallback_AddRef(bsc);
- ret->callback = bsc;
-
- IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&ret->serv_prov);
-
- return STATUSCLB(ret);
+ *ret_iface = STATUSCLB(ret);
+ return S_OK;
}
/***********************************************************************
@@ -511,25 +529,33 @@ HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pb
hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk);
if(SUCCEEDED(hres)) {
hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc);
+ IUnknown_Release(unk);
if(SUCCEEDED(hres)) {
hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder);
if(SUCCEEDED(hres)) {
- prev = holder->callback;
- IBindStatusCallback_AddRef(prev);
+ if(ppbscPrevious) {
+ IBindStatusCallback_AddRef(holder->callback);
+ *ppbscPrevious = holder->callback;
+ }
+
+ set_callback(holder, pbsc);
+
IBindStatusCallback_Release(bsc);
IBindStatusCallback_Release(STATUSCLB(holder));
+ return S_OK;
}else {
prev = bsc;
}
}
- IUnknown_Release(unk);
IBindCtx_RevokeObjectParam(pbc, BSCBHolder);
}
- bsc = create_bsc(pbsc);
- hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc);
- IBindStatusCallback_Release(bsc);
+ hres = wrap_callback(pbsc, &bsc);
+ if(SUCCEEDED(hres)) {
+ hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)bsc);
+ IBindStatusCallback_Release(bsc);
+ }
if(FAILED(hres)) {
if(prev)
IBindStatusCallback_Release(prev);
More information about the wine-cvs
mailing list