From: Francis De Brabandere <francisdb@gmail.com> When an external object invokes a script function reference or class method while a script frame is on the stack and the host leaves the error unhandled, native returns SCRIPT_E_RECORDED and DISP_E_EXCEPTION respectively to the caller. Wine returns the raw error code instead; mark these with todo_wine. --- dlls/vbscript/tests/run.c | 60 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 8a1a731fb3b..f54efd099e2 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -149,6 +149,7 @@ DEFINE_EXPECT(OnLeaveScript); #define DISPID_GLOBAL_ISARRAYFIXED 1028 #define DISPID_GLOBAL_MAXCHARSIZE 1029 #define DISPID_GLOBAL_INVOKEDISP 1030 +#define DISPID_GLOBAL_INVOKEMETHOD 1031 #define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 @@ -1239,6 +1240,7 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD { L"firstDayOfWeek", DISPID_GLOBAL_WEEKSTARTDAY }, { L"globalCallback", DISPID_GLOBAL_GLOBALCALLBACK }, { L"invokeDisp", DISPID_GLOBAL_INVOKEDISP }, + { L"invokeMethod", DISPID_GLOBAL_INVOKEMETHOD }, { L"testObj", DISPID_GLOBAL_TESTOBJ }, { L"collectionObj" , DISPID_GLOBAL_COLLOBJ }, { L"vbvar", DISPID_GLOBAL_VBVAR, REF_EXPECT(global_vbvar_d) }, @@ -1378,12 +1380,46 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, ok(V_VT(arg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(arg)); /* Mimic an external object invoking a function reference back into the - * engine while a script frame is still on the stack. The result is - * dropped so the test observes only how the engine reports the error. */ + * engine while a script frame is on the stack. With the host leaving + * the error unhandled, native returns SCRIPT_E_RECORDED to the caller; + * Wine returns the raw error code instead. */ memset(&ei, 0, sizeof(ei)); hr = IDispatch_Invoke(V_DISPATCH(arg), DISPID_VALUE, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, &ei, NULL); - trace("invokeDisp: inner Invoke returned %08lx\n", hr); + todo_wine ok(hr == SCRIPT_E_RECORDED, "inner Invoke returned %08lx\n", hr); + return S_OK; + } + + case DISPID_GLOBAL_INVOKEMETHOD: { + DISPPARAMS params = { NULL, NULL, 0, 0 }; + VARIANT *arg = pdp->rgvarg; + IDispatchEx *dispex; + EXCEPINFO ei; + VARIANT v; + DISPID did; + BSTR str; + HRESULT hr; + + ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); + if(V_VT(arg) == (VT_VARIANT|VT_BYREF)) + arg = V_VARIANTREF(arg); + ok(V_VT(arg) == VT_DISPATCH, "V_VT(arg) = %d\n", V_VT(arg)); + + hr = IDispatch_QueryInterface(V_DISPATCH(arg), &IID_IDispatchEx, (void**)&dispex); + ok(hr == S_OK, "QueryInterface(IDispatchEx) returned %08lx\n", hr); + str = SysAllocString(L"raiser"); + hr = IDispatchEx_GetDispID(dispex, str, fdexNameCaseInsensitive, &did); + ok(hr == S_OK, "GetDispID(raiser) returned %08lx\n", hr); + SysFreeString(str); + + /* As above, but for a class method invoked by an external object. With + * the host leaving the error unhandled, native returns DISP_E_EXCEPTION + * to the caller; Wine returns the raw error code instead. */ + memset(&ei, 0, sizeof(ei)); + V_VT(&v) = VT_EMPTY; + hr = IDispatchEx_InvokeEx(dispex, did, 0, DISPATCH_METHOD, ¶ms, &v, &ei, NULL); + todo_wine ok(hr == DISP_E_EXCEPTION, "inner InvokeEx returned %08lx\n", hr); + IDispatchEx_Release(dispex); return S_OK; } @@ -3607,6 +3643,23 @@ static void test_getref_external_caller_error(void) CHECK_CALLED(OnScriptError); } +static void test_external_caller_method_error(void) +{ + static const WCHAR *src = + L"Class C\n" + L" Public Sub raiser\n" + L" Err.Raise 5\n" + L" End Sub\n" + L"End Class\n" + L"Call invokeMethod(new C)\n"; + HRESULT hres; + + SET_EXPECT(OnScriptError); + hres = parse_script_wr(src); + ok(hres == S_OK, "parse_script_wr returned %08lx\n", hres); + CHECK_CALLED(OnScriptError); +} + static void test_msgbox(void) { HRESULT hres; @@ -4306,6 +4359,7 @@ static void run_tests(void) test_redefine_scope(); test_getref_error_reporting(); test_getref_external_caller_error(); + test_external_caller_method_error(); test_parse_context(); test_callbacks(); test_multiple_parse(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10980