Fix a couple of tests for w2k (Russian).
[wine] / dlls / oleaut32 / tests / vartest.c
1 /*
2  * VARIANT test program
3  *
4  * Copyright 1998 Jean-Claude Cote
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  * NOTES
21  * - Does not test IDispatch, IUnknown, IRecordInfo, DECIMAL, CY, I8/UI8
22  */
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <math.h>
28 #include <float.h>
29 #include <time.h>
30
31 #define NONAMELESSUNION
32 #define NONAMELESSSTRUCT
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winsock.h"
36 #include "wine/test.h"
37 #include "winuser.h"
38 #include "wingdi.h"
39 #include "winnls.h"
40 #include "winerror.h"
41 #include "winnt.h"
42
43 #include "wtypes.h"
44 #include "oleauto.h"
45
46 static HMODULE hOleaut32;
47
48 static HRESULT (WINAPI *pVarBstrFromI1)(CHAR,LCID,ULONG,BSTR*)=NULL;
49
50 static HRESULT (WINAPI *pVarI1FromBool)(VARIANT_BOOL,CHAR*)=NULL;
51 static HRESULT (WINAPI *pVarI1FromDate)(DATE,CHAR*)=NULL;
52 static HRESULT (WINAPI *pVarI1FromI4)(LONG,CHAR*)=NULL;
53 static HRESULT (WINAPI *pVarI1FromR8)(double,CHAR*)=NULL;
54 static HRESULT (WINAPI *pVarI1FromStr)(OLECHAR*,LCID,ULONG,CHAR*);
55 static HRESULT (WINAPI *pVarI1FromUI1)(BYTE,CHAR*)=NULL;
56
57 static HRESULT (WINAPI *pVarI2FromUI2)(USHORT,short*)=NULL;
58
59 static HRESULT (WINAPI *pVarUI2FromBool)(VARIANT_BOOL,USHORT*)=NULL;
60 static HRESULT (WINAPI *pVarUI2FromDate)(DATE,USHORT*)=NULL;
61 static HRESULT (WINAPI *pVarUI2FromI2)(short,USHORT*)=NULL;
62 static HRESULT (WINAPI *pVarUI2FromI4)(LONG,USHORT*);
63 static HRESULT (WINAPI *pVarUI2FromR8)(double,USHORT*)=NULL;
64 static HRESULT (WINAPI *pVarUI2FromStr)(OLECHAR*,LCID,ULONG,USHORT*)=NULL;
65
66 static HRESULT (WINAPI *pVarUI4FromBool)(VARIANT_BOOL,ULONG*)=NULL;
67 static HRESULT (WINAPI *pVarUI4FromDate)(DATE,ULONG*)=NULL;
68 static HRESULT (WINAPI *pVarUI4FromI2)(short,ULONG*)=NULL;
69 static HRESULT (WINAPI *pVarUI4FromR8)(double,ULONG*)=NULL;
70 static HRESULT (WINAPI *pVarUI4FromStr)(OLECHAR*,LCID,ULONG,ULONG*)=NULL;
71
72 static HRESULT (WINAPI *pVarUdateFromDate)(DATE,ULONG,UDATE*);
73 static HRESULT (WINAPI *pVarDateFromUdate)(UDATE*,ULONG,DATE*);
74 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
75 static INT (WINAPI *pVariantTimeToSystemTime)(double,LPSYSTEMTIME);
76 static INT (WINAPI *pDosDateTimeToVariantTime)(USHORT,USHORT,double*);
77 static INT (WINAPI *pVariantTimeToDosDateTime)(double,USHORT*,USHORT *);
78 static HRESULT (WINAPI *pVarFormatNumber)(LPVARIANT,int,int,int,int,ULONG,BSTR*);
79 static HRESULT (WINAPI *pVarFormat)(LPVARIANT,LPOLESTR,int,int,ULONG,BSTR*);
80
81 /* Get a conversion function ptr, return if function not available */
82 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
83   if (!p##func) { trace("function " # func " not available, not testing it\n"); return; }
84
85   /* Is a given function exported from oleaut32? */
86 #define HAVE_FUNC(func) ((void*)GetProcAddress(hOleaut32, #func) != NULL)
87
88 /* Have IRecordInfo data type? */
89 #define HAVE_OLEAUT32_RECORD  HAVE_FUNC(SafeArraySetRecordInfo)
90 /* Have CY data type? */
91 #define HAVE_OLEAUT32_CY      HAVE_FUNC(VarCyAdd)
92 /* Have I8/UI8 data type? */
93 #define HAVE_OLEAUT32_I8      HAVE_FUNC(VarI8FromI1)
94
95 /* When comparing floating point values we cannot expect an exact match
96  * because the rounding errors depend on the exact algorithm.
97  */
98 #define EQ_DOUBLE(a,b)     (fabs((a)-(b))<1e-14)
99
100 #define MAX_BUFFER  1024
101
102 static char* WtoA( OLECHAR* p )
103 {
104     static char buffer[MAX_BUFFER];
105     DWORD len = WideCharToMultiByte( CP_ACP, 0, p, -1, buffer+1, sizeof(buffer)-3, NULL, NULL );
106     buffer[0] = '\"';
107     buffer[len] = '\"';
108     buffer[len+1] = 0;
109     return buffer;
110 }
111
112 static OLECHAR* AtoW( const char* p )
113 {
114     OLECHAR *buffer;
115     DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
116     buffer = malloc( len * sizeof(OLECHAR) );
117     MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
118     return buffer;
119 }
120
121 static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
122 {
123     while (*str1 && (*str1 == *str2)) { str1++; str2++; }
124     return *str1 - *str2;
125 }
126
127 static const struct _vartypes {
128     int ind;
129     HRESULT vcind1,vcind2,vcex1,vcex2;
130     int todoind1,todoind2,todowcex1,todowcex2;
131 } vartypes[] = {
132     {0, 0,          0x80070057, 0,          0x80020008,0,1 },
133     {1, 0,          0x80070057, 0,          0x80020008,0,1 },
134     {2, 0,          0,          0,          0x80020005 },
135     {3, 0,          0,          0,          0x80020005 },
136     {4, 0,          0,          0,          0x80020005 },
137     {5, 0,          0,          0,          0x80020005 },
138     {6, 0,          0,          0,          0x80020005 },
139     {7, 0,          0,          0,          0x80020005 },
140     {77,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
141     {78,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
142     {79,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
143     {80,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
144     {81,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
145     {82,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
146     {83,0x80020008, 0x80070057, 0,          0x80020005,0,1,1 },
147     {84,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
148     {85,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
149     {86,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
150     {87,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
151     {88,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
152     {89,0x80020008, 0x80070057, 0,          0x80020005,0,1,1 },
153     {90,0x80020008, 0x80070057, 0,          0x80020005,0,1,1 },
154     {91,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
155     {92,0x80020008, 0x80070057, 0,          0x80020005,0,1 },
156     {93,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
157     {94,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
158     {95,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
159     {96,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
160     {97,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
161     {98,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
162     {99,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
163 };
164
165 static const char *strfromr8[] = {
166 "1",
167 "-1",
168 "21",
169 "-21",
170 "321",
171 "-321",
172 "4321",
173 "-4321",
174 "54321",
175 "-54321",
176 "654321",
177 "-654321",
178 "7654321",
179 "-7654321",
180 "87654321",
181 "-87654321",
182 "987654321",
183 "-987654321",
184 "1987654321",
185 "-1987654321",
186 "21987654321",
187 "-21987654321",
188 "321987654321",
189 "-321987654321",
190 "4321987654321",
191 "-4321987654321",
192 "54321987654321",
193 "-54321987654321",
194 "654321987654321",
195 "-654321987654321",
196 "7.65432198765432E+15",
197 "-7.65432198765432E+15",
198 "8.76543219876543E+16",
199 "-8.76543219876543E+16",
200 "9.87654321987654E+17",
201 "-9.87654321987654E+17",
202 "1.98765432198765E+18",
203 "-1.98765432198765E+18",
204 "2.19876543219877E+19",
205 "-2.19876543219877E+19",
206 "1",
207 "0",
208 "-1",
209 "1.2",
210 "0.2",
211 "-1.2",
212 "1.23",
213 "0.23",
214 "-1.23",
215 "1.234",
216 "0.234",
217 "-1.234",
218 "1.2345",
219 "0.2345",
220 "-1.2345",
221 "1.23456",
222 "0.23456",
223 "-1.23456",
224 "1.234567",
225 "0.234567",
226 "-1.234567",
227 "1.2345678",
228 "0.2345678",
229 "-1.2345678",
230 "1.23456789",
231 "0.23456789",
232 "-1.23456789",
233 "1.234567891",
234 "0.234567891",
235 "-1.234567891",
236 "1.2345678912",
237 "0.2345678912",
238 "-1.2345678912",
239 "1.23456789123",
240 "0.23456789123",
241 "-1.23456789123",
242 "1.234567891234",
243 "0.234567891234",
244 "-1.234567891234",
245 "1.2345678912345",
246 "0.2345678912345",
247 "-1.2345678912345",
248 "1.23456789123456",
249 "0.23456789123456",
250 "-1.23456789123456",
251 "1.23456789123457",
252 "0.234567891234567",
253 "-1.23456789123457",
254 "1.23456789123457",
255 "0.234567891234568",
256 "-1.23456789123457",
257 "1.23456789123457",
258 "0.234567891234568",
259 "-1.23456789123457",
260 "1.23456789123457",
261 "0.234567891234568",
262 "-1.23456789123457",
263 "1.23456789123457",
264 "0.234567891234568",
265 "-1.23456789123457",
266 "2",
267 "-2",
268 "22.2",
269 "-22.2",
270 "322.23",
271 "-322.23",
272 "4322.234",
273 "-4322.234",
274 "54322.2345",
275 "-54322.2345",
276 "654322.23456",
277 "-654322.23456",
278 "7654322.234567",
279 "-7654322.234567",
280 "87654322.2345678",
281 "-87654322.2345678",
282 "987654322.234568",
283 "-987654322.234568",
284 "1987654322.23457",
285 "-1987654322.23457",
286 "21987654322.2346",
287 "-21987654322.2346",
288 "321987654322.235",
289 "-321987654322.235",
290 "4321987654322.23",
291 "-4321987654322.23",
292 "54321987654322.2",
293 "-54321987654322.2",
294 "654321987654322",
295 "-654321987654322",
296 "7.65432198765432E+15",
297 "-7.65432198765432E+15",
298 "8.76543219876543E+16",
299 "-8.76543219876543E+16",
300 "9.87654321987654E+17",
301 "-9.87654321987654E+17",
302 "1.98765432198765E+18",
303 "-1.98765432198765E+18",
304 "2.19876543219877E+19",
305 "-2.19876543219877E+19",
306 /* r4 tests */
307 "1",
308 "-1",
309 "21",
310 "-21",
311 "321",
312 "-321",
313 "4321",
314 "-4321",
315 "54321",
316 "-54321",
317 "654321",
318 "-654321",
319 "7654321",
320 "-7654321",
321 "8.765432E+07",
322 "-8.765432E+07",
323 "9.876543E+08",
324 "-9.876543E+08",
325 "1.987654E+09",
326 "-1.987654E+09",
327 "1",
328 "0",
329 "-1",
330 "1.2",
331 "0.2",
332 "-1.2",
333 "1.23",
334 "0.23",
335 "-1.23",
336 "1.234",
337 "0.234",
338 "-1.234",
339 "1.2345",
340 "0.2345",
341 "-1.2345",
342 "1.23456",
343 "0.23456",
344 "-1.23456",
345 "1.234567",
346 "0.234567",
347 "-1.234567",
348 "1.234568",
349 "0.2345678",
350 "-1.234568",
351 "1.234568",
352 "0.2345679",
353 "-1.234568",
354 "1.234568",
355 "0.2345679",
356 "-1.234568",
357 "2",
358 "-2",
359 "22.2",
360 "-22.2",
361 "322.23",
362 "-322.23",
363 "4322.234",
364 "-4322.234",
365 "54322.23",
366 "-54322.23",
367 "654322.3",
368 "-654322.3",
369 "7654322",
370 "-7654322",
371 "8.765432E+07",
372 "-8.765432E+07",
373 "9.876543E+08",
374 "-9.876543E+08",
375 "1.987654E+09",
376 "-1.987654E+09",
377 };
378
379 /* These are the strings we use for the XxxFromStr tests.
380  * The arrays that follow define the expected results for each type.
381  */
382 static const char* _pTestStrA[] = {
383     "-2",
384     "-1",
385     "-0.51",
386     "-0.5",
387     "-0.49",
388     "-0.0",
389     "0.0",
390     "0.49",
391     "0.5",
392     "0.51",
393     "1",
394     "127",
395     "128",
396     "129",
397     "255",
398     "256",
399     "257",
400     "32767",
401     "32768",
402     "-32768",
403     "-32769",
404     "16777216",
405     "16777217",
406     "-16777216",
407     "16777217",
408     "2147483647",
409     "2147483648",
410     "-2147483647",
411     "-2147483648",
412
413     "",
414     " ",
415     "1F",
416     "1G",
417     " 1 ",
418     " 1 2 ",
419     "1,2,3",
420     "1 2 3",
421     "1,2, 3",
422     "1;2;3",
423     "1.2.3",
424
425     "0.",
426     ".0",
427     "0.1E12",
428     "2.4,E1",
429     "   +3.2,E1",
430     "4E2.5",
431     "   2E+2",
432     "1 E+2",
433     ".",
434     ".E2",
435     "1000000000000000000000000000000000000000000000000000000000000000",
436     "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
437     "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
438     "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
439     "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
440     "65535",
441     "65535.5",
442     "65536",
443     "4294967295",
444     "4294967296",
445
446     "1 January 99",
447     "December 31, 2078",
448     "January 1, 1900",
449     "January 2 1900",
450     "11.11.1999",
451     "11/11/1999",
452     " 11 / 11 / 1999",
453     "11/11/1999:11:11:1134",
454     "11/11/1999 11:11:11:1",
455     "\t1999/\t11/21 11 :11:11am",
456
457     "11/11/1999 11:11:11Am",
458     "11/11/1999 11:11:11PM",
459     "11/11/199911:11:11PM",
460     "11/11/1999 0:0:11am",
461     "11/11/1999 11,11:11am",
462     "11/11/1999 11:11:11am",
463     "11/11/1999 11/11:11am",
464     "11/11/1999 11:11AM",
465     "11/11/1999 1AM",
466     "11/11/1999 0AM",
467
468     "11/11/1999 11:11:11",
469     "11/13/1999 0AM",
470     "13/13/1999 0AM",
471     "13/11/1999 0AM",
472     "11/33/1999 0AM",
473     "11/11/1999 AM",
474     "1/1/0 0AM",
475     "1/1/-1 0AM",
476     "1999 January 3 9AM",
477     "1 January 1999 11AM",
478
479     "4AM 11/11/1999",
480     "4:22 11/11/1999 AM",
481     " 1 1 /11/1999",
482     "11-11/1999 11:11:11.12AM",
483     "1999 January 3, 9AM",
484     "December, 31, 2078",
485     "December, 31, 2078,",
486     "December, 31 2078",
487     "11/99",
488     "11-1999",
489
490     "true",
491     "True",
492     "TRue",
493     "TRUE",
494     " TRUE",
495     "FALSE ",
496     "False",
497     "JustSomeText",
498     "Just Some Text",
499
500     "1.5",
501     "2.5",
502     "3.5",
503     "4.5",
504 };
505 #define NB_OLE_STRINGS (sizeof(_pTestStrA)/sizeof(*_pTestStrA))
506
507 static const struct _strret_date {
508     HRESULT error;
509     DATE retval;
510     BOOL todo_rc;
511     BOOL todo_val;
512 } strrets_DATE[NB_OLE_STRINGS] = {
513     { 0x80020005 },
514     { 0x80020005 },
515     { 0x80020005 },
516     { 0x80020005 },
517     { 0x80020005 },
518     { 0x80020005 },
519     { 0,           0.0, 1 },
520     { 0,           0.03402777777777, 1 },
521     { 0,           0.00347222222222, 1 },
522     { 0,           0.03541666666666, 1 },
523     { 0x80020005 },
524     { 0x80020005 },
525     { 0x80020005 },
526     { 0x80020005 },
527     { 0x80020005 },
528     { 0x80020005 },
529     { 0x80020005 },
530     { 0x80020005 },
531     { 0x80020005 },
532     { 0x80020005 },
533     { 0x80020005 },
534     { 0x80020005,  0.0, 1 },
535     { 0x80020005,  0.0, 1 },
536     { 0x80020005 },
537     { 0x80020005,  0.0, 1 },
538     { 0x80020005 },
539     { 0x80020005 },
540     { 0x80020005 },
541     { 0x80020005 },
542     { 0x80020005 },
543     { 0x80020005 },
544     { 0x80020005 },
545     { 0x80020005 },
546     { 0x80020005 },
547     { 0,           37623.0, 1 },
548     { 0,           37623.0 },
549     { 0,           37623.0 },
550     { 0,           37623.0 },
551     { 0x80020005,  0.0, 1 },
552     { 0,           0.04309027777777, 0, 1 },
553     { 0x80020005 },
554     { 0x80020005 },
555     { 0x80020005,  0.0, 1 },
556     { 0x80020005,  0.0, 1 },
557     { 0x80020005 },
558     { 0x80020005,  0.0, 1 },
559     { 0x80020005 },
560     { 0x80020005 },
561     { 0x80020005 },
562     { 0x80020005 },
563     { 0x80020005 },
564     { 0x80020005 },
565     { 0x80020005 },
566     { 0x80020005 },
567     { 0x80020005 },
568     { 0x80020005 },
569     { 0x80020005 },
570     { 0x80020005 },
571     { 0x80020005 },
572     { 0x80020005 },
573     { 0,           36161.0, 1 },
574     { 0,           65380.0 },
575     { 0,           2.0},
576     { 0,           3.0 },
577     { 0x80020005,  0.0, 1 },
578     { 0,           36475.0 },
579     { 0,           36475.0 },
580     { 0x80020005 },
581     { 0x80020005 },
582     { 0,           36485.466099537036, 1 },
583     { 0,           36475.466099537036 },
584     { 0,           36475.966099537036 },
585     { 0x80020005,  0.0, 1 },
586     { 0,           36475.000127314815 },
587     { 0x80020005 },
588     { 0,           36475.466099537036 },
589     { 0x80020005 },
590     { 0,           36475.465972222222 },
591     { 0,           36475.041666666664, 1 },
592     { 0,           36475.0, 1 },
593     { 0,           36475.466099537036 },
594     { 0,           36477.0, 1 },
595     { 0x80020005 },
596     { 0,           36477.0, 1 },
597     { 0x80020005 },
598     { 0x80020005,  0.0, 1 },
599     { 0,           36526.0, 1 },
600     { 0x80020005 },
601     { 0,           36163.375000000000, 1 },
602     { 0,           36161.458333333336, 1 },
603     { 0,           36475.166666666664, 1 },
604     { 0x80020005,  0.0, 1 },
605     { 0x80020005 },
606     { 0x80020005,  0.0, 1 },
607     { 0x80020005 },
608     { 0,           65380.0 },
609     { 0x80020005,  0.0, 1 },
610     { 0,           65380.0 },
611     { 0,           36465.0, 1 },
612     { 0,           36465.0, 1 },
613     { 0x80020005 },
614     { 0x80020005 },
615     { 0x80020005 },
616     { 0x80020005 },
617     { 0x80020005 },
618     { 0x80020005 },
619     { 0x80020005 },
620     { 0x80020005 },
621     { 0x80020005 },
622     { 0,           0.045138888888889, 1 },
623     { 0,           0.086805555555556, 1 },
624     { 0,           0.128472222222222, 1 },
625     { 0,           0.170138888888889, 1 },
626 };
627 static const struct _strret_b {
628     HRESULT error;
629     BOOL retval;
630 } strrets_B[NB_OLE_STRINGS] = {
631     { 0,           VARIANT_TRUE },
632     { 0,           VARIANT_TRUE },
633     { 0,           VARIANT_TRUE },
634     { 0,           VARIANT_TRUE },
635     { 0,           VARIANT_TRUE },
636     { 0,           VARIANT_FALSE },
637     { 0,           VARIANT_FALSE },
638     { 0,           VARIANT_TRUE },
639     { 0,           VARIANT_TRUE },
640     { 0,           VARIANT_TRUE },
641     { 0,           VARIANT_TRUE },
642     { 0,           VARIANT_TRUE },
643     { 0,           VARIANT_TRUE },
644     { 0,           VARIANT_TRUE },
645     { 0,           VARIANT_TRUE },
646     { 0,           VARIANT_TRUE },
647     { 0,           VARIANT_TRUE },
648     { 0,           VARIANT_TRUE },
649     { 0,           VARIANT_TRUE },
650     { 0,           VARIANT_TRUE },
651     { 0,           VARIANT_TRUE },
652     { 0,           VARIANT_TRUE },
653     { 0,           VARIANT_TRUE },
654     { 0,           VARIANT_TRUE },
655     { 0,           VARIANT_TRUE },
656     { 0,           VARIANT_TRUE },
657     { 0,           VARIANT_TRUE },
658     { 0,           VARIANT_TRUE },
659     { 0,           VARIANT_TRUE },
660     { 0x80020005 },
661     { 0x80020005 },
662     { 0x80020005 },
663     { 0x80020005 },
664     { 0,           VARIANT_TRUE },
665     { 0x80020005 },
666     { 0,           VARIANT_TRUE },
667     { 0x80020005 },
668     { 0x80020005 },
669     { 0x80020005 },
670     { 0x80020005 },
671     { 0,           VARIANT_FALSE },
672     { 0,           VARIANT_FALSE },
673     { 0,           VARIANT_TRUE },
674     { 0,           VARIANT_TRUE },
675     { 0,           VARIANT_TRUE },
676     { 0x80020005 },
677     { 0,           VARIANT_TRUE },
678     { 0x80020005 },
679     { 0x80020005 },
680     { 0x80020005 },
681     { 0,           VARIANT_TRUE },
682     { 0,           VARIANT_TRUE },
683     { 0,           VARIANT_TRUE },
684     { 0,           VARIANT_TRUE },
685     { 0,           VARIANT_TRUE },
686     { 0,           VARIANT_TRUE },
687     { 0,           VARIANT_TRUE },
688     { 0,           VARIANT_TRUE },
689     { 0,           VARIANT_TRUE },
690     { 0,           VARIANT_TRUE },
691     { 0x80020005 },
692     { 0x80020005 },
693     { 0x80020005 },
694     { 0x80020005 },
695     { 0x80020005 },
696     { 0x80020005 },
697     { 0x80020005 },
698     { 0x80020005 },
699     { 0x80020005 },
700     { 0x80020005 },
701     { 0x80020005 },
702     { 0x80020005 },
703     { 0x80020005 },
704     { 0x80020005 },
705     { 0x80020005 },
706     { 0x80020005 },
707     { 0x80020005 },
708     { 0x80020005 },
709     { 0x80020005 },
710     { 0x80020005 },
711     { 0x80020005 },
712     { 0x80020005 },
713     { 0x80020005 },
714     { 0x80020005 },
715     { 0x80020005 },
716     { 0x80020005 },
717     { 0x80020005 },
718     { 0x80020005 },
719     { 0x80020005 },
720     { 0x80020005 },
721     { 0x80020005 },
722     { 0x80020005 },
723     { 0x80020005 },
724     { 0x80020005 },
725     { 0x80020005 },
726     { 0x80020005 },
727     { 0x80020005 },
728     { 0x80020005 },
729     { 0x80020005 },
730     { 0x80020005 },
731     { 0,           VARIANT_TRUE },
732     { 0,           VARIANT_TRUE },
733     { 0,           VARIANT_TRUE },
734     { 0,           VARIANT_TRUE },
735     { 0x80020005 },
736     { 0x80020005 },
737     { 0,           VARIANT_FALSE },
738     { 0x80020005 },
739     { 0x80020005 },
740     { 0,           VARIANT_TRUE },
741     { 0,           VARIANT_TRUE },
742     { 0,           VARIANT_TRUE },
743     { 0,           VARIANT_TRUE },
744 };
745 static const struct _strret_r8 {
746     HRESULT error;
747     DOUBLE retval;
748 } strrets_R8[NB_OLE_STRINGS] = {
749     { 0,           -2.000000 },
750     { 0,           -1.000000 },
751     { 0,           -0.510000 },
752     { 0,           -0.500000 },
753     { 0,           -0.490000 },
754     { 0,           0.000000 },
755     { 0,           0.000000 },
756     { 0,           0.490000 },
757     { 0,           0.500000 },
758     { 0,           0.510000 },
759     { 0,           1.000000 },
760     { 0,           127.000000 },
761     { 0,           128.000000 },
762     { 0,           129.000000 },
763     { 0,           255.000000 },
764     { 0,           256.000000 },
765     { 0,           257.000000 },
766     { 0,           32767.000000 },
767     { 0,           32768.000000 },
768     { 0,           -32768.000000 },
769     { 0,           -32769.000000 },
770     { 0,           16777216.000000 },
771     { 0,           16777217.000000 },
772     { 0,           -16777216.000000 },
773     { 0,           16777217.000000 },
774     { 0,           2147483647.000000 },
775     { 0,           2147483648.000000 },
776     { 0,           -2147483647.000000 },
777     { 0,           -2147483648.000000 },
778     { 0x80020005 },
779     { 0x80020005 },
780     { 0x80020005 },
781     { 0x80020005 },
782     { 0,           1.000000 },
783     { 0x80020005 },
784     { 0,           123.000000 },
785     { 0x80020005 },
786     { 0x80020005 },
787     { 0x80020005 },
788     { 0x80020005 },
789     { 0,           0.000000 },
790     { 0,           0.000000 },
791     { 0,           100000000000.000000 },
792     { 0,           24.000000 },
793     { 0,           32.000000 },
794     { 0x80020005 },
795     { 0,           200.000000 },
796     { 0x80020005 },
797     { 0x80020005 },
798     { 0x80020005 },
799     { 0,           1e63 },
800     { 0,           1.000000 },
801     { 0,           1.000000 },
802     { 0,           99999999999999997e183 },
803     { 0,           1.000000 },
804     { 0,           65535.000000 },
805     { 0,           65535.500000 },
806     { 0,           65536.000000 },
807     { 0,           4294967295.000000 },
808     { 0,           4294967296.000000 },
809     { 0x80020005 },
810     { 0x80020005 },
811     { 0x80020005 },
812     { 0x80020005 },
813     { 0x80020005 },
814     { 0x80020005 },
815     { 0x80020005 },
816     { 0x80020005 },
817     { 0x80020005 },
818     { 0x80020005 },
819     { 0x80020005 },
820     { 0x80020005 },
821     { 0x80020005 },
822     { 0x80020005 },
823     { 0x80020005 },
824     { 0x80020005 },
825     { 0x80020005 },
826     { 0x80020005 },
827     { 0x80020005 },
828     { 0x80020005 },
829     { 0x80020005 },
830     { 0x80020005 },
831     { 0x80020005 },
832     { 0x80020005 },
833     { 0x80020005 },
834     { 0x80020005 },
835     { 0x80020005 },
836     { 0x80020005 },
837     { 0x80020005 },
838     { 0x80020005 },
839     { 0x80020005 },
840     { 0x80020005 },
841     { 0x80020005 },
842     { 0x80020005 },
843     { 0x80020005 },
844     { 0x80020005 },
845     { 0x80020005 },
846     { 0x80020005 },
847     { 0x80020005 },
848     { 0x80020005 },
849     { 0x80020005 },
850     { 0x80020005 },
851     { 0x80020005 },
852     { 0x80020005 },
853     { 0x80020005 },
854     { 0x80020005 },
855     { 0x80020005 },
856     { 0x80020005 },
857     { 0x80020005 },
858     { 0,           1.500000 },
859     { 0,           2.500000 },
860     { 0,           3.500000 },
861     { 0,           4.500000 },
862 };
863 static const struct _strret_r4 {
864     HRESULT error;
865     FLOAT retval;
866 } strrets_R4[NB_OLE_STRINGS] = {
867     { 0,           -2.000000F },
868     { 0,           -1.000000F },
869     { 0,           -0.510000F },
870     { 0,           -0.500000F },
871     { 0,           -0.490000F },
872     { 0,           0.000000F },
873     { 0,           0.000000F },
874     { 0,           0.490000F },
875     { 0,           0.500000F },
876     { 0,           0.510000F },
877     { 0,           1.000000F },
878     { 0,           127.000000F },
879     { 0,           128.000000F },
880     { 0,           129.000000F },
881     { 0,           255.000000F },
882     { 0,           256.000000F },
883     { 0,           257.000000F },
884     { 0,           32767.000000F },
885     { 0,           32768.000000F },
886     { 0,           -32768.000000F },
887     { 0,           -32769.000000F },
888     { 0,           16777216.000000F },
889     { 0,           16777216.000000F },
890     { 0,           -16777216.000000F },
891     { 0,           16777216.000000F },
892     { 0,           2147483648.000000F },
893     { 0,           2147483648.000000F },
894     { 0,           -2147483648.000000F },
895     { 0,           -2147483648.000000F },
896     { 0x80020005 },
897     { 0x80020005 },
898     { 0x80020005 },
899     { 0x80020005 },
900     { 0,           1.000000F },
901     { 0x80020005 },
902     { 0,           123.000000F },
903     { 0x80020005 },
904     { 0x80020005 },
905     { 0x80020005 },
906     { 0x80020005 },
907     { 0,           0.000000F },
908     { 0,           0.000000F },
909     { 0,           99999997952.000000F },
910     { 0,           24.000000F },
911     { 0,           32.000000F },
912     { 0x80020005 },
913     { 0,           200.000000F },
914     { 0x80020005 },
915     { 0x80020005 },
916     { 0x80020005 },
917     { 0x8002000A },
918     { 0,           1.000000F },
919     { 0,           1.000000F },
920     { 0x8002000A },
921     { 0,           1.000000F },
922     { 0,           65535.000000F },
923     { 0,           65535.500000F },
924     { 0,           65536.000000F },
925     { 0,           4294967296.000000F },
926     { 0,           4294967296.000000F },
927     { 0x80020005 },
928     { 0x80020005 },
929     { 0x80020005 },
930     { 0x80020005 },
931     { 0x80020005 },
932     { 0x80020005 },
933     { 0x80020005 },
934     { 0x80020005 },
935     { 0x80020005 },
936     { 0x80020005 },
937     { 0x80020005 },
938     { 0x80020005 },
939     { 0x80020005 },
940     { 0x80020005 },
941     { 0x80020005 },
942     { 0x80020005 },
943     { 0x80020005 },
944     { 0x80020005 },
945     { 0x80020005 },
946     { 0x80020005 },
947     { 0x80020005 },
948     { 0x80020005 },
949     { 0x80020005 },
950     { 0x80020005 },
951     { 0x80020005 },
952     { 0x80020005 },
953     { 0x80020005 },
954     { 0x80020005 },
955     { 0x80020005 },
956     { 0x80020005 },
957     { 0x80020005 },
958     { 0x80020005 },
959     { 0x80020005 },
960     { 0x80020005 },
961     { 0x80020005 },
962     { 0x80020005 },
963     { 0x80020005 },
964     { 0x80020005 },
965     { 0x80020005 },
966     { 0x80020005 },
967     { 0x80020005 },
968     { 0x80020005 },
969     { 0x80020005 },
970     { 0x80020005 },
971     { 0x80020005 },
972     { 0x80020005 },
973     { 0x80020005 },
974     { 0x80020005 },
975     { 0x80020005 },
976     { 0,           1.500000F },
977     { 0,           2.500000F },
978     { 0,           3.500000F },
979     { 0,           4.500000F },
980 };
981 static const struct _strret_i4 {
982     HRESULT error;
983     LONG retval;
984 } strrets_I4[NB_OLE_STRINGS] = {
985     { 0,           -2L },
986     { 0,           -1L },
987     { 0,           -1L },
988     { 0,           0L },
989     { 0,           0L },
990     { 0,           0L },
991     { 0,           0L },
992     { 0,           0L },
993     { 0,           0L },
994     { 0,           1L },
995     { 0,           1L },
996     { 0,           127L },
997     { 0,           128L },
998     { 0,           129L },
999     { 0,           255L },
1000     { 0,           256L },
1001     { 0,           257L },
1002     { 0,           32767L },
1003     { 0,           32768L },
1004     { 0,           -32768L },
1005     { 0,           -32769L },
1006     { 0,           16777216L },
1007     { 0,           16777217L },
1008     { 0,           -16777216L },
1009     { 0,           16777217L },
1010     { 0,           2147483647L },
1011     { 0x8002000A },
1012     { 0,           -2147483647L },
1013     { 0,           0x80000000L },
1014     { 0x80020005 },
1015     { 0x80020005 },
1016     { 0x80020005 },
1017     { 0x80020005 },
1018     { 0,           1L },
1019     { 0x80020005 },
1020     { 0,           123L },
1021     { 0x80020005 },
1022     { 0x80020005 },
1023     { 0x80020005 },
1024     { 0x80020005 },
1025     { 0,           0L },
1026     { 0,           0L },
1027     { 0x8002000A },
1028     { 0,           24L },
1029     { 0,           32L },
1030     { 0x80020005 },
1031     { 0,           200L },
1032     { 0x80020005 },
1033     { 0x80020005 },
1034     { 0x80020005 },
1035     { 0x8002000A },
1036     { 0,           1L },
1037     { 0,           1L },
1038     { 0x8002000A },
1039     { 0,           1L },
1040     { 0,           65535L },
1041     { 0,           65536L },
1042     { 0,           65536L },
1043     { 0x8002000A },
1044     { 0x8002000A },
1045     { 0x80020005 },
1046     { 0x80020005 },
1047     { 0x80020005 },
1048     { 0x80020005 },
1049     { 0x80020005 },
1050     { 0x80020005 },
1051     { 0x80020005 },
1052     { 0x80020005 },
1053     { 0x80020005 },
1054     { 0x80020005 },
1055     { 0x80020005 },
1056     { 0x80020005 },
1057     { 0x80020005 },
1058     { 0x80020005 },
1059     { 0x80020005 },
1060     { 0x80020005 },
1061     { 0x80020005 },
1062     { 0x80020005 },
1063     { 0x80020005 },
1064     { 0x80020005 },
1065     { 0x80020005 },
1066     { 0x80020005 },
1067     { 0x80020005 },
1068     { 0x80020005 },
1069     { 0x80020005 },
1070     { 0x80020005 },
1071     { 0x80020005 },
1072     { 0x80020005 },
1073     { 0x80020005 },
1074     { 0x80020005 },
1075     { 0x80020005 },
1076     { 0x80020005 },
1077     { 0x80020005 },
1078     { 0x80020005 },
1079     { 0x80020005 },
1080     { 0x80020005 },
1081     { 0x80020005 },
1082     { 0x80020005 },
1083     { 0x80020005 },
1084     { 0x80020005 },
1085     { 0x80020005 },
1086     { 0x80020005 },
1087     { 0x80020005 },
1088     { 0x80020005 },
1089     { 0x80020005 },
1090     { 0x80020005 },
1091     { 0x80020005 },
1092     { 0x80020005 },
1093     { 0x80020005 },
1094     { 0,           2L },
1095     { 0,           2L },
1096     { 0,           4L },
1097     { 0,           4L },
1098 };
1099 static const struct _strret_i2 {
1100     HRESULT error;
1101     SHORT retval;
1102 } strrets_I2[NB_OLE_STRINGS] = {
1103     { 0,           -2 },
1104     { 0,           -1 },
1105     { 0,           -1 },
1106     { 0,           0 },
1107     { 0,           0 },
1108     { 0,           0 },
1109     { 0,           0 },
1110     { 0,           0 },
1111     { 0,           0 },
1112     { 0,           1 },
1113     { 0,           1 },
1114     { 0,           127 },
1115     { 0,           128 },
1116     { 0,           129 },
1117     { 0,           255 },
1118     { 0,           256 },
1119     { 0,           257 },
1120     { 0,           32767 },
1121     { 0x8002000A },
1122     { 0,           -32768 },
1123     { 0x8002000A },
1124     { 0x8002000A },
1125     { 0x8002000A },
1126     { 0x8002000A },
1127     { 0x8002000A },
1128     { 0x8002000A },
1129     { 0x8002000A },
1130     { 0x8002000A },
1131     { 0x8002000A },
1132     { 0x80020005 },
1133     { 0x80020005 },
1134     { 0x80020005 },
1135     { 0x80020005 },
1136     { 0,           1 },
1137     { 0x80020005 },
1138     { 0,           123 },
1139     { 0x80020005 },
1140     { 0x80020005 },
1141     { 0x80020005 },
1142     { 0x80020005 },
1143     { 0,           0 },
1144     { 0,           0 },
1145     { 0x8002000A },
1146     { 0,           24 },
1147     { 0,           32 },
1148     { 0x80020005 },
1149     { 0,           200 },
1150     { 0x80020005 },
1151     { 0x80020005 },
1152     { 0x80020005 },
1153     { 0x8002000A },
1154     { 0,           1 },
1155     { 0,           1 },
1156     { 0x8002000A },
1157     { 0,           1 },
1158     { 0x8002000A },
1159     { 0x8002000A },
1160     { 0x8002000A },
1161     { 0x8002000A },
1162     { 0x8002000A },
1163     { 0x80020005 },
1164     { 0x80020005 },
1165     { 0x80020005 },
1166     { 0x80020005 },
1167     { 0x80020005 },
1168     { 0x80020005 },
1169     { 0x80020005 },
1170     { 0x80020005 },
1171     { 0x80020005 },
1172     { 0x80020005 },
1173     { 0x80020005 },
1174     { 0x80020005 },
1175     { 0x80020005 },
1176     { 0x80020005 },
1177     { 0x80020005 },
1178     { 0x80020005 },
1179     { 0x80020005 },
1180     { 0x80020005 },
1181     { 0x80020005 },
1182     { 0x80020005 },
1183     { 0x80020005 },
1184     { 0x80020005 },
1185     { 0x80020005 },
1186     { 0x80020005 },
1187     { 0x80020005 },
1188     { 0x80020005 },
1189     { 0x80020005 },
1190     { 0x80020005 },
1191     { 0x80020005 },
1192     { 0x80020005 },
1193     { 0x80020005 },
1194     { 0x80020005 },
1195     { 0x80020005 },
1196     { 0x80020005 },
1197     { 0x80020005 },
1198     { 0x80020005 },
1199     { 0x80020005 },
1200     { 0x80020005 },
1201     { 0x80020005 },
1202     { 0x80020005 },
1203     { 0x80020005 },
1204     { 0x80020005 },
1205     { 0x80020005 },
1206     { 0x80020005 },
1207     { 0x80020005 },
1208     { 0x80020005 },
1209     { 0x80020005 },
1210     { 0x80020005 },
1211     { 0x80020005 },
1212     { 0,           2 },
1213     { 0,           2 },
1214     { 0,           4 },
1215     { 0,           4 },
1216 };
1217 static const struct _strret_i1 {
1218     HRESULT error;
1219     CHAR retval;
1220 } strrets_I1[NB_OLE_STRINGS] = {
1221     { 0,           -2 },
1222     { 0,           -1 },
1223     { 0,           -1 },
1224     { 0,           0 },
1225     { 0,           0 },
1226     { 0,           0 },
1227     { 0,           0 },
1228     { 0,           0 },
1229     { 0,           0 },
1230     { 0,           1 },
1231     { 0,           1 },
1232     { 0,           127 },
1233     { 0x8002000A },
1234     { 0x8002000A },
1235     { 0x8002000A },
1236     { 0x8002000A },
1237     { 0x8002000A },
1238     { 0x8002000A },
1239     { 0x8002000A },
1240     { 0x8002000A },
1241     { 0x8002000A },
1242     { 0x8002000A },
1243     { 0x8002000A },
1244     { 0x8002000A },
1245     { 0x8002000A },
1246     { 0x8002000A },
1247     { 0x8002000A },
1248     { 0x8002000A },
1249     { 0x8002000A },
1250     { 0x80020005 },
1251     { 0x80020005 },
1252     { 0x80020005 },
1253     { 0x80020005 },
1254     { 0,           1 },
1255     { 0x80020005 },
1256     { 0,           123 },
1257     { 0x80020005 },
1258     { 0x80020005 },
1259     { 0x80020005 },
1260     { 0x80020005 },
1261     { 0,           0 },
1262     { 0,           0 },
1263     { 0x8002000A },
1264     { 0,           24 },
1265     { 0,           32 },
1266     { 0x80020005 },
1267     { 0x8002000A },
1268     { 0x80020005 },
1269     { 0x80020005 },
1270     { 0x80020005 },
1271     { 0x8002000A },
1272     { 0,           1 },
1273     { 0,           1 },
1274     { 0x8002000A },
1275     { 0,           1 },
1276     { 0x8002000A },
1277     { 0x8002000A },
1278     { 0x8002000A },
1279     { 0x8002000A },
1280     { 0x8002000A },
1281     { 0x80020005 },
1282     { 0x80020005 },
1283     { 0x80020005 },
1284     { 0x80020005 },
1285     { 0x80020005 },
1286     { 0x80020005 },
1287     { 0x80020005 },
1288     { 0x80020005 },
1289     { 0x80020005 },
1290     { 0x80020005 },
1291     { 0x80020005 },
1292     { 0x80020005 },
1293     { 0x80020005 },
1294     { 0x80020005 },
1295     { 0x80020005 },
1296     { 0x80020005 },
1297     { 0x80020005 },
1298     { 0x80020005 },
1299     { 0x80020005 },
1300     { 0x80020005 },
1301     { 0x80020005 },
1302     { 0x80020005 },
1303     { 0x80020005 },
1304     { 0x80020005 },
1305     { 0x80020005 },
1306     { 0x80020005 },
1307     { 0x80020005 },
1308     { 0x80020005 },
1309     { 0x80020005 },
1310     { 0x80020005 },
1311     { 0x80020005 },
1312     { 0x80020005 },
1313     { 0x80020005 },
1314     { 0x80020005 },
1315     { 0x80020005 },
1316     { 0x80020005 },
1317     { 0x80020005 },
1318     { 0x80020005 },
1319     { 0x80020005 },
1320     { 0x80020005 },
1321     { 0x80020005 },
1322     { 0x80020005 },
1323     { 0x80020005 },
1324     { 0x80020005 },
1325     { 0x80020005 },
1326     { 0x80020005 },
1327     { 0x80020005 },
1328     { 0x80020005 },
1329     { 0x80020005 },
1330     { 0,           2 },
1331     { 0,           2 },
1332     { 0,           4 },
1333     { 0,           4 },
1334 };
1335 static const struct _strret_u1 {
1336     HRESULT error;
1337     BYTE retval;
1338 } strrets_U1[NB_OLE_STRINGS] = {
1339     { 0x8002000A },
1340     { 0x8002000A },
1341     { 0x8002000A },
1342     { 0,           0 },
1343     { 0,           0 },
1344     { 0,           0 },
1345     { 0,           0 },
1346     { 0,           0 },
1347     { 0,           0 },
1348     { 0,           1 },
1349     { 0,           1 },
1350     { 0,           0x7F },
1351     { 0,           0x80 },
1352     { 0,           0x81 },
1353     { 0,           0xFF },
1354     { 0x8002000A },
1355     { 0x8002000A },
1356     { 0x8002000A },
1357     { 0x8002000A },
1358     { 0x8002000A },
1359     { 0x8002000A },
1360     { 0x8002000A },
1361     { 0x8002000A },
1362     { 0x8002000A },
1363     { 0x8002000A },
1364     { 0x8002000A },
1365     { 0x8002000A },
1366     { 0x8002000A },
1367     { 0x8002000A },
1368     { 0x80020005 },
1369     { 0x80020005 },
1370     { 0x80020005 },
1371     { 0x80020005 },
1372     { 0,           1 },
1373     { 0x80020005 },
1374     { 0,           0x7B },
1375     { 0x80020005 },
1376     { 0x80020005 },
1377     { 0x80020005 },
1378     { 0x80020005 },
1379     { 0,           0 },
1380     { 0,           0 },
1381     { 0x8002000A },
1382     { 0,           0x18 },
1383     { 0,           0x20 },
1384     { 0x80020005 },
1385     { 0,           0xC8 },
1386     { 0x80020005 },
1387     { 0x80020005 },
1388     { 0x80020005 },
1389     { 0x8002000A },
1390     { 0,           1 },
1391     { 0,           1 },
1392     { 0x8002000A },
1393     { 0,           1 },
1394     { 0x8002000A },
1395     { 0x8002000A },
1396     { 0x8002000A },
1397     { 0x8002000A },
1398     { 0x8002000A },
1399     { 0x80020005 },
1400     { 0x80020005 },
1401     { 0x80020005 },
1402     { 0x80020005 },
1403     { 0x80020005 },
1404     { 0x80020005 },
1405     { 0x80020005 },
1406     { 0x80020005 },
1407     { 0x80020005 },
1408     { 0x80020005 },
1409     { 0x80020005 },
1410     { 0x80020005 },
1411     { 0x80020005 },
1412     { 0x80020005 },
1413     { 0x80020005 },
1414     { 0x80020005 },
1415     { 0x80020005 },
1416     { 0x80020005 },
1417     { 0x80020005 },
1418     { 0x80020005 },
1419     { 0x80020005 },
1420     { 0x80020005 },
1421     { 0x80020005 },
1422     { 0x80020005 },
1423     { 0x80020005 },
1424     { 0x80020005 },
1425     { 0x80020005 },
1426     { 0x80020005 },
1427     { 0x80020005 },
1428     { 0x80020005 },
1429     { 0x80020005 },
1430     { 0x80020005 },
1431     { 0x80020005 },
1432     { 0x80020005 },
1433     { 0x80020005 },
1434     { 0x80020005 },
1435     { 0x80020005 },
1436     { 0x80020005 },
1437     { 0x80020005 },
1438     { 0x80020005 },
1439     { 0x80020005 },
1440     { 0x80020005 },
1441     { 0x80020005 },
1442     { 0x80020005 },
1443     { 0x80020005 },
1444     { 0x80020005 },
1445     { 0x80020005 },
1446     { 0x80020005 },
1447     { 0x80020005 },
1448     { 0,           2 },
1449     { 0,           2 },
1450     { 0,           4 },
1451     { 0,           4 },
1452 };
1453
1454 static const struct _strret_U2 {
1455     HRESULT error;
1456     WORD retval;
1457 } strrets_U2[NB_OLE_STRINGS] = {
1458     { 0x8002000A },
1459     { 0x8002000A },
1460     { 0x8002000A },
1461     { 0,           0 },
1462     { 0,           0 },
1463     { 0,           0 },
1464     { 0,           0 },
1465     { 0,           0 },
1466     { 0,           0 },
1467     { 0,           1 },
1468     { 0,           1 },
1469     { 0,           127 },
1470     { 0,           128 },
1471     { 0,           129 },
1472     { 0,           255 },
1473     { 0,           256 },
1474     { 0,           257 },
1475     { 0,           32767 },
1476     { 0,           32768 },
1477     { 0x8002000A },
1478     { 0x8002000A },
1479     { 0x8002000A },
1480     { 0x8002000A },
1481     { 0x8002000A },
1482     { 0x8002000A },
1483     { 0x8002000A },
1484     { 0x8002000A },
1485     { 0x8002000A },
1486     { 0x8002000A },
1487     { 0x80020005 },
1488     { 0x80020005 },
1489     { 0x80020005 },
1490     { 0x80020005 },
1491     { 0,           1 },
1492     { 0x80020005 },
1493     { 0,           123 },
1494     { 0x80020005 },
1495     { 0x80020005 },
1496     { 0x80020005 },
1497     { 0x80020005 },
1498     { 0,           0 },
1499     { 0,           0 },
1500     { 0x8002000A },
1501     { 0,           24 },
1502     { 0,           32 },
1503     { 0x80020005 },
1504     { 0,           200 },
1505     { 0x80020005 },
1506     { 0x80020005 },
1507     { 0x80020005 },
1508     { 0x8002000A },
1509     { 0,           1 },
1510     { 0,           1 },
1511     { 0x8002000A },
1512     { 0,           1 },
1513     { 0,           65535 },
1514     { 0x8002000A },
1515     { 0x8002000A },
1516     { 0x8002000A },
1517     { 0x8002000A },
1518     { 0x80020005 },
1519     { 0x80020005 },
1520     { 0x80020005 },
1521     { 0x80020005 },
1522     { 0x80020005 },
1523     { 0x80020005 },
1524     { 0x80020005 },
1525     { 0x80020005 },
1526     { 0x80020005 },
1527     { 0x80020005 },
1528     { 0x80020005 },
1529     { 0x80020005 },
1530     { 0x80020005 },
1531     { 0x80020005 },
1532     { 0x80020005 },
1533     { 0x80020005 },
1534     { 0x80020005 },
1535     { 0x80020005 },
1536     { 0x80020005 },
1537     { 0x80020005 },
1538     { 0x80020005 },
1539     { 0x80020005 },
1540     { 0x80020005 },
1541     { 0x80020005 },
1542     { 0x80020005 },
1543     { 0x80020005 },
1544     { 0x80020005 },
1545     { 0x80020005 },
1546     { 0x80020005 },
1547     { 0x80020005 },
1548     { 0x80020005 },
1549     { 0x80020005 },
1550     { 0x80020005 },
1551     { 0x80020005 },
1552     { 0x80020005 },
1553     { 0x80020005 },
1554     { 0x80020005 },
1555     { 0x80020005 },
1556     { 0x80020005 },
1557     { 0x80020005 },
1558     { 0x80020005 },
1559     { 0x80020005 },
1560     { 0x80020005 },
1561     { 0x80020005 },
1562     { 0x80020005 },
1563     { 0x80020005 },
1564     { 0x80020005 },
1565     { 0x80020005 },
1566     { 0x80020005 },
1567     { 0,           2 },
1568     { 0,           2 },
1569     { 0,           4 },
1570     { 0,           4 },
1571 };
1572
1573 static const struct _strret_U4 {
1574     HRESULT error;
1575     DWORD retval;
1576 } strrets_U4[NB_OLE_STRINGS] = {
1577     { 0x8002000A },
1578     { 0x8002000A },
1579     { 0x8002000A },
1580     { 0,           0 },
1581     { 0,           0 },
1582     { 0,           0 },
1583     { 0,           0 },
1584     { 0,           0 },
1585     { 0,           0 },
1586     { 0,           1 },
1587     { 0,           1 },
1588     { 0,           127 },
1589     { 0,           128 },
1590     { 0,           129 },
1591     { 0,           255 },
1592     { 0,           256 },
1593     { 0,           257 },
1594     { 0,           32767 },
1595     { 0,           32768 },
1596     { 0x8002000A },
1597     { 0x8002000A },
1598     { 0,           16777216 },
1599     { 0,           16777217 },
1600     { 0x8002000A },
1601     { 0,           16777217 },
1602     { 0,           2147483647 },
1603     { 0,           2147483648U },
1604     { 0x8002000A },
1605     { 0x8002000A },
1606     { 0x80020005 },
1607     { 0x80020005 },
1608     { 0x80020005 },
1609     { 0x80020005 },
1610     { 0,           1 },
1611     { 0x80020005 },
1612     { 0,           123 },
1613     { 0x80020005 },
1614     { 0x80020005 },
1615     { 0x80020005 },
1616     { 0x80020005 },
1617     { 0,           0 },
1618     { 0,           0 },
1619     { 0x8002000A },
1620     { 0,           24 },
1621     { 0,           32 },
1622     { 0x80020005 },
1623     { 0,           200 },
1624     { 0x80020005 },
1625     { 0x80020005 },
1626     { 0x80020005 },
1627     { 0x8002000A },
1628     { 0,           1 },
1629     { 0,           1 },
1630     { 0x8002000A },
1631     { 0,           1 },
1632     { 0,           65535 },
1633     { 0,           65536 },
1634     { 0,           65536 },
1635     { 0,           4294967295U },
1636     { 0x8002000A },
1637     { 0x80020005 },
1638     { 0x80020005 },
1639     { 0x80020005 },
1640     { 0x80020005 },
1641     { 0x80020005 },
1642     { 0x80020005 },
1643     { 0x80020005 },
1644     { 0x80020005 },
1645     { 0x80020005 },
1646     { 0x80020005 },
1647     { 0x80020005 },
1648     { 0x80020005 },
1649     { 0x80020005 },
1650     { 0x80020005 },
1651     { 0x80020005 },
1652     { 0x80020005 },
1653     { 0x80020005 },
1654     { 0x80020005 },
1655     { 0x80020005 },
1656     { 0x80020005 },
1657     { 0x80020005 },
1658     { 0x80020005 },
1659     { 0x80020005 },
1660     { 0x80020005 },
1661     { 0x80020005 },
1662     { 0x80020005 },
1663     { 0x80020005 },
1664     { 0x80020005 },
1665     { 0x80020005 },
1666     { 0x80020005 },
1667     { 0x80020005 },
1668     { 0x80020005 },
1669     { 0x80020005 },
1670     { 0x80020005 },
1671     { 0x80020005 },
1672     { 0x80020005 },
1673     { 0x80020005 },
1674     { 0x80020005 },
1675     { 0x80020005 },
1676     { 0x80020005 },
1677     { 0x80020005 },
1678     { 0x80020005 },
1679     { 0x80020005 },
1680     { 0x80020005 },
1681     { 0x80020005 },
1682     { 0x80020005 },
1683     { 0x80020005 },
1684     { 0x80020005 },
1685     { 0x80020005 },
1686     { 0,           2 },
1687     { 0,           2 },
1688     { 0,           4 },
1689     { 0,           4 },
1690 };
1691
1692 static void test_variant(void)
1693 {
1694         HMODULE hdll;
1695         VARIANTARG va;
1696         VARIANTARG vb;
1697         VARIANTARG vc;
1698         VARIANTARG vd;
1699         VARIANTARG ve;
1700
1701         HRESULT rc;
1702         LCID lcid;
1703         int theInt = 0;
1704         int* pInt = &theInt;
1705         VARIANT_BOOL b = 0;
1706         VARIANT_BOOL* pBool = &b;
1707         unsigned short uShort = 0;
1708         unsigned short* pUShort = &uShort;
1709         unsigned long uLong = 0;
1710         unsigned long* pULong = &uLong;
1711         CHAR theChar;
1712         CHAR* pChar = &theChar;
1713         BYTE byte;
1714         BYTE* pByte = &byte;
1715         short s = 0;
1716         short* pShort = &s;
1717         long Long = 0;
1718         long* pLong = &Long;
1719         float f = 0;
1720         float* pFloat = &f;
1721         double d = 0;
1722         double* pDouble = &d;
1723
1724         BSTR bstr = NULL;
1725         int off, i = 0;
1726         OLECHAR* pOleChar[NB_OLE_STRINGS];
1727
1728         for (i=0; i<NB_OLE_STRINGS;i++) {
1729                 pOleChar[i]=AtoW(_pTestStrA[i]);
1730         }
1731         lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
1732
1733         /* Start testing the Low-Level API ( the coercions )
1734          */
1735     hdll=LoadLibraryA("netapi32.dll");
1736     pVarI1FromBool=(void*)GetProcAddress(hdll,"VarI1FromBool");
1737     pVarI1FromDate=(void*)GetProcAddress(hdll,"VarI1FromDate");
1738     pVarI1FromI4=(void*)GetProcAddress(hdll,"VarI1FromI4");
1739     pVarI1FromR8=(void*)GetProcAddress(hdll,"VarI1FromR8");
1740     pVarI1FromStr=(void*)GetProcAddress(hdll,"VarI1FromStr");
1741     pVarI1FromUI1=(void*)GetProcAddress(hdll,"VarI1FromUI1");
1742
1743     pVarI2FromUI2=(void*)GetProcAddress(hdll,"VarI2FromUI2");
1744
1745     pVarUI2FromBool=(void*)GetProcAddress(hdll,"VarUI2FromBool");
1746     pVarUI2FromDate=(void*)GetProcAddress(hdll,"VarUI2FromDate");
1747     pVarUI2FromI2=(void*)GetProcAddress(hdll,"VarUI2FromI2");
1748     pVarUI2FromI4=(void*)GetProcAddress(hdll,"VarUI2FromI4");
1749     pVarUI2FromR8=(void*)GetProcAddress(hdll,"VarUI2FromR8");
1750     pVarUI2FromStr=(void*)GetProcAddress(hdll,"VarUI2FromStr");
1751
1752     pVarUI4FromBool=(void*)GetProcAddress(hdll,"VarUI4FromBool");
1753     pVarUI4FromDate=(void*)GetProcAddress(hdll,"VarUI4FromDate");
1754     pVarUI4FromI2=(void*)GetProcAddress(hdll,"VarUI4FromI2");
1755     pVarUI4FromR8=(void*)GetProcAddress(hdll,"VarUI4FromR8");
1756     pVarUI4FromStr=(void*)GetProcAddress(hdll,"VarUI4FromStr");
1757
1758         /* unsigned char from...
1759          */
1760         trace( "======== Testing VarUI1FromXXX ========\n");
1761
1762 #define XOK "should return S_OK\n"
1763 #define XOV "should return DISP_E_OVERFLOW\n"
1764         /* Crashes on Win95: VarUI1FromI2( 0, NULL ) */
1765
1766         ok(VarUI1FromStr(NULL, lcid, 0, pByte) == DISP_E_TYPEMISMATCH,"should return DISP_E_TYPEMISMATCH");
1767         ok(S_OK == VarUI1FromI2( 0, pByte ), XOK);
1768         ok(*pByte == 0,"should give 0 byte value");
1769
1770         ok(S_OK == VarUI1FromI2( 69, pByte ), XOK);
1771         ok(*pByte == 69,"should give 69 byte value");
1772
1773         ok(S_OK == VarUI1FromI2( 70, pByte ), XOK);
1774         ok(*pByte == 70,"should give 70 byte value");
1775
1776         ok(S_OK == VarUI1FromI2( 128, pByte ), XOK);
1777         ok(*pByte == 128,"should give 128 byte value");
1778
1779         ok(S_OK == VarUI1FromI2( 255, pByte ), XOK);
1780         ok(*pByte == 255,"should give 255 byte value");
1781
1782         ok(DISP_E_OVERFLOW == VarUI1FromI2( 256, pByte ), XOV);
1783         ok(DISP_E_OVERFLOW == VarUI1FromI2( 257, pByte ), XOV);
1784
1785         ok(S_OK == VarUI1FromR8( 0.0, pByte ), XOK);
1786         ok(*pByte == 0,"0.0 float should be converted to 0");
1787
1788         ok(S_OK == VarUI1FromR8( 69.33, pByte ), XOK);
1789         ok(*pByte == 0x45, "expected 69 (hex 0x45) as byte value");
1790
1791         ok(S_OK == VarUI1FromR8( 69.66, pByte ), XOK);
1792         ok(*pByte == 0x46, "expected 70 (hex 0x46) as byte value");
1793
1794         ok(DISP_E_OVERFLOW == VarUI1FromR8( -69.33, pByte ), XOV);
1795         ok(DISP_E_OVERFLOW == VarUI1FromR8( -69.66, pByte ), XOV);
1796
1797         ok(S_OK == VarUI1FromR8( -0.5, pByte ), XOK);
1798         ok(*pByte == 0,"-0.5 should give return 0");
1799
1800         ok(DISP_E_OVERFLOW == VarUI1FromR8( -0.51, pByte ), XOV);
1801
1802         ok(S_OK == VarUI1FromR8( -0.49, pByte ), XOK);
1803         ok(*pByte == 0,"-0.49 should give return 0");
1804
1805         ok(S_OK == VarUI1FromR8( 0.5, pByte ), XOK);
1806         ok(*pByte == 0,"0.5 should give return 0");
1807
1808         ok(S_OK == VarUI1FromR8( 0.51, pByte ), XOK);
1809         ok(*pByte == 1,"0.51 should give return 1");
1810
1811         ok(S_OK == VarUI1FromR8( 0.49, pByte ), XOK);
1812         ok(*pByte == 0,"0.49 should give return 0");
1813
1814         ok(S_OK == VarUI1FromDate( 0.0, pByte ), XOK);
1815         ok(*pByte == 0,"0.0 date should give return 0");
1816
1817         ok(S_OK == VarUI1FromDate( 69.33, pByte ), XOK);
1818         ok(*pByte == 0x45,"69.33 date should give return 0x45");
1819
1820         ok(S_OK == VarUI1FromDate( 69.66, pByte ), XOK);
1821         ok(*pByte == 0x46,"69.66 date should give return 0x46");
1822
1823         ok(DISP_E_OVERFLOW == VarUI1FromDate( -69.33, pByte ), XOV);
1824
1825         ok(DISP_E_OVERFLOW == VarUI1FromDate( -69.66, pByte ), XOV);
1826
1827         ok(S_OK == VarUI1FromBool( VARIANT_TRUE, pByte ), XOK);
1828         ok(*pByte == 0xff, "true should be converted to 0xff");
1829
1830         ok(S_OK == VarUI1FromBool( VARIANT_FALSE, pByte ), XOK);
1831         ok(*pByte == 0, "false should be converted to 0");
1832
1833         for (i = 0; i < NB_OLE_STRINGS; i++)
1834         {
1835             *pByte= 42;
1836             rc=VarUI1FromStr( pOleChar[i], lcid, 0, pByte );
1837             ok(rc == strrets_U1[i].error,
1838                "VarUI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1839                i,_pTestStrA[i],rc,strrets_U1[i].error);
1840             if (rc == 0 && strrets_U1[i].error == 0) {
1841                 ok(*pByte == strrets_U1[i].retval,
1842                    "VarUI1FromStr([%d]=\"%s\") got %02x instead of %02x",
1843                    i,_pTestStrA[i],*pByte,strrets_U1[i].retval);
1844             }
1845         }
1846
1847         /* unsigned short from ... */
1848         trace( "======== Testing VarUI2FromXXX ========\n");
1849
1850     if (pVarUI2FromI2) {
1851         ok(DISP_E_OVERFLOW == pVarUI2FromI2( -1, pUShort ), XOV);
1852         ok(S_OK == pVarUI2FromI2( 0, NULL ), XOK);
1853
1854         ok(S_OK == pVarUI2FromI2( 0, pUShort ), XOK);
1855         ok(*pUShort == 0,"0 should be 0");
1856         ok(S_OK == pVarUI2FromI2( 69, pUShort ), XOK);
1857         ok(*pUShort == 69,"69 should be 69");
1858         ok(S_OK == pVarUI2FromI2( 70, pUShort ), XOK);
1859         ok(*pUShort == 70,"70 should be 70");
1860
1861         ok(S_OK == pVarUI2FromI2( 128, pUShort ), XOK);
1862         ok(*pUShort == 128,"128 should be 128");
1863     }
1864
1865     if (pVarUI2FromI4) {
1866         ok(S_OK == pVarUI2FromI4( 65535, pUShort ), XOK);
1867         ok(*pUShort == 65535,"65535 should be 65535");
1868         ok(DISP_E_OVERFLOW == pVarUI2FromI4( 65536, pUShort ), XOV);
1869         ok(DISP_E_OVERFLOW == pVarUI2FromI4( 65537, pUShort ), XOV);
1870     }
1871
1872     if (pVarUI2FromR8) {
1873         ok(S_OK == pVarUI2FromR8( 0.0, pUShort ), XOK);
1874         ok(*pUShort == 0,"0.0 should be 0");
1875         ok(S_OK == pVarUI2FromR8( 69.33, pUShort ), XOK);
1876         ok(*pUShort == 69,"69.33 should be 69");
1877         ok(S_OK == pVarUI2FromR8( 69.66, pUShort ), XOK);
1878         ok(*pUShort == 70,"69.66 should be 70");
1879
1880         ok(DISP_E_OVERFLOW == pVarUI2FromR8( -69.33, pUShort ), XOV);
1881         ok(DISP_E_OVERFLOW == pVarUI2FromR8( -69.66, pUShort ), XOV);
1882
1883         ok(S_OK == pVarUI2FromR8( -0.5, pUShort ), XOK);
1884         ok(*pUShort == 0, "-0.5 -> 0");
1885         ok(DISP_E_OVERFLOW == pVarUI2FromR8( -0.51, pUShort ), XOV);
1886         ok(S_OK == pVarUI2FromR8( -0.49, pUShort ), XOK);
1887         ok(*pUShort == 0, "-0.49 -> 0");
1888
1889         ok(S_OK == pVarUI2FromR8( 0.5, pUShort ), XOK);
1890         ok(*pUShort == 0,"0.5 should be 0");
1891         ok(S_OK == pVarUI2FromR8( 0.51, pUShort ), XOK);
1892         ok(*pUShort == 1,"0.51 should be 1");
1893         ok(S_OK == pVarUI2FromR8( 0.49, pUShort ), XOK);
1894         ok(*pUShort == 0,"0.49 should be 0");
1895     }
1896
1897     if (pVarUI2FromDate) {
1898         ok(S_OK == pVarUI2FromDate( 0.0, pUShort ), XOK);
1899         ok(*pUShort == 0,"0.0 should be 0");
1900         ok(S_OK == pVarUI2FromDate( 69.33, pUShort ), XOK);
1901         ok(*pUShort == 69,"69.33 should be 69");
1902         ok(S_OK == pVarUI2FromDate( 69.66, pUShort ), XOK);
1903         ok(*pUShort == 70,"69.66 should be 70");
1904         ok(DISP_E_OVERFLOW == pVarUI2FromDate( -69.33, pUShort ), XOV);
1905         ok(DISP_E_OVERFLOW == pVarUI2FromDate( -69.66, pUShort ), XOV);
1906     }
1907
1908     if (pVarUI2FromBool) {
1909         ok(S_OK == pVarUI2FromBool( VARIANT_TRUE, pUShort ), XOK);
1910         ok(*pUShort == 65535,"TRUE should be 65535");
1911         ok(S_OK == pVarUI2FromBool( VARIANT_FALSE, pUShort ), XOK);
1912         ok(*pUShort == 0,"FALSE should be 0");
1913     }
1914
1915     if (pVarUI2FromStr) {
1916         ok(DISP_E_TYPEMISMATCH == pVarUI2FromStr( NULL, lcid, 0, pUShort ), "should return DISP_E_TYPEMISMATCH");
1917
1918         for (i = 0; i < NB_OLE_STRINGS; i++)
1919         {
1920             *pUShort=42;
1921             rc=pVarUI2FromStr( pOleChar[i], lcid, 0, pUShort );
1922             ok(rc == strrets_U2[i].error,
1923                "VarUI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1924                i,_pTestStrA[i],rc,strrets_U2[i].error);
1925             if (rc == 0 && strrets_U2[i].error == 0) {
1926                 ok(*pUShort == strrets_U2[i].retval,
1927                    "VarUI2FromStr([%d]=\"%s\") got %u instead of %u",
1928                    i,_pTestStrA[i],*pUShort,strrets_U2[i].retval);
1929             }
1930         }
1931     }
1932
1933         /* unsigned long from ...
1934          */
1935         trace( "======== Testing VarUI4FromXXX ========\n");
1936
1937     if (pVarUI4FromI2) {
1938         ok(S_OK == pVarUI4FromI2( 0, NULL ), XOK);
1939
1940         ok(S_OK == pVarUI4FromI2( 0, pULong ), XOK);
1941         ok(*pULong == 0,"0 should be 0");
1942         ok(S_OK == pVarUI4FromI2( 69, pULong ), XOK);
1943         ok(*pULong == 69,"69 should be 69");
1944
1945         ok(S_OK == pVarUI4FromI2( 70, pULong ), XOK);
1946         ok(*pULong == 70,"70 should be 70");
1947
1948         ok(S_OK == pVarUI4FromI2( 128, pULong ), XOK);
1949         ok(*pULong == 128,"128 should be 128");
1950         ok(S_OK == pVarUI4FromI2( 255, pULong ), XOK);
1951         ok(*pULong == 255,"255 should be 255");
1952     }
1953
1954     if (pVarUI4FromR8) {
1955         ok(S_OK == pVarUI4FromR8( 4294967295.0, pULong ), XOK);
1956         ok(*pULong == 4294967295U,"4294967295.0 should be 4294967295");
1957         ok(DISP_E_OVERFLOW == pVarUI4FromR8( 4294967296.0, pULong ), XOV);
1958
1959         ok(S_OK == pVarUI4FromR8( 0.0, pULong ), XOK);
1960         ok(*pULong == 0,"0 should be 0");
1961         ok(S_OK == pVarUI4FromR8( 69.33, pULong ), XOK);
1962         ok(*pULong == 69,"69.33 should be 69");
1963         ok(S_OK == pVarUI4FromR8( 69.66, pULong ), XOK);
1964         ok(*pULong == 70,"69.66 should be 70");
1965         ok(DISP_E_OVERFLOW == pVarUI4FromR8( -69.33, pULong ), XOV);
1966         ok(DISP_E_OVERFLOW == pVarUI4FromR8( -69.66, pULong ), XOV);
1967
1968         ok(S_OK == pVarUI4FromR8( -0.5, pULong ), XOK);
1969         ok(*pULong == 0,"-0.5 should be 0");
1970
1971         ok(DISP_E_OVERFLOW == pVarUI4FromR8( -0.51, pULong ), XOV);
1972
1973         ok(S_OK == pVarUI4FromR8( -0.49, pULong ), XOK);
1974         ok(*pULong == 0,"-0.49 should be 0");
1975
1976         ok(S_OK == pVarUI4FromR8( 0.5, pULong ), XOK);
1977         ok(*pULong == 0,"0.5 should be 0");
1978         ok(S_OK == pVarUI4FromR8( 0.51, pULong ), XOK);
1979         ok(*pULong == 1,"0.51 should be 1");
1980         ok(S_OK == pVarUI4FromR8( 0.49, pULong ), XOK);
1981         ok(*pULong == 0,"0.49 should be 0");
1982     }
1983
1984     if (pVarUI4FromDate) {
1985         ok(S_OK == pVarUI4FromDate( 0.0, pULong ), XOK);
1986         ok(*pULong == 0,"0.0 should be 0");
1987         ok(S_OK == pVarUI4FromDate( 69.33, pULong ), XOK);
1988         ok(*pULong == 69,"69.33 should be 69");
1989         ok(S_OK == pVarUI4FromDate( 69.66, pULong ), XOK);
1990         ok(*pULong == 70,"69.66 should be 70");
1991         ok(DISP_E_OVERFLOW == pVarUI4FromDate( -69.33, pULong ), XOV);
1992         ok(DISP_E_OVERFLOW == pVarUI4FromDate( -69.66, pULong ), XOV);
1993     }
1994
1995     if (pVarUI4FromBool) {
1996         ok(S_OK == pVarUI4FromBool( VARIANT_TRUE, pULong ), XOK);
1997         ok(*pULong == 4294967295U, "TRUE should be 4294967295");
1998         ok(S_OK == pVarUI4FromBool( VARIANT_FALSE, pULong ), XOK);
1999         ok(*pULong == 0, "FALSE should be 0");
2000     }
2001
2002     if (pVarUI4FromStr) {
2003         ok(DISP_E_TYPEMISMATCH == pVarUI4FromStr( NULL, lcid, 0, pULong ), "should erturn DISP_E_TYPEMISMATCH");
2004         for (i = 0; i < NB_OLE_STRINGS; i++)
2005         {
2006             *pULong=42;
2007             rc=pVarUI4FromStr( pOleChar[i], lcid, 0, pULong );
2008             ok(rc == strrets_U4[i].error,
2009                "VarUI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2010                i,_pTestStrA[i],rc,strrets_U4[i].error);
2011             if (rc == 0 && strrets_U4[i].error == 0) {
2012                 ok(*pULong == strrets_U4[i].retval,
2013                    "VarUI4FromStr([%d]=\"%s\") got %lu instead of %lu",
2014                    i,_pTestStrA[i],*pULong,strrets_U4[i].retval);
2015             }
2016         }
2017     }
2018
2019         /* CHAR from ...
2020          */
2021         trace( "======== Testing VarI1FromXXX ========\n");
2022
2023     if (pVarI1FromBool) {
2024         ok(S_OK == pVarI1FromBool( VARIANT_TRUE, pByte ), XOK);
2025         ok(*pByte == 0xff,"true should be 0xff");
2026
2027         ok(S_OK == pVarI1FromBool( VARIANT_TRUE, pChar ), XOK);
2028         ok(*pChar == -1, "TRUE should be -1");
2029
2030         ok(S_OK == pVarI1FromBool( VARIANT_FALSE, pChar ), XOK);
2031         ok(*pChar == 0, "FALSE should be 0");
2032     }
2033
2034     if (pVarI1FromUI1) {
2035         ok(DISP_E_OVERFLOW == pVarI1FromUI1( (unsigned char)32767, pChar ), XOV);
2036         ok(*pChar == 0, "should still be 0");
2037         ok(DISP_E_OVERFLOW == pVarI1FromUI1( (unsigned char)65535, pChar ), XOV);
2038         ok(*pChar == 0, "should still be 0");
2039     }
2040
2041     if (pVarI1FromI4) {
2042         ok(DISP_E_OVERFLOW == pVarI1FromI4( 32767, pChar ), XOV);
2043         ok(*pChar == 0, "should still be 0");
2044         ok(DISP_E_OVERFLOW == pVarI1FromI4( 32768, pChar ), XOV);
2045         ok(*pChar == 0, "should still be 0");
2046         ok(DISP_E_OVERFLOW == pVarI1FromI4( -32768, pChar ), XOV);
2047         ok(*pChar == 0, "should still be 0");
2048         ok(DISP_E_OVERFLOW == pVarI1FromI4( -32769, pChar ), XOV);
2049         ok(*pChar == 0, "should still be 0");
2050     }
2051
2052     if (pVarI1FromR8) {
2053         ok(S_OK == pVarI1FromR8( 69.33, pChar ), XOK);
2054         ok(*pChar == 69, "69.33 should be 69");
2055         ok(S_OK == pVarI1FromR8( 69.66, pChar ), XOK);
2056         ok(*pChar == 70, "69.66 should be 70");
2057
2058         ok(S_OK == pVarI1FromR8( -69.33, pChar ), XOK);
2059         ok(*pChar == -69, "-69.33 should be -69");
2060         ok(S_OK == pVarI1FromR8( -69.66, pChar ), XOK);
2061         ok(*pChar == -70, "-69.66 should be -70");
2062     }
2063
2064     if (pVarI1FromDate) {
2065         ok(S_OK == pVarI1FromDate( -69.66, pChar ), XOK);
2066         ok(*pChar == -70, "-69.66 should be -70");
2067     }
2068
2069     if (pVarI1FromStr) {
2070         for (i = 0; i < NB_OLE_STRINGS; i++)
2071         {
2072             *pChar=42;
2073             rc=pVarI1FromStr( pOleChar[i], lcid, 0, pChar );
2074             ok(rc == strrets_I1[i].error,
2075                "VarI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2076                i,_pTestStrA[i],rc,strrets_I1[i].error);
2077             if (rc == 0 && strrets_I1[i].error == 0) {
2078                 ok(*pChar == strrets_I1[i].retval,
2079                    "VarI1FromStr([%d]=\"%s\") got %d instead of %d",
2080                    i,_pTestStrA[i],*pChar,strrets_I1[i].retval);
2081             }
2082         }
2083     }
2084
2085         /* short from ...
2086          */
2087         trace( "======== Testing VarI2FromXXX ========\n");
2088
2089     if (pVarI2FromUI2) {
2090         ok(S_OK == pVarI2FromUI2( 32767, pShort ), XOK);
2091         ok(*pShort == 32767, "should be 32767");
2092         ok(DISP_E_OVERFLOW == pVarI2FromUI2( 65535, pShort ), XOV);
2093         ok(*pShort == 32767, "pShort should be unchanged");
2094     }
2095
2096         ok(S_OK == VarI2FromI4( 32767, pShort ), XOK);
2097         ok(*pShort == 32767, "should be 32767");
2098         ok(DISP_E_OVERFLOW == VarI2FromI4( 32768, pShort ), XOV);
2099         ok(*pShort == 32767, "should still be 32767");
2100         ok(S_OK == VarI2FromI4( -32768, pShort ), XOK);
2101         ok(*pShort == -32768, "should be -32768");
2102         ok(DISP_E_OVERFLOW == VarI2FromI4( -32769, pShort ), XOV);
2103         ok(*pShort == -32768, "should still be -32768");
2104
2105         ok(S_OK == VarI2FromR8( 69.33, pShort ), XOK);
2106         ok(*pShort == 69, "should be 69");
2107         ok(S_OK == VarI2FromR8( 69.66, pShort ), XOK);
2108         ok(*pShort == 70, "should be 70");
2109         ok(S_OK == VarI2FromR8( -69.33, pShort ), XOK);
2110         ok(*pShort == -69, "should be -69");
2111         ok(S_OK == VarI2FromR8( -69.66, pShort ), XOK);
2112         ok(*pShort == -70, "should be -70");
2113         ok(S_OK == VarI2FromDate( -69.66, pShort ), XOK);
2114         ok(*pShort == -70, "should be -70");
2115
2116         for (i = 0; i < NB_OLE_STRINGS; i++)
2117         {
2118             *pShort=42;
2119             rc=VarI2FromStr( pOleChar[i], lcid, 0, pShort );
2120             ok(rc == strrets_I2[i].error,
2121                "VarI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2122                i,_pTestStrA[i],rc,strrets_I2[i].error);
2123             if (rc == 0 && strrets_I2[i].error == 0) {
2124                 ok(*pShort == strrets_I2[i].retval,
2125                    "VarI2FromStr([%d]=\"%s\") got %d instead of %d",
2126                    i,_pTestStrA[i],*pShort,strrets_I2[i].retval);
2127             }
2128         }
2129
2130         /* long from ...
2131          */
2132         trace( "======== Testing VarI4FromXXX ========\n");
2133
2134         ok(S_OK == VarI4FromI2( 3, (long*)pInt ), XOK);
2135         ok(*pInt == 3,"should be 3");
2136
2137         ok(S_OK == VarI4FromR8( 69.33, pLong ), XOK);
2138         ok(*pLong == 69,"should be 69");
2139         ok(S_OK == VarI4FromR8( 69.66, pLong ), XOK);
2140         ok(*pLong == 70,"should be 70");
2141         ok(S_OK == VarI4FromR8( -69.33, pLong ), XOK);
2142         ok(*pLong == -69,"should be -69");
2143         ok(S_OK == VarI4FromR8( -69.66, pLong ), XOK);
2144         ok(*pLong == -70,"should be -70");
2145
2146         ok(S_OK == VarI4FromR8( 2147483647.0, pLong ), XOK);
2147         ok(*pLong == 2147483647,"should be 2147483647");
2148         ok(DISP_E_OVERFLOW == VarI4FromR8( 2147483648.0, pLong ), XOV);
2149         ok(*pLong == 2147483647,"should still be 2147483647");
2150
2151         ok(S_OK == VarI4FromR8( -2147483647.0, pLong ), XOK);
2152         ok(*pLong == -2147483647,"should be -2147483647");
2153         ok(S_OK == VarI4FromR8( -2147483648.0, pLong ), XOK);
2154         ok(*pLong == 0x80000000L,"should be -2147483648");
2155         ok(DISP_E_OVERFLOW == VarI4FromR8( -2147483649.0, pLong ), XOV);
2156         ok(*pLong == 0x80000000L,"should still be -2147483648");
2157         ok(DISP_E_OVERFLOW == VarI4FromDate( -2147483649.0, pLong ), XOV);
2158         ok(*pLong == 0x80000000L,"should still be -2147483648");
2159
2160         for (i = 0; i < NB_OLE_STRINGS; i++)
2161         {
2162             *pLong=42;
2163             rc=VarI4FromStr( pOleChar[i], lcid, 0, pLong );
2164             ok(rc == strrets_I4[i].error,
2165                "VarI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2166                i,_pTestStrA[i],rc,strrets_I4[i].error);
2167             if (rc == 0 && strrets_I4[i].error == 0) {
2168                 ok(*pLong == strrets_I4[i].retval,
2169                    "VarI4FromStr([%d]=\"%s\") got %ld instead of %ld",
2170                    i,_pTestStrA[i],*pLong,strrets_I4[i].retval);
2171             }
2172         }
2173
2174         /* float from ...
2175          */
2176         trace( "======== Testing VarR4FromXXX ========\n");
2177
2178         ok(S_OK == VarR4FromI4( 16777216, pFloat ), XOK);
2179         ok(16777216.0 == *pFloat,"should be 16777216.0");
2180
2181         ok(S_OK == VarR4FromI4( 16777217, pFloat ), XOK);
2182         ok(16777216.0 == *pFloat,"should be 16777216.0");
2183         ok(S_OK == VarR4FromI4( -16777216, pFloat ), XOK);
2184         ok(-16777216.0 == *pFloat,"should be -16777216.0");
2185         ok(S_OK == VarR4FromI4( -16777217, pFloat ), XOK);
2186         ok(-16777216.0 == *pFloat,"should be -16777216.0");
2187
2188         ok(S_OK == VarR4FromR8( 16777216.0, pFloat ), XOK);
2189         ok(16777216.0 == *pFloat,"should be 16777216.0");
2190         ok(S_OK == VarR4FromR8( 16777217.0, pFloat ), XOK);
2191         ok(16777216.0 == *pFloat,"should be 16777216.0");
2192         ok(S_OK == VarR4FromR8( -16777216.0, pFloat ), XOK);
2193         ok(-16777216.0 == *pFloat,"should be -16777216.0");
2194         ok(S_OK == VarR4FromR8( -16777217.0, pFloat ), XOK);
2195         ok(-16777216.0 == *pFloat,"should be -16777216.0");
2196
2197         ok(S_OK == VarR4FromR8( 16777218e31, pFloat ), XOK);
2198         ok(*pFloat == 167772177736353110000000000000000000000.000000,
2199                 "should be 167772177736353110000000000000000000000.000000");
2200         ok(DISP_E_OVERFLOW == VarR4FromR8( 16777218e32, pFloat ), XOV);
2201         ok(*pFloat == 167772177736353110000000000000000000000.000000,
2202                 "should still be 167772177736353110000000000000000000000.000000");
2203         ok(S_OK == VarR4FromDate( 16777218e31, pFloat ), XOK);
2204         ok(*pFloat == 167772177736353110000000000000000000000.000000,
2205                 "should be 167772177736353110000000000000000000000.000000");
2206
2207         for (i = 0; i < NB_OLE_STRINGS; i++)
2208         {
2209             *pFloat=42.0;
2210             rc=VarR4FromStr( pOleChar[i], lcid, 0, pFloat );
2211             ok(rc == strrets_R4[i].error,
2212                    "VarR4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2213                    i,_pTestStrA[i],rc,strrets_R4[i].error);
2214             if (rc == 0 && strrets_R4[i].error == 0) {
2215                 ok(*pFloat == strrets_R4[i].retval,
2216                    "VarR4FromStr([%d]=\"%s\")  got %f instead of %f",
2217                    i,_pTestStrA[i],*pFloat,strrets_R4[i].retval);
2218             }
2219         }
2220
2221         /* double from ...
2222          */
2223         trace( "======== Testing VarR8FromXXX ========\n");
2224
2225         ok(S_OK == VarR8FromDate( 900719925474099.0, pDouble ), XOK);
2226         ok(*pDouble == 900719925474099.000000,"should be 900719925474099.000000\n");
2227         for (i = 0; i < NB_OLE_STRINGS; i++)
2228         {
2229             *pDouble=42.0;
2230             rc=VarR8FromStr( pOleChar[i], lcid, 0, pDouble );
2231             ok(rc == strrets_R8[i].error,
2232                "VarR8FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2233                i,_pTestStrA[i],rc,strrets_R8[i].error);
2234             if (rc == 0 && strrets_R8[i].error == 0) {
2235                 ok(*pDouble == strrets_R8[i].retval,
2236                    "VarR8FromStr([%d]=\"%s\") got %.15f instead of %.15f",
2237                    i,_pTestStrA[i],*pDouble,strrets_R8[i].retval);
2238             }
2239         }
2240
2241         /* date from ...
2242          */
2243         trace( "======== Testing VarDateFromXXX ========\n");
2244
2245         ok(S_OK == VarDateFromI4( 2958465, pDouble ), XOK);
2246         ok(*pDouble == 2958465.000000,"should be 2958465.000000");
2247     rc=VarDateFromI4( 2958466, pDouble );
2248     ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
2249        "got %lx",rc);
2250         ok(*pDouble == 2958465.000000,"should still be 2958465.000000");
2251         ok(S_OK == VarDateFromI4( -657434, pDouble ), XOK);
2252         ok(*pDouble == -657434.000000,"should be -657434.000000");
2253     rc=VarDateFromI4( -657435, pDouble );
2254     ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
2255        "got %lx",rc);
2256         ok(*pDouble == -657434.000000,"should still be -657434.000000");
2257
2258         ok(S_OK == VarDateFromR8( 2958465.9999, pDouble ), XOK);
2259         ok(*pDouble == 2958465.999900, "should be 2958465.999900");
2260     rc=VarDateFromR8( 2958466, pDouble );
2261     ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
2262        "got %lx",rc);
2263         ok(*pDouble == 2958465.999900, "should still be 2958465.999900");
2264         ok(S_OK == VarDateFromR8( -657434.9999, pDouble ), XOK);
2265         ok(*pDouble == -657434.999900,"should be -657434.999900");
2266     rc=VarDateFromR8( -657435, pDouble );
2267     ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
2268        "got %lx",rc);
2269         ok(*pDouble == -657434.999900,"should still be -657434.999900");
2270
2271         ok(S_OK == VarDateFromR8( 0.0, pDouble ), XOK);
2272         ok(*pDouble == 0.0,"0.0 should be 0.0");
2273         ok(S_OK == VarDateFromR8( 1.0, pDouble ), XOK);
2274         ok(*pDouble == 1.0,"1.0 should be 1.0");
2275         ok(S_OK == VarDateFromR8( 2.25, pDouble ), XOK);
2276         ok(*pDouble == 2.25,"2.25 should be 2.25");
2277         ok(S_OK == VarDateFromR8( -2.0, pDouble ), XOK);
2278         ok(*pDouble == -2.0,"-2.0 should be -2.0");
2279
2280         /* Need some parsing function in Linux to emulate this...
2281          * Still in progess.
2282          */
2283         for (i = 0; i < NB_OLE_STRINGS; i++)
2284         {
2285             *pDouble=42.0;
2286             rc=VarDateFromStr( pOleChar[i], lcid, LOCALE_NOUSEROVERRIDE, pDouble );
2287             ok(i == 94 /* FIXME: Bug in native */ || rc == strrets_DATE[i].error,
2288                "VarDateFromStr([%d]=\"%s\") rc= %lx instead of %lx",
2289                i,_pTestStrA[i],rc,strrets_DATE[i].error);
2290             if (rc == 0 && strrets_DATE[i].error == 0) {
2291                ok(EQ_DOUBLE(*pDouble,strrets_DATE[i].retval),
2292                   "VarDateFromStr([%d]=\"%s\") got %.15f instead of %.15f",
2293                   i,_pTestStrA[i],*pDouble,strrets_DATE[i].retval);
2294             }
2295         }
2296         /* bool from ...
2297          */
2298         trace( "======== Testing VarBoolFromXXX ========\n");
2299
2300         ok(S_OK == VarBoolFromI4( 0, pBool ), XOK);
2301         ok(VARIANT_FALSE == *pBool, "expected FALSE");
2302         ok(S_OK == VarBoolFromI4( 1, pBool ), XOK);
2303         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2304         ok(S_OK == VarBoolFromI4( -1, pBool ), XOK);
2305         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2306         ok(S_OK == VarBoolFromI4( 2, pBool ), XOK);
2307         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2308
2309         ok(S_OK == VarBoolFromUI1( ' ', pBool ), XOK);
2310         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2311         ok(S_OK == VarBoolFromUI1( '\0', pBool ), XOK);
2312         ok(VARIANT_FALSE == *pBool, "expected FALSE");
2313         ok(S_OK == VarBoolFromUI1( 0x0000, pBool ), XOK);
2314         ok(VARIANT_FALSE == *pBool, "expected FALSE");
2315         ok(S_OK == VarBoolFromUI1( (unsigned char)0xFFF, pBool ), XOK);
2316         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2317         ok(S_OK == VarBoolFromUI1( (unsigned char)0xFFFF, pBool ), XOK);
2318         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2319
2320         ok(S_OK == VarBoolFromR8( 0.0, pBool ), XOK);
2321         ok(VARIANT_FALSE == *pBool, "expected FALSE");
2322         ok(S_OK == VarBoolFromR8( 1.1, pBool ), XOK);
2323         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2324         ok(S_OK == VarBoolFromR8( 0.5, pBool ), XOK);
2325         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2326         ok(S_OK == VarBoolFromR8( 0.49, pBool ), XOK);
2327         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2328         ok(S_OK == VarBoolFromR8( 0.51, pBool ), XOK);
2329         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2330         ok(S_OK == VarBoolFromR8( -0.5, pBool ), XOK);
2331         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2332         ok(S_OK == VarBoolFromR8( -0.49, pBool ), XOK);
2333         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2334         ok(S_OK == VarBoolFromR8( -0.51, pBool ), XOK);
2335         ok(VARIANT_TRUE == *pBool, "expected TRUE");
2336
2337
2338         for (i = 0; i < NB_OLE_STRINGS; i++)
2339         {
2340             *pBool=42;
2341             rc=VarBoolFromStr( pOleChar[i], lcid, 0, pBool );
2342             ok(rc == strrets_B[i].error,
2343                "VarBoolFromStr([%d]=\"%s\") rc=%lx instead of %lx",
2344                i,_pTestStrA[i],rc,strrets_B[i].error);
2345             if (rc == 0 && strrets_B[i].error == 0) {
2346                 ok(*pBool == strrets_B[i].retval,
2347                    "VarBoolFromStr([%d]=\"%s\") got %x instead of %x",
2348                    i,_pTestStrA[i],*pBool,strrets_B[i].retval);
2349             }
2350         }
2351
2352         /* BSTR from ...
2353          */
2354         trace( "======== Testing VarBSTRFromXXX ========\n");
2355
2356         /* integers...
2357          */
2358     if (pVarBstrFromI1) {
2359         ok(S_OK == pVarBstrFromI1( -100, 0, 0, &bstr ), XOK);
2360         ok(!strcmp(WtoA(bstr),"\"-100\""),"should be string -100");
2361     }
2362
2363         ok(S_OK == VarBstrFromUI1( 0x5A, 0, 0, &bstr ), XOK);
2364         ok(!strcmp(WtoA(bstr),"\"90\""),"should be string 90");
2365         ok(S_OK == VarBstrFromI4( 2958465, 0, 0, &bstr ), XOK);
2366         ok(!strcmp(WtoA(bstr),"\"2958465\""),"should be string 2958465");
2367
2368         /* reals...
2369          */
2370         off = 0;
2371         d=0;
2372         for( i=0; i<20; i++ )
2373         {
2374                 char xval[80];
2375                 /* add an integer to the real number
2376                  */
2377                 d += ((i%9)+1) * pow( 10, i );
2378
2379                 ok(S_OK == VarBstrFromR8( d, lcid, 0, &bstr ), XOK);
2380                 sprintf(xval,"\"%s\"",strfromr8[off]);
2381                 ok(!strcmp(xval,WtoA(bstr)),
2382                    "d is %.15f, should be cvt. to %s, but return val is %s",
2383                    d,strfromr8[off],WtoA(bstr));
2384                 off++;
2385
2386                 ok(S_OK == VarBstrFromR8( -d, lcid, 0, &bstr ), XOK);
2387                 sprintf(xval,"\"%s\"",strfromr8[off]);
2388                 ok(!strcmp(xval,WtoA(bstr)),
2389                    "d is %.15f, should be cvt. to %s, but return val is %s",
2390                    -d,strfromr8[off],WtoA(bstr));
2391                 off++;
2392         }
2393         d=0;
2394         for( i=0; i<20; i++ )
2395         {
2396                 char xval[80];
2397                 /* add a decimal to the real number
2398                  */
2399                 d += ((i%9)+1) * pow( 10, (i*-1) );
2400                 ok(S_OK == VarBstrFromR8( d, lcid, 0, &bstr ), XOK);
2401                 sprintf(xval,"\"%s\"",strfromr8[off]);
2402                 ok(!strcmp(xval,WtoA(bstr)),
2403                    "d is %.15f, should be cvt. to %s, but return val is %s",
2404                    d,strfromr8[off],WtoA(bstr));
2405                 off++;
2406                 ok(S_OK == VarBstrFromR8( d-1, lcid, 0, &bstr ), XOK);
2407                 sprintf(xval,"\"%s\"",strfromr8[off]);
2408                 ok(!strcmp(xval,WtoA(bstr)),
2409                    "d is %.15f, should be cvt. to %s, but return val is %s",
2410                    d-1,strfromr8[off],WtoA(bstr));
2411                 off++;
2412                 ok(S_OK == VarBstrFromR8( -d, lcid, 0, &bstr ), XOK);
2413                 sprintf(xval,"\"%s\"",strfromr8[off]);
2414                 ok(!strcmp(xval,WtoA(bstr)),
2415                    "d is %.15f, should be cvt. to %s, but return val is %s",
2416                    -d,strfromr8[off],WtoA(bstr));
2417                 off++;
2418         }
2419
2420         d=0;
2421         for( i=0; i<20; i++ )
2422         {
2423                 char xval[80];
2424                 /* add an integer to the real number
2425                  */
2426                 d += ((i%9)+1) * pow( 10, i );
2427                 /* add a decimal to the real number
2428                  */
2429                 d += ((i%9)+1) * pow( 10, (i*-1) );
2430                 ok(S_OK == VarBstrFromR8( d, lcid, 0, &bstr ), XOK);
2431                 sprintf(xval,"\"%s\"",strfromr8[off]);
2432                 ok(!strcmp(xval,WtoA(bstr)),
2433                    "d is %.15f, should be cvt. to %s, but return val is %s",
2434                    d,strfromr8[off],WtoA(bstr));
2435                         off++;
2436                 ok(S_OK == VarBstrFromR8( -d, lcid, 0, &bstr ), XOK);
2437                 sprintf(xval,"\"%s\"",strfromr8[off]);
2438                 ok(!strcmp(xval,WtoA(bstr)),
2439                    "d is %.15f, should be cvt. to %s, but return val is %s",
2440                    -d,strfromr8[off],WtoA(bstr));
2441                         off++;
2442         }
2443
2444         d=0;
2445         for( i=0; i<10; i++ )
2446         {
2447                 char xval[80];
2448                 /* add an integer to the real number
2449                  */
2450                 d += ((i%9)+1) * pow( 10, i );
2451                 ok(S_OK == VarBstrFromR4( (float)d, lcid, 0, &bstr ), XOK);
2452                 sprintf(xval,"\"%s\"",strfromr8[off]);
2453                 ok(!strcmp(xval,WtoA(bstr)),
2454                    "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2455                    i,d,strfromr8[off],WtoA(bstr));
2456                 off++;
2457                 ok(S_OK == VarBstrFromR4( (float)-d, lcid, 0, &bstr ), XOK);
2458                 sprintf(xval,"\"%s\"",strfromr8[off]);
2459                 ok(!strcmp(xval,WtoA(bstr)),
2460                    "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2461                    i,-d,strfromr8[off],WtoA(bstr));
2462                 off++;
2463         }
2464         d=0;
2465         for( i=0; i<10; i++ )
2466         {
2467                 char xval[80];
2468                 /* add a decimal to the real number
2469                  */
2470                 d += ((i%9)+1) * pow( 10, (i*-1) );
2471                 ok(S_OK == VarBstrFromR4( (float)d, lcid, 0, &bstr ), XOK);
2472                 sprintf(xval,"\"%s\"",strfromr8[off]);
2473                 ok(!strcmp(xval,WtoA(bstr)),
2474                    "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2475                    i,d,strfromr8[off],WtoA(bstr));
2476                 off++;
2477                 ok(S_OK == VarBstrFromR4( (float)(d-1), lcid, 0, &bstr ), XOK);
2478                 sprintf(xval,"\"%s\"",strfromr8[off]);
2479                 ok(!strcmp(xval,WtoA(bstr)),
2480                    "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2481                    i,d-1,strfromr8[off],WtoA(bstr));
2482                 off++;
2483                 ok(S_OK == VarBstrFromR4( (float)-d, lcid, 0, &bstr ), XOK);
2484                 sprintf(xval,"\"%s\"",strfromr8[off]);
2485                 ok(!strcmp(xval,WtoA(bstr)),
2486                    "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2487                    i,-d,strfromr8[off],WtoA(bstr));
2488                 off++;
2489         }
2490
2491         d=0;
2492         for( i=0; i<10; i++ )
2493         {
2494         static int istodo[10]={0,0,0,0,0,1,0,0,0,0};
2495             char xval[80];
2496                 /* add an integer to the real number
2497                  */
2498                 d += ((i%9)+1) * pow( 10, i );
2499                 /* add a decimal to the real number
2500                  */
2501                 d += ((i%9)+1) * pow( 10, (i*-1) );
2502                 ok(S_OK == VarBstrFromR4( (float)d, lcid, 0, &bstr ), XOK);
2503                 sprintf(xval,"\"%s\"",strfromr8[off]);
2504         if (istodo[i]) {
2505             todo_wine {
2506                 ok(!strcmp(xval,WtoA(bstr)),
2507                        "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2508                        i,d,strfromr8[off],WtoA(bstr));
2509             }
2510         } else {
2511             ok(!strcmp(xval,WtoA(bstr)),
2512                    "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2513                    i,d,strfromr8[off],WtoA(bstr));
2514         }
2515         off++;
2516                 ok(S_OK == VarBstrFromR4( (float)-d, lcid, 0, &bstr ), XOK);
2517                 sprintf(xval,"\"%s\"",strfromr8[off]);
2518         if (istodo[i]) {
2519             todo_wine {
2520                         ok(!strcmp(xval,WtoA(bstr)),
2521                            "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2522                            i,-d,strfromr8[off],WtoA(bstr));
2523             }
2524         } else {
2525                     ok(!strcmp(xval,WtoA(bstr)),
2526                        "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2527                        i,-d,strfromr8[off],WtoA(bstr));
2528         }
2529         off++;
2530         }
2531
2532         ok(S_OK == VarBstrFromBool( 0x00, lcid, 0, &bstr ), XOK);
2533         ok(!strcmp(WtoA(bstr),"\"False\""),"should be 'False'");
2534         ok(S_OK == VarBstrFromBool( 0xFF, lcid, 0, &bstr ), XOK);
2535         ok(!strcmp(WtoA(bstr),"\"True\""),"should be 'True'");
2536
2537         ok(S_OK == VarBstrFromDate( 0.0, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2538         ok(!strcmp(WtoA(bstr),"\"12:00:00 AM\""),
2539        "should be '12:00:00 AM', but is %s\n",WtoA(bstr));
2540
2541         ok(S_OK == VarBstrFromDate( 3.34, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2542         ok(strcmp(WtoA(bstr),"\"1/2/1900 8:09:36 AM\"")==0 ||
2543        strcmp(WtoA(bstr),"\"1/2/00 8:09:36 AM\"")==0 /* Win95 */,
2544        "should be '1/2/1900 8:09:36 AM', but is %s\n",WtoA(bstr));
2545
2546         ok(S_OK == VarBstrFromDate( 3339.34, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2547         ok(strcmp(WtoA(bstr),"\"2/20/1909 8:09:36 AM\"")==0 ||
2548        strcmp(WtoA(bstr),"\"2/20/09 8:09:36 AM\"")==0 /* Win95 */,
2549        "should be '2/20/1909 8:09:36 AM', but is %s\n",WtoA(bstr));
2550
2551         ok(S_OK == VarBstrFromDate( 365.00, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2552         ok(strcmp(WtoA(bstr),"\"12/30/1900\"")==0 ||
2553        strcmp(WtoA(bstr),"\"12/30/00\"")==0 /* Win95 */,
2554        "should be '12/30/1900', but is %s\n",WtoA(bstr));
2555
2556         ok(S_OK == VarBstrFromDate( 365.25, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2557         ok(strcmp(WtoA(bstr),"\"12/30/1900 6:00:00 AM\"")==0 ||
2558        strcmp(WtoA(bstr),"\"12/30/00 6:00:00 AM\"")==0 /* Win95 */,
2559        "should be '12/30/1900 6:00:00 AM', but is %s\n",WtoA(bstr));
2560
2561         ok(S_OK == VarBstrFromDate( 1461.0, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2562         ok(strcmp(WtoA(bstr),"\"12/31/1903\"")==0 ||
2563        strcmp(WtoA(bstr),"\"12/31/03\"")==0 /* Win95 */,
2564        "should be '12/31/1903', but is %s\n",WtoA(bstr));
2565
2566         ok(S_OK == VarBstrFromDate( 1461.5, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
2567         ok(strcmp(WtoA(bstr),"\"12/31/1903 12:00:00 PM\"")==0 ||
2568        strcmp(WtoA(bstr),"\"12/31/03 12:00:00 PM\"")==0 /* Win95 */,
2569        "should be '12/31/1903 12:00:00 PM', but is %s\n",WtoA(bstr));
2570
2571         /* Test variant API...
2572          */
2573         trace( "======== Testing Hi-Level Variant API ========\n");
2574
2575         bstr = SysAllocString( pOleChar[4] );
2576
2577         VariantClear( &va );
2578
2579         VariantInit( &va );
2580         VariantInit( &vb );
2581         VariantInit( &vc );
2582         VariantInit( &vd );
2583         VariantInit( &ve );
2584
2585         V_VT(&va) = VT_BSTR;
2586         V_UNION(&va,bstrVal) = bstr;
2587         ok(S_OK == VariantClear( &va ), XOK);
2588         SysFreeString( bstr );
2589         SysFreeString( bstr );
2590
2591         ok(S_OK == VariantCopy( &vb, &va ), XOK);
2592         ok(S_OK == VariantClear( &vb ), XOK);
2593         ok(S_OK == VariantClear( &va ), XOK);
2594
2595         V_VT(&va) = VT_R8;
2596         d = 4.123;
2597         V_UNION(&va,dblVal) = d;
2598         ok(S_OK == VariantCopy( &va, &va ), XOK);
2599         ok(V_R8(&va) == 4.123,"should be 4.123");
2600
2601         V_VT(&va) = VT_R8 | VT_BYREF;
2602         d = 31.123;
2603         V_UNION(&va,pdblVal) = &d;
2604         ok(S_OK == VariantCopyInd( &va, &va ), XOK);
2605         ok(V_R8(&va) == 31.123,"should be 31.123");
2606
2607         V_VT(&va) = VT_R8;
2608         d = 1.123;
2609         V_UNION(&va,dblVal) = d;
2610         ok(S_OK == VariantCopy( &vb, &va ), XOK);
2611         ok(V_R8(&vb) == 1.123,"should be 1.123");
2612
2613         V_VT(&va) = VT_R8 | VT_BYREF;
2614         d = 123.123;
2615         V_UNION(&va,pdblVal) = &d;
2616         ok(S_OK == VariantCopy( &vb, &va ), XOK);
2617         ok(*(V_R8REF(&vb)) == 123.123,"should be 123.123");
2618
2619         V_VT(&va) = VT_R8 | VT_BYREF;
2620         d = 111.2;
2621         V_UNION(&va,pdblVal) = &d;
2622         ok(S_OK == VariantCopyInd( &vb, &va ), XOK);
2623         ok(V_R8(&vb) == 111.2,"should be 111.2");
2624
2625         V_VT(&va) = VT_R8 | VT_BYREF;
2626         d = 1211.123453;
2627         V_UNION(&va,pdblVal) = &d;
2628         ok(S_OK == VariantChangeTypeEx( &va, &va, lcid, 0, VT_I2 ), XOK);
2629         ok(V_VT(&va) == VT_I2,"should be type VT_I2");
2630
2631         V_VT(&va) = VT_I4;
2632         V_UNION(&va,intVal) = 4;
2633         ok(S_OK == VariantChangeTypeEx(&vb, &va, lcid, 0, VT_BSTR ), XOK);
2634         ok(!strcmp(WtoA(V_BSTR(&vb)),"\"4\""),"should be 4");
2635
2636         V_VT(&va) = VT_DATE;
2637         V_UNION(&va,date) = 34465.332431;
2638         ok(S_OK == VariantChangeTypeEx(&vb, &va, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR ), XOK);
2639         ok(strcmp(WtoA(V_BSTR(&vb)),"\"5/11/1994 7:58:42 AM\"")==0 ||
2640        strcmp(WtoA(V_BSTR(&vb)),"\"5/11/94 7:58:42 AM\"")==0 /* Win95 */,
2641        "should be 5/11/94 7:58:42 AM got %s",WtoA(V_BSTR(&vb)));
2642
2643         bstr = pOleChar[4];
2644         V_VT(&va) = VT_BSTR;
2645         V_UNION(&va,bstrVal) = bstr;
2646         ok(S_OK == VariantChangeTypeEx(&vb, &va, lcid, 0, VT_R8 ), XOK);
2647         ok(V_R8(&vb) == -0.490000,"should be -0.49");
2648
2649         V_VT(&vc) = VT_BSTR | VT_BYREF;
2650         V_UNION(&vc,pbstrVal) = &bstr;
2651         V_VT(&vb) = VT_VARIANT | VT_BYREF;
2652         V_UNION(&vb,pvarVal) = &vc;
2653         V_VT(&va) = VT_VARIANT | VT_BYREF;
2654         V_UNION(&va,pvarVal) = &vb;
2655         ok(E_INVALIDARG == VariantCopyInd( &vd, &va ), "expect E_INVALIDARG");
2656
2657         /* test what happens when bad vartypes are passed in */
2658         trace( "======== Testing different VARTYPES ========\n" );
2659
2660         for( i=0; i<sizeof(vartypes)/sizeof(vartypes[0]); i++ )
2661         {
2662                     /* Trying to use variants that are set to be BSTR but
2663                      * do not contain a valid pointer makes the program crash
2664                      * in Windows so we will skip those. We do not need them
2665                      * anyway to illustrate the behavior.
2666                      */
2667                     V_VT(&va) = vartypes[i].ind;
2668                     d = 4.123;
2669                     V_UNION(&va,dblVal) = d;
2670                     rc = VariantCopyInd( &vb, &va );
2671             if (vartypes[i].todoind1) {
2672                 todo_wine {
2673                             ok(vartypes[i].vcind1 == rc,
2674                                "%d: vt %d, return value %lx, expected was %lx",
2675                                i,vartypes[i].ind,rc,vartypes[i].vcind1);
2676                 }
2677             } else {
2678                         ok(vartypes[i].vcind1 == rc,
2679                            "%d: vt %d, return value %lx, expected was %lx",
2680                            i,vartypes[i].ind,rc,vartypes[i].vcind1);
2681             }
2682                     V_VT(&va) = vartypes[i].ind | VT_BYREF;
2683                     d = 4.123;
2684                     V_UNION(&va,pdblVal) = &d;
2685                     rc = VariantCopyInd( &vb, &va );
2686                         ok(vartypes[i].vcind2 == rc,
2687                            "%d: vt %d, return value %lx, expected was %lx",
2688                            i,vartypes[i].ind,rc,vartypes[i].vcind2);
2689                     V_VT(&va) = VT_R8;
2690                     d = 4.123;
2691                     V_UNION(&va,dblVal) = d;
2692                     rc = VariantChangeTypeEx( &vb, &va, lcid, 0, (VARTYPE)i );
2693             if (vartypes[i].todowcex1) {
2694                 todo_wine {
2695                             ok(vartypes[i].vcex1 == rc || rc == DISP_E_BADVARTYPE,
2696                                "%d: vt %d, return value %lx, expected was %lx",
2697                                i,vartypes[i].ind,rc,vartypes[i].vcex1);
2698                 }
2699             } else {
2700                         ok(vartypes[i].vcex1 == rc || rc == DISP_E_BADVARTYPE,
2701                            "%d: vt %d, return value %lx, expected was %lx",
2702                            i,vartypes[i].ind,rc,vartypes[i].vcex1);
2703             }
2704                     V_VT(&va) = VT_R8;
2705                     d = 4.123;
2706                     V_UNION(&va,dblVal) = d;
2707                     rc = VariantChangeTypeEx( &vb, &va, lcid, 0, (VARTYPE)(i | VT_BYREF) );
2708             if (vartypes[i].todowcex2) {
2709                 todo_wine {
2710                             ok(vartypes[i].vcex2 == rc || rc == DISP_E_BADVARTYPE,
2711                                "%d: vt %d, return value %lx, expected was %lx",
2712                                i,vartypes[i].ind,rc,vartypes[i].vcex2);
2713                 }
2714             } else {
2715                         ok(vartypes[i].vcex2 == rc || rc == DISP_E_BADVARTYPE,
2716                            "%d: vt %d, return value %lx, expected was %lx",
2717                            i,vartypes[i].ind,rc,vartypes[i].vcex2);
2718             }
2719
2720                 V_VT(&va) = 99;
2721                 d = 4.123;
2722                 V_UNION(&va,dblVal) = d;
2723                 ok(DISP_E_BADVARTYPE == VariantClear( &va ), "should give DISP_E_BADVARTYPE");
2724         }
2725         VariantClear( &va );
2726         VariantClear( &vb );
2727         VariantClear( &vc );
2728         VariantClear( &vd );
2729         VariantClear( &ve );
2730         /* There is alot of memory leaks but this is simply a test program.
2731          */
2732 }
2733
2734 static void test_VariantInit(void)
2735 {
2736   VARIANTARG v1, v2;
2737
2738   /* Test that VariantInit() only sets the type */
2739   memset(&v1, -1, sizeof(v1));
2740   v2 = v1;
2741   V_VT(&v2) = VT_EMPTY;
2742   VariantInit(&v1);
2743   ok(!memcmp(&v1, &v2, sizeof(v1)), "VariantInit() set extra fields\n");
2744 }
2745
2746 /* All possible combinations of extra V_VT() flags */
2747 static const VARTYPE ExtraFlags[16] =
2748 {
2749   0,
2750   VT_VECTOR,
2751   VT_ARRAY,
2752   VT_BYREF,
2753   VT_RESERVED,
2754   VT_VECTOR|VT_ARRAY,
2755   VT_VECTOR|VT_BYREF,
2756   VT_VECTOR|VT_RESERVED,
2757   VT_VECTOR|VT_ARRAY|VT_BYREF,
2758   VT_VECTOR|VT_ARRAY|VT_RESERVED,
2759   VT_VECTOR|VT_BYREF|VT_RESERVED,
2760   VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED,
2761   VT_ARRAY|VT_BYREF,
2762   VT_ARRAY|VT_RESERVED,
2763   VT_ARRAY|VT_BYREF|VT_RESERVED,
2764   VT_BYREF|VT_RESERVED,
2765 };
2766
2767 /* Determine if a vt is valid for VariantClear() */
2768 static int IsValidVariantClearVT(VARTYPE vt, VARTYPE extraFlags)
2769 {
2770   int ret = 0;
2771
2772   /* Only the following flags/types are valid */
2773   if ((vt <= VT_LPWSTR || vt == VT_RECORD || vt == VT_CLSID) &&
2774       vt != (VARTYPE)15 &&
2775       (vt < (VARTYPE)24 || vt > (VARTYPE)31) &&
2776       (!(extraFlags & (VT_BYREF|VT_ARRAY)) || vt > VT_NULL) &&
2777       (extraFlags == 0 || extraFlags == VT_BYREF || extraFlags == VT_ARRAY ||
2778        extraFlags == (VT_ARRAY|VT_BYREF)))
2779     ret = 1; /* ok */
2780
2781   if ((vt == VT_RECORD && !HAVE_OLEAUT32_RECORD) ||
2782       ((vt == VT_I8 || vt == VT_UI8) && !HAVE_OLEAUT32_I8))
2783     ret = 0; /* Old versions of oleaut32 */
2784   return ret;
2785 }
2786
2787 static void test_VariantClear(void)
2788 {
2789   HRESULT hres;
2790   VARIANTARG v;
2791   size_t i;
2792
2793 #if 0
2794   /* Crashes: Native does not test input for NULL, so neither does Wine */
2795   hres = VariantClear(NULL);
2796 #endif
2797
2798   /* Only the type field is set, to VT_EMPTY */
2799   V_VT(&v) = VT_UI4;
2800   V_UI4(&v) = ~0u;
2801   hres = VariantClear(&v);
2802   ok(hres == S_OK && V_VT(&v) == VT_EMPTY, "VariantClear: Type set to %d\n", V_VT(&v));
2803   ok(V_UI4(&v) == ~0u, "VariantClear: Overwrote value\n");
2804
2805   /* Test all possible V_VT values.
2806    * Also demonstrates that null pointers in 'v' are not dereferenced.
2807    * Individual variant tests should test VariantClear() with non-NULL values.
2808    */
2809   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2810   {
2811     VARTYPE vt;
2812
2813     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2814     {
2815       HRESULT hExpected = DISP_E_BADVARTYPE;
2816
2817       memset(&v, 0, sizeof(v));
2818       V_VT(&v) = vt | ExtraFlags[i];
2819
2820       hres = VariantClear(&v);
2821
2822       if (IsValidVariantClearVT(vt, ExtraFlags[i]))
2823         hExpected = S_OK;
2824
2825       ok(hres == hExpected, "VariantClear: expected 0x%lX, got 0x%lX for vt %d | 0x%X\n",
2826          hExpected, hres, vt, ExtraFlags[i]);
2827     }
2828   }
2829 }
2830
2831 static void test_VariantCopy(void)
2832 {
2833   VARIANTARG vSrc, vDst;
2834   VARTYPE vt;
2835   size_t i;
2836   HRESULT hres, hExpected;
2837
2838   /* Establish that the failure/other cases are dealt with. Individual tests
2839    * for each type should verify that data is copied correctly, references
2840    * are updated, etc.
2841    */
2842
2843   /* vSrc == vDst */
2844   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2845   {
2846     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2847     {
2848       memset(&vSrc, 0, sizeof(vSrc));
2849       V_VT(&vSrc) = vt | ExtraFlags[i];
2850
2851       hExpected = DISP_E_BADVARTYPE;
2852       /* src is allowed to be a VT_CLSID */
2853       if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
2854         hExpected = S_OK;
2855
2856       hres = VariantCopy(&vSrc, &vSrc);
2857
2858       ok(hres == hExpected,
2859          "Copy(src==dst): expected 0x%lX, got 0x%lX for src==dest vt %d|0x%X\n",
2860          hExpected, hres, vt, ExtraFlags[i]);
2861     }
2862   }
2863
2864   /* Test that if VariantClear() fails on dest, the function fails. This also
2865    * shows that dest is in fact cleared and not just overwritten
2866    */
2867   memset(&vSrc, 0, sizeof(vSrc));
2868   V_VT(&vSrc) = VT_UI1;
2869
2870   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2871   {
2872     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2873     {
2874       hExpected = DISP_E_BADVARTYPE;
2875
2876       memset(&vDst, 0, sizeof(vDst));
2877       V_VT(&vDst) = vt | ExtraFlags[i];
2878
2879       if (IsValidVariantClearVT(vt, ExtraFlags[i]))
2880         hExpected = S_OK;
2881
2882       hres = VariantCopy(&vDst, &vSrc);
2883
2884       ok(hres == hExpected,
2885          "Copy(bad dst): expected 0x%lX, got 0x%lX for dest vt %d|0x%X\n",
2886          hExpected, hres, vt, ExtraFlags[i]);
2887       if (hres == S_OK)
2888         ok(V_VT(&vDst) == VT_UI1,
2889            "Copy(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
2890     }
2891   }
2892
2893   /* Test that VariantClear() checks vSrc for validity before copying */
2894   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2895   {
2896     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2897     {
2898       hExpected = DISP_E_BADVARTYPE;
2899
2900       memset(&vDst, 0, sizeof(vDst));
2901       V_VT(&vDst) = VT_EMPTY;
2902
2903       memset(&vSrc, 0, sizeof(vSrc));
2904       V_VT(&vSrc) = vt | ExtraFlags[i];
2905
2906       /* src is allowed to be a VT_CLSID */
2907       if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
2908         hExpected = S_OK;
2909
2910       hres = VariantCopy(&vDst, &vSrc);
2911
2912       ok(hres == hExpected,
2913          "Copy(bad src): expected 0x%lX, got 0x%lX for src vt %d|0x%X\n",
2914          hExpected, hres, vt, ExtraFlags[i]);
2915       if (hres == S_OK)
2916         ok(V_VT(&vDst) == (vt|ExtraFlags[i]),
2917            "Copy(bad src): expected vt = %d, got %d\n",
2918            vt | ExtraFlags[i], V_VT(&vDst));
2919     }
2920   }
2921 }
2922
2923 /* Determine if a vt is valid for VariantCopyInd() */
2924 static int IsValidVariantCopyIndVT(VARTYPE vt, VARTYPE extraFlags)
2925 {
2926   int ret = 0;
2927
2928   if ((extraFlags & VT_ARRAY) ||
2929      (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
2930      !(extraFlags & (VT_VECTOR|VT_RESERVED))))
2931   {
2932     ret = 1; /* ok */
2933   }
2934   return ret;
2935 }
2936
2937 static void test_VariantCopyInd(void)
2938 {
2939   VARIANTARG vSrc, vDst, vRef, vRef2;
2940   VARTYPE vt;
2941   size_t i;
2942   BYTE buffer[64];
2943   HRESULT hres, hExpected;
2944
2945   memset(buffer, 0, sizeof(buffer));
2946
2947   /* vSrc == vDst */
2948   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2949   {
2950     if (ExtraFlags[i] & VT_ARRAY)
2951       continue; /* Native crashes on NULL safearray */
2952
2953     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2954     {
2955       memset(&vSrc, 0, sizeof(vSrc));
2956       V_VT(&vSrc) = vt | ExtraFlags[i];
2957
2958       hExpected = DISP_E_BADVARTYPE;
2959       if (!(ExtraFlags[i] & VT_BYREF))
2960       {
2961         /* if src is not by-reference, acts as VariantCopy() */
2962         if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
2963           hExpected = S_OK;
2964       }
2965       else
2966       {
2967         if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
2968             vt == VT_DISPATCH || vt == VT_RECORD)
2969           continue; /* Need valid ptrs for deep copies */
2970
2971         V_BYREF(&vSrc) = &buffer;
2972         hExpected = E_INVALIDARG;
2973
2974         if ((vt == VT_I8 || vt == VT_UI8) &&
2975             ExtraFlags[i] == VT_BYREF)
2976         {
2977           if (HAVE_OLEAUT32_I8)
2978             hExpected = S_OK; /* Only valid if I8 is a known type */
2979         }
2980         else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
2981           hExpected = S_OK;
2982       }
2983
2984       hres = VariantCopyInd(&vSrc, &vSrc);
2985
2986       ok(hres == hExpected,
2987          "CopyInd(src==dst): expected 0x%lX, got 0x%lX for src==dst vt %d|0x%X\n",
2988          hExpected, hres, vt, ExtraFlags[i]);
2989     }
2990   }
2991
2992   /* Bad dest */
2993   memset(&vSrc, 0, sizeof(vSrc));
2994   V_VT(&vSrc) = VT_UI1|VT_BYREF;
2995   V_BYREF(&vSrc) = &buffer;
2996
2997   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
2998   {
2999     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3000     {
3001       memset(&vDst, 0, sizeof(vDst));
3002       V_VT(&vDst) = vt | ExtraFlags[i];
3003
3004       hExpected = DISP_E_BADVARTYPE;
3005
3006       if (IsValidVariantClearVT(vt, ExtraFlags[i]))
3007         hExpected = S_OK;
3008
3009       hres = VariantCopyInd(&vDst, &vSrc);
3010
3011       ok(hres == hExpected,
3012          "CopyInd(bad dst): expected 0x%lX, got 0x%lX for dst vt %d|0x%X\n",
3013          hExpected, hres, vt, ExtraFlags[i]);
3014       if (hres == S_OK)
3015         ok(V_VT(&vDst) == VT_UI1,
3016            "CopyInd(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
3017     }
3018   }
3019
3020   /* bad src */
3021   for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
3022   {
3023     if (ExtraFlags[i] & VT_ARRAY)
3024       continue; /* Native crashes on NULL safearray */
3025
3026     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3027     {
3028       memset(&vDst, 0, sizeof(vDst));
3029       V_VT(&vDst) = VT_EMPTY;
3030
3031       memset(&vSrc, 0, sizeof(vSrc));
3032       V_VT(&vSrc) = vt | ExtraFlags[i];
3033
3034       hExpected = DISP_E_BADVARTYPE;
3035       if (!(ExtraFlags[i] & VT_BYREF))
3036       {
3037         /* if src is not by-reference, acts as VariantCopy() */
3038         if (vt != VT_CLSID && IsValidVariantClearVT(vt, ExtraFlags[i]))
3039           hExpected = S_OK;
3040       }
3041       else
3042       {
3043         if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
3044             vt == VT_DISPATCH || vt == VT_RECORD)
3045           continue; /* Need valid ptrs for deep copies, see vartype.c */
3046
3047         V_BYREF(&vSrc) = &buffer;
3048
3049         hExpected = E_INVALIDARG;
3050
3051         if ((vt == VT_I8 || vt == VT_UI8) &&
3052             ExtraFlags[i] == VT_BYREF)
3053         {
3054           if (HAVE_OLEAUT32_I8)
3055             hExpected = S_OK; /* Only valid if I8 is a known type */
3056         }
3057         else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
3058           hExpected = S_OK;
3059       }
3060
3061       hres = VariantCopyInd(&vDst, &vSrc);
3062
3063       ok(hres == hExpected,
3064          "CopyInd(bad src): expected 0x%lX, got 0x%lX for src vt %d|0x%X\n",
3065          hExpected, hres, vt, ExtraFlags[i]);
3066       if (hres == S_OK)
3067       {
3068         if (vt == VT_VARIANT && ExtraFlags[i] == VT_BYREF)
3069         {
3070           /* Type of vDst should be the type of the referenced variant.
3071            * Since we set the buffer to all zeros, its type should be
3072            * VT_EMPTY.
3073            */
3074           ok(V_VT(&vDst) == VT_EMPTY,
3075              "CopyInd(bad src): expected dst vt = VT_EMPTY, got %d|0x%X\n",
3076              V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
3077         }
3078         else
3079         {
3080           ok(V_VT(&vDst) == (vt|(ExtraFlags[i] & ~VT_BYREF)),
3081              "CopyInd(bad src): expected dst vt = %d|0x%X, got %d|0x%X\n",
3082              vt, ExtraFlags[i] & ~VT_BYREF,
3083              V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
3084         }
3085       }
3086     }
3087   }
3088
3089   /* By-reference variants are dereferenced */
3090   V_VT(&vRef) = VT_UI1;
3091   V_UI1(&vRef) = 0x77;
3092   V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
3093   V_VARIANTREF(&vSrc) = &vRef;
3094   VariantInit(&vDst);
3095
3096   hres = VariantCopyInd(&vDst, &vSrc);
3097   ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
3098      "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
3099       V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
3100
3101   /* By-reference variant to a by-reference type succeeds */
3102   V_VT(&vRef) = VT_UI1|VT_BYREF;
3103   V_UI1REF(&vRef) = buffer; buffer[0] = 0x88;
3104   V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
3105   V_VARIANTREF(&vSrc) = &vRef;
3106   VariantInit(&vDst);
3107
3108   hres = VariantCopyInd(&vDst, &vSrc);
3109   ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
3110      "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
3111       V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
3112
3113   /* But a by-reference variant to a by-reference variant fails */
3114   V_VT(&vRef2) = VT_UI1;
3115   V_UI1(&vRef2) = 0x77;
3116   V_VT(&vRef) = VT_VARIANT|VT_BYREF;
3117   V_VARIANTREF(&vRef) = &vRef2;
3118   V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
3119   V_VARIANTREF(&vSrc) = &vRef;
3120   VariantInit(&vDst);
3121
3122   hres = VariantCopyInd(&vDst, &vSrc);
3123   ok(hres == E_INVALIDARG,
3124      "CopyInd(ref->ref): expected E_INVALIDARG, got 0x%08lx\n", hres);
3125 }
3126
3127 /* Macros for converting and testing the result of VarParseNumFromStr */
3128 #define FAILDIG 255
3129 #define CONVERTN(str,dig,flags) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)); \
3130   memset(rgb, FAILDIG, sizeof(rgb)); memset(&np,-1,sizeof(np)); np.cDig = dig; np.dwInFlags = flags; \
3131   hres = VarParseNumFromStr(buff,lcid,LOCALE_NOUSEROVERRIDE,&np,rgb)
3132 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
3133 #define EXPECT(a,b,c,d,e,f) ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
3134   if (hres == (HRESULT)S_OK) { \
3135     ok(np.cDig == (a), "Expected cDig = %d, got %d\n", (a), np.cDig); \
3136     ok(np.dwInFlags == (b), "Expected dwInFlags = 0x%lx, got 0x%lx\n", (ULONG)(b), np.dwInFlags); \
3137     ok(np.dwOutFlags == (c), "Expected dwOutFlags = 0x%lx, got 0x%lx\n", (ULONG)(c), np.dwOutFlags); \
3138     ok(np.cchUsed == (d), "Expected cchUsed = %d, got %d\n", (d), np.cchUsed); \
3139     ok(np.nBaseShift == (e), "Expected nBaseShift = %d, got %d\n", (e), np.nBaseShift); \
3140     ok(np.nPwr10 == (f), "Expected nPwr10 = %d, got %d\n", (f), np.nPwr10); \
3141   }
3142 #define EXPECTRGB(a,b) ok(rgb[a] == b, "Digit[%d], expected %d, got %d\n", a, b, rgb[a])
3143 #define EXPECTFAIL ok(hres == (HRESULT)DISP_E_TYPEMISMATCH, "Call succeeded, hres = %08lx\n", hres)
3144 #define EXPECT2(a,b) EXPECTRGB(0,a); EXPECTRGB(1,b)
3145
3146 static void test_VarParseNumFromStr(void)
3147 {
3148   HRESULT hres;
3149   OLECHAR buff[128];
3150   /* Ensure all tests are using the same locale characters for '$', ',' etc */
3151   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
3152   NUMPARSE np;
3153   BYTE rgb[128];
3154
3155   /** No flags **/
3156
3157   /* Consume a single digit */
3158   CONVERT("7", 0);
3159   EXPECT(1,0,0,1,0,0);
3160   EXPECT2(7,FAILDIG);
3161
3162   /* cDig is not literal digits - zeros are suppressed and nPwr10 is increased */
3163   CONVERT("10", 0);
3164   EXPECT(1,0,0,2,0,1);
3165   /* Note: Win32 writes the trailing zeros if they are within cDig's limits,
3166    * but then excludes them from the returned cDig count.
3167    * In our implementation we don't bother writing them at all.
3168    */
3169   EXPECTRGB(0, 1);
3170
3171   /* if cDig is too small and numbers follow, sets INEXACT */
3172   CONVERTN("11",1, 0);
3173   EXPECT(1,0,NUMPRS_INEXACT,2,0,1);
3174   EXPECT2(1,FAILDIG);
3175
3176   /* Strips leading zeros */
3177   CONVERT("01", 0);
3178   EXPECT(1,0,0,2,0,0);
3179   EXPECT2(1,FAILDIG);
3180
3181   /* Strips leading zeros */
3182   CONVERTN("01",1, 0);
3183   EXPECT(1,0,0,2,0,0);
3184   EXPECT2(1,FAILDIG);
3185
3186
3187   /* Fails on non digits */
3188   CONVERT("a", 0);
3189   EXPECTFAIL;
3190   EXPECTRGB(0,FAILDIG);
3191
3192   /** NUMPRS_LEADING_WHITE/NUMPRS_TRAILING_WHITE **/
3193
3194   /* Without flag, fails on whitespace */
3195   CONVERT(" 0", 0);
3196   EXPECTFAIL;
3197   EXPECTRGB(0,FAILDIG);
3198
3199
3200   /* With flag, consumes whitespace */
3201   CONVERT(" 0", NUMPRS_LEADING_WHITE);
3202   EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
3203   EXPECT2(0,FAILDIG);
3204
3205   /* Test TAB once, then assume it acts as space for all cases */
3206   CONVERT("\t0", NUMPRS_LEADING_WHITE);
3207   EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
3208   EXPECT2(0,FAILDIG);
3209
3210
3211   /* Doesn't pick up trailing whitespace without flag */
3212   CONVERT("0 ", 0);
3213   EXPECT(1,0,0,1,0,0);
3214   EXPECT2(0,FAILDIG);
3215
3216   /* With flag, consumes trailing whitespace */
3217   CONVERT("0 ", NUMPRS_TRAILING_WHITE);
3218   EXPECT(1,NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
3219   EXPECT2(0,FAILDIG);
3220
3221   /* Leading flag only consumes leading */
3222   CONVERT(" 0 ", NUMPRS_LEADING_WHITE);
3223   EXPECT(1,NUMPRS_LEADING_WHITE,NUMPRS_LEADING_WHITE,2,0,0);
3224   EXPECT2(0,FAILDIG);
3225
3226   /* Both flags consumes both */
3227   CONVERT(" 0 ", NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE);
3228   EXPECT(1,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,NUMPRS_LEADING_WHITE|NUMPRS_TRAILING_WHITE,3,0,0);
3229   EXPECT2(0,FAILDIG);
3230
3231   /** NUMPRS_LEADING_PLUS/NUMPRS_TRAILING_PLUS **/
3232
3233   /* Without flag, fails on + */
3234   CONVERT("+0", 0);
3235   EXPECTFAIL;
3236   EXPECTRGB(0,FAILDIG);
3237
3238   /* With flag, consumes + */
3239   CONVERT("+0", NUMPRS_LEADING_PLUS);
3240   EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
3241   EXPECT2(0,FAILDIG);
3242
3243   /* Without flag, doesn't consume trailing + */
3244   CONVERT("0+", 0);
3245   EXPECT(1,0,0,1,0,0);
3246   EXPECT2(0,FAILDIG);
3247
3248   /* With flag, consumes trailing + */
3249   CONVERT("0+", NUMPRS_TRAILING_PLUS);
3250   EXPECT(1,NUMPRS_TRAILING_PLUS,NUMPRS_TRAILING_PLUS,2,0,0);
3251   EXPECT2(0,FAILDIG);
3252
3253   /* With leading flag, doesn't consume trailing + */
3254   CONVERT("+0+", NUMPRS_LEADING_PLUS);
3255   EXPECT(1,NUMPRS_LEADING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
3256   EXPECT2(0,FAILDIG);
3257
3258   /* Trailing + doesn't get consumed if we specify both (unlike whitespace) */
3259   CONVERT("+0+", NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS);
3260   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_TRAILING_PLUS,NUMPRS_LEADING_PLUS,2,0,0);
3261   EXPECT2(0,FAILDIG);
3262
3263   /** NUMPRS_LEADING_MINUS/NUMPRS_TRAILING_MINUS **/
3264
3265   /* Without flag, fails on - */
3266   CONVERT("-0", 0);
3267   EXPECTFAIL;
3268   EXPECTRGB(0,FAILDIG);
3269
3270   /* With flag, consumes - */
3271   CONVERT("-0", NUMPRS_LEADING_MINUS);
3272   EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
3273   EXPECT2(0,FAILDIG);
3274
3275   /* Without flag, doesn't consume trailing - */
3276   CONVERT("0-", 0);
3277   EXPECT(1,0,0,1,0,0);
3278   EXPECT2(0,FAILDIG);
3279
3280   /* With flag, consumes trailing - */
3281   CONVERT("0-", NUMPRS_TRAILING_MINUS);
3282   EXPECT(1,NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_TRAILING_MINUS,2,0,0);
3283   EXPECT2(0,FAILDIG);
3284
3285   /* With leading flag, doesn't consume trailing - */
3286   CONVERT("-0-", NUMPRS_LEADING_MINUS);
3287   EXPECT(1,NUMPRS_LEADING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
3288   EXPECT2(0,FAILDIG);
3289
3290   /* Trailing - doesn't get consumed if we specify both (unlike whitespace) */
3291   CONVERT("-0-", NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS);
3292   EXPECT(1,NUMPRS_LEADING_MINUS|NUMPRS_TRAILING_MINUS,NUMPRS_NEG|NUMPRS_LEADING_MINUS,2,0,0);
3293   EXPECT2(0,FAILDIG);
3294
3295   /** NUMPRS_HEX_OCT **/
3296
3297   /* Could be hex, octal or decimal - With flag reads as decimal */
3298   CONVERT("0", NUMPRS_HEX_OCT);
3299   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
3300   EXPECT2(0,FAILDIG);
3301
3302   /* Doesn't recognise hex in .asm sytax */
3303   CONVERT("0h", NUMPRS_HEX_OCT);
3304   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
3305   EXPECT2(0,FAILDIG);
3306
3307   /* Doesn't fail with valid leading string but no digits */
3308   CONVERT("0x", NUMPRS_HEX_OCT);
3309   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
3310   EXPECT2(0,FAILDIG);
3311
3312   /* Doesn't recognise hex format humbers at all! */
3313   CONVERT("0x0", NUMPRS_HEX_OCT);
3314   EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
3315   EXPECT2(0,FAILDIG);
3316
3317   /* Doesn't recognise plain hex digits either */
3318   CONVERT("FE", NUMPRS_HEX_OCT);
3319   EXPECTFAIL;
3320   EXPECTRGB(0,FAILDIG);
3321
3322   /* Octal */
3323   CONVERT("0100", NUMPRS_HEX_OCT);
3324   EXPECT(1,NUMPRS_HEX_OCT,0,4,0,2);
3325   EXPECTRGB(0,1);
3326   todo_wine
3327   {
3328     EXPECTRGB(1,0);
3329     EXPECTRGB(2,0);
3330   }
3331   EXPECTRGB(3,FAILDIG);
3332
3333   /** NUMPRS_PARENS **/
3334
3335   /* Empty parens = error */
3336   CONVERT("()", NUMPRS_PARENS);
3337   EXPECTFAIL;
3338   EXPECTRGB(0,FAILDIG);
3339
3340   /* With flag, trailing parens not consumed */
3341   CONVERT("0()", NUMPRS_PARENS);
3342   EXPECT(1,NUMPRS_PARENS,0,1,0,0);
3343   EXPECT2(0,FAILDIG);
3344
3345   /* With flag, Number in parens made negative and parens consumed */
3346   CONVERT("(0)", NUMPRS_PARENS);
3347   EXPECT(1,NUMPRS_PARENS,NUMPRS_NEG|NUMPRS_PARENS,3,0,0);
3348   EXPECT2(0,FAILDIG);
3349
3350   /** NUMPRS_THOUSANDS **/
3351
3352   /* With flag, thousands sep. not needed */
3353   CONVERT("0", NUMPRS_THOUSANDS);
3354   EXPECT(1,NUMPRS_THOUSANDS,0,1,0,0);
3355   EXPECT2(0,FAILDIG);
3356
3357   /* With flag, thousands sep. and following digits consumed */
3358   CONVERT("1,000", NUMPRS_THOUSANDS);
3359   EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
3360   EXPECTRGB(0,1);
3361
3362   /* With flag and decimal point, thousands sep. but not decimals consumed */
3363   CONVERT("1,000.0", NUMPRS_THOUSANDS);
3364   EXPECT(1,NUMPRS_THOUSANDS,NUMPRS_THOUSANDS,5,0,3);
3365   EXPECTRGB(0,1);
3366
3367   /** NUMPRS_CURRENCY **/
3368
3369   /* Without flag, chokes on currency sign */
3370   CONVERT("$11", 0);
3371   EXPECTFAIL;
3372   EXPECTRGB(0,FAILDIG);
3373
3374   /* With flag, consumes currency sign */
3375   CONVERT("$11", NUMPRS_CURRENCY);
3376   EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
3377   EXPECT2(1,1);
3378   EXPECTRGB(2,FAILDIG);
3379
3380   /* With flag only, doesn't consume decimal point */
3381   CONVERT("$11.1", NUMPRS_CURRENCY);
3382   EXPECT(2,NUMPRS_CURRENCY,NUMPRS_CURRENCY,3,0,0);
3383   EXPECT2(1,1);
3384   EXPECTRGB(2,FAILDIG);
3385
3386   /* With flag and decimal flag, consumes decimal point and following digits */
3387   CONVERT("$11.1", NUMPRS_CURRENCY|NUMPRS_DECIMAL);
3388   EXPECT(3,NUMPRS_CURRENCY|NUMPRS_DECIMAL,NUMPRS_CURRENCY|NUMPRS_DECIMAL,5,0,-1);
3389   EXPECT2(1,1);
3390   EXPECTRGB(2,1);
3391   EXPECTRGB(3,FAILDIG);
3392
3393   /* Thousands flag can only be used with currency */
3394   CONVERT("$1,234", NUMPRS_CURRENCY|NUMPRS_THOUSANDS);
3395   EXPECT(4,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,NUMPRS_CURRENCY|NUMPRS_THOUSANDS,6,0,0);
3396   EXPECT2(1,2);
3397   EXPECTRGB(2,3);
3398   EXPECTRGB(3,4);
3399   EXPECTRGB(4,FAILDIG);
3400
3401   /** NUMPRS_DECIMAL **/
3402
3403   /* With flag, consumes decimal point */
3404   CONVERT("1.1", NUMPRS_DECIMAL);
3405   EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
3406   EXPECT2(1,1);
3407   EXPECTRGB(2,FAILDIG);
3408
3409   /* With flag, consumes decimal point. Skipping the decimal part is not an error */
3410   CONVERT("1.", NUMPRS_DECIMAL);
3411   EXPECT(1,NUMPRS_DECIMAL,NUMPRS_DECIMAL,2,0,0);
3412   EXPECT2(1,FAILDIG);
3413
3414   /* Consumes only one decimal point */
3415   CONVERT("1.1.", NUMPRS_DECIMAL);
3416   EXPECT(2,NUMPRS_DECIMAL,NUMPRS_DECIMAL,3,0,-1);
3417   EXPECT2(1,1);
3418   EXPECTRGB(2,FAILDIG);
3419
3420   /** NUMPRS_EXPONENT **/
3421
3422   /* Without flag, doesn't consume exponent */
3423   CONVERT("1e1", 0);
3424   EXPECT(1,0,0,1,0,0);
3425   EXPECT2(1,FAILDIG);
3426
3427   /* With flag, consumes exponent */
3428   CONVERT("1e1", NUMPRS_EXPONENT);
3429   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
3430   EXPECT2(1,FAILDIG);
3431
3432   /* Negative exponents are accepted without flags */
3433   CONVERT("1e-1", NUMPRS_EXPONENT);
3434   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,4,0,-1);
3435   EXPECT2(1,FAILDIG);
3436
3437   /* As are positive exponents and leading exponent 0's */
3438   CONVERT("1e+01", NUMPRS_EXPONENT);
3439   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,5,0,1);
3440   EXPECT2(1,FAILDIG);
3441
3442   /* Doesn't consume a real number exponent */
3443   CONVERT("1e1.", NUMPRS_EXPONENT);
3444   EXPECT(1,NUMPRS_EXPONENT,NUMPRS_EXPONENT,3,0,1);
3445   EXPECT2(1,FAILDIG);
3446
3447   /* Powers of 10 are calculated from the position of any decimal point */
3448   CONVERT("1.5e20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
3449   EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,6,0,19);
3450   EXPECT2(1,5);
3451
3452   CONVERT("1.5e-20", NUMPRS_EXPONENT|NUMPRS_DECIMAL);
3453   EXPECT(2,NUMPRS_EXPONENT|NUMPRS_DECIMAL,NUMPRS_EXPONENT|NUMPRS_DECIMAL,7,0,-21);
3454   EXPECT2(1,5);
3455
3456   /** NUMPRS_USE_ALL **/
3457
3458   /* Flag expects all digits */
3459   CONVERT("0", NUMPRS_USE_ALL);
3460   EXPECT(1,NUMPRS_USE_ALL,0,1,0,0);
3461   EXPECT2(0,FAILDIG);
3462
3463   /* Rejects anything trailing */
3464   CONVERT("0 ", NUMPRS_USE_ALL);
3465   EXPECTFAIL;
3466   EXPECT2(0,FAILDIG);
3467
3468   /* Unless consumed by trailing flag */
3469   CONVERT("0 ", NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE);
3470   EXPECT(1,NUMPRS_USE_ALL|NUMPRS_TRAILING_WHITE,NUMPRS_TRAILING_WHITE,2,0,0);
3471   EXPECT2(0,FAILDIG);
3472
3473   /** Combinations **/
3474
3475   /* Leading whitepace and plus, doesn't consume trailing whitespace */
3476   CONVERT("+ 0 ", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
3477   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
3478   EXPECT2(0,FAILDIG);
3479
3480   /* Order of whitepace and plus is unimportant */
3481   CONVERT(" +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
3482   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,3,0,0);
3483   EXPECT2(0,FAILDIG);
3484
3485   /* Leading whitespace can be repeated */
3486   CONVERT(" + 0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
3487   EXPECT(1,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE,4,0,0);
3488   EXPECT2(0,FAILDIG);
3489
3490   /* But plus/minus etc. cannot */
3491   CONVERT("+ +0", NUMPRS_LEADING_PLUS|NUMPRS_LEADING_WHITE);
3492   EXPECTFAIL;
3493   EXPECTRGB(0,FAILDIG);
3494
3495   /* Inexact is not set if trailing zeros are removed */
3496   CONVERTN("10", 1, 0);
3497   EXPECT(1,0,0,2,0,1);
3498   EXPECT2(1,FAILDIG);
3499
3500   /* Make sure a leading 0 is stripped but decimals after it get read */
3501   CONVERT("-0.51", NUMPRS_STD);
3502   EXPECT(2,NUMPRS_STD,NUMPRS_NEG|NUMPRS_DECIMAL|NUMPRS_LEADING_MINUS,5,0,-2);
3503   EXPECT2(5,1);
3504 }
3505
3506 /* Macros for converting and testing the result of VarNumFromParseNum */
3507 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
3508 #undef CONVERT
3509 #define CONVERT(a,b,c,d,e,f,bits) \
3510     np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
3511     np.nBaseShift = (e); np.nPwr10 = (f); hres = VarNumFromParseNum(&np, rgb, bits, &vOut)
3512 #define EXPECT_OVERFLOW ok(hres == (HRESULT)DISP_E_OVERFLOW, "Expected overflow, hres = %08lx\n", hres)
3513 #define EXPECT_OK ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
3514   if (hres == (HRESULT)S_OK)
3515 #define EXPECT_TYPE(typ) ok(V_VT(&vOut) == typ,"Expected Type = " #typ ", got %d\n", V_VT(&vOut))
3516 #define EXPECT_I1(val) EXPECT_OK { EXPECT_TYPE(VT_I1); \
3517   ok(V_I1(&vOut) == val, "Expected i1 = %d, got %d\n", (signed char)val, V_I1(&vOut)); }
3518 #define EXPECT_UI1(val) EXPECT_OK { EXPECT_TYPE(VT_UI1); \
3519   ok(V_UI1(&vOut) == val, "Expected ui1 = %d, got %d\n", (BYTE)val, V_UI1(&vOut)); }
3520 #define EXPECT_I2(val) EXPECT_OK { EXPECT_TYPE(VT_I2); \
3521   ok(V_I2(&vOut) == val, "Expected i2 = %d, got %d\n", (SHORT)val, V_I2(&vOut)); }
3522 #define EXPECT_UI2(val) EXPECT_OK { EXPECT_TYPE(VT_UI2); \
3523   ok(V_UI2(&vOut) == val, "Expected ui2 = %d, got %d\n", (USHORT)val, V_UI2(&vOut)); }
3524 #define EXPECT_I4(val) EXPECT_OK { EXPECT_TYPE(VT_I4); \
3525   ok(V_I4(&vOut) == val, "Expected i4 = %ld, got %ld\n", (LONG)val, V_I4(&vOut)); }
3526 #define EXPECT_UI4(val) EXPECT_OK { EXPECT_TYPE(VT_UI4); \
3527   ok(V_UI4(&vOut) == val, "Expected ui4 = %ld, got %ld\n", (ULONG)val, V_UI4(&vOut)); }
3528 #define EXPECT_I8(val) EXPECT_OK { EXPECT_TYPE(VT_I8); \
3529   ok(V_I8(&vOut) == val, "Expected i8 = %lld, got %lld\n", (LONG64)val, V_I8(&vOut)); }
3530 #define EXPECT_UI8(val) EXPECT_OK { EXPECT_TYPE(VT_UI8); \
3531   ok(V_UI8(&vOut) == val, "Expected ui8 = %lld, got %lld\n", (ULONG64)val, V_UI8(&vOut)); }
3532 #define EXPECT_R4(val) EXPECT_OK { EXPECT_TYPE(VT_R4); \
3533   ok(V_R4(&vOut) == val, "Expected r4 = %f, got %f\n", val, V_R4(&vOut)); }
3534 #define EXPECT_R8(val) EXPECT_OK { EXPECT_TYPE(VT_R8); \
3535   ok(V_R8(&vOut) == val, "Expected r8 = %g, got %g\n", val, V_R8(&vOut)); }
3536 #define CY_MULTIPLIER 10000
3537 #define EXPECT_CY(val) EXPECT_OK { EXPECT_TYPE(VT_CY); \
3538   ok(V_CY(&vOut).int64 == (LONG64)(val * CY_MULTIPLIER), "Expected r8 = %lld, got %lld\n", (LONG64)val, V_CY(&vOut).int64); }
3539
3540 static void test_VarNumFromParseNum(void)
3541 {
3542   HRESULT hres;
3543   NUMPARSE np;
3544   BYTE rgb[128];
3545   VARIANT vOut;
3546
3547   /* Convert the number 1 to different types */
3548   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1); EXPECT_I1(1);
3549   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1); EXPECT_UI1(1);
3550   /* Prefers a signed type to unsigned of the same size */
3551   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1|VTBIT_UI1); EXPECT_I1(1);
3552   /* But takes the smaller size if possible */
3553   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I2|VTBIT_UI1); EXPECT_UI1(1);
3554
3555   /* Try different integer sizes */
3556 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
3557
3558   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, INTEGER_VTBITS); EXPECT_I1(1);
3559   /* 127 */
3560   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 7);
3561   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I1(127);
3562   /* 128 */
3563   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
3564   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(128);
3565   /* 255 */
3566   SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 5);
3567   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(255);
3568   /* 256 */
3569   SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 6);
3570   CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I2(256);
3571   /* 32767 */
3572   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 7);
3573   CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_I2(32767);
3574   /* 32768 */
3575   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
3576   CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_UI2(32768);
3577
3578   /* Assume the above pattern holds for remaining positive integers; test negative */
3579
3580   /* -128 */
3581   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
3582   CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I1(-128);
3583   /* -129 */
3584   SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 9);
3585   CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I2(-129);
3586   /* -32768 */
3587   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
3588   CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I2(-32768);
3589   /* -32768 */
3590   SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 9);
3591   CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I4(-32769);
3592
3593   /* Assume the above pattern holds for remaining negative integers */
3594
3595   /* Negative numbers overflow if we have only unsigned outputs */
3596   /* -1 */
3597   SETRGB(0, 1); CONVERT(1,0,NUMPRS_NEG,1,0,0, VTBIT_UI1); EXPECT_OVERFLOW;
3598   /* -0.6 */
3599   SETRGB(0, 6); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_OVERFLOW;
3600
3601   /* Except that rounding is done first, so -0.5 to 0 are accepted as 0 */
3602   /* -0.5 */
3603   SETRGB(0, 5); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_UI1(0);
3604
3605   /* Float is acceptable for an integer input value */
3606   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4); EXPECT_R4(1.0f);
3607   /* As is double */
3608   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8); EXPECT_R8(1.0);
3609   /* As is currency */
3610   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY); EXPECT_CY(1);
3611
3612   /* Float is preferred over double */
3613   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4|VTBIT_R8); EXPECT_R4(1.0f);
3614
3615   /* Double is preferred over currency */
3616   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8|VTBIT_CY); EXPECT_R8(1.0);
3617
3618   /* Currency is preferred over decimal */
3619   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY|VTBIT_DECIMAL); EXPECT_CY(1);
3620 }
3621
3622 #define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) \
3623   memset(&ud, 0, sizeof(ud)); \
3624   res = pVarUdateFromDate(dt, flags, &ud); \
3625   ok(r == res && (FAILED(r) || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d && \
3626      ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s && \
3627      ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)), \
3628      "%.16g expected %lx, %d,%d,%d,%d,%d,%d,%d  %d %d, got %lx, %d,%d,%d,%d,%d,%d,%d  %d %d\n", \
3629      dt, r, d, m, y, h, mn, s, ms, dw, dy, res, ud.st.wDay, ud.st.wMonth, \
3630      ud.st.wYear, ud.st.wHour, ud.st.wMinute, ud.st.wSecond, \
3631      ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear)
3632
3633 static void test_VarUdateFromDate(void)
3634 {
3635   UDATE ud;
3636   HRESULT res;
3637
3638   CHECKPTR(VarUdateFromDate);
3639   DT2UD(29221.0,0,S_OK,1,1,1980,0,0,0,0,2,1);        /* 1 Jan 1980 */
3640   DT2UD(29222.0,0,S_OK,2,1,1980,0,0,0,0,3,2);        /* 2 Jan 1980 */
3641   DT2UD(33238.0,0,S_OK,31,12,1990,0,0,0,0,1,365);    /* 31 Dec 1990 */
3642   DT2UD(0.0,0,S_OK,30,12,1899,0,0,0,0,6,364);        /* 30 Dec 1899 - VT_DATE 0.0 */
3643   DT2UD(-657434.0,0,S_OK,1,1,100,0,0,0,0,5,1);       /* 1 Jan 100 - Min */
3644   DT2UD(-657435.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* < 1 Jan 100 => err */
3645   DT2UD(2958465.0,0,S_OK,31,12,9999,0,0,0,0,5,365);  /* 31 Dec 9999 - Max */
3646   DT2UD(2958466.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* > 31 Dec 9999 => err  */
3647
3648   /* VAR_VALIDDATE doesn't prevent upper and lower bounds being checked */
3649   DT2UD(-657435.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
3650   DT2UD(2958466.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
3651
3652   /* Times */
3653   DT2UD(29221.25,0,S_OK,1,1,1980,6,0,0,0,2,1);           /* 6 AM */
3654   DT2UD(29221.33333333,0,S_OK,1,1,1980,8,0,0,0,2,1);     /* 8 AM */
3655   DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1);           /* 12 AM */
3656   DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
3657   DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
3658
3659 }
3660
3661 #define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) \
3662   ud.st.wYear = (y); ud.st.wMonth = (m); ud.st.wDay = (d); ud.st.wHour = (h); \
3663   ud.st.wMinute = (mn); ud.st.wSecond = (s); ud.st.wMilliseconds = (ms); \
3664   ud.st.wDayOfWeek = (dw); ud.wDayOfYear = (dy); \
3665   res = pVarDateFromUdate(&ud, (flags), &out); \
3666   ok((r) == res && (FAILED(r) || fabs(out-(dt)) < 1.0e-11), \
3667      "expected %lx, %.16g, got %lx, %.16g\n", r, dt, res, out)
3668
3669 static void test_VarDateFromUdate(void)
3670 {
3671   UDATE ud;
3672   double out;
3673   HRESULT res;
3674
3675   CHECKPTR(VarDateFromUdate);
3676   UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK,29221.0);      /* 1 Jan 1980 */
3677   UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK,29222.0);      /* 2 Jan 1980 */
3678   UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK,33238.0);    /* 31 Dec 1990 */
3679   UD2T(31,12,90,0,0,0,0,0,0,0,S_OK,33238.0);      /* year < 100 is 1900+year! */
3680   UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK,0.0);      /* 30 Dec 1899 - VT_DATE 0.0 */
3681   UD2T(1,1,100,0,0,0,0,0,0,0,S_OK,-657434.0);     /* 1 Jan 100 - Min */
3682   UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK,2958465.0);  /* 31 Dec 9999 - Max */
3683   UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0); /* > 31 Dec 9999 => err  */
3684
3685   UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */
3686
3687   UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0);      /* Rolls back to 31 Dec 1899 */
3688   UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0);     /* Rolls fwd to 1/1/1981 */
3689 }
3690
3691 #define ST2DT(d,m,y,h,mn,s,ms,r,dt) \
3692   st.wYear = y; st.wMonth = m; st.wDay = d; st.wHour = h; st.wMinute = mn; \
3693   st.wSecond = s; st.wMilliseconds = ms; st.wDayOfWeek = 0; \
3694   res = pSystemTimeToVariantTime(&st, &out); \
3695   ok(r == res && (!r || fabs(out-dt) < 1.0e-11), \
3696      "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out)
3697
3698 static void test_SystemTimeToVariantTime(void)
3699 {
3700   SYSTEMTIME st;
3701   double out;
3702   int res;
3703
3704   CHECKPTR(SystemTimeToVariantTime);
3705   ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0);
3706   ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0);
3707   ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0);   /* Rolls back to 31 Dec 1899 */
3708   ST2DT(1,13,1980,0,0,0,0,FALSE,29587.0); /* Fails on invalid month */
3709   ST2DT(31,12,90,0,0,0,0,TRUE,33238.0);   /* year < 100 is 1900+year! */
3710 }
3711
3712 #define DT2ST(dt,r,d,m,y,h,mn,s,ms) \
3713   memset(&st, 0, sizeof(st)); \
3714   res = pVariantTimeToSystemTime(dt, &st); \
3715   ok(r == res && (!r || (st.wYear == y && st.wMonth == m && st.wDay == d && \
3716      st.wHour == h && st.wMinute == mn && st.wSecond == s && \
3717      st.wMilliseconds == ms)), \
3718      "%.16g expected %d, %d,%d,%d,%d,%d,%d,%d, got %d, %d,%d,%d,%d,%d,%d,%d\n", \
3719      dt, r, d, m, y, h, mn, s, ms, res, st.wDay, st.wMonth, st.wYear, \
3720      st.wHour, st.wMinute, st.wSecond, st.wMilliseconds)
3721
3722 static void test_VariantTimeToSystemTime(void)
3723 {
3724   SYSTEMTIME st;
3725   int res;
3726
3727   CHECKPTR(VariantTimeToSystemTime);
3728   DT2ST(29221.0,1,1,1,1980,0,0,0,0);
3729   DT2ST(29222.0,1,2,1,1980,0,0,0,0);
3730 }
3731
3732 #define MKDOSDATE(d,m,y) ((d & 0x1f) | ((m & 0xf) << 5) | (((y-1980) & 0x7f) << 9))
3733 #define MKDOSTIME(h,m,s) (((s>>1) & 0x1f) | ((m & 0x3f) << 5) | ((h & 0x1f) << 11))
3734
3735 #define DOS2DT(d,m,y,h,mn,s,r,dt) out = 0.0; \
3736   dosDate = MKDOSDATE(d,m,y); \
3737   dosTime = MKDOSTIME(h,mn,s); \
3738   res = pDosDateTimeToVariantTime(dosDate, dosTime, &out); \
3739   ok(r == res && (!r || fabs(out-dt) < 1.0e-11), \
3740      "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out)
3741
3742 static void test_DosDateTimeToVariantTime(void)
3743 {
3744   USHORT dosDate, dosTime;
3745   double out;
3746   INT res;
3747
3748   CHECKPTR(DosDateTimeToVariantTime);
3749
3750   /* Date */
3751   DOS2DT(1,1,1980,0,0,0,1,29221.0); /* 1/1/1980 */
3752   DOS2DT(31,12,2099,0,0,0,1,73050.0); /* 31/12/2099 */
3753   /* Dates are limited to the dos date max of 31/12/2099 */
3754   DOS2DT(31,12,2100,0,0,0,0,0.0); /* 31/12/2100 */
3755   /* Days and months of 0 cause date to roll back 1 day or month */
3756   DOS2DT(0,1,1980,0,0,0,1,29220.0); /* 0 Day => 31/12/1979 */
3757   DOS2DT(1,0,1980,0,0,0,1,29190.0); /* 0 Mth =>  1/12/1979 */
3758   DOS2DT(0,0,1980,0,0,0,1,29189.0); /* 0 D/M => 30/11/1979 */
3759   /* Days > days in the month cause date to roll forward 1 month */
3760   DOS2DT(29,2,1981,0,0,0,1,29646.0); /* 29/2/1981 -> 3/1/1980 */
3761   DOS2DT(30,2,1981,0,0,0,1,29647.0); /* 30/2/1981 -> 4/1/1980 */
3762   /* Takes leap years into account when rolling forward */
3763   DOS2DT(29,2,1980,0,0,0,1,29280.0); /* 2/29/1980 */
3764   /* Months > 12 cause an error */
3765   DOS2DT(2,13,1980,0,0,0,0,0.0);
3766
3767   /* Time */
3768   DOS2DT(1,1,1980,0,0,29,1,29221.00032407407); /* 1/1/1980 12:00:28 AM */
3769   DOS2DT(1,1,1980,0,0,31,1,29221.00034722222); /* 1/1/1980 12:00:30 AM */
3770   DOS2DT(1,1,1980,0,59,0,1,29221.04097222222); /* 1/1/1980 12:59:00 AM */
3771   DOS2DT(1,1,1980,0,60,0,0,0.0);               /* Invalid seconds */
3772   DOS2DT(1,1,1980,23,0,0,1,29221.95833333333); /* 1/1/1980 11:00:00 PM */
3773   DOS2DT(1,1,1980,24,0,0,0,0.0);               /* Invalid hours */
3774 }
3775
3776 #define DT2DOS(dt,r,d,m,y,h,mn,s) dosTime = dosDate = 0; \
3777   expDosDate = MKDOSDATE(d,m,y); \
3778   expDosTime = MKDOSTIME(h,mn,s); \
3779   res = pVariantTimeToDosDateTime(dt, &dosDate, &dosTime); \
3780   ok(r == res && (!r || (dosTime == expDosTime && dosDate == expDosDate)), \
3781      "%g: expected %d,%d(%d/%d/%d),%d(%d:%d:%d) got %d,%d(%d/%d/%d),%d(%d:%d:%d)\n", \
3782      dt, r, expDosDate, expDosDate & 0x1f, (expDosDate >> 5) & 0xf, 1980 + (expDosDate >> 9), \
3783      expDosTime, expDosTime >> 11, (expDosTime >> 5) & 0x3f, (expDosTime & 0x1f), \
3784      res, dosDate, dosDate & 0x1f, (dosDate >> 5) & 0xf, 1980 + (dosDate >> 9), \
3785      dosTime, dosTime >> 11, (dosTime >> 5) & 0x3f, (dosTime & 0x1f))
3786
3787 static void test_VariantTimeToDosDateTime(void)
3788 {
3789   USHORT dosDate, dosTime, expDosDate, expDosTime;
3790   INT res;
3791
3792   CHECKPTR(VariantTimeToDosDateTime);
3793
3794   /* Date */
3795   DT2DOS(29221.0,1,1,1,1980,0,0,0);   /* 1/1/1980 */
3796   DT2DOS(73050.0,1,31,12,2099,0,0,0); /* 31/12/2099 */
3797   DT2DOS(29220.0,0,0,0,0,0,0,0);      /* 31/12/1979 - out of range */
3798   DT2DOS(73415.0,0,0,0,0,0,0,0);      /* 31/12/2100 - out of range */
3799
3800   /* Time */
3801   DT2DOS(29221.00032407407,1,1,1,1980,0,0,29); /* 1/1/1980 12:00:28 AM */
3802   DT2DOS(29221.00034722222,1,1,1,1980,0,0,31); /* 1/1/1980 12:00:30 AM */
3803   DT2DOS(29221.04097222222,1,1,1,1980,0,59,0); /* 1/1/1980 12:59:00 AM */
3804   DT2DOS(29221.95833333333,1,1,1,1980,23,0,0); /* 1/1/1980 11:00:00 PM */
3805 }
3806
3807 #define FMT_NUMBER(vt,val) \
3808   VariantInit(&v); V_VT(&v) = vt; val(&v) = 1; \
3809   hres = pVarFormatNumber(&v,2,0,0,0,0,&str); \
3810   ok(hres == S_OK, "VarFormatNumber (vt %d): returned %8lx\n", vt, hres); \
3811   if (hres == S_OK) \
3812     ok(str && strcmpW(str,szResult1) == 0, \
3813        "VarFormatNumber (vt %d): string different\n", vt)
3814
3815 static void test_VarFormatNumber(void)
3816 {
3817   static WCHAR szSrc1[] = { '1','\0' };
3818   static WCHAR szResult1[] = { '1','.','0','0','\0' };
3819   static WCHAR szSrc2[] = { '-','1','\0' };
3820   static WCHAR szResult2[] = { '(','1','.','0','0',')','\0' };
3821   char buff[8];
3822   HRESULT hres;
3823   VARIANT v;
3824   BSTR str = NULL;
3825
3826   CHECKPTR(VarFormatNumber);
3827
3828   GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
3829   if (buff[0] != '.' || buff[1])
3830   {
3831     trace("Skipping VarFormatNumber tests as decimal seperator is '%s'\n", buff);
3832     return;
3833   }
3834
3835   FMT_NUMBER(VT_I1, V_I1);
3836   FMT_NUMBER(VT_UI1, V_UI1);
3837   FMT_NUMBER(VT_I2, V_I2);
3838   FMT_NUMBER(VT_UI2, V_UI2);
3839   FMT_NUMBER(VT_I4, V_I4);
3840   FMT_NUMBER(VT_UI4, V_UI4);
3841   todo_wine {
3842   FMT_NUMBER(VT_I8, V_I8);
3843   FMT_NUMBER(VT_UI8, V_UI8);
3844   }
3845   FMT_NUMBER(VT_R4, V_R4);
3846   FMT_NUMBER(VT_R8, V_R8);
3847   FMT_NUMBER(VT_BOOL, V_BOOL);
3848
3849   V_VT(&v) = VT_BSTR;
3850   V_BSTR(&v) = SysAllocString(szSrc1);
3851
3852   hres = pVarFormatNumber(&v,2,0,0,0,0,&str);
3853   ok(hres == S_OK, "VarFormatNumber (bstr): returned %8lx\n", hres);
3854   if (hres == S_OK)
3855     ok(str && strcmpW(str, szResult1) == 0, "VarFormatNumber (bstr): string different\n");
3856   SysFreeString(V_BSTR(&v));
3857   SysFreeString(str);
3858
3859   V_BSTR(&v) = SysAllocString(szSrc2);
3860   hres = pVarFormatNumber(&v,2,0,-1,0,0,&str);
3861   ok(hres == S_OK, "VarFormatNumber (bstr): returned %8lx\n", hres);
3862   if (hres == S_OK)
3863     ok(str && strcmpW(str, szResult2) == 0, "VarFormatNumber (-bstr): string different\n");
3864   SysFreeString(V_BSTR(&v));
3865   SysFreeString(str);
3866 }
3867
3868 #define SIGNED_VTBITS (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8|VTBIT_R4|VTBIT_R8)
3869
3870 #define VARFMT(vt,v,val,fmt,ret,str) do { \
3871   if (out) SysFreeString(out); out = NULL; \
3872   V_VT(&in) = (vt); v(&in) = val; \
3873   if (fmt) MultiByteToWideChar(CP_ACP, 0, fmt, -1, buffW, sizeof(buffW)/sizeof(WCHAR)); \
3874   hres = pVarFormat(&in,fmt ? buffW : NULL,fd,fw,flags,&out); \
3875   if (SUCCEEDED(hres)) WideCharToMultiByte(CP_ACP, 0, out, -1, buff, sizeof(buff),0,0); \
3876   else buff[0] = '\0'; \
3877   ok(hres == ret && (FAILED(ret) || !strcmp(buff, str)), \
3878      "VT %d|0x%04x Format %s: expected 0x%08lx, '%s', got 0x%08lx, '%s'\n", \
3879      (vt)&VT_TYPEMASK,(vt)&~VT_TYPEMASK,fmt?fmt:"<null>",ret,str,hres,buff); \
3880   } while(0)
3881
3882 typedef struct tagFMTRES
3883 {
3884   LPCSTR fmt;
3885   LPCSTR one_res;
3886   LPCSTR zero_res;
3887 } FMTRES;
3888
3889 static const FMTRES VarFormat_results[] =
3890 {
3891   { NULL, "1", "0" },
3892   { "", "1", "0" },
3893   { "General Number", "1", "0" },
3894   { "Percent", "100.00%", "0.00%" },
3895   { "Standard", "1.00", "0.00" },
3896   { "Scientific","1.00E+00", "0.00E+00" },
3897   { "True/False", "True", "False" },
3898 /*  { "On/Off", "On", "Off" },
3899   { "Yes/No", "Yes", "No")}, */
3900   { "#", "1", "" },
3901   { "##", "1", "" },
3902   { "#.#", "1.", "." },
3903   { "0", "1", "0" },
3904   { "00", "01", "00" },
3905   { "0.0", "1.0", "0.0" },
3906   { "00\\c\\o\\p\\y", "01copy","00copy" },
3907   { "\"pos\";\"neg\"", "pos", "pos" },
3908   { "\"pos\";\"neg\";\"zero\"","pos", "zero" }
3909 };
3910
3911 typedef struct tagFMTDATERES
3912 {
3913   DATE   val;
3914   LPCSTR fmt;
3915   LPCSTR res;
3916 } FMTDATERES;
3917
3918 static const FMTDATERES VarFormat_date_results[] =
3919 {
3920   { 0.0, "w", "7" },
3921   { 0.0, "w", "6" },
3922   { 0.0, "w", "5" },
3923   { 0.0, "w", "4" },
3924   { 0.0, "w", "3" },
3925   { 0.0, "w", "2" },
3926   { 0.0, "w", "1" }, /* First 7 entries must remain in this order! */
3927   { 2.525, "am/pm", "pm" },
3928   { 2.525, "AM/PM", "PM" },
3929   { 2.525, "A/P", "P" },
3930   { 2.525, "a/p", "p" },
3931   { 2.525, "q", "1" },
3932   { 2.525, "d", "1" },
3933   { 2.525, "dd", "01" },
3934   { 2.525, "ddd", "Mon" },
3935   { 2.525, "dddd", "Monday" },
3936   { 2.525, "mmm", "Jan" },
3937   { 2.525, "mmmm", "January" },
3938   { 2.525, "y", "1" },
3939   { 2.525, "yy", "00" },
3940   { 2.525, "yyy", "001" },
3941   { 2.525, "yyyy", "1900" },
3942   { 2.525, "dd mm yyyy hh:mm:ss", "01 01 1900 12:36:00" },
3943   { 2.525, "dd mm yyyy mm", "01 01 1900 01" },
3944   { 2.525, "dd mm yyyy :mm", "01 01 1900 :01" },
3945   { 2.525, "dd mm yyyy hh:mm", "01 01 1900 12:36" },
3946   { 2.525, "mm mm", "01 01" },
3947   { 2.525, "mm :mm:ss", "01 :01:00" },
3948   { 2.525, "mm :ss:mm", "01 :00:01" },
3949   { 2.525, "hh:mm :ss:mm", "12:36 :00:01" },
3950   { 2.525, "hh:dd :mm:mm", "12:01 :01:01" },
3951   { 2.525, "dd:hh :mm:mm", "01:12 :36:01" },
3952   { 2.525, "hh :mm:mm", "12 :36:01" },
3953   { 2.525, "dd :mm:mm", "01 :01:01" },
3954   { 2.525, "dd :mm:nn", "01 :01:36" },
3955   { 2.725, "hh:nn:ss A/P", "05:24:00 P" }
3956 };
3957
3958 #define VNUMFMT(vt,v) \
3959   for (i = 0; i < sizeof(VarFormat_results)/sizeof(FMTRES); i++) \
3960   { \
3961     VARFMT(vt,v,1,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].one_res); \
3962     VARFMT(vt,v,0,VarFormat_results[i].fmt,S_OK,VarFormat_results[i].zero_res); \
3963   } \
3964   if ((1 << vt) & SIGNED_VTBITS) \
3965   { \
3966     VARFMT(vt,v,-1,"\"pos\";\"neg\"",S_OK,"neg"); \
3967     VARFMT(vt,v,-1,"\"pos\";\"neg\";\"zero\"",S_OK,"neg"); \
3968   }
3969
3970 static void test_VarFormat(void)
3971 {
3972   static const WCHAR szTesting[] = { 't','e','s','t','i','n','g','\0' };
3973   size_t i;
3974   WCHAR buffW[256];
3975   char buff[256];
3976   VARIANT in;
3977   VARIANT_BOOL bTrue = VARIANT_TRUE, bFalse = VARIANT_FALSE;
3978   int fd = 0, fw = 0;
3979   ULONG flags = 0;
3980   BSTR bstrin, out = NULL;
3981   HRESULT hres;
3982
3983   CHECKPTR(VarFormat);
3984
3985   if (PRIMARYLANGID(LANGIDFROMLCID(GetUserDefaultLCID())) != LANG_ENGLISH)
3986   {
3987     trace("Skipping VarFormat tests for non english language\n");
3988     return;
3989   }
3990   GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
3991   if (buff[0] != '.' || buff[1])
3992   {
3993     trace("Skipping VarFormat tests as decimal seperator is '%s'\n", buff);
3994     return;
3995   }
3996   GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDIGITS, buff, sizeof(buff)/sizeof(char));
3997   if (buff[0] != '2' || buff[1])
3998   {
3999     trace("Skipping VarFormat tests as decimal places is '%s'\n", buff);
4000     return;
4001   }
4002
4003   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"True/False",S_OK,"True");
4004   VARFMT(VT_BOOL,V_BOOL,VARIANT_FALSE,"True/False",S_OK,"False");
4005
4006   VNUMFMT(VT_I1,V_I1);
4007   VNUMFMT(VT_I2,V_I2);
4008   VNUMFMT(VT_I4,V_I4);
4009   todo_wine {
4010   VNUMFMT(VT_I8,V_I8);
4011   }
4012   VNUMFMT(VT_INT,V_INT);
4013   VNUMFMT(VT_UI1,V_UI1);
4014   VNUMFMT(VT_UI2,V_UI2);
4015   VNUMFMT(VT_UI4,V_UI4);
4016   todo_wine {
4017   VNUMFMT(VT_UI8,V_UI8);
4018   }
4019   VNUMFMT(VT_UINT,V_UINT);
4020   VNUMFMT(VT_R4,V_R4);
4021   VNUMFMT(VT_R8,V_R8);
4022
4023   /* Reference types are dereferenced */
4024   VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bTrue,"True/False",S_OK,"True");
4025   VARFMT(VT_BOOL|VT_BYREF,V_BOOLREF,&bFalse,"True/False",S_OK,"False");
4026
4027   /* Dates */
4028   for (i = 0; i < sizeof(VarFormat_date_results)/sizeof(FMTDATERES); i++)
4029   {
4030     if (i < 7)
4031       fd = i + 1; /* Test first day */
4032     else
4033       fd = 0;
4034     VARFMT(VT_DATE,V_DATE,VarFormat_date_results[i].val,
4035            VarFormat_date_results[i].fmt,S_OK,
4036            VarFormat_date_results[i].res);
4037   }
4038
4039   /* Strings */
4040   bstrin = SysAllocString(szTesting);
4041   VARFMT(VT_BSTR,V_BSTR,bstrin,"",S_OK,"testing");
4042   VARFMT(VT_BSTR,V_BSTR,bstrin,"@",S_OK,"testing");
4043   VARFMT(VT_BSTR,V_BSTR,bstrin,"&",S_OK,"testing");
4044   VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x@\\x@",S_OK,"xtxesting");
4045   VARFMT(VT_BSTR,V_BSTR,bstrin,"\\x&\\x&",S_OK,"xtxesting");
4046   VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x",S_OK,"txesting");
4047   VARFMT(VT_BSTR,V_BSTR,bstrin,"@@@@@@@@",S_OK," testing");
4048   VARFMT(VT_BSTR,V_BSTR,bstrin,"@\\x@@@@@@@",S_OK," xtesting");
4049   VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&&",S_OK,"testing");
4050   VARFMT(VT_BSTR,V_BSTR,bstrin,"!&&&&&&&",S_OK,"testing");
4051   VARFMT(VT_BSTR,V_BSTR,bstrin,"&&&&&&&!",S_OK,"testing");
4052   VARFMT(VT_BSTR,V_BSTR,bstrin,">&&",S_OK,"TESTING");
4053   VARFMT(VT_BSTR,V_BSTR,bstrin,"<&&",S_OK,"testing");
4054   VARFMT(VT_BSTR,V_BSTR,bstrin,"<&>&",S_OK,"testing");
4055   SysFreeString(bstrin);
4056   /* Numeric values are converted to strings then output */
4057   VARFMT(VT_I1,V_I1,1,"<&>&",S_OK,"1");
4058
4059   /* 'out' is not cleared */
4060   out = (BSTR)0x1;
4061   pVarFormat(&in,NULL,fd,fw,flags,&out); /* Would crash if out is cleared */
4062   out = NULL;
4063
4064   /* Invalid args */
4065   hres = pVarFormat(&in,NULL,fd,fw,flags,NULL);
4066   ok(hres == E_INVALIDARG, "Null out: expected E_INVALIDARG, got 0x%08lx\n", hres);
4067   hres = pVarFormat(NULL,NULL,fd,fw,flags,&out);
4068   ok(hres == E_INVALIDARG, "Null in: expected E_INVALIDARG, got 0x%08lx\n", hres);
4069   fd = -1;
4070   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
4071   fd = 8;
4072   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
4073   fd = 0; fw = -1;
4074   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
4075   fw = 4;
4076   VARFMT(VT_BOOL,V_BOOL,VARIANT_TRUE,"",E_INVALIDARG,"");
4077 }
4078
4079 static HRESULT (WINAPI *pVarAbs)(LPVARIANT,LPVARIANT);
4080
4081 #define VARABS(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4082         memset(&vDst,0,sizeof(vDst)); hres = pVarAbs(&v,&vDst); \
4083         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
4084            "VarAbs: expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##rvt, (int)(rval), \
4085            hres, V_VT(&vDst), (int)V_##rvt(&vDst))
4086
4087 static void test_VarAbs(void)
4088 {
4089     static const WCHAR szNum[] = {'-','1','.','1','\0' };
4090     char buff[8];
4091     HRESULT hres;
4092     VARIANT v, vDst;
4093     size_t i;
4094
4095     CHECKPTR(VarAbs);
4096
4097     /* Test all possible V_VT values.
4098      */
4099     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
4100     {
4101         VARTYPE vt;
4102
4103         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4104         {
4105             HRESULT hExpected = DISP_E_BADVARTYPE;
4106
4107             memset(&v, 0, sizeof(v));
4108             V_VT(&v) = vt | ExtraFlags[i];
4109             V_VT(&vDst) = VT_EMPTY;
4110
4111             hres = pVarAbs(&v,&vDst);
4112             if (ExtraFlags[i] & (VT_ARRAY|VT_ARRAY) ||
4113                 (!ExtraFlags[i] && (vt == VT_UNKNOWN || vt == VT_BSTR ||
4114                  vt == VT_DISPATCH || vt == VT_ERROR || vt == VT_RECORD)))
4115             {
4116                 hExpected = DISP_E_TYPEMISMATCH;
4117             }
4118             else if (ExtraFlags[i] || vt >= VT_CLSID || vt == VT_VARIANT)
4119             {
4120                 hExpected = DISP_E_BADVARTYPE;
4121             }
4122             else if (IsValidVariantClearVT(vt, ExtraFlags[i]))
4123                 hExpected = S_OK;
4124
4125             /* Native always fails on some vartypes that should be valid. don't
4126              * check that Wine does the same; these are bugs in native.
4127              */
4128             if (vt == VT_I8 || vt == VT_UI8 || vt == VT_INT || vt == VT_UINT ||
4129                 vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4)
4130                 continue;
4131             ok(hres == hExpected, "VarAbs: expected 0x%lX, got 0x%lX for vt %d | 0x%X\n",
4132                hExpected, hres, vt, ExtraFlags[i]);
4133         }
4134     }
4135
4136     /* BOOL->I2, BSTR->R8, all others remain the same */
4137     VARABS(BOOL,VARIANT_TRUE,I2,-VARIANT_TRUE);
4138     VARABS(BOOL,VARIANT_FALSE,I2,VARIANT_FALSE);
4139     VARABS(I2,1,I2,1);
4140     VARABS(I2,-1,I2,1);
4141     VARABS(I4,1,I4,1);
4142     VARABS(I4,-1,I4,1);
4143     VARABS(UI1,1,UI1,1);
4144     VARABS(R4,1,R4,1);
4145     VARABS(R4,-1,R4,1);
4146     VARABS(R8,1,R8,1);
4147     VARABS(R8,-1,R8,1);
4148     GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
4149     if (buff[0] != '.' || buff[1])
4150     { 
4151         trace("Skipping VarAbs(BSTR) as decimal seperator is '%s'\n", buff);
4152         return;
4153     }
4154     V_VT(&v) = VT_BSTR;
4155     V_BSTR(&v) = (BSTR)szNum;
4156     memset(&vDst,0,sizeof(vDst));
4157     hres = pVarAbs(&v,&vDst);
4158     ok(hres == S_OK && V_VT(&vDst) == VT_R8 && V_R8(&vDst) == 1.1,
4159        "VarAbs: expected 0x0,%d,%g, got 0x%lX,%d,%g\n", VT_R8, 1.1, hres, V_VT(&vDst), V_R8(&vDst));
4160 }
4161
4162 static HRESULT (WINAPI *pVarNot)(LPVARIANT,LPVARIANT);
4163
4164 #define VARNOT(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
4165         memset(&vDst,0,sizeof(vDst)); hres = pVarNot(&v,&vDst); \
4166         ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
4167         "VarNot: expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##rvt, (int)(rval), \
4168         hres, V_VT(&vDst), (int)V_##rvt(&vDst))
4169
4170 static void test_VarNot(void)
4171 {
4172     static const WCHAR szNum0[] = {'0','\0' };
4173     static const WCHAR szNum1[] = {'1','\0' };
4174     HRESULT hres;
4175     VARIANT v, vDst;
4176     DECIMAL *pdec = &V_DECIMAL(&v);
4177     CY *pcy = &V_CY(&v);
4178     size_t i;
4179
4180     CHECKPTR(VarNot);
4181
4182     /* Test all possible V_VT values */
4183     for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
4184     {
4185         VARTYPE vt;
4186
4187         for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
4188         {
4189             HRESULT hExpected = DISP_E_BADVARTYPE;
4190
4191             memset(&v, 0, sizeof(v));
4192             V_VT(&v) = vt | ExtraFlags[i];
4193             V_VT(&vDst) = VT_EMPTY;
4194
4195             hres = pVarNot(&v,&vDst);
4196             switch (V_VT(&v))
4197             {
4198             case VT_I1:  case VT_UI1: case VT_I2:  case VT_UI2:
4199             case VT_INT: case VT_UINT: case VT_I4:  case VT_UI4:
4200             case VT_R4:  case VT_R8:
4201             case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
4202             case VT_DATE: case VT_CY:
4203                 hExpected = S_OK;
4204                 break;
4205             case VT_I8: case VT_UI8:
4206                 if (HAVE_OLEAUT32_I8)
4207                     hExpected = S_OK;
4208                 break;
4209             case VT_RECORD:
4210                 if (HAVE_OLEAUT32_RECORD)
4211                     hExpected = DISP_E_TYPEMISMATCH;
4212                 break;
4213             case VT_UNKNOWN: case VT_BSTR: case VT_DISPATCH: case VT_ERROR:
4214                 hExpected = DISP_E_TYPEMISMATCH;
4215                 break;
4216             default:
4217                 if (IsValidVariantClearVT(vt, ExtraFlags[i]) && vt != VT_CLSID)
4218                    hExpected = DISP_E_TYPEMISMATCH;
4219                 break;
4220             }
4221
4222             hres = pVarNot(&v,&vDst);
4223             if (V_VT(&v) == VT_DECIMAL)
4224             {
4225               todo_wine {
4226               ok(hres == hExpected, "VarNot: expected 0x%lX, got 0x%lX vt %d|0x%X\n",
4227                  hExpected, hres, vt, ExtraFlags[i]);
4228               }
4229             }
4230             else
4231               ok(hres == hExpected, "VarNot: expected 0x%lX, got 0x%lX vt %d|0x%X\n",
4232                  hExpected, hres, vt, ExtraFlags[i]);
4233         }
4234     }
4235     /* R4,R8,BSTR,DECIMAL,CY->I4, all others remain the same */
4236     VARNOT(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
4237     VARNOT(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
4238     VARNOT(I2,-1,I2,0);
4239     VARNOT(I2,0,I2,-1);
4240     VARNOT(I2,1,I2,-2);
4241     VARNOT(I4,1,I4,-2);
4242     VARNOT(I4,0,I4,-1);
4243     VARNOT(UI1,1,UI1,254);
4244     VARNOT(UI1,0,UI1,255);
4245     VARNOT(R4,1,I4,-2);
4246     VARNOT(R4,0,I4,-1);
4247     VARNOT(R8,1,I4,-2);
4248     VARNOT(R8,0,I4,-1);
4249     VARNOT(BSTR,(BSTR)szNum0,I4,-1);
4250     VARNOT(BSTR,(BSTR)szNum1,I4,-2);
4251
4252     todo_wine {
4253     V_VT(&v) = VT_DECIMAL;
4254     pdec->u.s.sign = DECIMAL_NEG;
4255     pdec->u.s.scale = 0;
4256     pdec->Hi32 = 0;
4257     pdec->u1.s1.Mid32 = 0;
4258     pdec->u1.s1.Lo32 = 1;
4259     VARNOT(DECIMAL,*pdec,I4,0);
4260     pcy->int64 = 10000;
4261     VARNOT(CY,*pcy,I4,-2);
4262     }
4263 }
4264
4265 START_TEST(vartest)
4266 {
4267   hOleaut32 = LoadLibraryA("oleaut32.dll");
4268
4269   test_variant();
4270   test_VariantInit();
4271   test_VariantClear();
4272   test_VariantCopy();
4273   test_VariantCopyInd();
4274   test_VarParseNumFromStr();
4275   test_VarNumFromParseNum();
4276   test_VarUdateFromDate();
4277   test_VarDateFromUdate();
4278   test_SystemTimeToVariantTime();
4279   test_VariantTimeToSystemTime();
4280   test_DosDateTimeToVariantTime();
4281   test_VariantTimeToDosDateTime();
4282   test_VarFormatNumber();
4283   test_VarFormat();
4284   test_VarAbs();
4285   test_VarNot();
4286 }