usrmarshal: Add a test for marshalling a SAFEARRAY of VT_BSTR.

This commit is contained in:
Jeremy White 2009-12-09 15:02:44 -06:00 committed by Alexandre Julliard
parent 185e5daed6
commit 7e0c4fa404
1 changed files with 90 additions and 2 deletions

View File

@ -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);