vbscript: Call OnScriptError for runtime errors.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e050ff5eb8
commit
681cee4ed6
@ -2223,8 +2223,14 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd
|
|||||||
|
|
||||||
assert(!exec.top);
|
assert(!exec.top);
|
||||||
|
|
||||||
if(extern_caller)
|
if(extern_caller) {
|
||||||
IActiveScriptSite_OnLeaveScript(ctx->site);
|
IActiveScriptSite_OnLeaveScript(ctx->site);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
if(!ctx->ei.scode)
|
||||||
|
ctx->ei.scode = hres;
|
||||||
|
hres = report_script_error(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(SUCCEEDED(hres) && res) {
|
if(SUCCEEDED(hres) && res) {
|
||||||
*res = exec.ret_val;
|
*res = exec.ret_val;
|
||||||
|
@ -2190,7 +2190,7 @@ static void test_msgbox(void)
|
|||||||
CHECK_CALLED(GetUIBehavior);
|
CHECK_CALLED(GetUIBehavior);
|
||||||
CHECK_CALLED(GetWindow);
|
CHECK_CALLED(GetWindow);
|
||||||
CHECK_CALLED(EnableModeless);
|
CHECK_CALLED(EnableModeless);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
uic_handling = SCRIPTUICHANDLING_NOUIERROR;
|
uic_handling = SCRIPTUICHANDLING_NOUIERROR;
|
||||||
|
|
||||||
@ -2199,7 +2199,7 @@ static void test_msgbox(void)
|
|||||||
hres = parse_script_ar("MsgBox \"testing...\"");
|
hres = parse_script_ar("MsgBox \"testing...\"");
|
||||||
ok(FAILED(hres), "script not failed\n");
|
ok(FAILED(hres), "script not failed\n");
|
||||||
CHECK_CALLED(GetUIBehavior);
|
CHECK_CALLED(GetUIBehavior);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT test_global_vars_ref(BOOL use_close)
|
static HRESULT test_global_vars_ref(BOOL use_close)
|
||||||
@ -2619,36 +2619,36 @@ static void run_tests(void)
|
|||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("throwInt(&h80080008&)");
|
hres = parse_script_ar("throwInt(&h80080008&)");
|
||||||
ok(hres == 0x80080008, "hres = %08x\n", hres);
|
ok(hres == 0x80080008, "hres = %08x\n", hres);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
/* DISP_E_BADINDEX */
|
/* DISP_E_BADINDEX */
|
||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("throwInt(&h8002000b&)");
|
hres = parse_script_ar("throwInt(&h8002000b&)");
|
||||||
ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
|
ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("throwInt(&h800a0009&)");
|
hres = parse_script_ar("throwInt(&h800a0009&)");
|
||||||
ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
|
ok(hres == MAKE_VBSERROR(9), "hres = %08x\n", hres);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
onerror_hres = S_OK;
|
onerror_hres = S_OK;
|
||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("throwInt(&h800a0009&)");
|
hres = parse_script_ar("throwInt(&h800a0009&)");
|
||||||
todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
|
ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
/* E_NOTIMPL */
|
/* E_NOTIMPL */
|
||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("throwInt(&h80004001&)");
|
hres = parse_script_ar("throwInt(&h80004001&)");
|
||||||
ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
|
ok(hres == MAKE_VBSERROR(445), "hres = %08x\n", hres);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
onerror_hres = S_OK;
|
onerror_hres = S_OK;
|
||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("throwInt(&h80004001&)");
|
hres = parse_script_ar("throwInt(&h80004001&)");
|
||||||
todo_wine ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
|
ok(hres == SCRIPT_E_REPORTED, "hres = %08x\n", hres);
|
||||||
todo_wine CHECK_CALLED(OnScriptError);
|
CHECK_CALLED(OnScriptError);
|
||||||
|
|
||||||
SET_EXPECT(global_testoptionalarg_i);
|
SET_EXPECT(global_testoptionalarg_i);
|
||||||
parse_script_a("call testOptionalArg(1,,2)");
|
parse_script_a("call testOptionalArg(1,,2)");
|
||||||
@ -2686,7 +2686,7 @@ static void run_tests(void)
|
|||||||
SET_EXPECT(OnScriptError);
|
SET_EXPECT(OnScriptError);
|
||||||
hres = parse_script_ar("x = y(\"a\")");
|
hres = parse_script_ar("x = y(\"a\")");
|
||||||
ok(FAILED(hres), "script didn't fail\n");
|
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_d);
|
||||||
SET_EXPECT(global_success_i);
|
SET_EXPECT(global_success_i);
|
||||||
|
@ -59,6 +59,12 @@ struct VBScript {
|
|||||||
LCID lcid;
|
LCID lcid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IActiveScriptError IActiveScriptError_iface;
|
||||||
|
LONG ref;
|
||||||
|
EXCEPINFO ei;
|
||||||
|
} VBScriptError;
|
||||||
|
|
||||||
static void change_state(VBScript *This, SCRIPTSTATE state)
|
static void change_state(VBScript *This, SCRIPTSTATE state)
|
||||||
{
|
{
|
||||||
if(This->state == 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)
|
static inline VBScript *impl_from_IActiveScript(IActiveScript *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, VBScript, IActiveScript_iface);
|
return CONTAINING_RECORD(iface, VBScript, IActiveScript_iface);
|
||||||
|
@ -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;
|
void release_dynamic_vars(dynamic_var_t*) DECLSPEC_HIDDEN;
|
||||||
IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
IDispatch *lookup_named_item(script_ctx_t*,const WCHAR*,unsigned) DECLSPEC_HIDDEN;
|
||||||
void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN;
|
void clear_ei(EXCEPINFO*) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT report_script_error(script_ctx_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT16 len;
|
UINT16 len;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user