ReactOS 0.4.16-dev-297-gc569aee
safearray.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "winnls.h"
#include "winsock2.h"
#include "winerror.h"
#include "winnt.h"
#include "wtypes.h"
#include "oleauto.h"
Include dependency graph for safearray.c:

Go to the source code of this file.

Classes

struct  IRecordInfoImpl
 
struct  xtunk_impl
 

Macros

#define COBJMACROS
 
#define CONST_VTABLE
 
#define GETPTR(func)   p##func = (void*)GetProcAddress(hOleaut32, #func)
 
#define START_REF_COUNT   1
 
#define RECORD_SIZE   64
 
#define RECORD_SIZE_FAIL   17
 
#define VARTYPE_NOT_SUPPORTED   0
 
#define MKARRAY(low, num, typ)
 
#define MKARRAYCONT(low, num, typ)
 

Typedefs

typedef struct IRecordInfoImpl IRecordInfoImpl
 

Functions

static HRESULT (WINAPI *pSafeArrayAllocDescriptorEx)(VARTYPE
 
static SAFEARRAY **static SAFEARRAY *static VARTYPE *static IRecordInfo **static SAFEARRAY *WINAPIpSafeArrayCreateEx (VARTYPE, UINT, SAFEARRAYBOUND *, LPVOID)
 
static SAFEARRAY *WINAPIpSafeArrayCreateVector (VARTYPE, LONG, ULONG)
 
static IRecordInfoImplimpl_from_IRecordInfo (IRecordInfo *iface)
 
static HRESULT WINAPI RecordInfo_QueryInterface (IRecordInfo *iface, REFIID riid, void **obj)
 
static ULONG WINAPI RecordInfo_AddRef (IRecordInfo *iface)
 
static ULONG WINAPI RecordInfo_Release (IRecordInfo *iface)
 
static HRESULT WINAPI RecordInfo_RecordInit (IRecordInfo *iface, PVOID pvNew)
 
static HRESULT WINAPI RecordInfo_RecordClear (IRecordInfo *iface, PVOID pvExisting)
 
static HRESULT WINAPI RecordInfo_RecordCopy (IRecordInfo *iface, PVOID pvExisting, PVOID pvNew)
 
static HRESULT WINAPI RecordInfo_GetGuid (IRecordInfo *iface, GUID *pguid)
 
static HRESULT WINAPI RecordInfo_GetName (IRecordInfo *iface, BSTR *pbstrName)
 
static HRESULT WINAPI RecordInfo_GetSize (IRecordInfo *iface, ULONG *size)
 
static HRESULT WINAPI RecordInfo_GetTypeInfo (IRecordInfo *iface, ITypeInfo **ppTypeInfo)
 
static HRESULT WINAPI RecordInfo_GetField (IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
 
static HRESULT WINAPI RecordInfo_GetFieldNoCopy (IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
 
static HRESULT WINAPI RecordInfo_PutField (IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
 
static HRESULT WINAPI RecordInfo_PutFieldNoCopy (IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
 
static HRESULT WINAPI RecordInfo_GetFieldNames (IRecordInfo *iface, ULONG *pcNames, BSTR *rgBstrNames)
 
static BOOL WINAPI RecordInfo_IsMatchingType (IRecordInfo *iface, IRecordInfo *info2)
 
static PVOID WINAPI RecordInfo_RecordCreate (IRecordInfo *iface)
 
static HRESULT WINAPI RecordInfo_RecordCreateCopy (IRecordInfo *iface, PVOID pvSource, PVOID *ppvDest)
 
static HRESULT WINAPI RecordInfo_RecordDestroy (IRecordInfo *iface, PVOID pvRecord)
 
static IRecordInfoImplIRecordInfoImpl_Construct (void)
 
static DWORD SAFEARRAY_GetVTSize (VARTYPE vt)
 
static void check_for_VT_INT_PTR (void)
 
static void test_safearray (void)
 
static void test_SafeArrayAllocDestroyDescriptor (void)
 
static void test_SafeArrayCreateLockDestroy (void)
 
static void test_VectorCreateLockDestroy (void)
 
static void test_LockUnlock (void)
 
static void test_SafeArrayGetPutElement (void)
 
static void test_SafeArrayGetPutElement_BSTR (void)
 
static HRESULT WINAPI tunk_QueryInterface (IUnknown *punk, REFIID riid, void **x)
 
static ULONG WINAPI tunk_AddRef (IUnknown *punk)
 
static ULONG WINAPI tunk_Release (IUnknown *punk)
 
static void test_SafeArrayGetPutElement_IUnknown (void)
 
static void test_SafeArrayRedim_IUnknown (void)
 
static void test_SafeArrayGetPutElement_VARIANT (void)
 
static void test_SafeArrayCopyData (void)
 
static void test_SafeArrayCreateEx (void)
 
static void test_SafeArrayClear (void)
 
static void test_SafeArrayCopy (void)
 
static void test_SafeArrayChangeTypeEx (void)
 
static void test_SafeArrayDestroyData (void)
 
static void test_safearray_layout (void)
 
 START_TEST (safearray)
 

Variables

const USHORT FADF_CREATEVECTOR = 0x2000
 
static HMODULE hOleaut32
 
static UINT
 
static BOOL has_i8
 
static BOOL has_int_ptr
 
static const USHORT ignored_copy_features []
 
static BOOL fail_GetSize
 
static const IRecordInfoVtbl RecordInfoVtbl
 
struct {
   VARTYPE   vt
 
   UINT   elemsize
 
   UINT   expflags
 
   UINT   addflags
 
vttypes []
 
static const IUnknownVtbl xtunk_vtbl
 
static struct xtunk_impl xtunk = {{&xtunk_vtbl}, 0}
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 27 of file safearray.c.

◆ CONST_VTABLE

#define CONST_VTABLE

Definition at line 28 of file safearray.c.

◆ GETPTR

#define GETPTR (   func)    p##func = (void*)GetProcAddress(hOleaut32, #func)

Definition at line 55 of file safearray.c.

◆ MKARRAY

#define MKARRAY (   low,
  num,
  typ 
)
Value:
sab.lLbound = low; sab.cElements = num; \
sa = SafeArrayCreate(typ, 1, &sab); ok(sa != NULL, "Create() failed.\n"); \
if (!sa) return; \
V_VT(&v) = VT_ARRAY|typ; V_ARRAY(&v) = sa; VariantInit(&v2)
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
@ VT_ARRAY
Definition: compat.h:2341
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint num
Definition: glext.h:9618
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
#define V_ARRAY(A)
Definition: oleauto.h:222
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568

Definition at line 1796 of file safearray.c.

◆ MKARRAYCONT

#define MKARRAYCONT (   low,
  num,
  typ 
)
Value:
sab.lLbound = low; sab.cElements = num; \
sa = SafeArrayCreate(typ, 1, &sab); if (!sa) continue; \
V_VT(&v) = VT_ARRAY|typ; V_ARRAY(&v) = sa; VariantInit(&v2)

Definition at line 1801 of file safearray.c.

◆ RECORD_SIZE

#define RECORD_SIZE   64

Definition at line 71 of file safearray.c.

◆ RECORD_SIZE_FAIL

#define RECORD_SIZE_FAIL   17

Definition at line 72 of file safearray.c.

◆ START_REF_COUNT

#define START_REF_COUNT   1

Definition at line 70 of file safearray.c.

◆ VARTYPE_NOT_SUPPORTED

#define VARTYPE_NOT_SUPPORTED   0

Definition at line 329 of file safearray.c.

Typedef Documentation

◆ IRecordInfoImpl

Function Documentation

◆ check_for_VT_INT_PTR()

static void check_for_VT_INT_PTR ( void  )
static

Definition at line 307 of file safearray.c.

308{
309 /* Set a global flag if VT_INT_PTR is supported */
310
311 SAFEARRAY* a;
312 SAFEARRAYBOUND bound;
313 bound.cElements = 0;
314 bound.lLbound = 0;
315 a = SafeArrayCreate(VT_INT_PTR, 1, &bound);
316 if (a) {
318 trace("VT_INT_PTR is supported\n");
321 ok(hres == S_OK, "got 0x%08x\n", hres);
322 }
323 else {
324 trace("VT_INT_PTR is not supported\n");
326 }
327}
#define trace
Definition: atltest.h:70
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ VT_INT_PTR
Definition: compat.h:2327
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define S_OK
Definition: intsafe.h:52
#define a
Definition: ke_i.h:78
HRESULT hres
Definition: protocol.c:465
static BOOL has_int_ptr
Definition: safearray.c:60

Referenced by START_TEST().

◆ HRESULT()

static HRESULT ( WINAPI pSafeArrayAllocDescriptorEx)
static

◆ impl_from_IRecordInfo()

static IRecordInfoImpl * impl_from_IRecordInfo ( IRecordInfo iface)
inlinestatic

Definition at line 85 of file safearray.c.

86{
87 return CONTAINING_RECORD(iface, IRecordInfoImpl, IRecordInfo_iface);
88}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by RecordInfo_AddRef(), RecordInfo_GetSize(), RecordInfo_RecordClear(), RecordInfo_RecordCopy(), and RecordInfo_Release().

◆ IRecordInfoImpl_Construct()

static IRecordInfoImpl * IRecordInfoImpl_Construct ( void  )
static

Definition at line 258 of file safearray.c.

259{
260 IRecordInfoImpl *rec;
261
262 rec = HeapAlloc(GetProcessHeap(), 0, sizeof(IRecordInfoImpl));
263 rec->IRecordInfo_iface.lpVtbl = &RecordInfoVtbl;
264 rec->ref = START_REF_COUNT;
265 rec->clearCalled = 0;
266 rec->sizeCalled = 0;
267 return rec;
268}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define START_REF_COUNT
Definition: safearray.c:70
static const IRecordInfoVtbl RecordInfoVtbl
Definition: safearray.c:235
IRecordInfo IRecordInfo_iface
Definition: recinfo.c:43
unsigned int sizeCalled
Definition: safearray.c:80
unsigned int clearCalled
Definition: safearray.c:81

Referenced by test_safearray_layout(), test_SafeArrayCreateEx(), and test_SafeArrayGetPutElement().

◆ pSafeArrayCreateEx()

static SAFEARRAY **static SAFEARRAY *static VARTYPE *static IRecordInfo **static SAFEARRAY *WINAPI * pSafeArrayCreateEx ( VARTYPE  ,
UINT  ,
SAFEARRAYBOUND ,
LPVOID   
)
static

◆ pSafeArrayCreateVector()

static SAFEARRAY *WINAPI * pSafeArrayCreateVector ( VARTYPE  ,
LONG  ,
ULONG   
)
static

◆ RecordInfo_AddRef()

static ULONG WINAPI RecordInfo_AddRef ( IRecordInfo iface)
static

Definition at line 105 of file safearray.c.

106{
108 return InterlockedIncrement(&This->ref);
109}
#define InterlockedIncrement
Definition: armddk.h:53
static IRecordInfoImpl * impl_from_IRecordInfo(IRecordInfo *iface)
Definition: safearray.c:85

◆ RecordInfo_GetField()

static HRESULT WINAPI RecordInfo_GetField ( IRecordInfo iface,
PVOID  pvData,
LPCOLESTR  szFieldName,
VARIANT pvarField 
)
static

Definition at line 175 of file safearray.c.

177{
178 ok(0, "unexpected call\n");
179 return E_NOTIMPL;
180}
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ RecordInfo_GetFieldNames()

static HRESULT WINAPI RecordInfo_GetFieldNames ( IRecordInfo iface,
ULONG pcNames,
BSTR rgBstrNames 
)
static

Definition at line 203 of file safearray.c.

205{
206 ok(0, "unexpected call\n");
207 return E_NOTIMPL;
208}

◆ RecordInfo_GetFieldNoCopy()

static HRESULT WINAPI RecordInfo_GetFieldNoCopy ( IRecordInfo iface,
PVOID  pvData,
LPCOLESTR  szFieldName,
VARIANT pvarField,
PVOID ppvDataCArray 
)
static

Definition at line 182 of file safearray.c.

184{
185 ok(0, "unexpected call\n");
186 return E_NOTIMPL;
187}

◆ RecordInfo_GetGuid()

static HRESULT WINAPI RecordInfo_GetGuid ( IRecordInfo iface,
GUID pguid 
)
static

Definition at line 144 of file safearray.c.

145{
146 ok(0, "unexpected call\n");
147 return E_NOTIMPL;
148}

◆ RecordInfo_GetName()

static HRESULT WINAPI RecordInfo_GetName ( IRecordInfo iface,
BSTR pbstrName 
)
static

Definition at line 150 of file safearray.c.

151{
152 ok(0, "unexpected call\n");
153 return E_NOTIMPL;
154}

◆ RecordInfo_GetSize()

static HRESULT WINAPI RecordInfo_GetSize ( IRecordInfo iface,
ULONG size 
)
static

Definition at line 156 of file safearray.c.

157{
159 This->sizeCalled++;
160 if (fail_GetSize)
161 {
163 return E_UNEXPECTED;
164 }
165 *size = RECORD_SIZE;
166 return S_OK;
167}
GLsizeiptr size
Definition: glext.h:5919
#define RECORD_SIZE_FAIL
Definition: safearray.c:72
static BOOL fail_GetSize
Definition: safearray.c:128
#define RECORD_SIZE
Definition: safearray.c:71
#define E_UNEXPECTED
Definition: winerror.h:2456

◆ RecordInfo_GetTypeInfo()

static HRESULT WINAPI RecordInfo_GetTypeInfo ( IRecordInfo iface,
ITypeInfo **  ppTypeInfo 
)
static

Definition at line 169 of file safearray.c.

170{
171 ok(0, "unexpected call\n");
172 return E_NOTIMPL;
173}

◆ RecordInfo_IsMatchingType()

static BOOL WINAPI RecordInfo_IsMatchingType ( IRecordInfo iface,
IRecordInfo info2 
)
static

Definition at line 210 of file safearray.c.

211{
212 ok(0, "unexpected call\n");
213 return FALSE;
214}

◆ RecordInfo_PutField()

static HRESULT WINAPI RecordInfo_PutField ( IRecordInfo iface,
ULONG  wFlags,
PVOID  pvData,
LPCOLESTR  szFieldName,
VARIANT pvarField 
)
static

Definition at line 189 of file safearray.c.

191{
192 ok(0, "unexpected call\n");
193 return E_NOTIMPL;
194}

◆ RecordInfo_PutFieldNoCopy()

static HRESULT WINAPI RecordInfo_PutFieldNoCopy ( IRecordInfo iface,
ULONG  wFlags,
PVOID  pvData,
LPCOLESTR  szFieldName,
VARIANT pvarField 
)
static

Definition at line 196 of file safearray.c.

198{
199 ok(0, "unexpected call\n");
200 return E_NOTIMPL;
201}

◆ RecordInfo_QueryInterface()

static HRESULT WINAPI RecordInfo_QueryInterface ( IRecordInfo iface,
REFIID  riid,
void **  obj 
)
static

Definition at line 90 of file safearray.c.

91{
92 *obj = NULL;
93
95 IsEqualIID(riid, &IID_IRecordInfo))
96 {
97 *obj = iface;
98 IRecordInfo_AddRef(iface);
99 return S_OK;
100 }
101
102 return E_NOINTERFACE;
103}
const GUID IID_IUnknown
REFIID riid
Definition: atlbase.h:39
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ RecordInfo_RecordClear()

static HRESULT WINAPI RecordInfo_RecordClear ( IRecordInfo iface,
PVOID  pvExisting 
)
static

Definition at line 130 of file safearray.c.

131{
133 This->clearCalled++;
134 return S_OK;
135}

◆ RecordInfo_RecordCopy()

static HRESULT WINAPI RecordInfo_RecordCopy ( IRecordInfo iface,
PVOID  pvExisting,
PVOID  pvNew 
)
static

Definition at line 137 of file safearray.c.

138{
140 This->recordcopy++;
141 return S_OK;
142}

◆ RecordInfo_RecordCreate()

static PVOID WINAPI RecordInfo_RecordCreate ( IRecordInfo iface)
static

Definition at line 216 of file safearray.c.

217{
218 ok(0, "unexpected call\n");
219 return NULL;
220}

◆ RecordInfo_RecordCreateCopy()

static HRESULT WINAPI RecordInfo_RecordCreateCopy ( IRecordInfo iface,
PVOID  pvSource,
PVOID ppvDest 
)
static

Definition at line 222 of file safearray.c.

224{
225 ok(0, "unexpected call\n");
226 return E_NOTIMPL;
227}

◆ RecordInfo_RecordDestroy()

static HRESULT WINAPI RecordInfo_RecordDestroy ( IRecordInfo iface,
PVOID  pvRecord 
)
static

Definition at line 229 of file safearray.c.

230{
231 ok(0, "unexpected call\n");
232 return E_NOTIMPL;
233}

◆ RecordInfo_RecordInit()

static HRESULT WINAPI RecordInfo_RecordInit ( IRecordInfo iface,
PVOID  pvNew 
)
static

Definition at line 122 of file safearray.c.

123{
124 ok(0, "unexpected call\n");
125 return E_NOTIMPL;
126}

◆ RecordInfo_Release()

static ULONG WINAPI RecordInfo_Release ( IRecordInfo iface)
static

Definition at line 111 of file safearray.c.

112{
115
116 if (!ref)
118
119 return ref;
120}
#define InterlockedDecrement
Definition: armddk.h:52
#define HeapFree(x, y, z)
Definition: compat.h:735
Definition: send.c:48
uint32_t ULONG
Definition: typedefs.h:59

◆ SAFEARRAY_GetVTSize()

static DWORD SAFEARRAY_GetVTSize ( VARTYPE  vt)
static

Definition at line 270 of file safearray.c.

271{
272 switch (vt)
273 {
274 case VT_I1:
275 case VT_UI1: return sizeof(BYTE);
276 case VT_BOOL:
277 case VT_I2:
278 case VT_UI2: return sizeof(SHORT);
279 case VT_I4:
280 case VT_UI4:
281 case VT_R4:
282 case VT_ERROR: return sizeof(LONG);
283 case VT_R8: return sizeof(LONG64);
284 case VT_I8:
285 case VT_UI8:
286 if (has_i8)
287 return sizeof(LONG64);
288 break;
289 case VT_INT:
290 case VT_UINT: return sizeof(INT);
291 case VT_INT_PTR:
292 case VT_UINT_PTR:
293 if (has_int_ptr)
294 return sizeof(UINT_PTR);
295 break;
296 case VT_CY: return sizeof(CY);
297 case VT_DATE: return sizeof(DATE);
298 case VT_BSTR: return sizeof(BSTR);
299 case VT_DISPATCH: return sizeof(LPDISPATCH);
300 case VT_VARIANT: return sizeof(VARIANT);
301 case VT_UNKNOWN: return sizeof(LPUNKNOWN);
302 case VT_DECIMAL: return sizeof(DECIMAL);
303 }
304 return 0;
305}
double DATE
Definition: compat.h:2253
union tagCY CY
struct tagDEC DECIMAL
struct tagVARIANT VARIANT
Definition: compat.h:2377
OLECHAR * BSTR
Definition: compat.h:2293
@ VT_UI8
Definition: compat.h:2315
@ VT_BSTR
Definition: compat.h:2303
@ VT_INT
Definition: compat.h:2316
@ VT_R4
Definition: compat.h:2299
@ VT_UINT_PTR
Definition: compat.h:2328
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_UI2
Definition: compat.h:2312
@ VT_DECIMAL
Definition: compat.h:2309
@ VT_ERROR
Definition: compat.h:2305
@ VT_R8
Definition: compat.h:2300
@ VT_CY
Definition: compat.h:2301
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_DATE
Definition: compat.h:2302
@ VT_BOOL
Definition: compat.h:2306
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
static BOOL has_i8
Definition: safearray.c:58
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static LPUNKNOWN
Definition: ndr_ole.c:49
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define INT
Definition: polytest.cpp:20
int64_t LONG64
Definition: typedefs.h:68
unsigned char BYTE
Definition: xxhash.c:193

◆ START_TEST()

START_TEST ( safearray  )

Definition at line 2086 of file safearray.c.

2087{
2088 hOleaut32 = GetModuleHandleA("oleaut32.dll");
2089
2090 has_i8 = GetProcAddress(hOleaut32, "VarI8FromI1") != NULL;
2091
2098
2117}
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HRESULT WINAPI SafeArrayAllocDescriptorEx(VARTYPE vt, UINT cDims, SAFEARRAY **ppsaOut)
Definition: safearray.c:521
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
HRESULT WINAPI SafeArrayGetRecordInfo(SAFEARRAY *psa, IRecordInfo **pRinfo)
Definition: safearray.c:1609
SAFEARRAY *WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, LPVOID pvExtra)
Definition: safearray.c:628
HRESULT WINAPI SafeArrayCopyData(SAFEARRAY *psaSource, SAFEARRAY *psaTarget)
Definition: safearray.c:1312
HRESULT WINAPI SafeArrayGetVartype(SAFEARRAY *psa, VARTYPE *pvt)
Definition: safearray.c:1534
static void test_SafeArrayGetPutElement_VARIANT(void)
Definition: safearray.c:1332
static void test_SafeArrayDestroyData(void)
Definition: safearray.c:1931
static void test_LockUnlock(void)
Definition: safearray.c:994
static void test_SafeArrayClear(void)
Definition: safearray.c:1648
static HMODULE hOleaut32
Definition: safearray.c:46
static void test_SafeArrayCreateEx(void)
Definition: safearray.c:1502
#define GETPTR(func)
Definition: safearray.c:55
static void test_safearray_layout(void)
Definition: safearray.c:2029
static void test_SafeArrayCreateLockDestroy(void)
Definition: safearray.c:825
static void test_SafeArrayRedim_IUnknown(void)
Definition: safearray.c:1303
static void test_SafeArrayGetPutElement_BSTR(void)
Definition: safearray.c:1206
static void test_SafeArrayGetPutElement_IUnknown(void)
Definition: safearray.c:1270
static void test_SafeArrayCopyData(void)
Definition: safearray.c:1371
static void test_SafeArrayChangeTypeEx(void)
Definition: safearray.c:1805
static void test_SafeArrayAllocDestroyDescriptor(void)
Definition: safearray.c:764
static void test_VectorCreateLockDestroy(void)
Definition: safearray.c:935
static void test_safearray(void)
Definition: safearray.c:380
static void test_SafeArrayGetPutElement(void)
Definition: safearray.c:1052
static void check_for_VT_INT_PTR(void)
Definition: safearray.c:307
static void test_SafeArrayCopy(void)
Definition: safearray.c:1688

◆ test_LockUnlock()

static void test_LockUnlock ( void  )
static

Definition at line 994 of file safearray.c.

995{
996 SAFEARRAYBOUND sab[4];
997 SAFEARRAY *sa;
999 BOOL bVector = FALSE;
1000 int dimension;
1001
1002 /* Failure cases */
1004 ok(hres == E_INVALIDARG, "Lock NULL array hres 0x%x\n", hres);
1006 ok(hres == E_INVALIDARG, "Lock NULL array hres 0x%x\n", hres);
1007
1008 for (dimension = 0; dimension < ARRAY_SIZE(sab); dimension++)
1009 {
1010 sab[dimension].lLbound = 0;
1011 sab[dimension].cElements = 8;
1012 }
1013
1014 sa = SafeArrayCreate(VT_UI1, ARRAY_SIZE(sab), sab);
1015
1016 /* Test maximum locks */
1017test_LockUnlock_Vector:
1018 if (sa)
1019 {
1020 int count = 0;
1021
1023 ok (hres == E_UNEXPECTED, "Bad %sUnlock gave hres 0x%x\n",
1024 bVector ? "vector " : "\n", hres);
1025
1026 while ((hres = SafeArrayLock(sa)) == S_OK)
1027 count++;
1028 ok (count == 65535 && hres == E_UNEXPECTED, "Lock %sfailed at %d; hres 0x%x\n",
1029 bVector ? "vector " : "\n", count, hres);
1030
1031 if (count == 65535 && hres == E_UNEXPECTED)
1032 {
1033 while ((hres = SafeArrayUnlock(sa)) == S_OK)
1034 count--;
1035 ok (count == 0 && hres == E_UNEXPECTED, "Unlock %sfailed at %d; hres 0x%x\n",
1036 bVector ? "vector " : "\n", count, hres);
1037 }
1038
1040 ok(hres == S_OK, "got 0x%08x\n", hres);
1041 }
1042
1043 if (bVector == FALSE && pSafeArrayCreateVector)
1044 {
1045 /* Test again with a vector */
1046 sa = pSafeArrayCreateVector(VT_UI1, 0, 100);
1047 bVector = TRUE;
1048 goto test_LockUnlock_Vector;
1049 }
1050}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT WINAPI SafeArrayUnlock(SAFEARRAY *psa)
Definition: safearray.c:831
HRESULT WINAPI SafeArrayLock(SAFEARRAY *psa)
Definition: safearray.c:795
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei count
Definition: gl.h:1545
static SAFEARRAY *WINAPI * pSafeArrayCreateVector(VARTYPE, LONG, ULONG)

Referenced by START_TEST().

◆ test_safearray()

static void test_safearray ( void  )
static

Definition at line 380 of file safearray.c.

381{
382 SAFEARRAY *a, b, *c;
383 unsigned int i, diff;
384 LONG indices[2];
386 SAFEARRAYBOUND bound, bounds[2];
387 VARIANT v,d;
388 LPVOID data;
389 IID iid;
390 VARTYPE vt;
391 LONG l;
392 unsigned char *ptr1, *ptr2;
393
395 ok( hres == S_OK, "SafeArrayDestroy( NULL) returned 0x%x\n", hres);
396
397 bound.cElements = 1;
398 bound.lLbound = 0;
399 a = SafeArrayCreate(-1, 1, &bound);
400 ok(NULL == a,"SAC(-1,1,[1,0]) not failed?\n");
401
402 bound.cElements = 0;
403 bound.lLbound = 42;
404 a = SafeArrayCreate(VT_I4, 1, &bound);
405 ok(NULL != a,"SAC(VT_I4,1,[0,0]) failed.\n");
406
407 hres = SafeArrayGetLBound(a, 1, &l);
408 ok(hres == S_OK, "SAGLB of 0 size dimensioned array failed with %x\n",hres);
409 ok(l == 42, "SAGLB of 0 size dimensioned array failed to return 42, but returned %d\n",l);
410 hres = SafeArrayGetUBound(a, 1, &l);
411 ok(hres == S_OK, "SAGUB of 0 size dimensioned array failed with %x\n",hres);
412 ok(l == 41, "SAGUB of 0 size dimensioned array failed to return 41, but returned %d\n",l);
413
415 ok(hres == S_OK, "SafeArrayAccessData of 0 size dimensioned array failed with %x\n", hres);
417
418 bound.cElements = 2;
419 hres = SafeArrayRedim(a, &bound);
420 ok(hres == S_OK,"SAR of a 0 elements dimension failed with hres %x\n", hres);
421 bound.cElements = 0;
422 hres = SafeArrayRedim(a, &bound);
423 ok(hres == S_OK || hres == E_OUTOFMEMORY,
424 "SAR to a 0 elements dimension failed with hres %x\n", hres);
426 ok(hres == S_OK,"SAD of 0 dim array failed with hres %x\n", hres);
427
429 a->rgsabound[0].cElements = 2;
430 a->rgsabound[0].lLbound = 1;
431 a->rgsabound[1].cElements = 4;
432 a->rgsabound[1].lLbound = 1;
433 a->cbElements = 2;
435 ok(hres == S_OK, "SafeArrayAllocData failed with hres %x\n", hres);
436
437 indices[0] = 4;
438 indices[1] = 2;
439 hres = SafeArrayPtrOfIndex(a, indices, (void **)&ptr1);
440 ok(hres == S_OK, "SAPOI failed with hres %x\n", hres);
441 SafeArrayAccessData(a, (void **)&ptr2);
442 ok(ptr1 - ptr2 == 14, "SAPOI got wrong ptr\n");
443 *(WORD *)ptr1 = 0x55aa;
445
446 bound.cElements = 10;
447 bound.lLbound = 1;
448 SafeArrayRedim(a, &bound);
449 ptr1 = NULL;
450 SafeArrayPtrOfIndex(a, indices, (void **)&ptr1);
451 ok(*(WORD *)ptr1 == 0x55aa, "Data not preserved when resizing array\n");
452
453 bound.cElements = 10;
454 bound.lLbound = 0;
455 SafeArrayRedim(a, &bound);
456 SafeArrayPtrOfIndex(a, indices, (void **)&ptr1);
457 ok(*(WORD *)ptr1 == 0 ||
458 broken(*(WORD *)ptr1 != 0), /* Win 2003 */
459 "Expanded area not zero-initialized\n");
460
461 indices[1] = 1;
462 SafeArrayPtrOfIndex(a, indices, (void **)&ptr1);
463 ok(*(WORD *)ptr1 == 0x55aa ||
464 broken(*(WORD *)ptr1 != 0x55aa), /* Win 2003 */
465 "Data not preserved when resizing array\n");
466
468 ok(hres == S_OK,"SAD failed with hres %x\n", hres);
469
470 bounds[0].cElements = 0; bounds[0].lLbound = 1;
471 bounds[1].cElements = 2; bounds[1].lLbound = 23;
472 a = SafeArrayCreate(VT_I4,2,bounds);
473 ok(a != NULL,"SAC(VT_INT32,2,...) with 0 element dim failed.\n");
474
476 ok(hres == S_OK,"SAD failed with hres %x\n", hres);
477 bounds[0].cElements = 1; bounds[0].lLbound = 1;
478 bounds[1].cElements = 0; bounds[1].lLbound = 23;
479 a = SafeArrayCreate(VT_I4,2,bounds);
480 ok(a != NULL,"SAC(VT_INT32,2,...) with 0 element dim failed.\n");
481
483 ok(hres == S_OK,"SAD failed with hres %x\n", hres);
484
485 bounds[0].cElements = 42; bounds[0].lLbound = 1;
486 bounds[1].cElements = 2; bounds[1].lLbound = 23;
487 a = SafeArrayCreate(VT_I4,2,bounds);
488 ok(a != NULL,"SAC(VT_INT32,2,...) failed.\n");
489
490 hres = SafeArrayGetLBound (a, 0, &l);
491 ok (hres == DISP_E_BADINDEX, "SAGLB 0 failed with %x\n", hres);
492 hres = SafeArrayGetLBound (a, 1, &l);
493 ok (hres == S_OK, "SAGLB 1 failed with %x\n", hres);
494 ok (l == 1, "SAGLB 1 returned %d instead of 1\n", l);
495 hres = SafeArrayGetLBound (a, 2, &l);
496 ok (hres == S_OK, "SAGLB 2 failed with %x\n", hres);
497 ok (l == 23, "SAGLB 2 returned %d instead of 23\n", l);
498 hres = SafeArrayGetLBound (a, 3, &l);
499 ok (hres == DISP_E_BADINDEX, "SAGLB 3 failed with %x\n", hres);
500
501 hres = SafeArrayGetUBound (a, 0, &l);
502 ok (hres == DISP_E_BADINDEX, "SAGUB 0 failed with %x\n", hres);
503 hres = SafeArrayGetUBound (a, 1, &l);
504 ok (hres == S_OK, "SAGUB 1 failed with %x\n", hres);
505 ok (l == 42, "SAGUB 1 returned %d instead of 42\n", l);
506 hres = SafeArrayGetUBound (a, 2, &l);
507 ok (hres == S_OK, "SAGUB 2 failed with %x\n", hres);
508 ok (l == 24, "SAGUB 2 returned %d instead of 24\n", l);
509 hres = SafeArrayGetUBound (a, 3, &l);
510 ok (hres == DISP_E_BADINDEX, "SAGUB 3 failed with %x\n", hres);
511
513 ok(i == 2, "getdims of 2 din array returned %d\n",i);
514
515 indices[0] = 0;
516 indices[1] = 23;
518 ok(DISP_E_BADINDEX == hres,"SAGE failed [0,23], hres 0x%x\n",hres);
519
520 indices[0] = 1;
521 indices[1] = 22;
523 ok(DISP_E_BADINDEX == hres,"SAGE failed [1,22], hres 0x%x\n",hres);
524
525 indices[0] = 1;
526 indices[1] = 23;
528 ok(S_OK == hres,"SAGE failed [1,23], hres 0x%x\n",hres);
529
530 indices[0] = 1;
531 indices[1] = 25;
533 ok(DISP_E_BADINDEX == hres,"SAGE failed [1,24], hres 0x%x\n",hres);
534
535 indices[0] = 3;
536 indices[1] = 23;
538 ok(S_OK == hres,"SAGE failed [42,23], hres 0x%x\n",hres);
539
540 hres = SafeArrayAccessData(a, (void**)&ptr1);
541 ok(S_OK == hres, "SAAD failed with 0x%x\n", hres);
542
543 indices[0] = 3;
544 indices[1] = 23;
545 hres = SafeArrayPtrOfIndex(a, indices, (void**)&ptr2);
546 ok(S_OK == hres,"SAPOI failed [1,23], hres 0x%x\n",hres);
547 diff = ptr2 - ptr1;
548 ok(diff == 8,"ptr difference is not 8, but %d (%p vs %p)\n", diff, ptr2, ptr1);
549
550 indices[0] = 3;
551 indices[1] = 24;
552 hres = SafeArrayPtrOfIndex(a, indices, (void**)&ptr2);
553 ok(S_OK == hres,"SAPOI failed [5,24], hres 0x%x\n",hres);
554 diff = ptr2 - ptr1;
555 ok(diff == 176,"ptr difference is not 176, but %d (%p vs %p)\n", diff, ptr2, ptr1);
556
557 indices[0] = 20;
558 indices[1] = 23;
559 hres = SafeArrayPtrOfIndex(a, indices, (void**)&ptr2);
560 ok(S_OK == hres,"SAPOI failed [20,23], hres 0x%x\n",hres);
561 diff = ptr2 - ptr1;
562 ok(diff == 76,"ptr difference is not 76, but %d (%p vs %p)\n", diff, ptr2, ptr1);
563
565 ok(S_OK == hres, "SAUAD failed with 0x%x\n", hres);
566
568 ok(hres == S_OK,"SAD failed with hres %x\n", hres);
569
570 for (i = 0; i < ARRAY_SIZE(vttypes); i++) {
571 if ((i == VT_I8 || i == VT_UI8) && has_i8)
572 {
573 vttypes[i].elemsize = sizeof(LONG64);
574 }
575
576 a = SafeArrayCreate(vttypes[i].vt, 1, &bound);
577
578 ok((!a && !vttypes[i].elemsize) ||
579 (a && vttypes[i].elemsize == a->cbElements),
580 "SAC(%d,1,[1,0]), %p result %d, expected %d\n",
581 vttypes[i].vt,a,(a?a->cbElements:0),vttypes[i].elemsize);
582
583 if (a)
584 {
585 ok(a->fFeatures == (vttypes[i].expflags | vttypes[i].addflags),
586 "SAC of %d returned feature flags %x, expected %x\n",
587 vttypes[i].vt, a->fFeatures,
588 vttypes[i].expflags|vttypes[i].addflags);
590 "SAGE for vt %d returned elemsize %d instead of expected %d\n",
592 }
593
594 if (!a) continue;
595
596 if (pSafeArrayGetVartype)
597 {
598 hres = pSafeArrayGetVartype(a, &vt);
599 ok(hres == S_OK, "SAGVT of arra y with vt %d failed with %x\n", vttypes[i].vt, hres);
600 /* Windows prior to Vista returns VT_UNKNOWN instead of VT_DISPATCH */
601 ok(broken(vt == VT_UNKNOWN) || vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
602 }
603
604 hres = SafeArrayCopy(a, &c);
605 ok(hres == S_OK, "failed to copy safearray of vt %d with hres %x\n", vttypes[i].vt, hres);
606
607 ok(vttypes[i].elemsize == c->cbElements,"copy of SAC(%d,1,[1,0]), result %d, expected %d\n",vttypes[i].vt,(c?c->cbElements:0),vttypes[i].elemsize
608 );
609 ok(c->fFeatures == (vttypes[i].expflags | vttypes[i].addflags),"SAC of %d returned feature flags %x, expected %x\n", vttypes[i].vt, c->fFeatures, vttypes[i].expflags|vttypes[i].addflags);
610 ok(SafeArrayGetElemsize(c) == vttypes[i].elemsize,"SAGE for vt %d returned elemsize %d instead of expected %d\n",vttypes[i].vt, SafeArrayGetElemsize(c),vttypes[i].elemsize);
611
612 if (pSafeArrayGetVartype) {
613 hres = pSafeArrayGetVartype(c, &vt);
614 ok(hres == S_OK, "SAGVT of array with vt %d failed with %x\n", vttypes[i].vt, hres);
615 /* Windows prior to Vista returns VT_UNKNOWN instead of VT_DISPATCH */
616 ok(broken(vt == VT_UNKNOWN) || vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
617 }
618
619 if (pSafeArrayCopyData) {
620 hres = pSafeArrayCopyData(a, c);
621 ok(hres == S_OK, "failed to copy safearray data of vt %d with hres %x\n", vttypes[i].vt, hres);
622
624 ok(hres == S_OK,"SADD of copy of array with vt %d failed with hres %x\n", vttypes[i].vt, hres);
625 }
626
628 ok(hres == S_OK,"SAD failed with hres %x\n", hres);
629
631 ok(hres == S_OK,"SAD of array with vt %d failed with hres %x\n", vttypes[i].vt, hres);
632 }
633
634 /* Test conversion of type|VT_ARRAY <-> VT_BSTR */
635 bound.lLbound = 0;
636 bound.cElements = 10;
637 a = SafeArrayCreate(VT_UI1, 1, &bound);
638 ok(a != NULL, "SAC failed.\n");
639 ok(S_OK == SafeArrayAccessData(a, &data),"SACD failed\n");
640 memcpy(data,"Hello World\n",10);
641 ok(S_OK == SafeArrayUnaccessData(a),"SAUD failed\n");
642 V_VT(&v) = VT_ARRAY|VT_UI1;
643 V_ARRAY(&v) = a;
644 hres = VariantChangeTypeEx(&v, &v, 0, 0, VT_BSTR);
645 ok(hres==S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %x\n",hres);
646 ok(V_VT(&v) == VT_BSTR,"CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.v\n",V_VT(&v));
647 ok(V_BSTR(&v)[0] == 0x6548,"First letter are not 'He', but %x\n", V_BSTR(&v)[0]);
648 VariantClear(&v);
649
650 VariantInit(&d);
651 V_VT(&v) = VT_BSTR;
654 ok(hres==S_OK, "CTE VT_BSTR -> VT_UI1|VT_ARRAY failed with %x\n",hres);
655 ok(V_VT(&d) == (VT_UI1|VT_ARRAY),"CTE BSTR -> VT_UI1|VT_ARRAY did not return VT_UI1|VT_ARRAY, but %d.v\n",V_VT(&v));
656 VariantClear(&v);
657 VariantClear(&d);
658
659 /* check locking functions */
660 a = SafeArrayCreate(VT_I4, 1, &bound);
661 ok(a!=NULL,"SAC should not fail\n");
662
664 ok(hres == S_OK,"SAAD failed with hres %x\n",hres);
665
667 ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy not failed with DISP_E_ARRAYISLOCKED, but with hres %x\n", hres);
668
670 ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy data not failed with DISP_E_ARRAYISLOCKED, but with hres %x\n", hres);
671
673 ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy descriptor not failed with DISP_E_ARRAYISLOCKED, but with hres %x\n", hres);
674
676 ok(hres == S_OK,"SAUD failed after lock/destroy test\n");
677
679 ok(hres == S_OK,"SAD failed after lock/destroy test\n");
680
681 /* Test if we need to destroy data before descriptor */
682 a = SafeArrayCreate(VT_I4, 1, &bound);
683 ok(a!=NULL,"SAC should not fail\n");
685 ok(hres == S_OK,"SADD with data in array failed with hres %x\n",hres);
686
687 /* IID functions */
688 /* init a small stack safearray */
689 memset(&b, 0, sizeof(b));
690 b.cDims = 1;
691 memset(&iid, 0x42, sizeof(IID));
692 hres = SafeArraySetIID(&b, &iid);
693 ok(hres == E_INVALIDARG, "Unexpected ret value %#x.\n", hres);
694
696 ok(hres == S_OK, "Failed to allocate array descriptor, hr %#x.\n", hres);
697 ok((a->fFeatures & FADF_HAVEIID) == 0, "Unexpected features mask %#x.\n", a->fFeatures);
698 hres = SafeArraySetIID(a, &iid);
699 ok(hres == E_INVALIDARG, "Unexpected ret value %#x.\n", hres);
700
702 ok(hres == S_OK,"SADD failed with hres %x\n",hres);
703
704 if (!pSafeArrayAllocDescriptorEx)
705 return;
706
707 for (i = 0; i < ARRAY_SIZE(vttypes); i++) {
708 a = NULL;
709 hres = pSafeArrayAllocDescriptorEx(vttypes[i].vt,1,&a);
710 ok(hres == S_OK, "SafeArrayAllocDescriptorEx gave hres 0x%x\n", hres);
711 ok(a->fFeatures == vttypes[i].expflags,"SAADE(%d) resulted with flags %x, expected %x\n", vttypes[i].vt, a->fFeatures, vttypes[i].expflags);
712 if (a->fFeatures & FADF_HAVEIID) {
713 hres = SafeArrayGetIID(a, &iid);
714 ok(hres == S_OK,"SAGIID failed for vt %d with hres %x\n", vttypes[i].vt,hres);
715 switch (vttypes[i].vt) {
716 case VT_UNKNOWN:
717 ok(IsEqualGUID(((GUID*)a)-1,&IID_IUnknown),"guid for VT_UNKNOWN is not IID_IUnknown\n");
718 ok(IsEqualGUID(&iid, &IID_IUnknown),"SAGIID returned wrong GUID for IUnknown\n");
719 break;
720 case VT_DISPATCH:
721 ok(IsEqualGUID(((GUID*)a)-1,&IID_IDispatch),"guid for VT_UNKNOWN is not IID_IDispatch\n");
722 ok(IsEqualGUID(&iid, &IID_IDispatch),"SAGIID returned wrong GUID for IDispatch\n");
723 break;
724 default:
725 ok(FALSE,"unknown vt %d with FADF_HAVEIID\n",vttypes[i].vt);
726 break;
727 }
728 } else {
729 hres = SafeArrayGetIID(a, &iid);
730 ok(hres == E_INVALIDARG,"SAGIID did not fail for vt %d with hres %x\n", vttypes[i].vt,hres);
731 }
732 if (a->fFeatures & FADF_RECORD) {
733 ok(vttypes[i].vt == VT_RECORD,"FADF_RECORD for non record %d\n",vttypes[i].vt);
734 }
735 if (a->fFeatures & FADF_HAVEVARTYPE) {
736 ok(vttypes[i].vt == ((DWORD*)a)[-1], "FADF_HAVEVARTYPE set, but vt %d mismatch stored %d\n",vttypes[i].vt,((DWORD*)a)[-1]);
737 }
738
739 hres = pSafeArrayGetVartype(a, &vt);
740 ok(hres == S_OK, "SAGVT of array with vt %d failed with %x\n", vttypes[i].vt, hres);
741
742 if (vttypes[i].vt == VT_DISPATCH) {
743 /* Special case. Checked against Windows. */
744 ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d\n", vt);
745 } else {
746 ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d\n", vttypes[i].vt, vt);
747 }
748
749 if (a->fFeatures & FADF_HAVEIID) {
750 hres = SafeArraySetIID(a, &IID_IStorage); /* random IID */
751 ok(hres == S_OK,"SASIID failed with FADF_HAVEIID set for vt %d with %x\n", vttypes[i].vt, hres);
752 hres = SafeArrayGetIID(a, &iid);
753 ok(hres == S_OK,"SAGIID failed with FADF_HAVEIID set for vt %d with %x\n", vttypes[i].vt, hres);
754 ok(IsEqualGUID(&iid, &IID_IStorage),"returned iid is not IID_IStorage\n");
755 } else {
756 hres = SafeArraySetIID(a, &IID_IStorage); /* random IID */
757 ok(hres == E_INVALIDARG,"SASIID did not failed with !FADF_HAVEIID set for vt %d with %x\n", vttypes[i].vt, hres);
758 }
760 ok(hres == S_OK,"SADD failed with hres %x\n",hres);
761 }
762}
#define broken(x)
Definition: atltest.h:178
r l[0]
Definition: byte_order.h:168
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned short VARTYPE
Definition: compat.h:2254
@ VT_RECORD
Definition: compat.h:2326
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayDestroyDescriptor(SAFEARRAY *psa)
Definition: safearray.c:755
HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
Definition: safearray.c:947
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
Definition: safearray.c:1379
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
Definition: safearray.c:1094
HRESULT WINAPI SafeArrayGetIID(SAFEARRAY *psa, GUID *pGuid)
Definition: safearray.c:1670
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
Definition: safearray.c:1066
HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa)
Definition: safearray.c:1256
UINT WINAPI SafeArrayGetElemsize(SAFEARRAY *psa)
Definition: safearray.c:1114
HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut)
Definition: safearray.c:476
HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvData)
Definition: safearray.c:1194
HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound)
Definition: safearray.c:1456
HRESULT WINAPI SafeArrayAllocData(SAFEARRAY *psa)
Definition: safearray.c:557
HRESULT WINAPI SafeArraySetIID(SAFEARRAY *psa, REFGUID guid)
Definition: safearray.c:1641
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct @1697 vttypes[]
UINT elemsize
Definition: safearray.c:332
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
const GUID IID_IDispatch
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define memset(x, y, z)
Definition: compat.h:39
HRESULT WINAPI VariantChangeTypeEx(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
Definition: variant.c:988
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
#define DISP_E_ARRAYISLOCKED
Definition: winerror.h:2522
#define DISP_E_BADINDEX
Definition: winerror.h:2520

Referenced by Global_InvokeEx(), and START_TEST().

◆ test_safearray_layout()

static void test_safearray_layout ( void  )
static

Definition at line 2029 of file safearray.c.

2030{
2031 IRecordInfoImpl *irec;
2033 GUID guid, *guidptr;
2034 SAFEARRAYBOUND sab;
2035 SAFEARRAY *sa;
2036 DWORD *dwptr;
2037 HRESULT hr;
2038
2039 sab.lLbound = 0;
2040 sab.cElements = 10;
2041
2042 /* GUID field */
2043 sa = SafeArrayCreate(VT_UNKNOWN, 1, &sab);
2044 ok(sa != NULL, "got %p\n", sa);
2045
2046 guidptr = (GUID*)sa - 1;
2047 ok(IsEqualIID(guidptr, &IID_IUnknown), "got %s\n", wine_dbgstr_guid(guidptr));
2048
2050 ok(hr == S_OK, "got 0x%08x\n", hr);
2051 ok(IsEqualIID(guidptr, &IID_IDispatch), "got %s\n", wine_dbgstr_guid(guidptr));
2052
2053 memcpy(guidptr, &IID_IUnknown, sizeof(GUID));
2055 ok(hr == S_OK, "got 0x%08x\n", hr);
2056 ok(IsEqualIID(&guid, &IID_IUnknown), "got %s\n", wine_dbgstr_guid(&guid));
2057
2059 ok(hr == S_OK, "got 0x%08x\n", hr);
2060
2061 /* VARTYPE field */
2062 sa = SafeArrayCreate(VT_UI1, 1, &sab);
2063 ok(sa != NULL, "got %p\n", sa);
2064
2065 dwptr = (DWORD*)sa - 1;
2066 ok(*dwptr == VT_UI1, "got %d\n", *dwptr);
2067
2069 ok(hr == S_OK, "got 0x%08x\n", hr);
2070
2071 /* IRecordInfo pointer */
2073 irec->ref = 1;
2074
2076 ok(sa != NULL, "failed to create array\n");
2077
2078 record = *((IRecordInfo**)sa - 1);
2079 ok(record == &irec->IRecordInfo_iface, "got %p\n", record);
2080
2082 ok(hr == S_OK, "got 0x%08x\n", hr);
2083 IRecordInfo_Release(&irec->IRecordInfo_iface);
2084}
const GUID * guid
static SAFEARRAY **static SAFEARRAY *static VARTYPE *static IRecordInfo **static SAFEARRAY *WINAPI * pSafeArrayCreateEx(VARTYPE, UINT, SAFEARRAYBOUND *, LPVOID)
static IRecordInfoImpl * IRecordInfoImpl_Construct(void)
Definition: safearray.c:258
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
HRESULT hr
Definition: shlfolder.c:183

Referenced by START_TEST().

◆ test_SafeArrayAllocDestroyDescriptor()

static void test_SafeArrayAllocDestroyDescriptor ( void  )
static

Definition at line 764 of file safearray.c.

765{
766 SAFEARRAY *sa;
768 UINT i;
769
770 /* Failure cases */
772 ok(hres == E_INVALIDARG, "0 dimensions gave hres 0x%x\n", hres);
773
775 ok(hres == E_INVALIDARG, "65536 dimensions gave hres 0x%x\n", hres);
776
777 if (0)
778 {
779 /* Crashes on 95: XP & Wine return E_POINTER */
781 ok(hres == E_POINTER,"NULL parm gave hres 0x%x\n", hres);
782 }
783
784 /* Test up to the dimension boundary case */
785 for (i = 5; i <= 65535; i += 30)
786 {
788 ok(hres == S_OK, "%d dimensions failed; hres 0x%x\n", i, hres);
789
790 if (hres == S_OK)
791 {
792 ok(SafeArrayGetDim(sa) == i, "Dimension is %d; should be %d\n",
794
796 ok(hres == S_OK, "destroy failed; hres 0x%x\n", hres);
797 }
798 }
799
800 if (!pSafeArrayAllocDescriptorEx)
801 return;
802
803 hres = pSafeArrayAllocDescriptorEx(VT_UI1, 0, &sa);
804 ok(hres == E_INVALIDARG, "0 dimensions gave hres 0x%x\n", hres);
805
806 hres = pSafeArrayAllocDescriptorEx(VT_UI1, 65536, &sa);
807 ok(hres == E_INVALIDARG, "65536 dimensions gave hres 0x%x\n", hres);
808
809 hres = pSafeArrayAllocDescriptorEx(VT_UI1, 1, NULL);
810 ok(hres == E_POINTER,"NULL parm gave hres 0x%x\n", hres);
811
812 hres = pSafeArrayAllocDescriptorEx(-1, 1, &sa);
813 ok(hres == S_OK, "VT = -1 gave hres 0x%x\n", hres);
814
815 sa->rgsabound[0].cElements = 0;
816 sa->rgsabound[0].lLbound = 1;
817
819 ok(hres == S_OK, "SafeArrayAllocData gave hres 0x%x\n", hres);
820
822 ok(hres == S_OK,"SafeArrayDestroy failed with hres %x\n",hres);
823}
unsigned int UINT
Definition: ndis.h:50
#define E_POINTER
Definition: winerror.h:2365

Referenced by START_TEST().

◆ test_SafeArrayChangeTypeEx()

static void test_SafeArrayChangeTypeEx ( void  )
static

Definition at line 1805 of file safearray.c.

1806{
1807 static const char *szHello = "Hello World";
1808 SAFEARRAYBOUND sab;
1809 SAFEARRAY *sa;
1810 VARIANTARG v,v2;
1811 VARTYPE vt;
1812 HRESULT hres;
1813
1814 /* VT_ARRAY|VT_UI1 -> VT_BSTR */
1815 MKARRAY(0,strlen(szHello)+1,VT_UI1);
1816 memcpy(sa->pvData, szHello, strlen(szHello)+1);
1817
1818 hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_BSTR);
1819 ok(hres == S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %x\n", hres);
1820 if (hres == S_OK)
1821 {
1822 ok(V_VT(&v2) == VT_BSTR, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.\n",V_VT(&v2));
1823 ok(strcmp((char*)V_BSTR(&v2),szHello) == 0,"Expected string '%s', got '%s'\n", szHello,
1824 (char*)V_BSTR(&v2));
1825 VariantClear(&v2);
1826 }
1827
1828 /* VT_VECTOR|VT_UI1 -> VT_BSTR */
1830 ok(hres == S_OK, "got 0x%08x\n", hres);
1832 {
1833 sa = pSafeArrayCreateVector(VT_UI1, 0, strlen(szHello)+1);
1834 ok(sa != NULL, "CreateVector() failed.\n");
1835 if (!sa)
1836 return;
1837
1838 memcpy(sa->pvData, szHello, strlen(szHello)+1);
1839 V_VT(&v) = VT_VECTOR|VT_UI1;
1840 V_ARRAY(&v) = sa;
1841 VariantInit(&v2);
1842
1843 hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_BSTR);
1844 ok(hres == DISP_E_BADVARTYPE, "CTE VT_VECTOR|VT_UI1 returned %x\n", hres);
1845
1846 /* (vector)VT_ARRAY|VT_UI1 -> VT_BSTR (In place) */
1847 V_VT(&v) = VT_ARRAY|VT_UI1;
1848 hres = VariantChangeTypeEx(&v, &v, 0, 0, VT_BSTR);
1849 ok(hres == S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %x\n", hres);
1850 if (hres == S_OK)
1851 {
1852 ok(V_VT(&v) == VT_BSTR, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.\n",V_VT(&v));
1853 ok(strcmp((char*)V_BSTR(&v),szHello) == 0,"Expected string '%s', got '%s'\n", szHello,
1854 (char*)V_BSTR(&v));
1855 VariantClear(&v);
1856 }
1857 }
1858
1859 /* To/from BSTR only works with arrays of VT_UI1 */
1860 for (vt = VT_EMPTY; vt <= VT_CLSID; vt++)
1861 {
1862 if (vt == VT_UI1)
1863 continue;
1864
1865 sab.lLbound = 0;
1866 sab.cElements = 1;
1867 sa = SafeArrayCreate(vt, 1, &sab);
1868 if (!sa) continue;
1869
1870 V_VT(&v) = VT_ARRAY|vt;
1871 V_ARRAY(&v) = sa;
1872 VariantInit(&v2);
1873
1874 hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_BSTR);
1875 if (vt == VT_INT_PTR || vt == VT_UINT_PTR)
1876 {
1877 ok(hres == DISP_E_BADVARTYPE, "expected DISP_E_BADVARTYPE, got 0x%08x\n", hres);
1879 }
1880 else
1881 {
1882 ok(hres == DISP_E_TYPEMISMATCH, "got 0x%08x for vt=%d, instead of DISP_E_TYPEMISMATCH\n", hres, vt);
1883 hres = VariantClear(&v);
1884 ok(hres == S_OK, "expected S_OK, got 0x%08x\n", hres);
1885 }
1886 VariantClear(&v2);
1887 }
1888
1889 /* Can't change an array of one type into array of another type , even
1890 * if the other type is the same size
1891 */
1893 {
1895 ok(sa != NULL, "CreateVector() failed.\n");
1896 if (!sa)
1897 return;
1898
1899 V_VT(&v) = VT_ARRAY|VT_UI1;
1900 V_ARRAY(&v) = sa;
1902 ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1->VT_ARRAY|VT_I1 returned %x\n", hres);
1903
1904 /* But can change to the same array type */
1906 ok(hres == S_OK, "got 0x%08x\n", hres);
1908 ok(sa != NULL, "CreateVector() failed.\n");
1909 if (!sa)
1910 return;
1911 V_VT(&v) = VT_ARRAY|VT_UI1;
1912 V_ARRAY(&v) = sa;
1914 ok(hres == S_OK, "CTE VT_ARRAY|VT_UI1->VT_ARRAY|VT_UI1 returned %x\n", hres);
1916 ok(hres == S_OK, "got 0x%08x\n", hres);
1917 VariantClear(&v2);
1918 }
1919
1920 /* NULL/EMPTY */
1921 MKARRAY(0,1,VT_UI1);
1922 hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_NULL);
1923 ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1 returned %x\n", hres);
1924 VariantClear(&v);
1925 MKARRAY(0,1,VT_UI1);
1926 hres = VariantChangeTypeEx(&v2, &v, 0, 0, VT_EMPTY);
1927 ok(hres == DISP_E_TYPEMISMATCH, "CTE VT_ARRAY|VT_UI1 returned %x\n", hres);
1928 VariantClear(&v);
1929}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
@ VT_NULL
Definition: compat.h:2296
@ VT_CLSID
Definition: compat.h:2337
@ VT_EMPTY
Definition: compat.h:2295
@ VT_VECTOR
Definition: compat.h:2340
#define MKARRAY(low, num, typ)
Definition: safearray.c:1796
#define DISP_E_BADVARTYPE
Definition: winerror.h:2517
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514

Referenced by START_TEST().

◆ test_SafeArrayClear()

static void test_SafeArrayClear ( void  )
static

Definition at line 1648 of file safearray.c.

1649{
1650 SAFEARRAYBOUND sab;
1651 SAFEARRAY *sa;
1652 VARIANTARG v;
1653 HRESULT hres;
1654
1655 sab.lLbound = 0;
1656 sab.cElements = 10;
1657 sa = SafeArrayCreate(VT_UI1, 1, &sab);
1658 ok(sa != NULL, "Create() failed.\n");
1659 if (!sa)
1660 return;
1661
1662 /* Test clearing non-NULL variants containing arrays */
1663 V_VT(&v) = VT_ARRAY|VT_UI1;
1664 V_ARRAY(&v) = sa;
1665 hres = VariantClear(&v);
1666 ok(hres == S_OK && V_VT(&v) == VT_EMPTY, "VariantClear: hres 0x%x, Type %d\n", hres, V_VT(&v));
1667 ok(V_ARRAY(&v) == sa, "VariantClear: Overwrote value\n");
1668
1669 sa = SafeArrayCreate(VT_UI1, 1, &sab);
1670 ok(sa != NULL, "Create() failed.\n");
1671 if (!sa)
1672 return;
1673
1674 V_VT(&v) = VT_SAFEARRAY;
1675 V_ARRAY(&v) = sa;
1676 hres = VariantClear(&v);
1677 ok(hres == DISP_E_BADVARTYPE, "VariantClear: hres 0x%x\n", hres);
1678
1680 V_ARRAYREF(&v) = &sa;
1681 hres = VariantClear(&v);
1682 ok(hres == DISP_E_BADVARTYPE, "VariantClear: hres 0x%x\n", hres);
1683
1685 ok(hres == S_OK, "got 0x%08x\n", hres);
1686}
@ VT_BYREF
Definition: compat.h:2342
@ VT_SAFEARRAY
Definition: compat.h:2321
#define V_ARRAYREF(A)
Definition: oleauto.h:223

Referenced by START_TEST().

◆ test_SafeArrayCopy()

static void test_SafeArrayCopy ( void  )
static

Definition at line 1688 of file safearray.c.

1689{
1690 SAFEARRAYBOUND sab;
1691 SAFEARRAY *sa, *sa2;
1692 VARIANTARG vSrc, vDst;
1693 HRESULT hres;
1694 int i;
1695
1696 sab.lLbound = 0;
1697 sab.cElements = 10;
1698 sa = SafeArrayCreate(VT_UI1, 1, &sab);
1699 ok(sa != NULL, "Create() failed.\n");
1700 if (!sa)
1701 return;
1702
1703 /* Test copying non-NULL variants containing arrays */
1704 V_VT(&vSrc) = (VT_ARRAY|VT_BYREF|VT_UI1);
1705 V_ARRAYREF(&vSrc) = &sa;
1706 V_VT(&vDst) = VT_EMPTY;
1707
1708 hres = VariantCopy(&vDst, &vSrc);
1709 ok(hres == S_OK && V_VT(&vDst) == (VT_ARRAY|VT_BYREF|VT_UI1),
1710 "VariantCopy: hres 0x%x, Type %d\n", hres, V_VT(&vDst));
1711 ok(V_ARRAYREF(&vDst) == &sa, "VariantClear: Performed deep copy\n");
1712
1713 V_VT(&vSrc) = (VT_ARRAY|VT_UI1);
1714 V_ARRAY(&vSrc) = sa;
1715 V_VT(&vDst) = VT_EMPTY;
1716
1717 hres = VariantCopy(&vDst, &vSrc);
1718 ok(hres == S_OK && V_VT(&vDst) == (VT_ARRAY|VT_UI1),
1719 "VariantCopy: hres 0x%x, Type %d\n", hres, V_VT(&vDst));
1720 ok(V_ARRAY(&vDst) != sa, "VariantClear: Performed shallow copy\n");
1721
1722 hres = SafeArrayDestroy(V_ARRAY(&vSrc));
1723 ok(hres == S_OK, "got 0x%08x\n", hres);
1724 hres = SafeArrayDestroy(V_ARRAY(&vDst));
1725 ok(hres == S_OK, "got 0x%08x\n", hres);
1726
1728 ok(hres == S_OK, "SafeArrayAllocDescriptor failed with error 0x%08x\n", hres);
1729
1730 sa->cbElements = 16;
1731 hres = SafeArrayCopy(sa, &sa2);
1732 ok(hres == S_OK, "SafeArrayCopy failed with error 0x%08x\n", hres);
1733 ok(sa != sa2, "SafeArrayCopy performed shallow copy\n");
1734
1735 hres = SafeArrayDestroy(sa2);
1736 ok(hres == S_OK, "got 0x%08x\n", hres);
1738 ok(hres == S_OK, "got 0x%08x\n", hres);
1739
1740 sa2 = (void*)0xdeadbeef;
1741 hres = SafeArrayCopy(NULL, &sa2);
1742 ok(hres == S_OK, "SafeArrayCopy failed with error 0x%08x\n", hres);
1743 ok(!sa2, "SafeArrayCopy didn't return NULL for output array\n");
1744
1746 ok(hres == S_OK, "SafeArrayAllocDescriptor failed with error 0x%08x\n", hres);
1747
1748 sa2 = (void*)0xdeadbeef;
1749 hres = SafeArrayCopy(sa, &sa2);
1750 ok(hres == E_INVALIDARG,
1751 "SafeArrayCopy with empty array should have failed with error E_INVALIDARG instead of 0x%08x\n",
1752 hres);
1753 ok(!sa2, "SafeArrayCopy didn't return NULL for output array\n");
1754
1755 hres = SafeArrayDestroy(sa2);
1756 ok(hres == S_OK, "got 0x%08x\n", hres);
1758 ok(hres == S_OK, "got 0x%08x\n", hres);
1759
1760 /* test feature copy */
1762 ok(hres == S_OK, "SafeArrayAllocDescriptor failed with error 0x%08x\n", hres);
1763 ok(sa->fFeatures == 0, "got src features 0x%04x\n", sa->fFeatures);
1764 sa->cbElements = 16;
1765
1766 for (i = 0; i < ARRAY_SIZE(ignored_copy_features); i++)
1767 {
1769
1770 sa->fFeatures |= feature;
1771 hres = SafeArrayCopy(sa, &sa2);
1772 ok(hres == S_OK, "got 0x%08x\n", hres);
1773 ok(sa2->fFeatures == 0, "got features 0x%04x\n", sa2->fFeatures);
1774 hres = SafeArrayDestroy(sa2);
1775 ok(hres == S_OK, "got 0x%08x\n", hres);
1776 sa->fFeatures &= ~feature;
1777 }
1778
1780
1781 /* copy from a vector */
1783 ok(sa->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR) ||
1784 broken(sa->fFeatures == FADF_CREATEVECTOR /* W2k */),
1785 "got 0x%08x\n", sa->fFeatures);
1786 hres = SafeArrayCopy(sa, &sa2);
1787 ok(hres == S_OK, "got 0x%08x\n", hres);
1788 ok(sa2->fFeatures == FADF_HAVEVARTYPE ||
1789 broken(!sa2->fFeatures /* W2k */), "got 0x%04x\n",
1790 sa2->fFeatures);
1791
1792 SafeArrayDestroy(sa2);
1794}
static const USHORT ignored_copy_features
Definition: safearray.c:88
const USHORT FADF_CREATEVECTOR
Definition: safearray.c:43
INTERNETFEATURELIST feature
Definition: misc.c:1719
unsigned short USHORT
Definition: pedump.c:61
USHORT fFeatures
Definition: compat.h:2356
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748

Referenced by START_TEST().

◆ test_SafeArrayCopyData()

static void test_SafeArrayCopyData ( void  )
static

Definition at line 1371 of file safearray.c.

1372{
1373 SAFEARRAYBOUND sab[4];
1374 SAFEARRAY *sa;
1375 SAFEARRAY *sacopy;
1376 HRESULT hres;
1377 int dimension, size = 1, i;
1378
1379 if (!pSafeArrayCopyData)
1380 {
1381 win_skip("SafeArrayCopyData not supported\n");
1382 return;
1383 }
1384
1385 for (dimension = 0; dimension < ARRAY_SIZE(sab); dimension++)
1386 {
1387 sab[dimension].lLbound = dimension * 2 + 2;
1388 sab[dimension].cElements = dimension * 3 + 1;
1389 size *= sab[dimension].cElements;
1390 }
1391
1392 sa = SafeArrayCreate(VT_INT, ARRAY_SIZE(sab), sab);
1393 ok(sa != NULL, "Copy test couldn't create array\n");
1394 sacopy = SafeArrayCreate(VT_INT, ARRAY_SIZE(sab), sab);
1395 ok(sacopy != NULL, "Copy test couldn't create copy array\n");
1396
1397 if (!sa || !sacopy)
1398 return;
1399
1400 ok(sa->cbElements == sizeof(int), "int size mismatch\n");
1401
1402 /* Fill the source array with some data; it doesn't matter what */
1403 for (dimension = 0; dimension < size; dimension++)
1404 {
1405 int* data = sa->pvData;
1406 data[dimension] = dimension;
1407 }
1408
1409 hres = pSafeArrayCopyData(sa, sacopy);
1410 ok(hres == S_OK, "copy data failed hres 0x%x\n", hres);
1411 if (hres == S_OK)
1412 {
1413 ok(!memcmp(sa->pvData, sacopy->pvData, size * sizeof(int)), "compared different\n");
1414 }
1415
1416 /* Failure cases */
1417 hres = pSafeArrayCopyData(NULL, sacopy);
1418 ok(hres == E_INVALIDARG, "Null copy source hres 0x%x\n", hres);
1419 hres = pSafeArrayCopyData(sa, NULL);
1420 ok(hres == E_INVALIDARG, "Null copy hres 0x%x\n", hres);
1421
1422 sacopy->rgsabound[0].cElements += 1;
1423 hres = pSafeArrayCopyData(sa, sacopy);
1424 ok(hres == E_INVALIDARG, "Bigger copy first dimension hres 0x%x\n", hres);
1425
1426 sacopy->rgsabound[0].cElements -= 2;
1427 hres = pSafeArrayCopyData(sa, sacopy);
1428 ok(hres == E_INVALIDARG, "Smaller copy first dimension hres 0x%x\n", hres);
1429 sacopy->rgsabound[0].cElements += 1;
1430
1431 sacopy->rgsabound[3].cElements += 1;
1432 hres = pSafeArrayCopyData(sa, sacopy);
1433 ok(hres == E_INVALIDARG, "Bigger copy last dimension hres 0x%x\n", hres);
1434
1435 sacopy->rgsabound[3].cElements -= 2;
1436 hres = pSafeArrayCopyData(sa, sacopy);
1437 ok(hres == E_INVALIDARG, "Smaller copy last dimension hres 0x%x\n", hres);
1438 sacopy->rgsabound[3].cElements += 1;
1439
1440 hres = SafeArrayDestroy(sacopy);
1441 ok(hres == S_OK, "got 0x%08x\n", hres);
1442 sacopy = NULL;
1443 hres = pSafeArrayCopyData(sa, sacopy);
1444 ok(hres == E_INVALIDARG, "->Null copy hres 0x%x\n", hres);
1445
1446 hres = SafeArrayCopy(sa, &sacopy);
1447 ok(hres == S_OK, "copy failed hres 0x%x\n", hres);
1448 ok(SafeArrayGetElemsize(sa) == SafeArrayGetElemsize(sacopy),"elemsize wrong\n");
1449 ok(SafeArrayGetDim(sa) == SafeArrayGetDim(sacopy),"dimensions wrong\n");
1450 ok(!memcmp(sa->pvData, sacopy->pvData, size * sizeof(int)), "compared different\n");
1451 hres = SafeArrayDestroy(sacopy);
1452 ok(hres == S_OK, "got 0x%08x\n", hres);
1453
1454 sacopy = SafeArrayCreate(VT_INT, ARRAY_SIZE(sab), sab);
1455 ok(sacopy != NULL, "Copy test couldn't create copy array\n");
1456 ok(sacopy->fFeatures == FADF_HAVEVARTYPE, "0x%04x\n", sacopy->fFeatures);
1457
1458 for (i = 0; i < ARRAY_SIZE(ignored_copy_features); i++)
1459 {
1461 USHORT orig = sacopy->fFeatures;
1462
1463 sa->fFeatures |= feature;
1464 hres = SafeArrayCopyData(sa, sacopy);
1465 ok(hres == S_OK, "got 0x%08x\n", hres);
1466 ok(sacopy->fFeatures == orig && orig == FADF_HAVEVARTYPE, "got features 0x%04x\n", sacopy->fFeatures);
1467 sa->fFeatures &= ~feature;
1468 }
1469
1470 hres = SafeArrayDestroy(sacopy);
1471 ok(hres == S_OK, "got 0x%08x\n", hres);
1473 ok(hres == S_OK, "got 0x%08x\n", hres);
1474
1475 /* copy data from a vector */
1477
1478 sacopy = SafeArrayCreateVector(VT_UI1, 0, 2);
1479 ok(sa->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR) ||
1480 broken(sa->fFeatures == FADF_CREATEVECTOR /* W2k */),
1481 "got 0x%08x\n", sa->fFeatures);
1482 ok(sacopy->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR) ||
1483 broken(sacopy->fFeatures == FADF_CREATEVECTOR /* W2k */),
1484 "got 0x%08x\n", sacopy->fFeatures);
1485 hres = SafeArrayCopyData(sa, sacopy);
1486 ok(hres == S_OK, "got 0x%08x\n", hres);
1487 ok(sacopy->fFeatures == (FADF_HAVEVARTYPE|FADF_CREATEVECTOR) ||
1488 broken(sacopy->fFeatures == FADF_CREATEVECTOR /* W2k */),
1489 "got 0x%04x\n", sacopy->fFeatures);
1490 SafeArrayDestroy(sacopy);
1491
1492 sacopy = SafeArrayCreate(VT_UI1, ARRAY_SIZE(sab), sab);
1493 ok(sacopy != NULL, "Copy test couldn't create copy array\n");
1494 ok(sacopy->fFeatures == FADF_HAVEVARTYPE, "0x%04x\n", sacopy->fFeatures);
1495 hres = SafeArrayCopyData(sa, sacopy);
1496 ok(hres == E_INVALIDARG, "got 0x%08x\n", hres);
1497 SafeArrayDestroy(sacopy);
1498
1500}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define win_skip
Definition: test.h:163
SAFEARRAYBOUND rgsabound[1]
Definition: compat.h:2360
PVOID pvData
Definition: compat.h:2359

Referenced by START_TEST().

◆ test_SafeArrayCreateEx()

static void test_SafeArrayCreateEx ( void  )
static

Definition at line 1502 of file safearray.c.

1503{
1504 IRecordInfoImpl* iRec;
1505 SAFEARRAYBOUND sab[4];
1506 SAFEARRAY *sa;
1507 HRESULT hres;
1508 UINT dimension;
1509
1510 if (!pSafeArrayCreateEx)
1511 {
1512 win_skip("SafeArrayCreateEx not supported\n");
1513 return;
1514 }
1515
1516 for (dimension = 0; dimension < ARRAY_SIZE(sab); dimension++)
1517 {
1518 sab[dimension].lLbound = 0;
1519 sab[dimension].cElements = 8;
1520 }
1521
1522 /* Failure cases */
1524 ok(sa == NULL, "CreateEx NULL bounds didn't fail\n");
1525
1526 /* test IID storage & defaulting */
1527 sa = pSafeArrayCreateEx(VT_DISPATCH, 1, sab, (PVOID)&IID_ITypeInfo);
1528 ok(sa != NULL, "CreateEx (ITypeInfo) failed\n");
1529
1530 if (sa)
1531 {
1532 GUID guid;
1533
1535 ok(hres == S_OK, "Failed to get array IID, hres %#x.\n", hres);
1536 ok(IsEqualGUID(&guid, &IID_ITypeInfo), "CreateEx (ITypeInfo) bad IID\n");
1538 ok(hres == S_OK, "Failed to set IID, hres = %8x\n", hres);
1540 ok(hres == S_OK && IsEqualGUID(&guid, &IID_IUnknown), "Set bad IID\n");
1542 ok(hres == S_OK, "got 0x%08x\n", hres);
1543 }
1544
1546 ok(sa != NULL, "CreateEx (NULL) failed\n");
1547
1548 if (sa)
1549 {
1550 GUID guid;
1551
1553 ok(hres == S_OK, "Failed to get array IID, hres %#x.\n", hres);
1554 ok(IsEqualGUID(&guid, &IID_IDispatch), "CreateEx (NULL) bad IID\n");
1556 ok(hres == S_OK, "got 0x%08x\n", hres);
1557 }
1558
1560 ok(sa != NULL, "CreateEx (NULL-Unk) failed\n");
1561
1562 if (sa)
1563 {
1564 GUID guid;
1565
1567 ok(hres == S_OK, "Failed to get array IID, hres %#x.\n", hres);
1568 ok(IsEqualGUID(&guid, &IID_IUnknown), "CreateEx (NULL-Unk) bad IID\n");
1570 ok(hres == S_OK, "got 0x%08x\n", hres);
1571 }
1572
1573 /* VT_RECORD failure case */
1574 sa = pSafeArrayCreateEx(VT_RECORD, 1, sab, NULL);
1575 ok(sa == NULL, "CreateEx (NULL-Rec) succeeded\n");
1576
1578
1579 /* Win32 doesn't care if GetSize fails */
1582 ok(sa != NULL, "CreateEx (Fail Size) failed\n");
1583 ok(iRec->ref == START_REF_COUNT + 1, "Wrong iRec refcount %d\n", iRec->ref);
1584 ok(iRec->sizeCalled == 1, "GetSize called %d times\n", iRec->sizeCalled);
1585 ok(iRec->clearCalled == 0, "Clear called %d times\n", iRec->clearCalled);
1586 if (sa)
1587 {
1588 ok(sa->cbElements == RECORD_SIZE_FAIL, "Altered size to %d\n", sa->cbElements);
1590 ok(hres == S_OK, "got 0x%08x\n", hres);
1591 ok(iRec->clearCalled == sab[0].cElements, "Destroy->Clear called %d times\n", iRec->clearCalled);
1592 ok(iRec->ref == START_REF_COUNT, "got %d, expected %d\n", iRec->ref, START_REF_COUNT);
1593 }
1594
1595 /* Test VT_RECORD array */
1597 iRec->ref = START_REF_COUNT;
1598 iRec->sizeCalled = 0;
1599 iRec->clearCalled = 0;
1601 ok(sa != NULL, "CreateEx (Rec) failed\n");
1602 ok(iRec->ref == START_REF_COUNT + 1, "Wrong iRec refcount %d\n", iRec->ref);
1603 ok(iRec->sizeCalled == 1, "GetSize called %d times\n", iRec->sizeCalled);
1604 ok(iRec->clearCalled == 0, "Clear called %d times\n", iRec->clearCalled);
1605 if (sa && pSafeArrayGetRecordInfo)
1606 {
1607 IRecordInfo* saRec = NULL;
1608 SAFEARRAY *sacopy;
1609
1610 hres = pSafeArrayGetRecordInfo(sa, &saRec);
1611 ok(hres == S_OK,"GRI failed\n");
1612 ok(saRec == &iRec->IRecordInfo_iface, "Different saRec\n");
1613 ok(iRec->ref == START_REF_COUNT + 2, "Didn't AddRef %d\n", iRec->ref);
1614 IRecordInfo_Release(saRec);
1615
1616 ok(sa->cbElements == RECORD_SIZE,"Elemsize is %d\n", sa->cbElements);
1617
1618 /* try to copy record based arrays */
1619 sacopy = pSafeArrayCreateEx(VT_RECORD, 1, sab, &iRec->IRecordInfo_iface);
1620 iRec->recordcopy = 0;
1621 iRec->clearCalled = 0;
1622 /* array copy code doesn't explicitly clear a record */
1623 hres = SafeArrayCopyData(sa, sacopy);
1624 ok(hres == S_OK, "got 0x%08x\n", hres);
1625 ok(iRec->recordcopy == sab[0].cElements, "got %d\n", iRec->recordcopy);
1626 ok(iRec->clearCalled == 0, "got %d\n", iRec->clearCalled);
1627
1628 hres = SafeArrayDestroy(sacopy);
1629 ok(hres == S_OK, "got 0x%08x\n", hres);
1630
1631 iRec->clearCalled = 0;
1632 iRec->sizeCalled = 0;
1634 ok(hres == S_OK, "got 0x%08x\n", hres);
1635 ok(iRec->sizeCalled == 0, "Destroy->GetSize called %d times\n", iRec->sizeCalled);
1636 ok(iRec->clearCalled == sab[0].cElements, "Destroy->Clear called %d times\n", iRec->clearCalled);
1637 ok(iRec->ref == START_REF_COUNT, "Wrong iRec refcount %d\n", iRec->ref);
1638 }
1639 else
1640 {
1642 ok(hres == S_OK, "got 0x%08x\n", hres);
1643 }
1644
1645 IRecordInfo_Release(&iRec->IRecordInfo_iface);
1646}
unsigned int recordcopy
Definition: safearray.c:82

Referenced by START_TEST().

◆ test_SafeArrayCreateLockDestroy()

static void test_SafeArrayCreateLockDestroy ( void  )
static

Definition at line 825 of file safearray.c.

826{
827 SAFEARRAYBOUND sab[4];
828 SAFEARRAY *sa;
830 VARTYPE vt;
831 UINT dimension;
832
833 for (dimension = 0; dimension < ARRAY_SIZE(sab); dimension++)
834 {
835 sab[dimension].lLbound = 0;
836 sab[dimension].cElements = 8;
837 }
838
839 /* Failure cases */
840/* This test crashes very early versions with no error checking...
841 sa = SafeArrayCreate(VT_UI1, 1, NULL);
842 ok(sa == NULL, "NULL bounds didn't fail\n");
843*/
844 sa = SafeArrayCreate(VT_UI1, 65536, sab);
845 ok(!sa, "Max bounds didn't fail\n");
846
847 memset(sab, 0, sizeof(sab));
848
849 /* Don't test 0 sized dimensions, as Windows has a bug which allows this */
850
851 for (dimension = 0; dimension < ARRAY_SIZE(sab); dimension++)
852 sab[dimension].cElements = 8;
853
854 /* Test all VARTYPES in 1-4 dimensions */
855 for (dimension = 1; dimension < 4; dimension++)
856 {
857 for (vt = VT_EMPTY; vt < VT_CLSID; vt++)
858 {
860
861 sa = SafeArrayCreate(vt, dimension, sab);
862
863 if (dwLen)
864 ok(sa != NULL, "VARTYPE %d (@%d dimensions) failed\n", vt, dimension);
865 else
866 ok(sa == NULL || vt == VT_R8,
867 "VARTYPE %d (@%d dimensions) succeeded!\n", vt, dimension);
868
869 if (sa)
870 {
871 ok(SafeArrayGetDim(sa) == dimension,
872 "VARTYPE %d (@%d dimensions) cDims is %d, expected %d\n",
873 vt, dimension, SafeArrayGetDim(sa), dimension);
874 ok(SafeArrayGetElemsize(sa) == dwLen || vt == VT_R8,
875 "VARTYPE %d (@%d dimensions) cbElements is %d, expected %d\n",
876 vt, dimension, SafeArrayGetElemsize(sa), dwLen);
877
878 if (vt != VT_UNKNOWN && vt != VT_DISPATCH)
879 {
880 ok((sa->fFeatures & FADF_HAVEIID) == 0,
881 "Non interface type should not have FADF_HAVEIID\n");
883 ok(hres == E_INVALIDARG, "Unexpected ret value %#x.\n", hres);
884 if (vt != VT_RECORD)
885 {
886 VARTYPE aVt;
887
888 ok(sa->fFeatures & FADF_HAVEVARTYPE,
889 "Non interface type should have FADF_HAVEVARTYPE\n");
890 if (pSafeArrayGetVartype)
891 {
892 hres = pSafeArrayGetVartype(sa, &aVt);
893 ok(hres == S_OK && aVt == vt,
894 "Non interface type %d: bad type %d, hres %x\n", vt, aVt, hres);
895 }
896 }
897 }
898 else
899 {
900 ok(sa->fFeatures & FADF_HAVEIID, "Interface type should have FADF_HAVEIID\n");
902 ok(hres == S_OK, "Failed to set array IID, hres %#x.\n", hres);
903 ok((sa->fFeatures & FADF_HAVEVARTYPE) == 0,
904 "Interface type %d should not have FADF_HAVEVARTYPE\n", vt);
905 }
906
908 ok(hres == S_OK, "Lock VARTYPE %d (@%d dimensions) failed; hres 0x%x\n",
909 vt, dimension, hres);
910
911 if (hres == S_OK)
912 {
914 ok(hres == DISP_E_ARRAYISLOCKED,"Destroy() got hres %x\n", hres);
915
917 ok(hres == DISP_E_ARRAYISLOCKED,"DestroyData() got hres %x\n", hres);
918
920 ok(hres == DISP_E_ARRAYISLOCKED,"DestroyDescriptor() got hres %x\n", hres);
921
923 ok(hres == S_OK, "Unlock VARTYPE %d (@%d dims) hres 0x%x\n",
924 vt, dimension, hres);
925
927 ok(hres == S_OK, "destroy VARTYPE %d (@%d dims) hres 0x%x\n",
928 vt, dimension, hres);
929 }
930 }
931 }
932 }
933}
static DWORD SAFEARRAY_GetVTSize(VARTYPE vt)
Definition: safearray.c:111

Referenced by START_TEST().

◆ test_SafeArrayDestroyData()

static void test_SafeArrayDestroyData ( void  )
static

Definition at line 1931 of file safearray.c.

1932{
1933 SAFEARRAYBOUND sab[2];
1934 SAFEARRAY *sa;
1935 HRESULT hres;
1936 int value = 0xdeadbeef;
1937 LONG index[1];
1938 void *temp_pvData;
1939 USHORT features;
1940
1941 sab[0].lLbound = 0;
1942 sab[0].cElements = 10;
1943 sa = SafeArrayCreate(VT_INT, 1, sab);
1944 ok(sa != NULL, "Create() failed.\n");
1945 ok(sa->fFeatures == FADF_HAVEVARTYPE, "got 0x%x\n", sa->fFeatures);
1946
1947 index[0] = 1;
1949
1950/* SafeArrayDestroyData shouldn't free pvData if FADF_STATIC is set. */
1951 features = (sa->fFeatures |= FADF_STATIC);
1952 temp_pvData = sa->pvData;
1954 ok(hres == S_OK, "SADData FADF_STATIC failed, error code %x.\n",hres);
1955 ok(features == sa->fFeatures, "got 0x%x\n", sa->fFeatures);
1956 ok(sa->pvData == temp_pvData, "SADData FADF_STATIC: pvData=%p, expected %p (fFeatures = %d).\n",
1957 sa->pvData, temp_pvData, sa->fFeatures);
1959 ok(value == 0, "Data not cleared after SADData\n");
1960
1961/* Clear FADF_STATIC, now really destroy the data. */
1962 features = (sa->fFeatures ^= FADF_STATIC);
1964 ok(hres == S_OK, "SADData !FADF_STATIC failed, error code %x.\n",hres);
1965 ok(features == sa->fFeatures, "got 0x%x\n", sa->fFeatures);
1966 ok(sa->pvData == NULL, "SADData !FADF_STATIC: pvData=%p, expected NULL.\n", sa->pvData);
1967
1969 ok(hres == S_OK, "SAD failed, error code %x.\n", hres);
1970
1971 /* two dimensions */
1972 sab[0].lLbound = 0;
1973 sab[0].cElements = 10;
1974 sab[1].lLbound = 0;
1975 sab[1].cElements = 10;
1976
1977 sa = SafeArrayCreate(VT_INT, 2, sab);
1978 ok(sa != NULL, "Create() failed.\n");
1979 ok(sa->fFeatures == FADF_HAVEVARTYPE, "got 0x%x\n", sa->fFeatures);
1980
1981 features = sa->fFeatures;
1983 ok(hres == S_OK, "got 0x%08x\n",hres);
1984 ok(features == sa->fFeatures, "got 0x%x\n", sa->fFeatures);
1985
1987
1988 /* try to destroy data from descriptor */
1990 ok(hres == S_OK, "got 0x%08x\n", hres);
1991 ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
1992
1994 ok(hres == S_OK, "got 0x%08x\n", hres);
1995 ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
1996
1998 ok(hres == S_OK, "got 0x%08x\n", hres);
1999
2001 ok(hres == S_OK, "got 0x%08x\n", hres);
2002 ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
2003
2005 ok(hres == S_OK, "got 0x%08x\n", hres);
2006 ok(sa->fFeatures == 0, "got 0x%x\n", sa->fFeatures);
2007
2009 ok(hres == S_OK, "got 0x%08x\n", hres);
2010
2011 /* vector case */
2012 sa = SafeArrayCreateVector(VT_I4, 0, 10);
2013 ok(sa != NULL, "got %p\n", sa);
2014 ok(sa->fFeatures == (FADF_CREATEVECTOR|FADF_HAVEVARTYPE), "got 0x%x\n", sa->fFeatures);
2015
2016 ok(sa->pvData != NULL, "got %p\n", sa->pvData);
2018 ok(hres == S_OK, "got 0x%08x\n", hres);
2020 ok(sa->fFeatures == FADF_HAVEVARTYPE, "got 0x%x\n", sa->fFeatures);
2022 ok(sa->pvData == NULL || broken(sa->pvData != NULL), "got %p\n", sa->pvData);
2023 /* There was a bug on windows, especially visible on 64bit systems,
2024 probably double-free or similar issue. */
2025 sa->pvData = NULL;
2027}
HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
Definition: safearray.c:864
GLuint index
Definition: glext.h:6031
#define todo_wine
Definition: custom.c:89
Definition: pdh_main.c:94

Referenced by START_TEST().

◆ test_SafeArrayGetPutElement()

static void test_SafeArrayGetPutElement ( void  )
static

Definition at line 1052 of file safearray.c.

1053{
1054 SAFEARRAYBOUND sab[4];
1056 SAFEARRAY *sa;
1057 HRESULT hres;
1058 int value = 0, gotvalue, dimension;
1059 IRecordInfoImpl *irec;
1060 unsigned int x,y,z,a;
1061
1062 for (dimension = 0; dimension < ARRAY_SIZE(sab); dimension++)
1063 {
1064 sab[dimension].lLbound = dimension * 2 + 1;
1065 sab[dimension].cElements = dimension * 3 + 1;
1066 }
1067
1068 sa = SafeArrayCreate(VT_INT, ARRAY_SIZE(sab), sab);
1069 if (!sa)
1070 return; /* Some early versions can't handle > 3 dims */
1071
1072 ok(sa->cbElements == sizeof(value), "int size mismatch\n");
1073
1074 /* Failure cases */
1075 for (x = 0; x < ARRAY_SIZE(sab); x++)
1076 {
1077 indices[0] = sab[0].lLbound;
1078 indices[1] = sab[1].lLbound;
1079 indices[2] = sab[2].lLbound;
1080 indices[3] = sab[3].lLbound;
1081
1082 indices[x] = indices[x] - 1;
1084 ok(hres == DISP_E_BADINDEX, "Put allowed too small index in dimension %d\n", x);
1086 ok(hres == DISP_E_BADINDEX, "Get allowed too small index in dimension %d\n", x);
1087
1088 indices[x] = sab[x].lLbound + sab[x].cElements;
1090 ok(hres == DISP_E_BADINDEX, "Put allowed too big index in dimension %d\n", x);
1092 ok(hres == DISP_E_BADINDEX, "Get allowed too big index in dimension %d\n", x);
1093 }
1094
1095 indices[0] = sab[0].lLbound;
1096 indices[1] = sab[1].lLbound;
1097 indices[2] = sab[2].lLbound;
1098 indices[3] = sab[3].lLbound;
1099
1101 ok(hres == E_INVALIDARG, "Put NULL array hres 0x%x\n", hres);
1103 ok(hres == E_INVALIDARG, "Get NULL array hres 0x%x\n", hres);
1104
1106 ok(hres == E_INVALIDARG, "Put NULL indices hres 0x%x\n", hres);
1108 ok(hres == E_INVALIDARG, "Get NULL indices hres 0x%x\n", hres);
1109
1110 if (0)
1111 {
1112 /* This is retarded. Windows checks every case of invalid parameters
1113 * except the following, which crashes. We ERR this in Wine.
1114 */
1116 ok(hres == E_INVALIDARG, "Put NULL value hres 0x%x\n", hres);
1117 }
1118
1120 ok(hres == E_INVALIDARG, "Get NULL value hres 0x%x\n", hres);
1121
1122 value = 0;
1123
1124 /* Make sure we can read and get back the correct values in 4 dimensions,
1125 * Each with a different size and lower bound.
1126 */
1127 for (x = 0; x < sab[0].cElements; x++)
1128 {
1129 indices[0] = sab[0].lLbound + x;
1130 for (y = 0; y < sab[1].cElements; y++)
1131 {
1132 indices[1] = sab[1].lLbound + y;
1133 for (z = 0; z < sab[2].cElements; z++)
1134 {
1135 indices[2] = sab[2].lLbound + z;
1136 for (a = 0; a < sab[3].cElements; a++)
1137 {
1138 indices[3] = sab[3].lLbound + a;
1140 ok(hres == S_OK, "Failed to put element at (%d,%d,%d,%d) hres 0x%x\n",
1141 x, y, z, a, hres);
1142 value++;
1143 }
1144 }
1145 }
1146 }
1147
1148 value = 0;
1149
1150 for (x = 0; x < sab[0].cElements; x++)
1151 {
1152 indices[0] = sab[0].lLbound + x;
1153 for (y = 0; y < sab[1].cElements; y++)
1154 {
1155 indices[1] = sab[1].lLbound + y;
1156 for (z = 0; z < sab[2].cElements; z++)
1157 {
1158 indices[2] = sab[2].lLbound + z;
1159 for (a = 0; a < sab[3].cElements; a++)
1160 {
1161 indices[3] = sab[3].lLbound + a;
1162 gotvalue = value / 3;
1163 hres = SafeArrayGetElement(sa, indices, &gotvalue);
1164 ok(hres == S_OK, "Failed to get element at (%d,%d,%d,%d) hres 0x%x\n",
1165 x, y, z, a, hres);
1166 if (hres == S_OK)
1167 ok(value == gotvalue, "Got value %d instead of %d at (%d,%d,%d,%d)\n",
1168 gotvalue, value, x, y, z, a);
1169 value++;
1170 }
1171 }
1172 }
1173 }
1175 ok(hres == S_OK, "got 0x%08x\n", hres);
1176
1177 /* VT_RECORD array */
1179 irec->ref = 1;
1180
1181 sab[0].lLbound = 0;
1182 sab[0].cElements = 8;
1183
1185 ok(sa != NULL, "failed to create array\n");
1186 ok(irec->ref == 2, "got %d\n", irec->ref);
1187
1188 index = 0;
1189 irec->recordcopy = 0;
1190 hres = SafeArrayPutElement(sa, &index, (void*)0xdeadbeef);
1191 ok(hres == S_OK, "got 0x%08x\n", hres);
1192 ok(irec->recordcopy == 1, "got %d\n", irec->recordcopy);
1193
1194 index = 0;
1195 irec->recordcopy = 0;
1196 hres = SafeArrayGetElement(sa, &index, (void*)0xdeadbeef);
1197 ok(hres == S_OK, "got 0x%08x\n", hres);
1198 ok(irec->recordcopy == 1, "got %d\n", irec->recordcopy);
1199
1201 ok(hres == S_OK, "got 0x%08x\n", hres);
1202 ok(irec->ref == 1, "got %d\n", irec->ref);
1203 IRecordInfo_Release(&irec->IRecordInfo_iface);
1204}
#define index(s, c)
Definition: various.h:29
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble z
Definition: glext.h:5874

Referenced by START_TEST().

◆ test_SafeArrayGetPutElement_BSTR()

static void test_SafeArrayGetPutElement_BSTR ( void  )
static

Definition at line 1206 of file safearray.c.

1207{
1208 SAFEARRAYBOUND sab;
1209 LONG indices[1];
1210 SAFEARRAY *sa;
1211 HRESULT hres;
1212 BSTR value = 0, gotvalue;
1213 const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
1214
1215 sab.lLbound = 1;
1216 sab.cElements = 1;
1217
1218 sa = SafeArrayCreate(VT_BSTR, 1, &sab);
1219 ok(sa != NULL, "BSTR test couldn't create array\n");
1220 if (!sa)
1221 return;
1222
1223 ok(sa->cbElements == sizeof(BSTR), "BSTR size mismatch\n");
1224
1225 indices[0] = sab.lLbound;
1226 value = SysAllocString(szTest);
1227 ok (value != NULL, "Expected non-NULL\n");
1229 ok(hres == S_OK, "Failed to put bstr element hres 0x%x\n", hres);
1230 gotvalue = NULL;
1231 hres = SafeArrayGetElement(sa, indices, &gotvalue);
1232 ok(hres == S_OK, "Failed to get bstr element at hres 0x%x\n", hres);
1233 if (hres == S_OK)
1234 ok(SysStringLen(value) == SysStringLen(gotvalue), "Got len %d instead of %d\n", SysStringLen(gotvalue), SysStringLen(value));
1236 ok(hres == S_OK, "got 0x%08x\n", hres);
1238 SysFreeString(gotvalue);
1239}
WCHAR OLECHAR
Definition: compat.h:2292
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271

Referenced by START_TEST().

◆ test_SafeArrayGetPutElement_IUnknown()

static void test_SafeArrayGetPutElement_IUnknown ( void  )
static

Definition at line 1270 of file safearray.c.

1271{
1272 SAFEARRAYBOUND sab;
1273 LONG indices[1];
1274 SAFEARRAY *sa;
1275 HRESULT hres;
1276 IUnknown *gotvalue;
1277
1278 sab.lLbound = 1;
1279 sab.cElements = 1;
1280 sa = SafeArrayCreate(VT_UNKNOWN, 1, &sab);
1281 ok(sa != NULL, "UNKNOWN test couldn't create array\n");
1282 if (!sa)
1283 return;
1284
1285 ok(sa->cbElements == sizeof(LPUNKNOWN), "LPUNKNOWN size mismatch\n");
1286
1287 indices[0] = sab.lLbound;
1288 xtunk.ref = 1;
1289 hres = SafeArrayPutElement(sa, indices, &xtunk.IUnknown_iface);
1290 ok(hres == S_OK, "Failed to put bstr element hres 0x%x\n", hres);
1291 ok(xtunk.ref == 2,"Failed to increment refcount of iface.\n");
1292 gotvalue = NULL;
1293 hres = SafeArrayGetElement(sa, indices, &gotvalue);
1294 ok(xtunk.ref == 3,"Failed to increment refcount of iface.\n");
1295 ok(hres == S_OK, "Failed to get bstr element at hres 0x%x\n", hres);
1296 if (hres == S_OK)
1297 ok(gotvalue == &xtunk.IUnknown_iface, "Got %p instead of %p\n", gotvalue, &xtunk.IUnknown_iface);
1299 ok(hres == S_OK, "got 0x%08x\n", hres);
1300 ok(xtunk.ref == 2,"Failed to decrement refcount of iface.\n");
1301}
static struct xtunk_impl xtunk
Definition: safearray.c:1247

Referenced by START_TEST().

◆ test_SafeArrayGetPutElement_VARIANT()

static void test_SafeArrayGetPutElement_VARIANT ( void  )
static

Definition at line 1332 of file safearray.c.

1333{
1334 SAFEARRAYBOUND sab;
1335 LONG indices[1];
1336 SAFEARRAY *sa;
1337 HRESULT hres;
1338 VARIANT value, gotvalue;
1339
1340 sab.lLbound = 1;
1341 sab.cElements = 1;
1342 sa = SafeArrayCreate(VT_VARIANT, 1, &sab);
1343 ok(sa != NULL, "VARIANT test couldn't create array\n");
1344 if (!sa)
1345 return;
1346
1347 ok(sa->cbElements == sizeof(VARIANT), "VARIANT size mismatch\n");
1348
1349 indices[0] = sab.lLbound;
1350 V_VT(&value) = VT_I4;
1351 V_I4(&value) = 0x42424242;
1353 ok(hres == S_OK, "Failed to put Variant I4 element hres 0x%x\n", hres);
1354
1355 V_VT(&gotvalue) = 0xdead;
1356 hres = SafeArrayGetElement(sa, indices, &gotvalue);
1357 ok(hres == S_OK, "Failed to get variant element at hres 0x%x\n", hres);
1358
1359 V_VT(&gotvalue) = VT_EMPTY;
1360 hres = SafeArrayGetElement(sa, indices, &gotvalue);
1361 ok(hres == S_OK, "Failed to get variant element at hres 0x%x\n", hres);
1362 if (hres == S_OK) {
1363 ok(V_VT(&value) == V_VT(&gotvalue), "Got type 0x%x instead of 0x%x\n", V_VT(&value), V_VT(&gotvalue));
1364 if (V_VT(&value) == V_VT(&gotvalue))
1365 ok(V_I4(&value) == V_I4(&gotvalue), "Got %d instead of %d\n", V_I4(&value), V_VT(&gotvalue));
1366 }
1368 ok(hres == S_OK, "got 0x%08x\n", hres);
1369}
#define V_I4(A)
Definition: oleauto.h:247

Referenced by START_TEST().

◆ test_SafeArrayRedim_IUnknown()

static void test_SafeArrayRedim_IUnknown ( void  )
static

Definition at line 1303 of file safearray.c.

1304{
1305 SAFEARRAYBOUND sab;
1306 LONG indices[1];
1307 SAFEARRAY *sa;
1308 HRESULT hres;
1309
1310 sab.lLbound = 1;
1311 sab.cElements = 2;
1312 sa = SafeArrayCreate(VT_UNKNOWN, 1, &sab);
1313 ok(sa != NULL, "UNKNOWN test couldn't create array\n");
1314 if (!sa)
1315 return;
1316
1317 ok(sa->cbElements == sizeof(LPUNKNOWN), "LPUNKNOWN size mismatch\n");
1318
1319 indices[0] = 2;
1320 xtunk.ref = 1;
1321 hres = SafeArrayPutElement(sa, indices, &xtunk.IUnknown_iface);
1322 ok(hres == S_OK, "Failed to put IUnknown element hres 0x%x\n", hres);
1323 ok(xtunk.ref == 2,"Failed to increment refcount of iface.\n");
1324 sab.cElements = 1;
1325 hres = SafeArrayRedim(sa, &sab);
1326 ok(hres == S_OK, "Failed to shrink array hres 0x%x\n", hres);
1327 ok(xtunk.ref == 1, "Failed to decrement refcount\n");
1329 ok(hres == S_OK, "got 0x%08x\n", hres);
1330}

Referenced by START_TEST().

◆ test_VectorCreateLockDestroy()

static void test_VectorCreateLockDestroy ( void  )
static

Definition at line 935 of file safearray.c.

936{
937 SAFEARRAY *sa;
939 VARTYPE vt;
940 int element;
941
943 {
944 win_skip("SafeArrayCreateVector not supported\n");
945 return;
946 }
948 ok(sa != NULL, "SACV with 0 elements failed.\n");
949
951 ok(hres == S_OK, "SafeArrayDestroy failed with hres %x\n",hres);
952
953 /* Test all VARTYPES in different lengths */
954 for (element = 1; element <= 101; element += 10)
955 {
956 for (vt = VT_EMPTY; vt < VT_CLSID; vt++)
957 {
959
961
962 if (dwLen)
963 ok(sa != NULL, "VARTYPE %d (@%d elements) failed\n", vt, element);
964 else
965 ok(sa == NULL, "VARTYPE %d (@%d elements) succeeded!\n", vt, element);
966
967 if (sa)
968 {
969 ok(SafeArrayGetDim(sa) == 1, "VARTYPE %d (@%d elements) cDims %d, not 1\n",
971 ok(SafeArrayGetElemsize(sa) == dwLen,
972 "VARTYPE %d (@%d elements) cbElements is %d, expected %d\n",
974
976 ok(hres == S_OK, "Lock VARTYPE %d (@%d elements) failed; hres 0x%x\n",
977 vt, element, hres);
978
979 if (hres == S_OK)
980 {
982 ok(hres == S_OK, "Unlock VARTYPE %d (@%d elements) failed; hres 0x%x\n",
983 vt, element, hres);
984
986 ok(hres == S_OK, "destroy VARTYPE %d (@%d elements) failed; hres 0x%x\n",
987 vt, element, hres);
988 }
989 }
990 }
991 }
992}

Referenced by START_TEST().

◆ tunk_AddRef()

static ULONG WINAPI tunk_AddRef ( IUnknown punk)
static

Definition at line 1254 of file safearray.c.

1255{
1256 return ++xtunk.ref;
1257}

◆ tunk_QueryInterface()

static HRESULT WINAPI tunk_QueryInterface ( IUnknown punk,
REFIID  riid,
void **  x 
)
static

Definition at line 1249 of file safearray.c.

1250{
1251 return E_FAIL;
1252}
#define E_FAIL
Definition: ddrawi.h:102

◆ tunk_Release()

static ULONG WINAPI tunk_Release ( IUnknown punk)
static

Definition at line 1259 of file safearray.c.

1260{
1261 return --xtunk.ref;
1262}

Variable Documentation

◆ addflags

UINT addflags

Definition at line 334 of file safearray.c.

◆ elemsize

UINT elemsize

Definition at line 332 of file safearray.c.

Referenced by test_safearray(), and xdr_vector().

◆ expflags

UINT expflags

Definition at line 333 of file safearray.c.

◆ FADF_CREATEVECTOR

◆ fail_GetSize

BOOL fail_GetSize
static

Definition at line 128 of file safearray.c.

Referenced by RecordInfo_GetSize(), and test_SafeArrayCreateEx().

◆ has_i8

BOOL has_i8
static

Definition at line 58 of file safearray.c.

Referenced by SAFEARRAY_GetVTSize(), START_TEST(), and test_safearray().

◆ has_int_ptr

BOOL has_int_ptr
static

Definition at line 60 of file safearray.c.

Referenced by check_for_VT_INT_PTR(), and SAFEARRAY_GetVTSize().

◆ hOleaut32

HMODULE hOleaut32
static

Definition at line 46 of file safearray.c.

Referenced by START_TEST().

◆ ignored_copy_features

const USHORT ignored_copy_features[]
static
Initial value:
=
{
FADF_AUTO,
FADF_STATIC,
FADF_EMBEDDED,
FADF_FIXEDSIZE
}

Definition at line 62 of file safearray.c.

◆ RecordInfoVtbl

const IRecordInfoVtbl RecordInfoVtbl
static
Initial value:
=
{
}
static HRESULT WINAPI RecordInfo_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource, PVOID *ppvDest)
Definition: safearray.c:222
static ULONG WINAPI RecordInfo_Release(IRecordInfo *iface)
Definition: safearray.c:111
static HRESULT WINAPI RecordInfo_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
Definition: safearray.c:229
static HRESULT WINAPI RecordInfo_GetFieldNames(IRecordInfo *iface, ULONG *pcNames, BSTR *rgBstrNames)
Definition: safearray.c:203
static HRESULT WINAPI RecordInfo_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo)
Definition: safearray.c:169
static ULONG WINAPI RecordInfo_AddRef(IRecordInfo *iface)
Definition: safearray.c:105
static HRESULT WINAPI RecordInfo_RecordClear(IRecordInfo *iface, PVOID pvExisting)
Definition: safearray.c:130
static BOOL WINAPI RecordInfo_IsMatchingType(IRecordInfo *iface, IRecordInfo *info2)
Definition: safearray.c:210
static HRESULT WINAPI RecordInfo_GetSize(IRecordInfo *iface, ULONG *size)
Definition: safearray.c:156
static HRESULT WINAPI RecordInfo_GetGuid(IRecordInfo *iface, GUID *pguid)
Definition: safearray.c:144
static PVOID WINAPI RecordInfo_RecordCreate(IRecordInfo *iface)
Definition: safearray.c:216
static HRESULT WINAPI RecordInfo_GetField(IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
Definition: safearray.c:175
static HRESULT WINAPI RecordInfo_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
Definition: safearray.c:182
static HRESULT WINAPI RecordInfo_GetName(IRecordInfo *iface, BSTR *pbstrName)
Definition: safearray.c:150
static HRESULT WINAPI RecordInfo_QueryInterface(IRecordInfo *iface, REFIID riid, void **obj)
Definition: safearray.c:90
static HRESULT WINAPI RecordInfo_RecordInit(IRecordInfo *iface, PVOID pvNew)
Definition: safearray.c:122
static HRESULT WINAPI RecordInfo_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
Definition: safearray.c:189
static HRESULT WINAPI RecordInfo_RecordCopy(IRecordInfo *iface, PVOID pvExisting, PVOID pvNew)
Definition: safearray.c:137
static HRESULT WINAPI RecordInfo_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
Definition: safearray.c:196

Definition at line 235 of file safearray.c.

Referenced by IRecordInfoImpl_Construct().

◆ UINT

Definition at line 48 of file safearray.c.

◆ vt

VARTYPE vt

Definition at line 331 of file safearray.c.

◆ 

struct { ... } vttypes[]

Referenced by test_safearray().

◆ xtunk

◆ xtunk_vtbl

static const IUnknownVtbl xtunk_vtbl
static
Initial value:
= {
}
static ULONG WINAPI tunk_Release(IUnknown *punk)
Definition: safearray.c:1259
static HRESULT WINAPI tunk_QueryInterface(IUnknown *punk, REFIID riid, void **x)
Definition: safearray.c:1249
static ULONG WINAPI tunk_AddRef(IUnknown *punk)
Definition: safearray.c:1254

Definition at line 1245 of file safearray.c.