shdocvw: Added navigation error handling.
authorPiotr Caban <piotr@codeweavers.com>
Mon, 14 Mar 2011 16:49:27 +0000 (17:49 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 15 Mar 2011 10:45:19 +0000 (11:45 +0100)
dlls/shdocvw/dochost.c
dlls/shdocvw/navigate.c
dlls/shdocvw/shdocvw.h

index 7b11c245caff11d1cfe31302df889b66b04ebd64..3c0dbd27a4ee435da658f36cc770c16e3edafad2 100644 (file)
@@ -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;
index 6e3ea46fb5657f82546c88090ce81e1f5f493f10..a6899b0c4d6904a3e960c675e57a881744439768 100644 (file)
@@ -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;
 }
index 3692e15ba4aad173c966d506bca9c5f955cb01f1..7abd0040647987a5dd2f0cc10f88853772bf89c3 100644 (file)
@@ -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);