oleaut32: VT_USERDEFINED records are passed by value.
This commit is contained in:
parent
4ac24dc2bf
commit
5c2fd1b192
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue