Jacek Caban : vbscript: Call OnScriptError for runtime errors.

Alexandre Julliard julliard at winehq.org
Fri Oct 4 16:34:05 CDT 2019


Module: wine
Branch: master
Commit: 681cee4ed6e64da5ee22d4f1962c89b35d45a287
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=681cee4ed6e64da5ee22d4f1962c89b35d45a287

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Oct  4 16:30:31 2019 +0200

vbscript: Call OnScriptError for runtime errors.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/vbscript/interp.c    |   8 +++-
 dlls/vbscript/tests/run.c |  22 ++++-----
 dlls/vbscript/vbscript.c  | 118 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/vbscript/vbscript.h  |   1 +
 4 files changed, 137 insertions(+), 12 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 82a9f79e8d..8649164764 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -2223,8 +2223,14 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd
 
     assert(!exec.top);
 
-    if(extern_caller)
+    if(extern_caller) {
         IActiveScriptSite_OnLeaveScript(ctx->site);
+        if(FAILED(hres)) {
+            if(!ctx->ei.scode)
+                ctx->ei.scode = hres;
+            hres = report_script_error(ctx);
+        }
+    }
 
     if(SUCCEEDED(hres) && res) {
         *res = exec.ret_val;
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index ebcc8836c4..7c06d9c0f5 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -2190,7 +2190,7 @@ static void test_msgbox(void)
     CHECK_CALLED(GetUIBehavior);
     CHECK_CALLED(GetWindow);
     CHECK_CALLED(EnableModeless);
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 
     uic_handling = SCRIPTUICHANDLING_NOUIERROR;
 
@@ -2199,7 +2199,7 @@ static void test_msgbox(void)
     hres = parse_script_ar("MsgBox \"testing...\"");
     ok(FAILED(hres), "script not failed\n");
     CHECK_CALLED(GetUIBehavior);
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 }
 
 static HRESULT test_global_vars_ref(BOOL use_close)
@@ -2619,36 +2619,36 @@ static void run_tests(void)
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("throwInt(&h80080008&)");
     ok(hres == 0x80080008, "hres = %08x\n", hres);
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 
     /* DISP_E_BADINDEX */
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("throwInt(&h8002000b&)");
     ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("throwInt(&h800a0009&)");
     ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 
     onerror_hres = S_OK;
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("throwInt(&h800a0009&)");
-    todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
-    todo_wine CHECK_CALLED(OnScriptError);
+    ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
+    CHECK_CALLED(OnScriptError);
 
     /* E_NOTIMPL */
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("throwInt(&h80004001&)");
     ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 
     onerror_hres = S_OK;
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("throwInt(&h80004001&)");
-    todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
-    todo_wine CHECK_CALLED(OnScriptError);
+    ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
+    CHECK_CALLED(OnScriptError);
 
     SET_EXPECT(global_testoptionalarg_i);
     parse_script_a("call testOptionalArg(1,,2)");
@@ -2686,7 +2686,7 @@ static void run_tests(void)
     SET_EXPECT(OnScriptError);
     hres = parse_script_ar("x = y(\"a\")");
     ok(FAILED(hres), "script didn't fail\n");
-    todo_wine CHECK_CALLED(OnScriptError);
+    CHECK_CALLED(OnScriptError);
 
     SET_EXPECT(global_success_d);
     SET_EXPECT(global_success_i);
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 790e61e3f0..3d76e5e6b9 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -59,6 +59,12 @@ struct VBScript {
     LCID lcid;
 };
 
+typedef struct {
+    IActiveScriptError IActiveScriptError_iface;
+    LONG ref;
+    EXCEPINFO ei;
+} VBScriptError;
+
 static void change_state(VBScript *This, SCRIPTSTATE state)
 {
     if(This->state == state)
@@ -249,6 +255,118 @@ static void decrease_state(VBScript *This, SCRIPTSTATE state)
     }
 }
 
+static inline VBScriptError *impl_from_IActiveScriptError(IActiveScriptError *iface)
+{
+    return CONTAINING_RECORD(iface, VBScriptError, IActiveScriptError_iface);
+}
+
+static HRESULT WINAPI VBScriptError_QueryInterface(IActiveScriptError *iface, REFIID riid, void **ppv)
+{
+    VBScriptError *This = impl_from_IActiveScriptError(iface);
+
+    if(IsEqualGUID(riid, &IID_IUnknown)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IActiveScriptError_iface;
+    }else if(IsEqualGUID(riid, &IID_IActiveScriptError)) {
+        TRACE("(%p)->(IID_IActiveScriptError %p)\n", This, ppv);
+        *ppv = &This->IActiveScriptError_iface;
+    }else {
+        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI VBScriptError_AddRef(IActiveScriptError *iface)
+{
+    VBScriptError *This = impl_from_IActiveScriptError(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI VBScriptError_Release(IActiveScriptError *iface)
+{
+    VBScriptError *This = impl_from_IActiveScriptError(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI VBScriptError_GetExceptionInfo(IActiveScriptError *iface, EXCEPINFO *excepinfo)
+{
+    VBScriptError *This = impl_from_IActiveScriptError(iface);
+
+    TRACE("(%p)->(%p)\n", This, excepinfo);
+
+    *excepinfo = This->ei;
+    excepinfo->bstrSource = SysAllocString(This->ei.bstrSource);
+    excepinfo->bstrDescription = SysAllocString(This->ei.bstrDescription);
+    excepinfo->bstrHelpFile = SysAllocString(This->ei.bstrHelpFile);
+    return S_OK;
+}
+
+static HRESULT WINAPI VBScriptError_GetSourcePosition(IActiveScriptError *iface, DWORD *source_context, ULONG *line, LONG *character)
+{
+    VBScriptError *This = impl_from_IActiveScriptError(iface);
+
+    FIXME("(%p)->(%p %p %p)\n", This, source_context, line, character);
+
+    if(source_context)
+        *source_context = 0;
+    if(line)
+        *line = 0;
+    if(character)
+        *character = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI VBScriptError_GetSourceLineText(IActiveScriptError *iface, BSTR *source)
+{
+    VBScriptError *This = impl_from_IActiveScriptError(iface);
+    FIXME("(%p)->(%p)\n", This, source);
+    return E_NOTIMPL;
+}
+
+static const IActiveScriptErrorVtbl VBScriptErrorVtbl = {
+    VBScriptError_QueryInterface,
+    VBScriptError_AddRef,
+    VBScriptError_Release,
+    VBScriptError_GetExceptionInfo,
+    VBScriptError_GetSourcePosition,
+    VBScriptError_GetSourceLineText
+};
+
+HRESULT report_script_error(script_ctx_t *ctx)
+{
+    VBScriptError *error;
+    HRESULT hres, result;
+
+    if(!(error = heap_alloc(sizeof(*error))))
+        return E_OUTOFMEMORY;
+    error->IActiveScriptError_iface.lpVtbl = &VBScriptErrorVtbl;
+
+    error->ref = 1;
+    error->ei = ctx->ei;
+    memset(&ctx->ei, 0, sizeof(ctx->ei));
+    result = error->ei.scode;
+
+    hres = IActiveScriptSite_OnScriptError(ctx->site, &error->IActiveScriptError_iface);
+    IActiveScriptError_Release(&error->IActiveScriptError_iface);
+    return hres == S_OK ? SCRIPT_E_REPORTED : result;
+}
+
 static inline VBScript *impl_from_IActiveScript(IActiveScript *iface)
 {
     return CONTAINING_RECORD(iface, VBScript, IActiveScript_iface);
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index c9f49594c7..1d9353ac77 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -360,6 +360,7 @@ HRESULT exec_script(script_ctx_t*,BOOL,function_t*,vbdisp_t*,DISPPARAMS*,VARIANT
 void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN;
 IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN;
 void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN;
+HRESULT report_script_error(script_ctx_t*) DECLSPEC_HIDDEN;
 
 typedef struct {
     UINT16 len;




More information about the wine-cvs mailing list