oleaut32: When marshalling VT_CARRAY, only marshall by reference for appropriate types.
This commit is contained in:
parent
c2c3b51650
commit
4f5271a17f
|
@ -37,14 +37,14 @@ static HRESULT (WINAPI *pVarAdd)(LPVARIANT,LPVARIANT,LPVARIANT);
|
||||||
/* ULL suffix is not portable */
|
/* ULL suffix is not portable */
|
||||||
#define ULL_CONST(dw1, dw2) ((((ULONGLONG)dw1) << 32) | (ULONGLONG)dw2)
|
#define ULL_CONST(dw1, dw2) ((((ULONGLONG)dw1) << 32) | (ULONGLONG)dw2)
|
||||||
|
|
||||||
const MYSTRUCT MYSTRUCT_BYVAL = {0x12345678, ULL_CONST(0xdeadbeef, 0x98765432)};
|
const MYSTRUCT MYSTRUCT_BYVAL = {0x12345678, ULL_CONST(0xdeadbeef, 0x98765432), {0,1,2,3,4,5,6,7}};
|
||||||
const MYSTRUCT MYSTRUCT_BYPTR = {0x91827364, ULL_CONST(0x88776655, 0x44332211)};
|
const MYSTRUCT MYSTRUCT_BYPTR = {0x91827364, ULL_CONST(0x88776655, 0x44332211), {0,1,2,3,4,5,6,7}};
|
||||||
const MYSTRUCT MYSTRUCT_ARRAY[5] = {
|
const MYSTRUCT MYSTRUCT_ARRAY[5] = {
|
||||||
{0x1a1b1c1d, ULL_CONST(0x1e1f1011, 0x12131415)},
|
{0x1a1b1c1d, ULL_CONST(0x1e1f1011, 0x12131415), {0,1,2,3,4,5,6,7}},
|
||||||
{0x2a2b2c2d, ULL_CONST(0x2e2f2021, 0x22232425)},
|
{0x2a2b2c2d, ULL_CONST(0x2e2f2021, 0x22232425), {0,1,2,3,4,5,6,7}},
|
||||||
{0x3a3b3c3d, ULL_CONST(0x3e3f3031, 0x32333435)},
|
{0x3a3b3c3d, ULL_CONST(0x3e3f3031, 0x32333435), {0,1,2,3,4,5,6,7}},
|
||||||
{0x4a4b4c4d, ULL_CONST(0x4e4f4041, 0x42434445)},
|
{0x4a4b4c4d, ULL_CONST(0x4e4f4041, 0x42434445), {0,1,2,3,4,5,6,7}},
|
||||||
{0x5a5b5c5d, ULL_CONST(0x5e5f5051, 0x52535455)},
|
{0x5a5b5c5d, ULL_CONST(0x5e5f5051, 0x52535455), {0,1,2,3,4,5,6,7}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -563,6 +563,17 @@ static HRESULT WINAPI Widget_VarArg(
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL mystruct_uint_ordered(UINT uarr[8])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sizeof(uarr) / sizeof(uarr[0]); i++)
|
||||||
|
if (uarr[i] != i)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI Widget_StructArgs(
|
static HRESULT WINAPI Widget_StructArgs(
|
||||||
IWidget * iface,
|
IWidget * iface,
|
||||||
MYSTRUCT byval,
|
MYSTRUCT byval,
|
||||||
|
@ -571,14 +582,17 @@ static HRESULT WINAPI Widget_StructArgs(
|
||||||
{
|
{
|
||||||
int i, diff = 0;
|
int i, diff = 0;
|
||||||
ok(byval.field1 == MYSTRUCT_BYVAL.field1 &&
|
ok(byval.field1 == MYSTRUCT_BYVAL.field1 &&
|
||||||
byval.field2 == MYSTRUCT_BYVAL.field2,
|
byval.field2 == MYSTRUCT_BYVAL.field2 &&
|
||||||
|
mystruct_uint_ordered(byval.uarr),
|
||||||
"Struct parameter passed by value corrupted\n");
|
"Struct parameter passed by value corrupted\n");
|
||||||
ok(byptr->field1 == MYSTRUCT_BYPTR.field1 &&
|
ok(byptr->field1 == MYSTRUCT_BYPTR.field1 &&
|
||||||
byptr->field2 == MYSTRUCT_BYPTR.field2,
|
byptr->field2 == MYSTRUCT_BYPTR.field2 &&
|
||||||
|
mystruct_uint_ordered(byptr->uarr),
|
||||||
"Struct parameter passed by pointer corrupted\n");
|
"Struct parameter passed by pointer corrupted\n");
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
if (arr[i].field1 != MYSTRUCT_ARRAY[i].field1 ||
|
if (arr[i].field1 != MYSTRUCT_ARRAY[i].field1 ||
|
||||||
arr[i].field2 != MYSTRUCT_ARRAY[i].field2)
|
arr[i].field2 != MYSTRUCT_ARRAY[i].field2 ||
|
||||||
|
! mystruct_uint_ordered(arr[i].uarr))
|
||||||
diff++;
|
diff++;
|
||||||
ok(diff == 0, "Array of structs corrupted\n");
|
ok(diff == 0, "Array of structs corrupted\n");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
@ -39,6 +39,7 @@ library TestTypelib
|
||||||
{
|
{
|
||||||
INT field1;
|
INT field1;
|
||||||
ULONGLONG field2;
|
ULONGLONG field2;
|
||||||
|
UINT uarr[8];
|
||||||
} MYSTRUCT;
|
} MYSTRUCT;
|
||||||
|
|
||||||
coclass ApplicationObject2;
|
coclass ApplicationObject2;
|
||||||
|
|
|
@ -638,6 +638,17 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Whether we pass this type by reference or by value */
|
||||||
|
static int
|
||||||
|
_passbyref(const TYPEDESC *td, ITypeInfo *tinfo) {
|
||||||
|
if (td->vt == VT_USERDEFINED ||
|
||||||
|
td->vt == VT_VARIANT ||
|
||||||
|
td->vt == VT_PTR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT
|
static HRESULT
|
||||||
serialize_param(
|
serialize_param(
|
||||||
ITypeInfo *tinfo,
|
ITypeInfo *tinfo,
|
||||||
|
@ -892,7 +903,8 @@ serialize_param(
|
||||||
if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
|
if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt));
|
||||||
if (debugout) TRACE_(olerelay)("[");
|
if (debugout) TRACE_(olerelay)("[");
|
||||||
for (i=0;i<arrsize;i++) {
|
for (i=0;i<arrsize;i++) {
|
||||||
hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)), buf);
|
LPBYTE base = _passbyref(&adesc->tdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg;
|
||||||
|
hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf);
|
||||||
if (hres)
|
if (hres)
|
||||||
return hres;
|
return hres;
|
||||||
if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
|
if (debugout && (i<arrsize-1)) TRACE_(olerelay)(",");
|
||||||
|
@ -1172,13 +1184,18 @@ deserialize_param(
|
||||||
}
|
}
|
||||||
case VT_CARRAY: {
|
case VT_CARRAY: {
|
||||||
/* arg is pointing to the start of the array. */
|
/* arg is pointing to the start of the array. */
|
||||||
|
LPBYTE base = (LPBYTE) arg;
|
||||||
ARRAYDESC *adesc = tdesc->u.lpadesc;
|
ARRAYDESC *adesc = tdesc->u.lpadesc;
|
||||||
int arrsize,i;
|
int arrsize,i;
|
||||||
arrsize = 1;
|
arrsize = 1;
|
||||||
if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
|
if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n");
|
||||||
for (i=0;i<adesc->cDims;i++)
|
for (i=0;i<adesc->cDims;i++)
|
||||||
arrsize *= adesc->rgbounds[i].cElements;
|
arrsize *= adesc->rgbounds[i].cElements;
|
||||||
*arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
|
if (_passbyref(&adesc->tdescElem, tinfo))
|
||||||
|
{
|
||||||
|
base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize);
|
||||||
|
*arg = (DWORD) base;
|
||||||
|
}
|
||||||
for (i=0;i<arrsize;i++)
|
for (i=0;i<arrsize;i++)
|
||||||
deserialize_param(
|
deserialize_param(
|
||||||
tinfo,
|
tinfo,
|
||||||
|
@ -1186,7 +1203,7 @@ deserialize_param(
|
||||||
debugout,
|
debugout,
|
||||||
alloc,
|
alloc,
|
||||||
&adesc->tdescElem,
|
&adesc->tdescElem,
|
||||||
(DWORD*)((LPBYTE)(*arg)+i*_xsize(&adesc->tdescElem, tinfo)),
|
(DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)),
|
||||||
buf
|
buf
|
||||||
);
|
);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
Loading…
Reference in New Issue