[PATCH] oleaut32: VT_USERDEFINED records are passed by value
Mikołaj Zalewski
mikolaj at zalewski.pl
Mon Sep 15 14:22:25 CDT 2008
---
dlls/oleaut32/tests/tmarshal.c | 35 +++++++++++++++++++++++++++++-
dlls/oleaut32/tests/tmarshal.idl | 9 +++++++
dlls/oleaut32/tests/tmarshal_dispids.h | 1 +
dlls/oleaut32/tmarshal.c | 37 ++++++++++++++++++++++++++++---
4 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/dlls/oleaut32/tests/tmarshal.c b/dlls/oleaut32/tests/tmarshal.c
index f705722..3c9cacf 100644
--- a/dlls/oleaut32/tests/tmarshal.c
+++ b/dlls/oleaut32/tests/tmarshal.c
@@ -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;
diff --git a/dlls/oleaut32/tests/tmarshal.idl b/dlls/oleaut32/tests/tmarshal.idl
index 2367f28..ea10797 100644
--- a/dlls/oleaut32/tests/tmarshal.idl
+++ b/dlls/oleaut32/tests/tmarshal.idl
@@ -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();
diff --git a/dlls/oleaut32/tests/tmarshal_dispids.h b/dlls/oleaut32/tests/tmarshal_dispids.h
index 803b94b..8fcf109 100644
--- a/dlls/oleaut32/tests/tmarshal_dispids.h
+++ b/dlls/oleaut32/tests/tmarshal_dispids.h
@@ -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
diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c
index 0123e52..fdfe07c 100644
--- a/dlls/oleaut32/tmarshal.c
+++ b/dlls/oleaut32/tmarshal.c
@@ -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);
--
1.5.4
--------------080602020203020103050005--
More information about the wine-patches
mailing list