From f1ebd2d8948243afc2e2f2a0d4222c8093112e8d Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Mon, 22 Mar 2010 14:44:52 +0000 Subject: [PATCH] dispex: Check whether the server function changes the type of the arguments. --- dlls/dispex/tests/marshal.c | 1 - dlls/dispex/usrmarshal.c | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/dlls/dispex/tests/marshal.c b/dlls/dispex/tests/marshal.c index b2777195493..43806219591 100644 --- a/dlls/dispex/tests/marshal.c +++ b/dlls/dispex/tests/marshal.c @@ -405,7 +405,6 @@ static void test_dispex(void) /* change one of the argument vts */ i = 0xbeef; hr = IDispatchEx_InvokeEx(dispex, 3, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, NULL, NULL); -todo_wine ok(hr == DISP_E_BADCALLEE, "got %08x\n", hr); hr = IDispatchEx_InvokeEx(dispex, 4, LOCALE_SYSTEM_DEFAULT, 0xffff, ¶ms, NULL, NULL, NULL); diff --git a/dlls/dispex/usrmarshal.c b/dlls/dispex/usrmarshal.c index 915e5bc3320..cc724691753 100644 --- a/dlls/dispex/usrmarshal.c +++ b/dlls/dispex/usrmarshal.c @@ -118,6 +118,7 @@ HRESULT __RPC_STUB IDispatchEx_InvokeEx_Stub(IDispatchEx* This, DISPID id, LCID { HRESULT hr; UINT arg; + VARTYPE *vt_list = NULL; TRACE("(%p)->(%08x, %04x, %08x, %p, %p, %p, %p, %d, %p, %p)\n", This, id, lcid, dwFlags, pdp, result, pei, pspCaller, byref_args, ref_idx, ref_arg); @@ -131,8 +132,30 @@ HRESULT __RPC_STUB IDispatchEx_InvokeEx_Stub(IDispatchEx* This, DISPID id, LCID if(dwFlags & NULL_RESULT) result = NULL; if(dwFlags & NULL_EXCEPINFO) pei = NULL; + /* Create an array of the original VTs to check that the function doesn't change + any on return. */ + if(byref_args) + { + vt_list = HeapAlloc(GetProcessHeap(), 0, pdp->cArgs * sizeof(vt_list[0])); + if(!vt_list) return E_OUTOFMEMORY; + for(arg = 0; arg < pdp->cArgs; arg++) + vt_list[arg] = V_VT(pdp->rgvarg + arg); + } + hr = IDispatchEx_InvokeEx(This, id, lcid, dwFlags & 0xffff, pdp, result, pei, pspCaller); + if(SUCCEEDED(hr) && byref_args) + { + for(arg = 0; arg < pdp->cArgs; arg++) + { + if(vt_list[arg] != V_VT(pdp->rgvarg + arg)) + { + hr = DISP_E_BADCALLEE; + break; + } + } + } + if(hr == DISP_E_EXCEPTION) { if(pei && pei->pfnDeferredFillIn) @@ -145,5 +168,6 @@ HRESULT __RPC_STUB IDispatchEx_InvokeEx_Stub(IDispatchEx* This, DISPID id, LCID for(arg = 0; arg < byref_args; arg++) VariantInit(pdp->rgvarg + ref_idx[arg]); + HeapFree(GetProcessHeap(), 0, vt_list); return hr; }