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