oleaut32: Split out the SAFEARRAY and BSTR tests so that they can be used in the upcoming VARIANT tests.

This commit is contained in:
Huw Davies 2006-05-02 12:00:30 +01:00 committed by Alexandre Julliard
parent 2e8a74d520
commit 747f08c8ae

View file

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