diff --git a/dlls/dispex/tests/marshal.c b/dlls/dispex/tests/marshal.c index 847f54eb421..b2777195493 100644 --- a/dlls/dispex/tests/marshal.c +++ b/dlls/dispex/tests/marshal.c @@ -232,6 +232,12 @@ static HRESULT WINAPI dispex_GetDispID(IDispatchEx* iface, return E_NOTIMPL; } +static HRESULT WINAPI defer_fn(EXCEPINFO *except) +{ + except->scode = E_OUTOFMEMORY; + return S_OK; +} + static HRESULT WINAPI dispex_InvokeEx(IDispatchEx* iface, DISPID id, LCID lcid, @@ -266,6 +272,11 @@ static HRESULT WINAPI dispex_InvokeEx(IDispatchEx* iface, { ok(wFlags == 0xf, "got %04x\n", wFlags); } + else if(id == 5) + { + if(pei) pei->pfnDeferredFillIn = defer_fn; + return DISP_E_EXCEPTION; + } return S_OK; } @@ -354,6 +365,7 @@ static void test_dispex(void) DISPPARAMS params; VARIANTARG args[10]; INT i; + EXCEPINFO excepinfo; hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); ok(hr == S_OK, "got %08x\n", hr); @@ -399,6 +411,14 @@ todo_wine hr = IDispatchEx_InvokeEx(dispex, 4, LOCALE_SYSTEM_DEFAULT, 0xffff, ¶ms, NULL, NULL, NULL); ok(hr == S_OK, "got %08x\n", hr); + params.cArgs = 0; + hr = IDispatchEx_InvokeEx(dispex, 5, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); + ok(hr == DISP_E_EXCEPTION, "got %08x\n", hr); + hr = IDispatchEx_InvokeEx(dispex, 5, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, &excepinfo, NULL); + ok(hr == DISP_E_EXCEPTION, "got %08x\n", hr); + ok(excepinfo.scode == E_OUTOFMEMORY, "got scode %08x\n", excepinfo.scode); + ok(excepinfo.pfnDeferredFillIn == NULL, "got non-NULL pfnDeferredFillIn\n"); + IDispatchEx_Release(dispex); end_host_object(tid, thread); } diff --git a/dlls/dispex/usrmarshal.c b/dlls/dispex/usrmarshal.c index c8c3563aae5..915e5bc3320 100644 --- a/dlls/dispex/usrmarshal.c +++ b/dlls/dispex/usrmarshal.c @@ -133,6 +133,15 @@ HRESULT __RPC_STUB IDispatchEx_InvokeEx_Stub(IDispatchEx* This, DISPID id, LCID hr = IDispatchEx_InvokeEx(This, id, lcid, dwFlags & 0xffff, pdp, result, pei, pspCaller); + if(hr == DISP_E_EXCEPTION) + { + if(pei && pei->pfnDeferredFillIn) + { + pei->pfnDeferredFillIn(pei); + pei->pfnDeferredFillIn = NULL; + } + } + for(arg = 0; arg < byref_args; arg++) VariantInit(pdp->rgvarg + ref_idx[arg]);