oleaut32: Unmarshall byref types correctly in IDispatch_Invoke_Proxy.

Byref arguments should only be passed in the rgVarRef array, not in
arg array. Copy the value into the rgVarRef array before calling the
remote function to ensure that memory isn't allocated for the byref
pointers during unmarshalling.
This commit is contained in:
Rob Shearman 2009-11-18 00:16:51 +00:00 committed by Alexandre Julliard
parent b60e98191c
commit 6d7572c0e7
2 changed files with 9 additions and 6 deletions

View File

@ -1364,7 +1364,6 @@ static void test_typelibmarshal(void)
ok_ole_success(hr, ITypeInfo_Invoke);
ok(V_VT(&varresult) == VT_EMPTY, "varresult should be VT_EMPTY\n");
ok(V_VT(&vararg[0]) == (VT_UI4|VT_BYREF), "arg VT not unmarshalled correctly: %x\n", V_VT(&vararg[0]));
todo_wine
ok(V_UI4REF(&vararg[0]) == &uval, "Byref pointer not preserved: %p/%p\n", &uval, V_UI4REF(&vararg[0]));
ok(*V_UI4REF(&vararg[0]) == 42, "Expected 42 to be returned instead of %u\n", *V_UI4REF(&vararg[0]));
VariantClear(&varresult);

View File

@ -1180,6 +1180,8 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
if (V_ISBYREF(arg)) {
rgVarRefIdx[cVarRef] = u;
VariantInit(&rgVarRef[cVarRef]);
VariantCopy(&rgVarRef[cVarRef], arg);
VariantClear(arg);
cVarRef++;
}
}
@ -1265,6 +1267,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
}
if (SUCCEEDED(hr)) {
/* copy ref args to arg array */
for (u=0; u<cVarRef; u++) {
unsigned i = rgVarRefIdx[u];
VariantCopy(&arg[i], &rgVarRef[u]);
}
pDispParams->rgvarg = arg;
hr = IDispatch_Invoke(This,
@ -1277,14 +1285,10 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
pExcepInfo,
pArgErr);
/* copy ref args to out list */
/* copy ref args from arg array */
for (u=0; u<cVarRef; u++) {
unsigned i = rgVarRefIdx[u];
VariantInit(&rgVarRef[u]);
VariantCopy(&rgVarRef[u], &arg[i]);
/* clear original if equal, to avoid double-free */
if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
VariantClear(&rgvarg[i]);
}
}