Piotr Caban : shdocvw: Added navigation error handling.

Alexandre Julliard julliard at winehq.org
Tue Mar 15 11:33:54 CDT 2011


Module: wine
Branch: master
Commit: ac53980faaef82823cb234169b687ef759b1cd53
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ac53980faaef82823cb234169b687ef759b1cd53

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Mar 14 17:49:27 2011 +0100

shdocvw: Added navigation error handling.

---

 dlls/shdocvw/dochost.c  |   34 +++++++++++++++++++++++++++
 dlls/shdocvw/navigate.c |   58 +++++++++++++++++++++++++++++++++++++++++++---
 dlls/shdocvw/shdocvw.h  |    1 +
 3 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/dlls/shdocvw/dochost.c b/dlls/shdocvw/dochost.c
index 7b11c24..3c0dbd2 100644
--- a/dlls/shdocvw/dochost.c
+++ b/dlls/shdocvw/dochost.c
@@ -472,6 +472,40 @@ static HRESULT WINAPI ClOleCommandTarget_Exec(IOleCommandTarget *iface,
             This->doc_navigate = V_UNKNOWN(pvaIn);
             return S_OK;
 
+        case 1: {
+            IHTMLWindow2 *win2;
+            SAFEARRAY *sa = V_ARRAY(pvaIn);
+            VARIANT status_code, url, htmlwindow;
+            LONG ind;
+            HRESULT hres;
+
+            if(V_VT(pvaIn) != VT_ARRAY || !sa)
+                return E_INVALIDARG;
+
+            ind = 0;
+            hres = SafeArrayGetElement(sa, &ind, &status_code);
+            if(FAILED(hres) || V_VT(&status_code)!=VT_I4)
+                return E_INVALIDARG;
+
+            ind = 1;
+            hres = SafeArrayGetElement(sa, &ind, &url);
+            if(FAILED(hres) || V_VT(&url)!=VT_BSTR)
+                return E_INVALIDARG;
+
+            ind = 3;
+            hres = SafeArrayGetElement(sa, &ind, &htmlwindow);
+            if(FAILED(hres) || V_VT(&htmlwindow)!=VT_UNKNOWN || !V_UNKNOWN(&htmlwindow))
+                return E_INVALIDARG;
+
+            hres = IUnknown_QueryInterface(V_UNKNOWN(&htmlwindow), &IID_IHTMLWindow2, (void**)&win2);
+            if(FAILED(hres))
+                return E_INVALIDARG;
+
+            handle_navigation_error(This, V_I4(&status_code), V_BSTR(&url), win2);
+            IHTMLWindow2_Release(win2);
+            return S_OK;
+        }
+
         default:
             FIXME("unsupported command %d of CGID_DocHostCmdPriv\n", nCmdID);
             return E_NOTIMPL;
diff --git a/dlls/shdocvw/navigate.c b/dlls/shdocvw/navigate.c
index 6e3ea46..a6899b0 100644
--- a/dlls/shdocvw/navigate.c
+++ b/dlls/shdocvw/navigate.c
@@ -241,6 +241,51 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
     return S_OK;
 }
 
+void handle_navigation_error(DocHost* doc_host, HRESULT hres, BSTR url, IHTMLWindow2 *win2)
+{
+    VARIANT var_status_code, var_frame_name, var_url;
+    DISPPARAMS dispparams;
+    VARIANTARG params[5];
+    VARIANT_BOOL cancel = VARIANT_FALSE;
+
+    dispparams.cArgs = 5;
+    dispparams.cNamedArgs = 0;
+    dispparams.rgdispidNamedArgs = NULL;
+    dispparams.rgvarg = params;
+
+    V_VT(params) = VT_BOOL|VT_BYREF;
+    V_BOOLREF(params) = &cancel;
+
+    V_VT(params+1) = VT_VARIANT|VT_BYREF;
+    V_VARIANTREF(params+1) = &var_status_code;
+    V_VT(&var_status_code) = VT_I4;
+    V_I4(&var_status_code) = hres;
+
+    V_VT(params+2) = VT_VARIANT|VT_BYREF;
+    V_VARIANTREF(params+2) = &var_frame_name;
+    V_VT(&var_frame_name) = VT_BSTR;
+    if(win2) {
+        hres = IHTMLWindow2_get_name(win2, &V_BSTR(&var_frame_name));
+        if(FAILED(hres))
+            V_BSTR(&var_frame_name) = NULL;
+    } else
+        V_BSTR(&var_frame_name) = NULL;
+
+    V_VT(params+3) = VT_VARIANT|VT_BYREF;
+    V_VARIANTREF(params+3) = &var_url;
+    V_VT(&var_url) = VT_BSTR;
+    V_BSTR(&var_url) = url;
+
+    V_VT(params+4) = VT_DISPATCH;
+    V_DISPATCH(params+4) = doc_host->disp;
+
+    call_sink(doc_host->cps.wbe2, DISPID_NAVIGATEERROR, &dispparams);
+    SysFreeString(V_BSTR(&var_frame_name));
+
+    if(!cancel)
+        FIXME("Navigate to error page\n");
+}
+
 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
         HRESULT hresult, LPCWSTR szError)
 {
@@ -250,10 +295,15 @@ static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *ifac
 
     set_status_text(This, emptyW);
 
-    if(This->doc_host) {
-        IOleClientSite_Release(&This->doc_host->IOleClientSite_iface);
-        This->doc_host = NULL;
-    }
+    if(!This->doc_host)
+        return S_OK;
+
+    /* FIXME: Check HTTP status code */
+    if(FAILED(hresult))
+        handle_navigation_error(This->doc_host, hresult, This->url, NULL);
+
+    IOleClientSite_Release(&This->doc_host->IOleClientSite_iface);
+    This->doc_host = NULL;
 
     return S_OK;
 }
diff --git a/dlls/shdocvw/shdocvw.h b/dlls/shdocvw/shdocvw.h
index 3692e15..7abd004 100644
--- a/dlls/shdocvw/shdocvw.h
+++ b/dlls/shdocvw/shdocvw.h
@@ -240,6 +240,7 @@ HRESULT navigate_url(DocHost*,LPCWSTR,const VARIANT*,const VARIANT*,VARIANT*,VAR
 HRESULT go_home(DocHost*);
 void set_doc_state(DocHost*,READYSTATE);
 HRESULT get_location_url(DocHost*,BSTR*);
+void handle_navigation_error(DocHost*,HRESULT,BSTR,IHTMLWindow2*);
 
 #define WM_DOCHOSTTASK (WM_USER+0x300)
 void push_dochost_task(DocHost*,task_header_t*,task_proc_t,BOOL);




More information about the wine-cvs mailing list