Separate "Enumerate Hardware Addresses" as function, as other netapi32
[wine] / dlls / oleaut32 / tests / safearray.c
1 /*
2  * SafeArray test program
3  *
4  * Copyright 2002 Marcus Meissner
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
25 #include <float.h>
26 #include <time.h>
27
28 #include "wine/test.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "wingdi.h"
32 #include "winnls.h"
33 #include "winerror.h"
34 #include "winnt.h"
35
36 #include "wtypes.h"
37 #include "oleauto.h"
38
39 static HRESULT (WINAPI *pSafeArrayAllocDescriptorEx)(VARTYPE,UINT,struct tagSAFEARRAY**)=NULL;
40 static HRESULT (WINAPI *pSafeArrayCopyData)(struct tagSAFEARRAY*,struct tagSAFEARRAY*)=NULL;
41 static HRESULT (WINAPI *pSafeArrayGetIID)(struct tagSAFEARRAY*,GUID*)=NULL;
42 static HRESULT (WINAPI *pSafeArraySetIID)(struct tagSAFEARRAY*,REFGUID)=NULL;
43 static HRESULT (WINAPI *pSafeArrayGetVartype)(struct tagSAFEARRAY*,VARTYPE*)=NULL;
44
45 #define VARTYPE_NOT_SUPPORTED 0
46 static struct {
47         VARTYPE vt;    /* VT */
48         UINT elemsize; /* elementsize by VT */
49         UINT expflags; /* fFeatures from SafeArrayAllocDescriptorEx */
50         UINT addflags; /* additional fFeatures from SafeArrayCreate */
51 } vttypes[] = {
52 {VT_EMPTY,    VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
53 {VT_NULL,     VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
54 {VT_I2,       2,                    FADF_HAVEVARTYPE,0},
55 {VT_I4,       4,                    FADF_HAVEVARTYPE,0},
56 {VT_R4,       4,                    FADF_HAVEVARTYPE,0},
57 {VT_R8,       8,                    FADF_HAVEVARTYPE,0},
58 {VT_CY,       8,                    FADF_HAVEVARTYPE,0},
59 {VT_DATE,     8,                    FADF_HAVEVARTYPE,0},
60 {VT_BSTR,     sizeof(BSTR),         FADF_HAVEVARTYPE,FADF_BSTR},
61 {VT_DISPATCH, sizeof(LPDISPATCH),   FADF_HAVEIID,    FADF_DISPATCH},
62 {VT_ERROR,    4,                    FADF_HAVEVARTYPE,0},
63 {VT_BOOL,     2,                    FADF_HAVEVARTYPE,0},
64 {VT_VARIANT,  sizeof(VARIANT),      FADF_HAVEVARTYPE,FADF_VARIANT},
65 {VT_UNKNOWN,  sizeof(LPUNKNOWN),    FADF_HAVEIID,    FADF_UNKNOWN},
66 {VT_DECIMAL,  sizeof(DECIMAL),      FADF_HAVEVARTYPE,0},
67 {15,          VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0}, /* no VT_xxx */
68 {VT_I1,       1,                    FADF_HAVEVARTYPE,0},
69 {VT_UI1,      1,                    FADF_HAVEVARTYPE,0},
70 {VT_UI2,      2,                    FADF_HAVEVARTYPE,0},
71 {VT_UI4,      4,                    FADF_HAVEVARTYPE,0},
72 {VT_I8,       VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
73 {VT_UI8,      VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
74 {VT_INT,      sizeof(INT),          FADF_HAVEVARTYPE,0},
75 {VT_UINT,     sizeof(UINT),         FADF_HAVEVARTYPE,0},
76 {VT_VOID,     VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
77 {VT_HRESULT,  VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
78 {VT_PTR,      VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
79 {VT_SAFEARRAY,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
80 {VT_CARRAY,   VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
81 {VT_USERDEFINED,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
82 {VT_LPSTR,    VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
83 {VT_LPWSTR,   VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
84 {VT_FILETIME, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
85 {VT_RECORD,   VARTYPE_NOT_SUPPORTED,FADF_RECORD,0},
86 {VT_BLOB,     VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
87 {VT_STREAM,   VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
88 {VT_STORAGE,  VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
89 {VT_STREAMED_OBJECT,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
90 {VT_STORED_OBJECT,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
91 {VT_BLOB_OBJECT,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
92 {VT_CF,       VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
93 {VT_CLSID,    VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
94 };
95
96 START_TEST(safearray)
97 {
98         HMODULE hdll;
99         SAFEARRAY       *a, b, *c;
100         unsigned int    i;
101         HRESULT         hres;
102         SAFEARRAYBOUND  bound;
103         VARIANT         v;
104         LPVOID          data;
105         IID             iid;
106         VARTYPE         vt;
107
108     hdll=LoadLibraryA("oleaut32.dll");
109     pSafeArrayAllocDescriptorEx=(void*)GetProcAddress(hdll,"SafeArrayAllocDescriptorEx");
110     pSafeArrayCopyData=(void*)GetProcAddress(hdll,"SafeArrayCopyData");
111     pSafeArrayGetIID=(void*)GetProcAddress(hdll,"SafeArrayGetIID");
112     pSafeArraySetIID=(void*)GetProcAddress(hdll,"SafeArraySetIID");
113     pSafeArrayGetVartype=(void*)GetProcAddress(hdll,"SafeArrayGetVartype");
114
115         hres = SafeArrayAllocDescriptor(0,&a);
116         ok(E_INVALIDARG == hres,"SAAD(0) failed with hres %lx",hres);
117
118         hres=SafeArrayAllocDescriptor(1,&a);
119         ok(S_OK == hres,"SAAD(1) failed with %lx",hres);
120
121         for (i=1;i<100;i++) {
122                 hres=SafeArrayAllocDescriptor(i,&a);
123                 ok(S_OK == hres,"SAAD(%d) failed with %lx",i,hres);
124                 
125                 ok(a->cDims == i,"a->cDims not initialised?");
126
127                 hres=SafeArrayDestroyDescriptor(a);
128                 ok(S_OK == hres,"SADD failed with %lx",hres);
129         }
130
131         hres=SafeArrayAllocDescriptor(65535,&a);
132         ok(S_OK == hres,"SAAD(65535) failed with %lx",hres);
133
134         hres=SafeArrayDestroyDescriptor(a);
135         ok(S_OK == hres,"SADD failed with %lx",hres);
136
137         hres=SafeArrayAllocDescriptor(65536,&a);
138         ok(E_INVALIDARG == hres,"SAAD(65536) failed with %lx",hres);
139
140         /* Crashes on Win95: SafeArrayAllocDescriptor(xxx,NULL) */
141         
142         bound.cElements = 1;
143         bound.lLbound   = 0;
144         a = SafeArrayCreate(-1, 1, &bound);
145         ok(NULL == a,"SAC(-1,1,[1,0]) not failed?");
146         
147         for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
148                 a = SafeArrayCreate(vttypes[i].vt, 1, &bound);
149                 ok(     ((a == NULL) && (vttypes[i].elemsize == 0)) ||
150                         ((a != NULL) && (vttypes[i].elemsize == a->cbElements)),
151                 "SAC(%d,1,[1,0]), result %ld, expected %d",vttypes[i].vt,(a?a->cbElements:0),vttypes[i].elemsize
152                 );
153         if (a!=NULL) {
154                         ok(a->fFeatures == (vttypes[i].expflags | vttypes[i].addflags),
155                "SAC of %d returned feature flags %x, expected %x",
156                vttypes[i].vt, a->fFeatures,
157                vttypes[i].expflags|vttypes[i].addflags);
158                 ok(SafeArrayGetElemsize(a) == vttypes[i].elemsize,
159                "SAGE for vt %d returned elemsize %d instead of expected %d",
160                vttypes[i].vt, SafeArrayGetElemsize(a),vttypes[i].elemsize);
161         }
162
163                 if (!a) continue;
164
165         if (pSafeArrayGetVartype) {
166             hres = pSafeArrayGetVartype(a, &vt);
167             ok(hres == S_OK, "SAGVT of arra y with vt %d failed with %lx", vttypes[i].vt, hres);
168             if (vttypes[i].vt == VT_DISPATCH) {
169                         /* Special case. Checked against Windows. */
170                         ok(vt == VT_UNKNOWN, "SAGVT of a        rray with VT_DISPATCH returned not VT_UNKNOWN, but %d", vt);
171             } else {
172                         ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d", vttypes[i].vt, vt);
173             }
174         }
175
176                 hres = SafeArrayCopy(a, &c);
177                 ok(hres == S_OK, "failed to copy safearray of vt %d with hres %lx", vttypes[i].vt, hres);
178
179                 ok(vttypes[i].elemsize == c->cbElements,"copy of SAC(%d,1,[1,0]), result %ld, expected %d",vttypes[i].vt,(c?c->cbElements:0),vttypes[i].elemsize
180                 );
181                 ok(c->fFeatures == (vttypes[i].expflags | vttypes[i].addflags),"SAC of %d returned feature flags %x, expected %x", vttypes[i].vt, c->fFeatures, vttypes[i].expflags|vttypes[i].addflags);
182                 ok(SafeArrayGetElemsize(c) == vttypes[i].elemsize,"SAGE for vt %d returned elemsize %d instead of expected %d",vttypes[i].vt, SafeArrayGetElemsize(c),vttypes[i].elemsize);
183
184         if (pSafeArrayGetVartype) {
185             hres = pSafeArrayGetVartype(c, &vt);
186             ok(hres == S_OK, "SAGVT of array with vt %d failed with %lx", vttypes[i].vt, hres);
187             if (vttypes[i].vt == VT_DISPATCH) {
188                 /* Special case. Checked against Windows. */
189                 ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d", vt);
190             } else {
191                 ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d", vttypes[i].vt, vt);
192             }
193         }
194
195         if (pSafeArrayCopyData) {
196             hres = pSafeArrayCopyData(a, c);
197             ok(hres == S_OK, "failed to copy safearray data of vt %d with hres %lx", vttypes[i].vt, hres);
198
199             hres = SafeArrayDestroyData(c);
200             ok(hres == S_OK,"SADD of copy of array with vt %d failed with hres %lx", vttypes[i].vt, hres);
201         }
202
203                 hres = SafeArrayDestroy(a);
204                 ok(hres == S_OK,"SAD of array with vt %d failed with hres %lx", vttypes[i].vt, hres);
205         }
206
207         /* Test conversion of type|VT_ARRAY <-> VT_BSTR */
208         bound.lLbound = 0;
209         bound.cElements = 10;
210         a = SafeArrayCreate(VT_UI1, 1, &bound);
211         ok(a != NULL, "SAC failed.");
212         ok(S_OK == SafeArrayAccessData(a, &data),"SACD failed");
213         memcpy(data,"Hello World",10);
214         ok(S_OK == SafeArrayUnaccessData(a),"SAUD failed");
215         V_VT(&v) = VT_ARRAY|VT_UI1;
216         V_ARRAY(&v) = a;
217         hres = VariantChangeTypeEx(&v, &v, 0, 0, VT_BSTR);
218         ok(hres==S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %lx",hres);
219         ok(V_VT(&v) == VT_BSTR,"CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.",V_VT(&v));
220         ok(V_BSTR(&v)[0] == 0x6548,"First letter are not 'He', but %x", V_BSTR(&v)[0]);
221
222         /* check locking functions */
223         a = SafeArrayCreate(VT_I4, 1, &bound);
224         ok(a!=NULL,"SAC should not fail");
225
226         hres = SafeArrayAccessData(a, &data);
227         ok(hres == S_OK,"SAAD failed with hres %lx",hres);
228
229         hres = SafeArrayDestroy(a);
230         ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy not failed with DISP_E_ARRAYISLOCKED, but with hres %lx", hres);
231
232         hres = SafeArrayDestroyData(a);
233         ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy data not failed with DISP_E_ARRAYISLOCKED, but with hres %lx", hres);
234
235         hres = SafeArrayDestroyDescriptor(a);
236         ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy descriptor not failed with DISP_E_ARRAYISLOCKED, but with hres %lx", hres);
237
238         hres = SafeArrayUnaccessData(a);
239         ok(hres == S_OK,"SAUD failed after lock/destroy test");
240
241         hres = SafeArrayDestroy(a);
242         ok(hres == S_OK,"SAD failed after lock/destroy test");
243
244         /* Test if we need to destroy data before descriptor */
245         a = SafeArrayCreate(VT_I4, 1, &bound);
246         ok(a!=NULL,"SAC should not fail");
247         hres = SafeArrayDestroyDescriptor(a);
248         ok(hres == S_OK,"SADD with data in array failed with hres %lx",hres);
249
250
251         /* IID functions */
252         /* init a small stack safearray */
253     if (pSafeArraySetIID) {
254         memset(&b, 0, sizeof(b));
255         b.cDims = 1;
256         memset(&iid, 0x42, sizeof(IID));
257         hres = pSafeArraySetIID(&b,&iid);
258         ok(hres == E_INVALIDARG,"SafeArraySetIID of non IID capable safearray did not return E_INVALIDARG, but %lx",hres);
259
260         hres = SafeArrayAllocDescriptor(1,&a);
261         ok((a->fFeatures & FADF_HAVEIID) == 0,"newly allocated descriptor with SAAD should not have FADF_HAVEIID");
262         hres = pSafeArraySetIID(a,&iid);
263         ok(hres == E_INVALIDARG,"SafeArraySetIID of newly allocated descriptor with SAAD should return E_INVALIDARG, but %lx",hres);
264     }
265
266     if (!pSafeArrayAllocDescriptorEx)
267         return;
268
269         for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
270                 hres = pSafeArrayAllocDescriptorEx(vttypes[i].vt,1,&a);
271                 ok(a->fFeatures == vttypes[i].expflags,"SAADE(%d) resulted with flags %x, expected %x\n", vttypes[i].vt, a->fFeatures, vttypes[i].expflags);
272                 if (a->fFeatures & FADF_HAVEIID) {
273                         hres = pSafeArrayGetIID(a, &iid);
274                         ok(hres == S_OK,"SAGIID failed for vt %d with hres %lx", vttypes[i].vt,hres);
275                         switch (vttypes[i].vt) {
276                         case VT_UNKNOWN:
277                                 ok(IsEqualGUID(((GUID*)a)-1,&IID_IUnknown),"guid for VT_UNKNOWN is not IID_IUnknown");
278                                 ok(IsEqualGUID(&iid, &IID_IUnknown),"SAGIID returned wrong GUID for IUnknown");
279                                 break;
280                         case VT_DISPATCH:
281                                 ok(IsEqualGUID(((GUID*)a)-1,&IID_IDispatch),"guid for VT_UNKNOWN is not IID_IDispatch");
282                                 ok(IsEqualGUID(&iid, &IID_IDispatch),"SAGIID returned wrong GUID for IDispatch");
283                                 break;
284                         default:
285                                 ok(FALSE,"unknown vt %d with FADF_HAVEIID",vttypes[i].vt);
286                                 break;
287                         }
288                 } else {
289                         hres = pSafeArrayGetIID(a, &iid);
290                         ok(hres == E_INVALIDARG,"SAGIID did not fail for vt %d with hres %lx", vttypes[i].vt,hres);
291                 }
292                 if (a->fFeatures & FADF_RECORD) {
293                         ok(vttypes[i].vt == VT_RECORD,"FADF_RECORD for non record %d",vttypes[i].vt);
294                 }
295                 if (a->fFeatures & FADF_HAVEVARTYPE) {
296                         ok(vttypes[i].vt == ((DWORD*)a)[-1], "FADF_HAVEVARTYPE set, but vt %d mismatch stored %ld",vttypes[i].vt,((DWORD*)a)[-1]);
297                 }
298
299                 hres = pSafeArrayGetVartype(a, &vt);
300                 ok(hres == S_OK, "SAGVT of array with vt %d failed with %lx", vttypes[i].vt, hres);
301
302                 if (vttypes[i].vt == VT_DISPATCH) {
303                         /* Special case. Checked against Windows. */
304                         ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d", vt);
305                 } else {
306                         ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d", vttypes[i].vt, vt);
307                 }
308
309                 if (a->fFeatures & FADF_HAVEIID) {
310                         hres = pSafeArraySetIID(a, &IID_IStorage); /* random IID */
311                         ok(hres == S_OK,"SASIID failed with FADF_HAVEIID set for vt %d with %lx", vttypes[i].vt, hres);
312                         hres = pSafeArrayGetIID(a, &iid);
313                         ok(hres == S_OK,"SAGIID failed with FADF_HAVEIID set for vt %d with %lx", vttypes[i].vt, hres);
314                         ok(IsEqualGUID(&iid, &IID_IStorage),"returned iid is not IID_IStorage");
315                 } else {
316                         hres = pSafeArraySetIID(a, &IID_IStorage); /* random IID */
317                         ok(hres == E_INVALIDARG,"SASIID did not failed with !FADF_HAVEIID set for vt %d with %lx", vttypes[i].vt, hres);
318                 }
319                 hres = SafeArrayDestroyDescriptor(a);
320                 ok(hres == S_OK,"SADD failed with hres %lx",hres);
321         }
322 }