From 681cee4ed6e64da5ee22d4f1962c89b35d45a287 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 4 Oct 2019 16:30:31 +0200 Subject: [PATCH] vbscript: Call OnScriptError for runtime errors. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- 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 82a9f79e8d8..86491647647 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 ebcc8836c40..7c06d9c0f51 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 790e61e3f04..3d76e5e6b9b 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 c9f49594c75..1d9353ac77f 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;