oleaut32: VT_USERDEFINED records are passed by value.

This commit is contained in:
Mikołaj Zalewski 2008-09-15 21:22:25 +02:00 committed by Alexandre Julliard
parent 4ac24dc2bf
commit 5c2fd1b192
4 changed files with 77 additions and 5 deletions

View File

@ -24,13 +24,26 @@
#include <ocidl.h>
#include <stdio.h>
#include <wine/test.h>
#include "wine/test.h"
#include "tmarshal.h"
#include "tmarshal_dispids.h"
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08lx\n", (unsigned long int)hr)
/* ULL suffix is not portable */
#define ULL_CONST(dw1, dw2) ((((ULONGLONG)dw1) << 32) | (ULONGLONG)dw2)
const MYSTRUCT MYSTRUCT_BYVAL = {0x12345678, ULL_CONST(0xdeadbeef, 0x98765432)};
const MYSTRUCT MYSTRUCT_BYPTR = {0x91827364, ULL_CONST(0x88776655, 0x44332211)};
const MYSTRUCT MYSTRUCT_ARRAY[5] = {
{0x1a1b1c1d, ULL_CONST(0x1e1f1011, 0x12131415)},
{0x2a2b2c2d, ULL_CONST(0x2e2f2021, 0x22232425)},
{0x3a3b3c3d, ULL_CONST(0x3e3f3031, 0x32333435)},
{0x4a4b4c4d, ULL_CONST(0x4e4f4041, 0x42434445)},
{0x5a5b5c5d, ULL_CONST(0x5e5f5051, 0x52535455)},
};
/* Debugging functions from wine/libs/wine/debug.c */
/* allocate some tmp string space */
@ -575,6 +588,18 @@ void WINAPI Widget_VarArg(
ok(hr == S_OK, "SafeArrayUnaccessData failed with %x\n", hr);
}
void WINAPI Widget_StructArgs(
IWidget * iface,
MYSTRUCT byval,
MYSTRUCT *byptr,
MYSTRUCT arr[5])
{
ok(memcmp(&byval, &MYSTRUCT_BYVAL, sizeof(MYSTRUCT))==0, "Struct parameter passed by value corrupted\n");
ok(memcmp(byptr, &MYSTRUCT_BYPTR, sizeof(MYSTRUCT))==0, "Struct parameter passed by pointer corrupted\n");
ok(memcmp(arr, MYSTRUCT_ARRAY, sizeof(MYSTRUCT_ARRAY))==0, "Array of structs corrupted\n");
}
HRESULT WINAPI Widget_Error(
IWidget __RPC_FAR * iface)
{
@ -616,6 +641,7 @@ static const struct IWidgetVtbl Widget_VTable =
Widget_VariantArrayPtr,
Widget_Variant,
Widget_VarArg,
Widget_StructArgs,
Widget_Error,
Widget_CloneInterface
};
@ -932,6 +958,8 @@ static void test_typelibmarshal(void)
DWORD tid;
BSTR bstr;
ITypeInfo *pTypeInfo;
MYSTRUCT mystruct;
MYSTRUCT mystructArray[5];
ok(pKEW != NULL, "Widget creation failed\n");
@ -1071,6 +1099,11 @@ static void test_typelibmarshal(void)
ok_ole_success(hr, IDispatch_Invoke);
VariantClear(&varresult);
/* call StructArgs (direct) */
mystruct = MYSTRUCT_BYPTR;
memcpy(mystructArray, MYSTRUCT_ARRAY, sizeof(mystructArray));
IWidget_StructArgs(pWidget, MYSTRUCT_BYVAL, &mystruct, mystructArray);
/* call Clone */
dispparams.cNamedArgs = 0;
dispparams.cArgs = 0;

View File

@ -35,6 +35,12 @@ library TestTypelib
STATE_WIDGETIFIED
} STATE;
typedef struct tagMYSTRUCT
{
INT field1;
ULONGLONG field2;
} MYSTRUCT;
coclass ApplicationObject2;
[
@ -111,6 +117,9 @@ library TestTypelib
[vararg, id(DISPID_TM_VARARG)]
void VarArg([in] int numexpect, [in] SAFEARRAY(VARIANT) values);
[id(DISPID_TM_STRUCTARGS)]
void StructArgs([in] MYSTRUCT byval, [in] MYSTRUCT *byptr, [in] MYSTRUCT arr[5]);
[id(DISPID_TM_ERROR)]
HRESULT Error();

View File

@ -33,5 +33,6 @@
#define DISPID_TM_ERROR 14
#define DISPID_TM_CLONEINTERFACE 15
#define DISPID_TM_TESTDUAL 16
#define DISPID_TM_STRUCTARGS 17
#define DISPID_NOA_BSTRRET 1

View File

@ -524,6 +524,22 @@ _argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) {
return (sizeof(DECIMAL)+3)/sizeof(DWORD);
case VT_VARIANT:
return (sizeof(VARIANT)+3)/sizeof(DWORD);
case VT_USERDEFINED:
{
ITypeInfo *tinfo2;
TYPEATTR *tattr;
HRESULT hres;
DWORD ret;
hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
if (FAILED(hres))
return 0; /* should fail critically in serialize_param */
ITypeInfo_GetTypeAttr(tinfo2,&tattr);
ret = (tattr->cbSizeInstance+3)/sizeof(DWORD);
ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
ITypeInfo_Release(tinfo2);
return ret;
}
default:
return 1;
}
@ -558,6 +574,22 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
case VT_UI1:
case VT_I1:
return 1;
case VT_USERDEFINED:
{
ITypeInfo *tinfo2;
TYPEATTR *tattr;
HRESULT hres;
DWORD ret;
hres = ITypeInfo_GetRefTypeInfo(tinfo,td->u.hreftype,&tinfo2);
if (FAILED(hres))
return 0;
ITypeInfo_GetTypeAttr(tinfo2,&tattr);
ret = tattr->cbSizeInstance;
ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
ITypeInfo_Release(tinfo2);
return ret;
}
default:
return 4;
}
@ -1149,9 +1181,6 @@ deserialize_param(
case TKIND_RECORD: {
int i;
if (alloc)
*arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,tattr->cbSizeInstance);
if (debugout) TRACE_(olerelay)("{");
for (i=0;i<tattr->cVars;i++) {
VARDESC *vdesc;
@ -1169,7 +1198,7 @@ deserialize_param(
debugout,
alloc,
&vdesc->elemdescVar.tdesc,
(DWORD*)(((LPBYTE)*arg)+vdesc->u.oInst),
(DWORD*)(((LPBYTE)arg)+vdesc->u.oInst),
buf
);
ITypeInfo2_ReleaseVarDesc(tinfo2, vdesc);