From 747f08c8aebf841001bde3de3a69b0e292ed4be1 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Tue, 2 May 2006 12:00:30 +0100 Subject: [PATCH] oleaut32: Split out the SAFEARRAY and BSTR tests so that they can be used in the upcoming VARIANT tests. --- dlls/oleaut32/tests/usrmarshal.c | 186 +++++++++++++++++++++++-------- 1 file changed, 138 insertions(+), 48 deletions(-) diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index 5d793159f14..9f2db8be979 100644 --- a/dlls/oleaut32/tests/usrmarshal.c +++ b/dlls/oleaut32/tests/usrmarshal.c @@ -32,13 +32,123 @@ #define LPSAFEARRAY_UNMARSHAL_WORKS 0 #define BSTR_UNMARSHAL_WORKS 0 +static inline SF_TYPE get_union_type(SAFEARRAY *psa) +{ + VARTYPE vt; + HRESULT hr; + + hr = SafeArrayGetVartype(psa, &vt); + if (FAILED(hr)) + return 0; + + if (psa->fFeatures & FADF_HAVEIID) + return SF_HAVEIID; + + switch (vt) + { + case VT_I1: + case VT_UI1: return SF_I1; + case VT_BOOL: + case VT_I2: + case VT_UI2: return SF_I2; + case VT_INT: + case VT_UINT: + case VT_I4: + case VT_UI4: + case VT_R4: return SF_I4; + case VT_DATE: + case VT_CY: + case VT_R8: + case VT_I8: + case VT_UI8: return SF_I8; + case VT_INT_PTR: + case VT_UINT_PTR: return (sizeof(UINT_PTR) == 4 ? SF_I4 : SF_I8); + case VT_BSTR: return SF_BSTR; + case VT_DISPATCH: return SF_DISPATCH; + case VT_VARIANT: return SF_VARIANT; + case VT_UNKNOWN: return SF_UNKNOWN; + /* Note: Return a non-zero size to indicate vt is valid. The actual size + * of a UDT is taken from the result of IRecordInfo_GetSize(). + */ + case VT_RECORD: return SF_RECORD; + default: return SF_ERROR; + } +} + +static ULONG get_cell_count(const SAFEARRAY *psa) +{ + const SAFEARRAYBOUND* psab = psa->rgsabound; + USHORT cCount = psa->cDims; + ULONG ulNumCells = 1; + + while (cCount--) + { + if (!psab->cElements) + return 0; + ulNumCells *= psab->cElements; + psab++; + } + return ulNumCells; +} + +static void check_safearray(void *buffer, LPSAFEARRAY lpsa) +{ + unsigned char *wiresa = buffer; + VARTYPE vt; + SF_TYPE sftype; + ULONG cell_count; + + if(!lpsa) + { + ok(*(DWORD *)wiresa == FALSE, "wiresa + 0x0 should be FALSE instead of 0x%08lx\n", *(DWORD *)wiresa); + return; + } + + SafeArrayGetVartype(lpsa, &vt); + sftype = get_union_type(lpsa); + cell_count = get_cell_count(lpsa); + + ok(*(DWORD *)wiresa == TRUE, "wiresa + 0x0 should be TRUE instead of 0x%08lx\n", *(DWORD *)wiresa); + wiresa += sizeof(DWORD); + ok(*(DWORD *)wiresa == lpsa->cDims, "wiresa + 0x4 should be lpsa->cDims instead of 0x%08lx\n", *(DWORD *)wiresa); + wiresa += sizeof(DWORD); + ok(*(WORD *)wiresa == lpsa->cDims, "wiresa + 0x8 should be lpsa->cDims instead of 0x%04x\n", *(WORD *)wiresa); + wiresa += sizeof(WORD); + ok(*(WORD *)wiresa == lpsa->fFeatures, "wiresa + 0xc should be lpsa->fFeatures instead of 0x%08x\n", *(WORD *)wiresa); + wiresa += sizeof(WORD); + ok(*(DWORD *)wiresa == lpsa->cbElements, "wiresa + 0x10 should be lpsa->cbElements instead of 0x%08lx\n", *(DWORD *)wiresa); + wiresa += sizeof(DWORD); + ok(*(WORD *)wiresa == lpsa->cLocks, "wiresa + 0x16 should be lpsa->cLocks instead of 0x%04x\n", *(WORD *)wiresa); + wiresa += sizeof(WORD); + ok(*(WORD *)wiresa == vt, "wiresa + 0x14 should be %04x instead of 0x%04x\n", vt, *(WORD *)wiresa); + wiresa += sizeof(WORD); + ok(*(DWORD *)wiresa == sftype, "wiresa + 0x18 should be %08lx instead of 0x%08lx\n", (DWORD)sftype, *(DWORD *)wiresa); + wiresa += sizeof(DWORD); + ok(*(DWORD *)wiresa == cell_count, "wiresa + 0x1c should be %lu instead of %lu\n", cell_count, *(DWORD *)wiresa); + wiresa += sizeof(DWORD); + ok(*(DWORD_PTR *)wiresa == (DWORD_PTR)lpsa->pvData, "wirestgm + 0x20 should be lpsa->pvData instead of 0x%08lx\n", *(DWORD_PTR *)wiresa); + wiresa += sizeof(DWORD_PTR); + if(sftype == SF_HAVEIID) + { + GUID guid; + SafeArrayGetIID(lpsa, &guid); + ok(IsEqualGUID(&guid, (GUID*)wiresa), "guid mismatch\n"); + wiresa += sizeof(GUID); + } + ok(!memcmp(wiresa, lpsa->rgsabound, sizeof(lpsa->rgsabound[0]) * lpsa->cDims), "bounds mismatch\n"); + wiresa += sizeof(lpsa->rgsabound[0]) * lpsa->cDims; + + ok(*(DWORD *)wiresa == cell_count, "wiresa + 0x2c should be %lu instead of %lu\n", cell_count, *(DWORD*)wiresa); + wiresa += sizeof(DWORD); + /* elements are now pointed to by wiresa */ +} + static void test_marshal_LPSAFEARRAY(void) { unsigned char *buffer; unsigned long size; LPSAFEARRAY lpsa; LPSAFEARRAY lpsa2 = NULL; - unsigned char *wiresa; SAFEARRAYBOUND sab; MIDL_STUB_MESSAGE stubMsg = { 0 }; USER_MARSHAL_CB umcb = { 0 }; @@ -58,34 +168,8 @@ static void test_marshal_LPSAFEARRAY(void) ok(size == 64, "size should be 64 bytes, not %ld\n", size); buffer = (unsigned char *)HeapAlloc(GetProcessHeap(), 0, size); LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); - wiresa = buffer; - ok(*(DWORD *)wiresa == TRUE, "wiresa + 0x0 should be TRUE instead of 0x%08lx\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - ok(*(DWORD *)wiresa == lpsa->cDims, "wiresa + 0x4 should be lpsa->cDims instead of 0x%08lx\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - ok(*(WORD *)wiresa == lpsa->cDims, "wiresa + 0x8 should be lpsa->cDims instead of 0x%04x\n", *(WORD *)wiresa); - wiresa += sizeof(WORD); - ok(*(WORD *)wiresa == lpsa->fFeatures, "wiresa + 0xc should be lpsa->fFeatures instead of 0x%08x\n", *(WORD *)wiresa); - wiresa += sizeof(WORD); - ok(*(DWORD *)wiresa == lpsa->cbElements, "wiresa + 0x10 should be lpsa->cbElements instead of 0x%08lx\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - ok(*(WORD *)wiresa == lpsa->cLocks, "wiresa + 0x16 should be lpsa->cLocks instead of 0x%04x\n", *(WORD *)wiresa); - wiresa += sizeof(WORD); - ok(*(WORD *)wiresa == VT_I2, "wiresa + 0x14 should be VT_I2 instead of 0x%04x\n", *(WORD *)wiresa); - wiresa += sizeof(WORD); - ok(*(DWORD *)wiresa == VT_I2, "wiresa + 0x18 should be VT_I2 instead of 0x%08lx\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - ok(*(DWORD *)wiresa == sab.cElements, "wiresa + 0x1c should be sab.cElements instead of %lu\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - ok(*(DWORD_PTR *)wiresa == (DWORD_PTR)lpsa->pvData, "wirestgm + 0x20 should be lpsa->pvData instead of 0x%08lx\n", *(DWORD_PTR *)wiresa); - wiresa += sizeof(DWORD_PTR); - ok(*(DWORD *)wiresa == sab.cElements, "wiresa + 0x24 should be sab.cElements instead of %lu\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - ok(*(LONG *)wiresa == sab.lLbound, "wiresa + 0x28 should be sab.clLbound instead of %ld\n", *(LONG *)wiresa); - wiresa += sizeof(LONG); - ok(*(DWORD *)wiresa == sab.cElements, "wiresa + 0x2c should be sab.cElements instead of %lu\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); - /* elements are now pointed to by wiresa */ + + check_safearray(buffer, lpsa); if (LPSAFEARRAY_UNMARSHAL_WORKS) { @@ -103,9 +187,7 @@ static void test_marshal_LPSAFEARRAY(void) ok(size == 4, "size should be 4 bytes, not %ld\n", size); buffer = (unsigned char *)HeapAlloc(GetProcessHeap(), 0, size); LPSAFEARRAY_UserMarshal(&umcb.Flags, buffer, &lpsa); - wiresa = buffer; - ok(*(DWORD *)wiresa == FALSE, "wiresa + 0x0 should be FALSE instead of 0x%08lx\n", *(DWORD *)wiresa); - wiresa += sizeof(DWORD); + check_safearray(buffer, lpsa); if (LPSAFEARRAY_UNMARSHAL_WORKS) { @@ -116,6 +198,27 @@ static void test_marshal_LPSAFEARRAY(void) HeapFree(GetProcessHeap(), 0, buffer); } +static void check_bstr(void *buffer, BSTR b) +{ + DWORD *wireb = buffer; + DWORD len = SysStringLen(b); + + ok(*wireb == len, "wv[0] %08lx\n", *wireb); + wireb++; + if(len) + ok(*wireb == len * 2, "wv[1] %08lx\n", *wireb); + else + ok(*wireb == 0xffffffff, "wv[1] %08lx\n", *wireb); + wireb++; + ok(*wireb == len, "wv[2] %08lx\n", *wireb); + if(len) + { + wireb++; + ok(!memcmp(wireb, b, len * 2), "strings differ\n"); + } + return; +} + static void test_marshal_BSTR(void) { unsigned long size; @@ -124,7 +227,7 @@ static void test_marshal_BSTR(void) unsigned char *buffer; BSTR b, b2; WCHAR str[] = {'m','a','r','s','h','a','l',' ','t','e','s','t','1',0}; - DWORD *wireb, len; + DWORD len; umcb.Flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); umcb.pReserve = NULL; @@ -143,15 +246,7 @@ static void test_marshal_BSTR(void) buffer = HeapAlloc(GetProcessHeap(), 0, size); BSTR_UserMarshal(&umcb.Flags, buffer, &b); - wireb = (DWORD*)buffer; - - ok(*wireb == len, "wv[0] %08lx\n", *wireb); - wireb++; - ok(*wireb == len * 2, "wv[1] %08lx\n", *wireb); - wireb++; - ok(*wireb == len, "wv[2] %08lx\n", *wireb); - wireb++; - ok(!memcmp(wireb, str, len * 2), "strings differ\n"); + check_bstr(buffer, b); if (BSTR_UNMARSHAL_WORKS) { @@ -171,13 +266,8 @@ static void test_marshal_BSTR(void) buffer = HeapAlloc(GetProcessHeap(), 0, size); BSTR_UserMarshal(&umcb.Flags, buffer, &b); - wireb = (DWORD*)buffer; - ok(*wireb == 0, "wv[0] %08lx\n", *wireb); - wireb++; - ok(*wireb == 0xffffffff, "wv[1] %08lx\n", *wireb); - wireb++; - ok(*wireb == 0, "wv[2] %08lx\n", *wireb); + check_bstr(buffer, b); HeapFree(GetProcessHeap(), 0, buffer); }