Module: wine Branch: master Commit: a8a050e975346b0e344bb45011dd63e30a163a6a URL: http://source.winehq.org/git/wine.git/?a=commit;h=a8a050e975346b0e344bb45011...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Jun 7 16:10:49 2017 +0200
mshtml: Added IBindCallbackRedirect implementation.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mshtml/binding.h | 9 ++++--- dlls/mshtml/navigate.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/htmldoc.c | 11 ++++++++ 3 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index 3a4e06b..f5b85e9 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -69,10 +69,11 @@ typedef struct { typedef struct BSCallbackVtbl BSCallbackVtbl;
struct BSCallback { - IBindStatusCallback IBindStatusCallback_iface; - IServiceProvider IServiceProvider_iface; - IHttpNegotiate2 IHttpNegotiate2_iface; - IInternetBindInfo IInternetBindInfo_iface; + IBindStatusCallback IBindStatusCallback_iface; + IServiceProvider IServiceProvider_iface; + IHttpNegotiate2 IHttpNegotiate2_iface; + IInternetBindInfo IInternetBindInfo_iface; + IBindCallbackRedirect IBindCallbackRedirect_iface;
const BSCallbackVtbl *vtbl;
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index cfa3753..d036364 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -248,6 +248,9 @@ static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *ifa }else if(IsEqualGUID(&IID_IInternetBindInfo, riid)) { TRACE("(%p)->(IID_IInternetBindInfo %p)\n", This, ppv); *ppv = &This->IInternetBindInfo_iface; + }else if(IsEqualGUID(&IID_IBindCallbackRedirect, riid)) { + TRACE("(%p)->(IID_IBindCallbackRedirect %p)\n", This, ppv); + *ppv = &This->IBindCallbackRedirect_iface; }
if(*ppv) { @@ -561,6 +564,63 @@ static const IInternetBindInfoVtbl InternetBindInfoVtbl = { InternetBindInfo_GetBindString };
+static inline BSCallback *impl_from_IBindCallbackRedirect(IBindCallbackRedirect *iface) +{ + return CONTAINING_RECORD(iface, BSCallback, IBindCallbackRedirect_iface); +} + +static HRESULT WINAPI BindCallbackRedirect_QueryInterface(IBindCallbackRedirect *iface, REFIID riid, void **ppv) +{ + BSCallback *This = impl_from_IBindCallbackRedirect(iface); + return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv); +} + +static ULONG WINAPI BindCallbackRedirect_AddRef(IBindCallbackRedirect *iface) +{ + BSCallback *This = impl_from_IBindCallbackRedirect(iface); + return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface); +} + +static ULONG WINAPI BindCallbackRedirect_Release(IBindCallbackRedirect *iface) +{ + BSCallback *This = impl_from_IBindCallbackRedirect(iface); + return IBindStatusCallback_Release(&This->IBindStatusCallback_iface); +} + +static HRESULT WINAPI BindCallbackRedirect_Redirect(IBindCallbackRedirect *iface, const WCHAR *url, VARIANT_BOOL *vbCancel) +{ + BSCallback *This = impl_from_IBindCallbackRedirect(iface); + HTMLDocumentObj *doc_obj; + BOOL cancel = FALSE; + BSTR frame_name = NULL; + HRESULT hres = S_OK; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(url), vbCancel); + + if(This->window && This->window->base.outer_window && (doc_obj = This->window->base.outer_window->doc_obj) + && doc_obj->doc_object_service) { + if(This->window->base.outer_window != doc_obj->basedoc.window) { + hres = IHTMLWindow2_get_name(&This->window->base.IHTMLWindow2_iface, &frame_name); + if(FAILED(hres)) + return hres; + } + + hres = IDocObjectService_FireBeforeNavigate2(doc_obj->doc_object_service, NULL, url, 0x40, + frame_name, NULL, 0, NULL, TRUE, &cancel); + SysFreeString(frame_name); + } + + *vbCancel = cancel ? VARIANT_TRUE : VARIANT_FALSE; + return hres; +} + +static const IBindCallbackRedirectVtbl BindCallbackRedirectVtbl = { + BindCallbackRedirect_QueryInterface, + BindCallbackRedirect_AddRef, + BindCallbackRedirect_Release, + BindCallbackRedirect_Redirect +}; + static inline BSCallback *impl_from_IServiceProvider(IServiceProvider *iface) { return CONTAINING_RECORD(iface, BSCallback, IServiceProvider_iface); @@ -610,6 +670,7 @@ void init_bscallback(BSCallback *This, const BSCallbackVtbl *vtbl, IMoniker *mon This->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl; This->IHttpNegotiate2_iface.lpVtbl = &HttpNegotiate2Vtbl; This->IInternetBindInfo_iface.lpVtbl = &InternetBindInfoVtbl; + This->IBindCallbackRedirect_iface.lpVtbl = &BindCallbackRedirectVtbl; This->vtbl = vtbl; This->ref = 1; This->bindf = bindf; diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index dafc109..6964f6e 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -1469,6 +1469,8 @@ static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMon REFIID riid, void **ppv) { IBindStatusCallback *callback = NULL; + IBindCallbackRedirect *redirect_callback; + IServiceProvider *service_provider; BINDINFO bindinfo; DWORD bindf; HRESULT hres; @@ -1511,6 +1513,15 @@ static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMon ok(bindinfo.pUnk == NULL, "bindinfo.pUnk=%p\n", bindinfo.pUnk); ok(bindinfo.dwReserved == 0, "bindinfo.dwReserved=%d\n", bindinfo.dwReserved);
+ hres = IBindStatusCallback_QueryInterface(callback, &IID_IServiceProvider, (void**)&service_provider); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres); + + hres = IServiceProvider_QueryService(service_provider, &IID_IBindCallbackRedirect, &IID_IBindCallbackRedirect, (void**)&redirect_callback); + ok(hres == S_OK, "QueryService(IID_IBindCallbackRedirect) returned %08x\n", hres); + + IBindCallbackRedirect_Release(redirect_callback); + IServiceProvider_Release(service_provider); + hres = IBindStatusCallback_OnStartBinding(callback, 0, &Binding); ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres);