Jeremy White : usrmarshal: Add a test for marshalling a SAFEARRAY of VT_BSTR.
Alexandre Julliard
julliard at winehq.org
Thu Dec 10 10:00:57 CST 2009
Module: wine
Branch: master
Commit: 7e0c4fa404c570e107953b8882a09afcedfe0f6c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7e0c4fa404c570e107953b8882a09afcedfe0f6c
Author: Jeremy White <jwhite at codeweavers.com>
Date: Wed Dec 9 15:02:44 2009 -0600
usrmarshal: Add a test for marshalling a SAFEARRAY of VT_BSTR.
---
dlls/oleaut32/tests/usrmarshal.c | 92 +++++++++++++++++++++++++++++++++++++-
1 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c
index d180946..d57802c 100644
--- a/dlls/oleaut32/tests/usrmarshal.c
+++ b/dlls/oleaut32/tests/usrmarshal.c
@@ -109,6 +109,14 @@ static ULONG get_cell_count(const SAFEARRAY *psa)
return ulNumCells;
}
+static DWORD elem_wire_size(LPSAFEARRAY lpsa, SF_TYPE sftype)
+{
+ if (sftype == SF_BSTR)
+ return sizeof(DWORD);
+ else
+ return lpsa->cbElements;
+}
+
static void check_safearray(void *buffer, LPSAFEARRAY lpsa)
{
unsigned char *wiresa = buffer;
@@ -136,7 +144,7 @@ static void check_safearray(void *buffer, LPSAFEARRAY lpsa)
wiresa += sizeof(WORD);
ok(*(WORD *)wiresa == lpsa->fFeatures, "wiresa + 0xa should be lpsa->fFeatures instead of 0x%08x\n", *(WORD *)wiresa);
wiresa += sizeof(WORD);
- ok(*(DWORD *)wiresa == lpsa->cbElements, "wiresa + 0xc should be lpsa->cbElements instead of 0x%08x\n", *(DWORD *)wiresa);
+ ok(*(DWORD *)wiresa == elem_wire_size(lpsa, sftype), "wiresa + 0xc should be 0x%08x instead of 0x%08x\n", elem_wire_size(lpsa, sftype), *(DWORD *)wiresa);
wiresa += sizeof(DWORD);
ok(*(WORD *)wiresa == lpsa->cLocks, "wiresa + 0x10 should be lpsa->cLocks instead of 0x%04x\n", *(WORD *)wiresa);
wiresa += sizeof(WORD);
@@ -197,7 +205,7 @@ static void init_user_marshal_cb(USER_MARSHAL_CB *umcb,
static void test_marshal_LPSAFEARRAY(void)
{
- unsigned char *buffer;
+ unsigned char *buffer, *p;
ULONG size, expected;
LPSAFEARRAY lpsa;
LPSAFEARRAY lpsa2 = NULL;
@@ -207,6 +215,10 @@ static void test_marshal_LPSAFEARRAY(void)
USER_MARSHAL_CB umcb;
HRESULT hr;
VARTYPE vt;
+ OLECHAR *values[10];
+ int expected_bstr_size;
+ int i;
+ LONG indices[1];
sab.lLbound = 5;
sab.cElements = 10;
@@ -324,6 +336,82 @@ static void test_marshal_LPSAFEARRAY(void)
SafeArrayDestroyData(lpsa);
SafeArrayDestroyDescriptor(lpsa);
+ /* Test an array of VT_BSTR */
+ sab.lLbound = 3;
+ sab.cElements = sizeof(values) / sizeof(values[0]);
+
+ lpsa = SafeArrayCreate(VT_BSTR, 1, &sab);
+ expected_bstr_size = 0;
+ for (i = 0; i < sab.cElements; i++)
+ {
+ int j;
+ WCHAR buf[128];
+ for (j = 0; j <= i; j++)
+ buf[j] = 'a' + j;
+ buf[j] = 0;
+ indices[0] = i + sab.lLbound;
+ values[i] = SysAllocString(buf);
+ hr = SafeArrayPutElement(lpsa, indices, values[i]);
+ ok(hr == S_OK, "Failed to put bstr element hr 0x%x\n", hr);
+ expected_bstr_size += (j * sizeof(WCHAR)) + (3 * sizeof(DWORD));
+ if (i % 2 == 0) /* Account for DWORD padding. Works so long as cElements is even */
+ expected_bstr_size += sizeof(WCHAR);
+ }
+
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ size = LPSAFEARRAY_UserSize(&umcb.Flags, 1, &lpsa);
+ expected = 44 + (sab.cElements * sizeof(DWORD)) + expected_bstr_size;
+ if (sizeof(void *) == 8) /* win64 */
+ expected += 12;
+ todo_wine
+ ok(size == (expected + sizeof(DWORD)), "size should be %u bytes, not %u\n", expected + (ULONG) sizeof(DWORD), size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ size = LPSAFEARRAY_UserSize(&umcb.Flags, 0, &lpsa);
+ todo_wine
+ ok(size == expected, "size should be %u bytes, not %u\n", expected, size);
+ buffer = HeapAlloc(GetProcessHeap(), 0, size);
+ memset(buffer, 0xcc, size);
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ p = LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa);
+ trace("LPSAFEARRAY_UserMarshal processed %ld bytes\n", p ? (long) (p - buffer) : 0);
+
+ check_safearray(buffer, lpsa);
+
+ lpsa2 = NULL;
+ if (LPSAFEARRAY_UNMARSHAL_WORKS)
+ {
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_DIFFERENTMACHINE);
+ p = LPSAFEARRAY_UserUnmarshal(&umcb.Flags, buffer, &lpsa2);
+ trace("LPSAFEARRAY_UserUnmarshal processed %ld bytes\n", p ? (long) (p - buffer) : 0);
+ ok(lpsa2 != NULL, "LPSAFEARRAY didn't unmarshal, result %p\n", p);
+ }
+
+ for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
+ {
+ BSTR gotvalue = NULL;
+
+ if (lpsa2)
+ {
+ indices[0] = i + sab.lLbound;
+ hr = SafeArrayGetElement(lpsa2, indices, &gotvalue);
+ ok(hr == S_OK, "Failed to get bstr element at hres 0x%x\n", hr);
+ if (hr == S_OK)
+ ok(VarBstrCmp(values[i], gotvalue, 0, 0) == VARCMP_EQ, "String %d does not match\n", i);
+ }
+
+ SysFreeString(values[i]);
+ }
+
+ if (LPSAFEARRAY_UNMARSHAL_WORKS)
+ {
+ init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, NULL, 0, MSHCTX_DIFFERENTMACHINE);
+ LPSAFEARRAY_UserFree(&umcb.Flags, &lpsa2);
+ }
+
+ HeapFree(GetProcessHeap(), 0, buffer);
+ SafeArrayDestroy(lpsa);
+
+
/* VARTYPE-less arrays with FADF_VARIANT */
hr = SafeArrayAllocDescriptor(1, &lpsa);
ok(hr == S_OK, "saad failed %08x\n", hr);
More information about the wine-cvs
mailing list