Mikołaj Zalewski : oleaut32: VT_USERDEFINED records are passed by value.

Alexandre Julliard julliard at winehq.org
Tue Sep 16 06:54:23 CDT 2008


Module: wine
Branch: master
Commit: 5c2fd1b192380fb741781db55b8fb93c2a336810
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5c2fd1b192380fb741781db55b8fb93c2a336810

Author: Mikołaj Zalewski <mikolaj at zalewski.pl>
Date:   Mon Sep 15 21:22:25 2008 +0200

oleaut32: VT_USERDEFINED records are passed by value.

---

 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..04f0d4d 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);




More information about the wine-cvs mailing list