diff --git a/dlls/urlmon/bindctx.c b/dlls/urlmon/bindctx.c index 3d241a6e6c6..9d24707d2a6 100644 --- a/dlls/urlmon/bindctx.c +++ b/dlls/urlmon/bindctx.c @@ -36,6 +36,551 @@ WINE_DEFAULT_DEBUG_CHANNEL(urlmon); +static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 }; + +extern IID IID_IBindStatusCallbackHolder; + +typedef struct { + const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl; + const IServiceProviderVtbl *lpServiceProviderVtbl; + const IHttpNegotiate2Vtbl *lpHttpNegotiate2Vtbl; + const IAuthenticateVtbl *lpAuthenticateVtbl; + + LONG ref; + + IBindStatusCallback *callback; + IServiceProvider *serv_prov; + + IHttpNegotiate *http_negotiate; + BOOL init_http_negotiate; + IHttpNegotiate2 *http_negotiate2; + BOOL init_http_negotiate2; + IAuthenticate *authenticate; + BOOL init_authenticate; +} BindStatusCallback; + +#define STATUSCLB(x) ((IBindStatusCallback*) &(x)->lpBindStatusCallbackVtbl) +#define SERVPROV(x) ((IServiceProvider*) &(x)->lpServiceProviderVtbl) +#define HTTPNEG2(x) ((IHttpNegotiate2*) &(x)->lpHttpNegotiate2Vtbl) +#define AUTHENTICATE(x) ((IAuthenticate*) &(x)->lpAuthenticateVtbl) + +#define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface) + +static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) { + TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv); + *ppv = STATUSCLB(This); + }else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid)) { + TRACE("(%p)->(IID_IBindStatusCallbackHolder, %p)\n", This, ppv); + *ppv = This; + }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { + TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv); + *ppv = SERVPROV(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate, %p)\n", This, ppv); + *ppv = HTTPNEG2(This); + }else if(IsEqualGUID(&IID_IHttpNegotiate2, riid)) { + TRACE("(%p)->(IID_IHttpNegotiate2, %p)\n", This, ppv); + *ppv = HTTPNEG2(This); + }else if(IsEqualGUID(&IID_IAuthenticate, riid)) { + TRACE("(%p)->(IID_IAuthenticate, %p)\n", This, ppv); + *ppv = AUTHENTICATE(This); + } + + if(*ppv) { + IBindStatusCallback_AddRef((IUnknown*)*ppv); + return S_OK; + } + + TRACE("Unsupported riid = %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + return ref; +} + +static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref = %d\n", This, ref); + + if(!ref) { + if(This->serv_prov) + IServiceProvider_Release(This->serv_prov); + if(This->http_negotiate) + IHttpNegotiate_Release(This->http_negotiate); + if(This->http_negotiate2) + IHttpNegotiate2_Release(This->http_negotiate2); + if(This->authenticate) + IAuthenticate_Release(This->authenticate); + IBindStatusCallback_Release(This->callback); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, + DWORD dwReserved, IBinding *pbind) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind); + + return IBindStatusCallback_OnStartBinding(This->callback, 0xff, pbind); +} + +static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%p)\n", This, pnPriority); + + return IBindStatusCallback_GetPriority(This->callback, pnPriority); +} + +static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%d)\n", This, reserved); + + return IBindStatusCallback_OnLowResource(This->callback, reserved); +} + +static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, + ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, + debugstr_w(szStatusText)); + + return IBindStatusCallback_OnProgress(This->callback, ulProgress, + ulProgressMax, ulStatusCode, szStatusText); +} + +static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, + HRESULT hresult, LPCWSTR szError) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError)); + + return IBindStatusCallback_OnStopBinding(This->callback, hresult, szError); +} + +static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, + DWORD *grfBINDF, BINDINFO *pbindinfo) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); + + return IBindStatusCallback_GetBindInfo(This->callback, grfBINDF, pbindinfo); +} + +static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, + DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed); + + return IBindStatusCallback_OnDataAvailable(This->callback, grfBSCF, dwSize, pformatetc, pstgmed); +} + +static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, + REFIID riid, IUnknown *punk) +{ + BindStatusCallback *This = STATUSCLB_THIS(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk); + + return IBindStatusCallback_OnObjectAvailable(This->callback, riid, punk); +} + +#undef STATUSCLB_THIS + +static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = { + BindStatusCallback_QueryInterface, + BindStatusCallback_AddRef, + BindStatusCallback_Release, + BindStatusCallback_OnStartBinding, + BindStatusCallback_GetPriority, + BindStatusCallback_OnLowResource, + BindStatusCallback_OnProgress, + BindStatusCallback_OnStopBinding, + BindStatusCallback_GetBindInfo, + BindStatusCallback_OnDataAvailable, + BindStatusCallback_OnObjectAvailable +}; + +#define SERVPROV_THIS(iface) DEFINE_THIS(BindStatusCallback, ServiceProvider, iface) + +static HRESULT WINAPI BSCServiceProvider_QueryInterface(IServiceProvider *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI BSCServiceProvider_AddRef(IServiceProvider *iface) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCServiceProvider_Release(IServiceProvider *iface) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCServiceProvider_QueryService(IServiceProvider *iface, + REFGUID guidService, REFIID riid, void **ppv) +{ + BindStatusCallback *This = SERVPROV_THIS(iface); + HRESULT hres; + + if(IsEqualGUID(&IID_IHttpNegotiate, guidService)) { + TRACE("(%p)->(IID_IHttpNegotiate %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_http_negotiate) { + This->init_http_negotiate = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate, + (void**)&This->http_negotiate); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate, + &IID_IHttpNegotiate, (void**)&This->http_negotiate); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + if(IsEqualGUID(&IID_IHttpNegotiate2, guidService)) { + TRACE("(%p)->(IID_IHttpNegotiate2 %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_http_negotiate2) { + This->init_http_negotiate2 = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IHttpNegotiate2, + (void**)&This->http_negotiate2); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IHttpNegotiate2, + &IID_IHttpNegotiate2, (void**)&This->http_negotiate2); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + if(IsEqualGUID(&IID_IAuthenticate, guidService)) { + TRACE("(%p)->(IID_IAuthenticate %s %p)\n", This, debugstr_guid(riid), ppv); + + if(!This->init_authenticate) { + This->init_authenticate = TRUE; + hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IAuthenticate, + (void**)&This->authenticate); + if(FAILED(hres) && This->serv_prov) + IServiceProvider_QueryService(This->serv_prov, &IID_IAuthenticate, + &IID_IAuthenticate, (void**)&This->authenticate); + } + + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); + } + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); + + hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv); + if(SUCCEEDED(hres)) + return S_OK; + + if(This->serv_prov) { + hres = IServiceProvider_QueryService(This->serv_prov, guidService, riid, ppv); + if(SUCCEEDED(hres)) + return S_OK; + } + + return E_NOINTERFACE; +} + +#undef SERVPROV_THIS + +static const IServiceProviderVtbl BSCServiceProviderVtbl = { + BSCServiceProvider_QueryInterface, + BSCServiceProvider_AddRef, + BSCServiceProvider_Release, + BSCServiceProvider_QueryService +}; + +#define HTTPNEG2_THIS(iface) DEFINE_THIS(BindStatusCallback, HttpNegotiate2, iface) + +static HRESULT WINAPI BSCHttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, + REFIID riid, void **ppv) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_QueryInterface(STATUSCLB(This), riid, ppv); +} + +static ULONG WINAPI BSCHttpNegotiate_AddRef(IHttpNegotiate2 *iface) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCHttpNegotiate_Release(IHttpNegotiate2 *iface) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCHttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, + LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + + TRACE("(%p)->(%s %s %d %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved, + pszAdditionalHeaders); + + *pszAdditionalHeaders = NULL; + + if(!This->http_negotiate) + return S_OK; + + return IHttpNegotiate_BeginningTransaction(This->http_negotiate, szURL, szHeaders, + dwReserved, pszAdditionalHeaders); +} + +static HRESULT WINAPI BSCHttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode, + LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, + LPWSTR *pszAdditionalRequestHeaders) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + LPWSTR additional_headers = NULL; + HRESULT hres = S_OK; + + TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders), + debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders); + + if(This->http_negotiate) + hres = IHttpNegotiate_OnResponse(This->http_negotiate, dwResponseCode, szResponseHeaders, + szRequestHeaders, &additional_headers); + + if(pszAdditionalRequestHeaders) + *pszAdditionalRequestHeaders = additional_headers; + else if(additional_headers) + CoTaskMemFree(additional_headers); + + return hres; +} + +static HRESULT WINAPI BSCHttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface, + BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) +{ + BindStatusCallback *This = HTTPNEG2_THIS(iface); + + TRACE("(%p)->(%p %p %ld)\n", This, pbSecurityId, pcbSecurityId, dwReserved); + + if(!This->http_negotiate2) + return E_FAIL; + + return IHttpNegotiate2_GetRootSecurityId(This->http_negotiate2, pbSecurityId, + pcbSecurityId, dwReserved); +} + +#undef HTTPNEG2_THIS + +static const IHttpNegotiate2Vtbl BSCHttpNegotiateVtbl = { + BSCHttpNegotiate_QueryInterface, + BSCHttpNegotiate_AddRef, + BSCHttpNegotiate_Release, + BSCHttpNegotiate_BeginningTransaction, + BSCHttpNegotiate_OnResponse, + BSCHttpNegotiate_GetRootSecurityId +}; + +#define AUTHENTICATE_THIS(iface) DEFINE_THIS(BindStatusCallback, Authenticate, iface) + +static HRESULT WINAPI BSCAuthenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_QueryInterface(AUTHENTICATE(This), riid, ppv); +} + +static ULONG WINAPI BSCAuthenticate_AddRef(IAuthenticate *iface) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_AddRef(STATUSCLB(This)); +} + +static ULONG WINAPI BSCAuthenticate_Release(IAuthenticate *iface) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + return IBindStatusCallback_Release(STATUSCLB(This)); +} + +static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface, + HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword) +{ + BindStatusCallback *This = AUTHENTICATE_THIS(iface); + FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword); + return E_NOTIMPL; +} + +#undef AUTHENTICATE_THIS + +static const IAuthenticateVtbl BSCAuthenticateVtbl = { + BSCAuthenticate_QueryInterface, + BSCAuthenticate_AddRef, + BSCAuthenticate_Release, + BSCAuthenticate_Authenticate +}; + +static IBindStatusCallback *create_bsc(IBindStatusCallback *bsc) +{ + BindStatusCallback *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BindStatusCallback)); + + ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl; + ret->lpServiceProviderVtbl = &BSCServiceProviderVtbl; + ret->lpHttpNegotiate2Vtbl = &BSCHttpNegotiateVtbl; + ret->lpAuthenticateVtbl = &BSCAuthenticateVtbl; + + ret->ref = 1; + + IBindStatusCallback_AddRef(bsc); + ret->callback = bsc; + + IBindStatusCallback_QueryInterface(bsc, &IID_IServiceProvider, (void**)&ret->serv_prov); + + return STATUSCLB(ret); +} + +/*********************************************************************** + * RegisterBindStatusCallback (urlmon.@) + * + * Register a bind status callback. + * + * PARAMS + * pbc [I] Binding context + * pbsc [I] Callback to register + * ppbscPrevious [O] Destination for previous callback + * dwReserved [I] Reserved, must be 0. + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any argument is invalid, or + * E_OUTOFMEMORY if memory allocation fails. + */ +HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, + IBindStatusCallback **ppbscPrevious, DWORD dwReserved) +{ + BindStatusCallback *holder; + IBindStatusCallback *bsc, *prev = NULL; + IUnknown *unk; + HRESULT hres; + + TRACE("(%p %p %p %x)\n", pbc, pbsc, ppbscPrevious, dwReserved); + + if (!pbc || !pbsc) + return E_INVALIDARG; + + hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk); + if(SUCCEEDED(hres)) { + hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&bsc); + if(SUCCEEDED(hres)) { + hres = IBindStatusCallback_QueryInterface(bsc, &IID_IBindStatusCallbackHolder, (void**)&holder); + if(SUCCEEDED(hres)) { + prev = holder->callback; + IBindStatusCallback_AddRef(prev); + IBindStatusCallback_Release(bsc); + IBindStatusCallback_Release(STATUSCLB(holder)); + }else { + prev = bsc; + } + } + + IUnknown_Release(unk); + IBindCtx_RevokeObjectParam(pbc, BSCBHolder); + } + + hres = IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown*)create_bsc(pbsc)); + if(FAILED(hres)) { + IBindStatusCallback_Release(prev); + return hres; + } + + if(ppbscPrevious) + *ppbscPrevious = prev; + return S_OK; +} + +/*********************************************************************** + * RevokeBindStatusCallback (URLMON.@) + * + * Unregister a bind status callback. + * + * pbc [I] Binding context + * pbsc [I] Callback to unregister + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any argument is invalid + */ +HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc) +{ + BindStatusCallback *holder; + IBindStatusCallback *callback; + IUnknown *unk; + BOOL dorevoke = FALSE; + HRESULT hres; + + TRACE("(%p %p)\n", pbc, pbsc); + + if (!pbc || !pbsc) + return E_INVALIDARG; + + hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, &unk); + if(FAILED(hres)) + return S_OK; + + hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&callback); + IUnknown_Release(unk); + if(FAILED(hres)) + return S_OK; + + hres = IBindStatusCallback_QueryInterface(callback, &IID_IBindStatusCallbackHolder, (void**)&holder); + if(SUCCEEDED(hres)) { + if(pbsc == holder->callback) + dorevoke = TRUE; + IBindStatusCallback_Release(STATUSCLB(holder)); + }else if(pbsc == callback) { + dorevoke = TRUE; + } + IBindStatusCallback_Release(callback); + + if(dorevoke) + IBindCtx_RevokeObjectParam(pbc, BSCBHolder); + + return S_OK; +} + typedef struct { const IBindCtxVtbl *lpBindCtxVtbl; diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c index 57126692edf..595c2ce61ec 100644 --- a/dlls/urlmon/tests/url.c +++ b/dlls/urlmon/tests/url.c @@ -714,7 +714,7 @@ static void test_CreateAsyncBindCtx(void) SET_EXPECT(QueryInterface_IServiceProvider); hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx); ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n", hres); - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); + CHECK_CALLED(QueryInterface_IServiceProvider); bindopts.cbStruct = sizeof(bindopts); hres = IBindCtx_GetBindOptions(bctx, &bindopts); @@ -788,7 +788,7 @@ static void test_CreateAsyncBindCtxEx(void) SET_EXPECT(QueryInterface_IServiceProvider); hres = CreateAsyncBindCtxEx(NULL, 0, &bsc, NULL, &bctx, 0); ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres); - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); + CHECK_CALLED(QueryInterface_IServiceProvider); hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk); ok(hres == S_OK, "QueryInterface(IID_IAsyncBindCtx) failed: %08x\n", hres); @@ -819,16 +819,16 @@ static void test_BindToStorage(int protocol, BOOL emul) SET_EXPECT(QueryInterface_IServiceProvider); hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx); - ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n\n", hres); + ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres); + CHECK_CALLED(QueryInterface_IServiceProvider); if(FAILED(hres)) return; - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); SET_EXPECT(QueryInterface_IServiceProvider); hres = RegisterBindStatusCallback(bctx, &bsc, &previousclb, 0); - ok(SUCCEEDED(hres), "RegisterBindStatusCallback failed: %08x\n", hres); + ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres); ok(previousclb == &bsc, "previousclb(%p) != sclb(%p)\n", previousclb, &bsc); - todo_wine CHECK_CALLED(QueryInterface_IServiceProvider); + CHECK_CALLED(QueryInterface_IServiceProvider); if(previousclb) IBindStatusCallback_Release(previousclb); @@ -903,7 +903,7 @@ static void test_BindToStorage(int protocol, BOOL emul) DispatchMessage(&msg); } - todo_wine CHECK_NOT_CALLED(QueryInterface_IServiceProvider); + CHECK_NOT_CALLED(QueryInterface_IServiceProvider); CHECK_CALLED(GetBindInfo); CHECK_CALLED(OnStartBinding); if(emulate_protocol) { diff --git a/dlls/urlmon/umon.c b/dlls/urlmon/umon.c index db42f7eac8c..9d17afa97e8 100644 --- a/dlls/urlmon/umon.c +++ b/dlls/urlmon/umon.c @@ -738,7 +738,7 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface, sizeof(schema)/sizeof(WCHAR), 0, NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; if(pmkToLeft) - FIXME("Unsupported pmkToLeft\n"); + FIXME("Unsupported pmkToLeft\n"); bret = InternetCrackUrlW(This->URLName, 0, ICU_ESCAPE, &url); if(!bret) { @@ -1208,85 +1208,6 @@ HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback return hr; } -/*********************************************************************** - * RegisterBindStatusCallback (URLMON.@) - * - * Register a bind status callback. - * - * PARAMS - * pbc [I] Binding context - * pbsc [I] Callback to register - * ppbscPrevious [O] Destination for previous callback - * dwReserved [I] Reserved, must be 0. - * - * RETURNS - * Success: S_OK. - * Failure: E_INVALIDARG, if any argument is invalid, or - * E_OUTOFMEMORY if memory allocation fails. - */ -HRESULT WINAPI RegisterBindStatusCallback( - IBindCtx *pbc, - IBindStatusCallback *pbsc, - IBindStatusCallback **ppbscPrevious, - DWORD dwReserved) -{ - IBindStatusCallback *prev; - - TRACE("(%p,%p,%p,%u)\n", pbc, pbsc, ppbscPrevious, dwReserved); - - if (pbc == NULL || pbsc == NULL) - return E_INVALIDARG; - - if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&prev))) - { - IBindCtx_RevokeObjectParam(pbc, BSCBHolder); - if (ppbscPrevious) - *ppbscPrevious = prev; - else - IBindStatusCallback_Release(prev); - } - - return IBindCtx_RegisterObjectParam(pbc, BSCBHolder, (IUnknown *)pbsc); -} - -/*********************************************************************** - * RevokeBindStatusCallback (URLMON.@) - * - * Unregister a bind status callback. - * - * pbc [I] Binding context - * pbsc [I] Callback to unregister - * - * RETURNS - * Success: S_OK. - * Failure: E_INVALIDARG, if any argument is invalid, or - * E_FAIL if pbsc wasn't registered with pbc. - */ -HRESULT WINAPI RevokeBindStatusCallback( - IBindCtx *pbc, - IBindStatusCallback *pbsc) -{ - IBindStatusCallback *callback; - HRESULT hr = E_FAIL; - - TRACE("(%p,%p)\n", pbc, pbsc); - - if (pbc == NULL || pbsc == NULL) - return E_INVALIDARG; - - if (SUCCEEDED(IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown **)&callback))) - { - if (callback == pbsc) - { - IBindCtx_RevokeObjectParam(pbc, BSCBHolder); - hr = S_OK; - } - IBindStatusCallback_Release(pbsc); - } - - return hr; -} - /*********************************************************************** * URLDownloadToFileA (URLMON.@) *