From 7e0c4fa404c570e107953b8882a09afcedfe0f6c Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Wed, 9 Dec 2009 15:02:44 -0600 Subject: [PATCH] usrmarshal: Add a test for marshalling a SAFEARRAY of VT_BSTR. --- dlls/oleaut32/tests/usrmarshal.c | 92 +++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index d1809460238..d57802cb3ba 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);