ReactOS  0.4.12-dev-914-g71f84a3
vartest.c
Go to the documentation of this file.
1 /*
2  * VARIANT test program
3  *
4  * Copyright 1998 Jean-Claude Cote
5  * Copyright 2006 Google (Benjamin Arai)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <float.h>
26 
27 #define COBJMACROS
28 #define CONST_VTABLE
29 
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winsock2.h"
33 #include "wine/test.h"
34 #include "winuser.h"
35 #include "wingdi.h"
36 #include "winnls.h"
37 #include "winerror.h"
38 #include "winnt.h"
39 
40 #include "wtypes.h"
41 #include "oleauto.h"
42 
44 
45 static HRESULT (WINAPI *pVarUdateFromDate)(DATE,ULONG,UDATE*);
46 static HRESULT (WINAPI *pVarDateFromUdate)(UDATE*,ULONG,DATE*);
47 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
48 static INT (WINAPI *pVariantTimeToSystemTime)(double,LPSYSTEMTIME);
49 static INT (WINAPI *pDosDateTimeToVariantTime)(USHORT,USHORT,double*);
50 static INT (WINAPI *pVariantTimeToDosDateTime)(double,USHORT*,USHORT *);
51 
52 static const WCHAR sz12[] = {'1','2','\0'};
53 /* the strings are localized */
54 static WCHAR sz12_false[32];
55 static WCHAR sz12_true[32];
56 
57 /* Get a conversion function ptr, return if function not available */
58 #define CHECKPTR(func) p##func = (void*)GetProcAddress(hOleaut32, #func); \
59  if (!p##func) { win_skip("function " # func " not available, not testing it\n"); return; }
60 
61 /* Has I8/UI8 data type? */
62 static BOOL has_i8;
63 
64 /* When comparing floating point values we cannot expect an exact match
65  * because the rounding errors depend on the exact algorithm.
66  */
67 #define EQ_DOUBLE(a,b) (fabs((a)-(b)) / (1.0+fabs(a)+fabs(b)) < 1e-14)
68 #define EQ_FLOAT(a,b) (fabs((a)-(b)) / (1.0+fabs(a)+fabs(b)) < 1e-7)
69 
70 #define SKIPTESTS(a) if((a > VT_CLSID+10) && (a < VT_BSTR_BLOB-10)) continue
71 
72 /* Allow our test macros to work for VT_NULL and VT_EMPTY too */
73 #define V_EMPTY(v) V_I4(v)
74 #define V_NULL(v) V_I4(v)
75 
76 /* Size constraints for overflow tests */
77 #define I1_MAX 0x7f
78 #define I1_MIN ((-I1_MAX)-1)
79 #define UI1_MAX 0xff
80 #define UI1_MIN 0
81 #define I2_MAX 0x7fff
82 #define I2_MIN ((-I2_MAX)-1)
83 #define UI2_MAX 0xffff
84 #define UI2_MIN 0
85 #define I4_MAX 0x7fffffff
86 #define I4_MIN ((-I4_MAX)-1)
87 #define UI4_MAX 0xffffffff
88 #define UI4_MIN 0
89 #define I8_MAX (((LONGLONG)I4_MAX << 32) | UI4_MAX)
90 #define I8_MIN ((-I8_MAX)-1)
91 #define UI8_MAX (((ULONGLONG)UI4_MAX << 32) | UI4_MAX)
92 #define UI8_MIN 0
93 #define DATE_MAX 2958465
94 #define DATE_MIN -657434
95 #define R4_MAX FLT_MAX
96 #define R4_MIN FLT_MIN
97 #define R8_MAX DBL_MAX
98 #define R8_MIN DBL_MIN
99 
100 #define DEFINE_EXPECT(func) \
101  static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
102 
103 #define SET_EXPECT(func) \
104  do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
105 
106 #define CHECK_EXPECT2(func) \
107  do { \
108  ok(expect_ ##func, "unexpected call " #func "\n"); \
109  called_ ## func = TRUE; \
110  }while(0)
111 
112 #define CHECK_EXPECT(func) \
113  do { \
114  CHECK_EXPECT2(func); \
115  expect_ ## func = FALSE; \
116  }while(0)
117 
118 #define CHECK_CALLED(func) \
119  do { \
120  ok(called_ ## func, "expected " #func "\n"); \
121  expect_ ## func = called_ ## func = FALSE; \
122  }while(0)
123 
124 DEFINE_EXPECT(dispatch_invoke);
125 
126 typedef struct
127 {
131 } DummyDispatch;
132 
134 {
135  return CONTAINING_RECORD(iface, DummyDispatch, IDispatch_iface);
136 }
137 
139 {
140  return 2;
141 }
142 
144 {
145  return 1;
146 }
147 
149  REFIID riid,
150  void** ppvObject)
151 {
152  *ppvObject = NULL;
153 
154  if (IsEqualIID(riid, &IID_IDispatch) ||
156  {
157  *ppvObject = iface;
158  IDispatch_AddRef(iface);
159  }
160 
161  return *ppvObject ? S_OK : E_NOINTERFACE;
162 }
163 
165 {
166  ok(0, "Unexpected call\n");
167  return E_NOTIMPL;
168 }
169 
171 {
172  ok(0, "Unexpected call\n");
173  return E_NOTIMPL;
174 }
175 
177  UINT cnames, LCID lcid, DISPID *dispid)
178 {
179  ok(0, "Unexpected call\n");
180  return E_NOTIMPL;
181 }
182 
184  DISPID dispid, REFIID riid,
185  LCID lcid, WORD wFlags,
187  VARIANT *res,
188  EXCEPINFO *ei,
189  UINT *arg_err)
190 {
192 
193  CHECK_EXPECT(dispatch_invoke);
194 
195  ok(dispid == DISPID_VALUE, "got dispid %d\n", dispid);
196  ok(IsEqualIID(riid, &IID_NULL), "go riid %s\n", wine_dbgstr_guid(riid));
197  ok(wFlags == DISPATCH_PROPERTYGET, "Flags wrong\n");
198 
199  ok(params->rgvarg == NULL, "got %p\n", params->rgvarg);
200  ok(params->rgdispidNamedArgs == NULL, "got %p\n", params->rgdispidNamedArgs);
201  ok(params->cArgs == 0, "got %d\n", params->cArgs);
202  ok(params->cNamedArgs == 0, "got %d\n", params->cNamedArgs);
203 
204  ok(res != NULL, "got %p\n", res);
205  ok(V_VT(res) == VT_EMPTY, "got %d\n", V_VT(res));
206  ok(ei == NULL, "got %p\n", ei);
207  ok(arg_err == NULL, "got %p\n", arg_err);
208 
209  if (FAILED(This->result))
210  return This->result;
211 
212  V_VT(res) = This->vt;
213  if (This->vt == VT_UI1)
214  V_UI1(res) = 34;
215  else if (This->vt == VT_NULL)
216  {
217  V_VT(res) = VT_NULL;
218  V_BSTR(res) = NULL;
219  }
220  else
221  memset(res, 0, sizeof(*res));
222 
223  return S_OK;
224 }
225 
226 static const IDispatchVtbl DummyDispatch_VTable =
227 {
235 };
236 
238 {
239  dispatch->IDispatch_iface.lpVtbl = &DummyDispatch_VTable;
240  dispatch->vt = vt;
241  dispatch->result = S_OK;
242 }
243 
244 typedef struct IRecordInfoImpl
245 {
247  LONG ref;
248  unsigned int recordclear;
249  unsigned int getsize;
250  unsigned int recordcopy;
251  struct __tagBRECORD *rec;
253 
255 {
256  return CONTAINING_RECORD(iface, IRecordInfoImpl, IRecordInfo_iface);
257 }
258 
260 {
261  *obj = NULL;
262 
263  if (IsEqualIID(riid, &IID_IUnknown) ||
264  IsEqualIID(riid, &IID_IRecordInfo))
265  {
266  *obj = iface;
267  IRecordInfo_AddRef(iface);
268  return S_OK;
269  }
270 
271  return E_NOINTERFACE;
272 }
273 
275 {
277  return InterlockedIncrement(&This->ref);
278 }
279 
281 {
284 
285  if (!ref)
287 
288  return ref;
289 }
290 
292 {
293  ok(0, "unexpected call\n");
294  return E_NOTIMPL;
295 }
296 
298 {
300  This->recordclear++;
301  This->rec->pvRecord = NULL;
302  return S_OK;
303 }
304 
306 {
308  This->recordcopy++;
309  ok(src == (void*)0xdeadbeef, "wrong src pointer %p\n", src);
310  return S_OK;
311 }
312 
314 {
315  ok(0, "unexpected call\n");
316  return E_NOTIMPL;
317 }
318 
320 {
321  ok(0, "unexpected call\n");
322  return E_NOTIMPL;
323 }
324 
326 {
328  This->getsize++;
329  *size = 0;
330  return S_OK;
331 }
332 
334 {
335  ok(0, "unexpected call\n");
336  return E_NOTIMPL;
337 }
338 
340  LPCOLESTR szFieldName, VARIANT *pvarField)
341 {
342  ok(0, "unexpected call\n");
343  return E_NOTIMPL;
344 }
345 
347  LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
348 {
349  ok(0, "unexpected call\n");
350  return E_NOTIMPL;
351 }
352 
354  LPCOLESTR szFieldName, VARIANT *pvarField)
355 {
356  ok(0, "unexpected call\n");
357  return E_NOTIMPL;
358 }
359 
361  PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
362 {
363  ok(0, "unexpected call\n");
364  return E_NOTIMPL;
365 }
366 
368  BSTR *rgBstrNames)
369 {
370  ok(0, "unexpected call\n");
371  return E_NOTIMPL;
372 }
373 
375 {
376  ok(0, "unexpected call\n");
377  return FALSE;
378 }
379 
381 {
382  ok(0, "unexpected call\n");
383  return NULL;
384 }
385 
387  PVOID *ppvDest)
388 {
389  ok(0, "unexpected call\n");
390  return E_NOTIMPL;
391 }
392 
394 {
395  ok(0, "unexpected call\n");
396  return E_NOTIMPL;
397 }
398 
399 static const IRecordInfoVtbl RecordInfoVtbl =
400 {
420 };
421 
423 {
424  IRecordInfoImpl *rec;
425 
426  rec = HeapAlloc(GetProcessHeap(), 0, sizeof(IRecordInfoImpl));
427  rec->IRecordInfo_iface.lpVtbl = &RecordInfoVtbl;
428  rec->ref = 1;
429  rec->recordclear = 0;
430  rec->getsize = 0;
431  rec->recordcopy = 0;
432 
433  return rec;
434 }
435 
436 static void init(void)
437 {
438  BSTR bstr;
439  HRESULT res;
440 
441  res = VarBstrFromBool(VARIANT_TRUE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
442  ok(res == S_OK && bstr[0], "Expected localized string for 'True'\n");
443  /* lstrcpyW / lstrcatW do not work on win95 */
444  memcpy(sz12_true, sz12, sizeof(sz12));
445  if (bstr) memcpy(&sz12_true[2], bstr, SysStringByteLen(bstr) + sizeof(WCHAR));
446  SysFreeString(bstr);
447 
448  res = VarBstrFromBool(VARIANT_FALSE, LANG_USER_DEFAULT, VAR_LOCALBOOL, &bstr);
449  ok(res == S_OK && bstr[0], "Expected localized string for 'False'\n");
450  memcpy(sz12_false, sz12, sizeof(sz12));
451  if (bstr) memcpy(&sz12_false[2], bstr, SysStringByteLen(bstr) + sizeof(WCHAR));
452  SysFreeString(bstr);
453 
454  hOleaut32 = GetModuleHandleA("oleaut32.dll");
455  has_i8 = GetProcAddress(hOleaut32, "VarI8FromI1") != NULL;
456  if (!has_i8)
457  skip("No support for I8 and UI8 data types\n");
458 }
459 
460 /* Functions to set a DECIMAL */
461 static void setdec(DECIMAL* dec, BYTE scl, BYTE sgn, ULONG hi32, ULONG64 lo64)
462 {
463  S(U(*dec)).scale = scl;
464  S(U(*dec)).sign = sgn;
465  dec->Hi32 = hi32;
466  U1(*dec).Lo64 = lo64;
467 }
468 
469 static void setdec64(DECIMAL* dec, BYTE scl, BYTE sgn, ULONG hi32, ULONG mid32, ULONG lo32)
470 {
471  S(U(*dec)).scale = scl;
472  S(U(*dec)).sign = sgn;
473  dec->Hi32 = hi32;
474  S1(U1(*dec)).Mid32 = mid32;
475  S1(U1(*dec)).Lo32 = lo32;
476 }
477 
478 /* return the string text of a given variant type */
479 static char vtstr_buffer[16][256];
480 static int vtstr_current=0;
481 static const char *vtstr(int x)
482 {
483  switch(x) {
484 #define CASE(vt) case VT_##vt: return #vt
485  CASE(EMPTY);
486  CASE(NULL);
487  CASE(I2);
488  CASE(I4);
489  CASE(R4);
490  CASE(R8);
491  CASE(CY);
492  CASE(DATE);
493  CASE(BSTR);
494  CASE(DISPATCH);
495  CASE(ERROR);
496  CASE(BOOL);
497  CASE(VARIANT);
498  CASE(UNKNOWN);
499  CASE(DECIMAL);
500  CASE(I1);
501  CASE(UI1);
502  CASE(UI2);
503  CASE(UI4);
504  CASE(I8);
505  CASE(UI8);
506  CASE(INT);
507  CASE(UINT);
508  CASE(VOID);
509  CASE(HRESULT);
510  CASE(PTR);
511  CASE(SAFEARRAY);
512  CASE(CARRAY);
513  CASE(USERDEFINED);
514  CASE(LPSTR);
515  CASE(LPWSTR);
516  CASE(RECORD);
517  CASE(INT_PTR);
518  CASE(UINT_PTR);
519  CASE(FILETIME);
520  CASE(BLOB);
521  CASE(STREAM);
522  CASE(STORAGE);
523  CASE(STREAMED_OBJECT);
524  CASE(STORED_OBJECT);
525  CASE(BLOB_OBJECT);
526  CASE(CF);
527  CASE(CLSID);
528  CASE(VERSIONED_STREAM);
529  CASE(VECTOR);
530  CASE(ARRAY);
531  CASE(BYREF);
532  CASE(RESERVED);
533  CASE(ILLEGAL);
534 #undef CASE
535 
536  case 0xfff:
537  return "VT_BSTR_BLOB/VT_ILLEGALMASKED/VT_TYPEMASK";
538 
539  default:
541  sprintf(vtstr_buffer[vtstr_current], "unknown variant type %d", x);
542  return vtstr_buffer[vtstr_current++];
543  }
544 }
545 
546 static const char *variantstr( const VARIANT *var )
547 {
549  switch(V_VT(var))
550  {
551  case VT_I1:
552  sprintf( vtstr_buffer[vtstr_current], "VT_I1(%d)", V_I1(var) ); break;
553  case VT_I2:
554  sprintf( vtstr_buffer[vtstr_current], "VT_I2(%d)", V_I2(var) ); break;
555  case VT_I4:
556  sprintf( vtstr_buffer[vtstr_current], "VT_I4(%d)", V_I4(var) ); break;
557  case VT_INT:
558  sprintf( vtstr_buffer[vtstr_current], "VT_INT(%d)", V_INT(var) ); break;
559  case VT_I8:
560  sprintf( vtstr_buffer[vtstr_current], "VT_I8(%x%08x)", (UINT)(V_I8(var) >> 32), (UINT)V_I8(var) ); break;
561  case VT_UI8:
562  sprintf( vtstr_buffer[vtstr_current], "VT_UI8(%x%08x)", (UINT)(V_UI8(var) >> 32), (UINT)V_UI8(var) ); break;
563  case VT_R4:
564  sprintf( vtstr_buffer[vtstr_current], "VT_R4(%g)", V_R4(var) ); break;
565  case VT_R8:
566  sprintf( vtstr_buffer[vtstr_current], "VT_R8(%g)", V_R8(var) ); break;
567  case VT_UI1:
568  sprintf( vtstr_buffer[vtstr_current], "VT_UI1(%u)", V_UI1(var) ); break;
569  case VT_UI2:
570  sprintf( vtstr_buffer[vtstr_current], "VT_UI2(%u)", V_UI2(var) ); break;
571  case VT_UI4:
572  sprintf( vtstr_buffer[vtstr_current], "VT_UI4(%u)", V_UI4(var) ); break;
573  case VT_UINT:
574  sprintf( vtstr_buffer[vtstr_current], "VT_UINT(%d)", V_UINT(var) ); break;
575  case VT_CY:
576  sprintf( vtstr_buffer[vtstr_current], "VT_CY(%x%08x)", S(V_CY(var)).Hi, S(V_CY(var)).Lo ); break;
577  case VT_DATE:
578  sprintf( vtstr_buffer[vtstr_current], "VT_DATE(%g)", V_DATE(var) ); break;
579  default:
580  return vtstr(V_VT(var));
581  }
582  return vtstr_buffer[vtstr_current++];
583 }
584 
586 {
587  if (V_VT(result) != V_VT(expected)) return FALSE;
588  switch(V_VT(expected))
589  {
590  case VT_EMPTY:
591  case VT_NULL:
592  return TRUE;
593 
594 #define CASE(vt) case VT_##vt: return (V_##vt(result) == V_##vt(expected))
595  CASE(BOOL);
596  CASE(I1);
597  CASE(UI1);
598  CASE(I2);
599  CASE(UI2);
600  CASE(I4);
601  CASE(UI4);
602  CASE(I8);
603  CASE(UI8);
604  CASE(INT);
605  CASE(UINT);
606 #undef CASE
607 
608  case VT_DATE:
609  return EQ_FLOAT(V_DATE(result), V_DATE(expected));
610  case VT_R4:
611  return EQ_FLOAT(V_R4(result), V_R4(expected));
612  case VT_R8:
613  return EQ_FLOAT(V_R8(result), V_R8(expected));
614  case VT_CY:
615  return (V_CY(result).int64 == V_CY(expected).int64);
616  case VT_BSTR:
617  return !lstrcmpW( V_BSTR(result), V_BSTR(expected) );
618  case VT_DECIMAL:
619  return !memcmp( &V_DECIMAL(result), &V_DECIMAL(expected), sizeof(DECIMAL) );
620  default:
621  ok(0, "unhandled variant type %s\n",vtstr(V_VT(expected)));
622  return FALSE;
623  }
624 }
625 
628 {
629  VARIANT old_arg = *arg;
630  VARIANT result;
631  HRESULT hres;
632 
633  memset( &result, 0, sizeof(result) );
634  hres = func( arg, &result );
635  ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
636  if (hres == S_OK)
637  ok_(__FILE__,line)( is_expected_variant( &result, expected ),
638  "got %s expected %s\n", variantstr(&result), variantstr(expected) );
639  ok_(__FILE__,line)( is_expected_variant( arg, &old_arg ), "Modified argument %s / %s\n",
640  variantstr(&old_arg), variantstr(arg));
641  VariantClear( &result );
642 }
643 
646 {
647  VARIANT old_left = *left, old_right = *right;
648  VARIANT result;
649  HRESULT hres;
650 
651  memset( &result, 0, sizeof(result) );
652  hres = func( left, right, &result );
653  ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
654  if (hres == S_OK)
655  ok_(__FILE__,line)( is_expected_variant( &result, expected ),
656  "got %s expected %s\n", variantstr(&result), variantstr(expected) );
657  ok_(__FILE__,line)( is_expected_variant( left, &old_left ), "Modified left argument %s / %s\n",
658  variantstr(&old_left), variantstr(left));
659  ok_(__FILE__,line)( is_expected_variant( right, &old_right ), "Modified right argument %s / %s\n",
660  variantstr(&old_right), variantstr(right));
661  VariantClear( &result );
662 }
663 
664 static int strcmp_wa(const WCHAR *strw, const char *stra)
665 {
666  WCHAR buf[512];
667  MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
668  return lstrcmpW(strw, buf);
669 }
670 
671 #define test_bstr_var(a,b) _test_bstr_var(__LINE__,a,b)
672 static void _test_bstr_var(unsigned line, const VARIANT *v, const char *str)
673 {
674  ok_(__FILE__,line)(V_VT(v) == VT_BSTR, "unexpected vt=%d\n", V_VT(v));
675  if(V_VT(v) == VT_BSTR)
676  ok(!strcmp_wa(V_BSTR(v), str), "v=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), str);
677 }
678 
679 static void test_VariantInit(void)
680 {
681  VARIANT v;
682 
683  memset(&v, -1, sizeof(v));
684  VariantInit(&v);
685  ok(V_VT(&v) == VT_EMPTY, "VariantInit() returned vt %d\n", V_VT(&v));
686 }
687 
688 /* All possible combinations of extra V_VT() flags */
689 static const VARTYPE ExtraFlags[16] =
690 {
691  0,
692  VT_VECTOR,
693  VT_ARRAY,
694  VT_BYREF,
695  VT_RESERVED,
707 };
708 
709 /* Determine if a vt is valid for VariantClear() */
711 {
712  BOOL ret = FALSE;
713 
714  /* Only the following flags/types are valid */
715  if ((vt <= VT_LPWSTR || vt == VT_RECORD || vt == VT_CLSID) &&
716  vt != (VARTYPE)15 &&
717  (vt < (VARTYPE)24 || vt > (VARTYPE)31) &&
718  (!(extraFlags & (VT_BYREF|VT_ARRAY)) || vt > VT_NULL) &&
719  (extraFlags == 0 || extraFlags == VT_BYREF || extraFlags == VT_ARRAY ||
720  extraFlags == (VT_ARRAY|VT_BYREF)))
721  ret = TRUE; /* ok */
722 
723  if (!has_i8 && (vt == VT_I8 || vt == VT_UI8))
724  ret = FALSE; /* Old versions of oleaut32 */
725  return ret;
726 }
727 
728 typedef struct
729 {
734 
736 {
737  return CONTAINING_RECORD(iface, test_VariantClearImpl, IUnknown_iface);
738 }
739 
741 {
743  This->events |= 0x1;
744  return E_NOINTERFACE;
745 }
746 
749  This->events |= 0x2;
750  return InterlockedIncrement(&This->ref);
751 }
752 
755  /* static class, won't be freed */
756  This->events |= 0x4;
757  return InterlockedDecrement(&This->ref);
758 }
759 
760 static const IUnknownVtbl test_VariantClear_vtbl = {
762  VC_AddRef,
763  VC_Release,
764 };
765 
767 
768 static void test_VariantClear(void)
769 {
770  struct __tagBRECORD *rec;
771  IRecordInfoImpl *recinfo;
772  HRESULT hres;
773  VARIANTARG v;
774  VARIANT v2;
775  size_t i;
776  LONG i4;
777  IUnknown *punk;
778 
779  /* Crashes: Native does not test input for NULL, so neither does Wine */
780  if (0)
782 
783  /* Only the type field is set, to VT_EMPTY */
784  V_VT(&v) = VT_UI4;
785  V_UI4(&v) = ~0u;
786  hres = VariantClear(&v);
787  ok((hres == S_OK && V_VT(&v) == VT_EMPTY),
788  "VariantClear: Type set to %d, res %08x\n", V_VT(&v), hres);
789  ok(V_UI4(&v) == ~0u, "VariantClear: Overwrote value\n");
790 
791  /* Test all possible V_VT values.
792  * Also demonstrates that null pointers in 'v' are not dereferenced.
793  * Individual variant tests should test VariantClear() with non-NULL values.
794  */
795  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
796  {
797  VARTYPE vt;
798 
799  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
800  {
801  HRESULT hExpected = DISP_E_BADVARTYPE;
802 
803  SKIPTESTS(vt);
804 
805  memset(&v, 0, sizeof(v));
806  V_VT(&v) = vt | ExtraFlags[i];
807 
808  hres = VariantClear(&v);
809 
811  hExpected = S_OK;
812 
813  ok(hres == hExpected, "VariantClear: expected 0x%X, got 0x%X for vt %d | 0x%X\n",
814  hExpected, hres, vt, ExtraFlags[i]);
815  }
816  }
817 
818  /* Some BYREF tests with non-NULL ptrs */
819 
820  /* VARIANT BYREF */
821  V_VT(&v2) = VT_I4;
822  V_I4(&v2) = 0x1234;
823  V_VT(&v) = VT_VARIANT | VT_BYREF;
824  V_VARIANTREF(&v) = &v2;
825 
826  hres = VariantClear(&v);
827  ok(hres == S_OK, "ret %08x\n", hres);
828  ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
829  ok(V_VARIANTREF(&v) == &v2, "variant ref %p\n", V_VARIANTREF(&v2));
830  ok(V_VT(&v2) == VT_I4, "vt %04x\n", V_VT(&v2));
831  ok(V_I4(&v2) == 0x1234, "i4 %04x\n", V_I4(&v2));
832 
833  /* I4 BYREF */
834  i4 = 0x4321;
835  V_VT(&v) = VT_I4 | VT_BYREF;
836  V_I4REF(&v) = &i4;
837 
838  hres = VariantClear(&v);
839  ok(hres == S_OK, "ret %08x\n", hres);
840  ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
841  ok(V_I4REF(&v) == &i4, "i4 ref %p\n", V_I4REF(&v2));
842  ok(i4 == 0x4321, "i4 changed %08x\n", i4);
843 
844 
845  /* UNKNOWN */
846  V_VT(&v) = VT_UNKNOWN;
849  hres = VariantClear(&v);
850  ok(hres == S_OK, "ret %08x\n", hres);
851  ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
852  ok(V_UNKNOWN(&v) == &test_myVariantClearImpl.IUnknown_iface, "unknown %p\n", V_UNKNOWN(&v));
853  /* Check that Release got called, but nothing else */
854  ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
855 
856  /* UNKNOWN BYREF */
858  V_VT(&v) = VT_UNKNOWN | VT_BYREF;
859  V_UNKNOWNREF(&v) = &punk;
861  hres = VariantClear(&v);
862  ok(hres == S_OK, "ret %08x\n", hres);
863  ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
864  ok(V_UNKNOWNREF(&v) == &punk, "unknown ref %p\n", V_UNKNOWNREF(&v));
865  /* Check that nothing got called */
866  ok(test_myVariantClearImpl.events == 0, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
867 
868  /* DISPATCH */
869  V_VT(&v) = VT_DISPATCH;
872  hres = VariantClear(&v);
873  ok(hres == S_OK, "ret %08x\n", hres);
874  ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
876  "dispatch %p\n", V_DISPATCH(&v));
877  /* Check that Release got called, but nothing else */
878  ok(test_myVariantClearImpl.events == 0x4, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
879 
880  /* DISPATCH BYREF */
882  V_VT(&v) = VT_DISPATCH | VT_BYREF;
883  V_DISPATCHREF(&v) = (IDispatch**)&punk;
885  hres = VariantClear(&v);
886  ok(hres == S_OK, "ret %08x\n", hres);
887  ok(V_VT(&v) == 0, "vt %04x\n", V_VT(&v));
888  ok(V_DISPATCHREF(&v) == (IDispatch**)&punk, "dispatch ref %p\n", V_DISPATCHREF(&v));
889  /* Check that nothing got called */
890  ok(test_myVariantClearImpl.events == 0, "Unexpected call. events %08x\n", test_myVariantClearImpl.events);
891 
892  /* RECORD */
893  recinfo = get_test_recordinfo();
894  V_VT(&v) = VT_RECORD;
895  rec = &V_UNION(&v, brecVal);
896  rec->pRecInfo = &recinfo->IRecordInfo_iface;
897  rec->pvRecord = (void*)0xdeadbeef;
898  recinfo->recordclear = 0;
899  recinfo->ref = 2;
900  recinfo->rec = rec;
901  hres = VariantClear(&v);
902  ok(hres == S_OK, "ret %08x\n", hres);
903  ok(rec->pvRecord == NULL, "got %p\n", rec->pvRecord);
904  ok(recinfo->recordclear == 1, "got %d\n", recinfo->recordclear);
905  ok(recinfo->ref == 1, "got %d\n", recinfo->ref);
906  IRecordInfo_Release(&recinfo->IRecordInfo_iface);
907 }
908 
909 static void test_VariantCopy(void)
910 {
911  struct __tagBRECORD *rec;
912  IRecordInfoImpl *recinfo;
913  VARIANTARG vSrc, vDst;
914  VARTYPE vt;
915  size_t i;
916  HRESULT hres, hExpected;
917 
918  /* Establish that the failure/other cases are dealt with. Individual tests
919  * for each type should verify that data is copied correctly, references
920  * are updated, etc.
921  */
922 
923  /* vSrc == vDst */
924  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
925  {
926  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
927  {
928  SKIPTESTS(vt);
929 
930  memset(&vSrc, 0, sizeof(vSrc));
931  V_VT(&vSrc) = vt | ExtraFlags[i];
932 
933  hExpected = DISP_E_BADVARTYPE;
934  /* src is allowed to be a VT_CLSID */
936  hExpected = S_OK;
937 
938  hres = VariantCopy(&vSrc, &vSrc);
939 
940  ok(hres == hExpected,
941  "Copy(src==dst): expected 0x%X, got 0x%X for src==dest vt %d|0x%X\n",
942  hExpected, hres, vt, ExtraFlags[i]);
943  }
944  }
945 
946  /* Test that if VariantClear() fails on dest, the function fails. This also
947  * shows that dest is in fact cleared and not just overwritten
948  */
949  memset(&vSrc, 0, sizeof(vSrc));
950  V_VT(&vSrc) = VT_UI1;
951 
952  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
953  {
954  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
955  {
956  SKIPTESTS(vt);
957 
958  hExpected = DISP_E_BADVARTYPE;
959 
960  memset(&vDst, 0, sizeof(vDst));
961  V_VT(&vDst) = vt | ExtraFlags[i];
962 
964  hExpected = S_OK;
965 
966  hres = VariantCopy(&vDst, &vSrc);
967 
968  ok(hres == hExpected,
969  "Copy(bad dst): expected 0x%X, got 0x%X for dest vt %d|0x%X\n",
970  hExpected, hres, vt, ExtraFlags[i]);
971  if (hres == S_OK)
972  ok(V_VT(&vDst) == VT_UI1,
973  "Copy(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
974  }
975  }
976 
977  /* Test that VariantClear() checks vSrc for validity before copying */
978  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
979  {
980  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
981  {
982  SKIPTESTS(vt);
983 
984  hExpected = DISP_E_BADVARTYPE;
985 
986  memset(&vDst, 0, sizeof(vDst));
987  V_VT(&vDst) = VT_EMPTY;
988 
989  memset(&vSrc, 0, sizeof(vSrc));
990  V_VT(&vSrc) = vt | ExtraFlags[i];
991 
992  /* src is allowed to be a VT_CLSID */
994  hExpected = S_OK;
995 
996  hres = VariantCopy(&vDst, &vSrc);
997 
998  ok(hres == hExpected,
999  "Copy(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
1000  hExpected, hres, vt, ExtraFlags[i]);
1001  if (hres == S_OK)
1002  {
1003  ok(V_VT(&vDst) == (vt|ExtraFlags[i]),
1004  "Copy(bad src): expected vt = %d, got %d\n",
1005  vt | ExtraFlags[i], V_VT(&vDst));
1006  VariantClear(&vDst);
1007  }
1008  }
1009  }
1010 
1011  /* Test that copying a NULL BSTR results in an empty BSTR */
1012  memset(&vDst, 0, sizeof(vDst));
1013  V_VT(&vDst) = VT_EMPTY;
1014  memset(&vSrc, 0, sizeof(vSrc));
1015  V_VT(&vSrc) = VT_BSTR;
1016  hres = VariantCopy(&vDst, &vSrc);
1017  ok(hres == S_OK, "Copy(NULL BSTR): Failed to copy a NULL BSTR\n");
1018  if (hres == S_OK)
1019  {
1020  ok((V_VT(&vDst) == VT_BSTR) && V_BSTR(&vDst),
1021  "Copy(NULL BSTR): should have non-NULL result\n");
1022  if ((V_VT(&vDst) == VT_BSTR) && V_BSTR(&vDst))
1023  {
1024  ok(*V_BSTR(&vDst) == 0, "Copy(NULL BSTR): result not empty\n");
1025  }
1026  VariantClear(&vDst);
1027  }
1028 
1029  /* copy RECORD */
1030  recinfo = get_test_recordinfo();
1031 
1032  memset(&vDst, 0, sizeof(vDst));
1033  V_VT(&vDst) = VT_EMPTY;
1034 
1035  V_VT(&vSrc) = VT_RECORD;
1036  rec = &V_UNION(&vSrc, brecVal);
1037  rec->pRecInfo = &recinfo->IRecordInfo_iface;
1038  rec->pvRecord = (void*)0xdeadbeef;
1039 
1040  recinfo->recordclear = 0;
1041  recinfo->recordcopy = 0;
1042  recinfo->getsize = 0;
1043  recinfo->rec = rec;
1044  hres = VariantCopy(&vDst, &vSrc);
1045  ok(hres == S_OK, "ret %08x\n", hres);
1046 
1047  rec = &V_UNION(&vDst, brecVal);
1048  ok(rec->pvRecord != (void*)0xdeadbeef && rec->pvRecord != NULL, "got %p\n", rec->pvRecord);
1049  ok(rec->pRecInfo == &recinfo->IRecordInfo_iface, "got %p\n", rec->pRecInfo);
1050  ok(recinfo->getsize == 1, "got %d\n", recinfo->recordclear);
1051  ok(recinfo->recordcopy == 1, "got %d\n", recinfo->recordclear);
1052 
1053  VariantClear(&vDst);
1054  VariantClear(&vSrc);
1055 }
1056 
1057 /* Determine if a vt is valid for VariantCopyInd() */
1059 {
1060  BOOL ret = FALSE;
1061 
1062  if ((extraFlags & VT_ARRAY) ||
1063  (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
1064  !(extraFlags & (VT_VECTOR|VT_RESERVED))))
1065  {
1066  ret = TRUE; /* ok */
1067  }
1068  return ret;
1069 }
1070 
1071 static void test_VariantCopyInd(void)
1072 {
1073  VARIANTARG vSrc, vDst, vRef, vRef2;
1074  VARTYPE vt;
1075  size_t i;
1076  BYTE buffer[64];
1077  HRESULT hres, hExpected;
1078 
1079  memset(buffer, 0, sizeof(buffer));
1080 
1081  /* vSrc == vDst */
1082  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1083  {
1084  if (ExtraFlags[i] & VT_ARRAY)
1085  continue; /* Native crashes on NULL safearray */
1086 
1087  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1088  {
1089  SKIPTESTS(vt);
1090 
1091  memset(&vSrc, 0, sizeof(vSrc));
1092  V_VT(&vSrc) = vt | ExtraFlags[i];
1093 
1094  hExpected = DISP_E_BADVARTYPE;
1095  if (!(ExtraFlags[i] & VT_BYREF))
1096  {
1097  /* if src is not by-reference, acts as VariantCopy() */
1099  hExpected = S_OK;
1100  }
1101  else
1102  {
1103  if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
1104  vt == VT_DISPATCH || vt == VT_RECORD)
1105  continue; /* Need valid ptrs for deep copies */
1106 
1107  V_BYREF(&vSrc) = &buffer;
1108  hExpected = E_INVALIDARG;
1109 
1110  if ((vt == VT_I8 || vt == VT_UI8) &&
1111  ExtraFlags[i] == VT_BYREF)
1112  {
1113  if (has_i8)
1114  hExpected = S_OK; /* Only valid if I8 is a known type */
1115  }
1116  else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
1117  hExpected = S_OK;
1118  }
1119 
1120  hres = VariantCopyInd(&vSrc, &vSrc);
1121 
1122  ok(hres == hExpected,
1123  "CopyInd(src==dst): expected 0x%X, got 0x%X for src==dst vt %d|0x%X\n",
1124  hExpected, hres, vt, ExtraFlags[i]);
1125  }
1126  }
1127 
1128  /* Bad dest */
1129  memset(&vSrc, 0, sizeof(vSrc));
1130  V_VT(&vSrc) = VT_UI1|VT_BYREF;
1131  V_BYREF(&vSrc) = &buffer;
1132 
1133  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1134  {
1135  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1136  {
1137  SKIPTESTS(vt);
1138 
1139  memset(&vDst, 0, sizeof(vDst));
1140  V_VT(&vDst) = vt | ExtraFlags[i];
1141 
1142  hExpected = DISP_E_BADVARTYPE;
1143 
1145  hExpected = S_OK;
1146 
1147  hres = VariantCopyInd(&vDst, &vSrc);
1148 
1149  ok(hres == hExpected,
1150  "CopyInd(bad dst): expected 0x%X, got 0x%X for dst vt %d|0x%X\n",
1151  hExpected, hres, vt, ExtraFlags[i]);
1152  if (hres == S_OK)
1153  ok(V_VT(&vDst) == VT_UI1,
1154  "CopyInd(bad dst): expected vt = VT_UI1, got %d\n", V_VT(&vDst));
1155  }
1156  }
1157 
1158  /* bad src */
1159  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
1160  {
1161  if (ExtraFlags[i] & VT_ARRAY)
1162  continue; /* Native crashes on NULL safearray */
1163 
1164  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
1165  {
1166  SKIPTESTS(vt);
1167 
1168  memset(&vDst, 0, sizeof(vDst));
1169  V_VT(&vDst) = VT_EMPTY;
1170 
1171  memset(&vSrc, 0, sizeof(vSrc));
1172  V_VT(&vSrc) = vt | ExtraFlags[i];
1173 
1174  hExpected = DISP_E_BADVARTYPE;
1175  if (!(ExtraFlags[i] & VT_BYREF))
1176  {
1177  /* if src is not by-reference, acts as VariantCopy() */
1179  hExpected = S_OK;
1180  }
1181  else
1182  {
1183  if (vt == VT_SAFEARRAY || vt == VT_BSTR || vt == VT_UNKNOWN ||
1184  vt == VT_DISPATCH || vt == VT_RECORD)
1185  continue; /* Need valid ptrs for deep copies, see vartype.c */
1186 
1187  V_BYREF(&vSrc) = &buffer;
1188 
1189  hExpected = E_INVALIDARG;
1190 
1191  if ((vt == VT_I8 || vt == VT_UI8) &&
1192  ExtraFlags[i] == VT_BYREF)
1193  {
1194  if (has_i8)
1195  hExpected = S_OK; /* Only valid if I8 is a known type */
1196  }
1197  else if (IsValidVariantCopyIndVT(vt, ExtraFlags[i]))
1198  hExpected = S_OK;
1199  }
1200 
1201  hres = VariantCopyInd(&vDst, &vSrc);
1202 
1203  ok(hres == hExpected,
1204  "CopyInd(bad src): expected 0x%X, got 0x%X for src vt %d|0x%X\n",
1205  hExpected, hres, vt, ExtraFlags[i]);
1206  if (hres == S_OK)
1207  {
1208  if (vt == VT_VARIANT && ExtraFlags[i] == VT_BYREF)
1209  {
1210  /* Type of vDst should be the type of the referenced variant.
1211  * Since we set the buffer to all zeros, its type should be
1212  * VT_EMPTY.
1213  */
1214  ok(V_VT(&vDst) == VT_EMPTY,
1215  "CopyInd(bad src): expected dst vt = VT_EMPTY, got %d|0x%X\n",
1216  V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
1217  }
1218  else
1219  {
1220  ok(V_VT(&vDst) == (vt|(ExtraFlags[i] & ~VT_BYREF)),
1221  "CopyInd(bad src): expected dst vt = %d|0x%X, got %d|0x%X\n",
1222  vt, ExtraFlags[i] & ~VT_BYREF,
1223  V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK);
1224  }
1225  VariantClear(&vDst);
1226  }
1227  }
1228  }
1229 
1230  /* By-reference variants are dereferenced */
1231  V_VT(&vRef) = VT_UI1;
1232  V_UI1(&vRef) = 0x77;
1233  V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1234  V_VARIANTREF(&vSrc) = &vRef;
1235  VariantInit(&vDst);
1236 
1237  hres = VariantCopyInd(&vDst, &vSrc);
1238  ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
1239  ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x77,
1240  "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
1241  V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
1242 
1243  /* By-reference variant to a by-reference type succeeds */
1244  V_VT(&vRef) = VT_UI1|VT_BYREF;
1245  V_UI1REF(&vRef) = buffer; buffer[0] = 0x88;
1246  V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1247  V_VARIANTREF(&vSrc) = &vRef;
1248  VariantInit(&vDst);
1249 
1250  hres = VariantCopyInd(&vDst, &vSrc);
1251  ok(hres == S_OK, "VariantCopyInd failed: 0x%08x\n", hres);
1252  ok(V_VT(&vDst) == VT_UI1 && V_UI1(&vDst) == 0x88,
1253  "CopyInd(deref): expected dst vt = VT_UI1, val 0x77, got %d|0x%X, 0x%2X\n",
1254  V_VT(&vDst) & VT_TYPEMASK, V_VT(&vDst) & ~VT_TYPEMASK, V_UI1(&vDst));
1255 
1256  /* But a by-reference variant to a by-reference variant fails */
1257  V_VT(&vRef2) = VT_UI1;
1258  V_UI1(&vRef2) = 0x77;
1259  V_VT(&vRef) = VT_VARIANT|VT_BYREF;
1260  V_VARIANTREF(&vRef) = &vRef2;
1261  V_VT(&vSrc) = VT_VARIANT|VT_BYREF;
1262  V_VARIANTREF(&vSrc) = &vRef;
1263  VariantInit(&vDst);
1264 
1265  hres = VariantCopyInd(&vDst, &vSrc);
1266  ok(hres == E_INVALIDARG,
1267  "CopyInd(ref->ref): expected E_INVALIDARG, got 0x%08x\n", hres);
1268 }
1269 
1270 static HRESULT (WINAPI *pVarParseNumFromStr)(OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
1271 
1272 /* Macros for converting and testing the result of VarParseNumFromStr */
1273 #define FAILDIG 255
1274 
1275 static HRESULT convert_str( const char *str, INT dig, ULONG flags,
1276  NUMPARSE *np, BYTE rgb[128], LCID lcid )
1277 {
1278  OLECHAR buff[128];
1280  memset( rgb, FAILDIG, 128 );
1281  memset( np, 255, sizeof(*np) );
1282  np->cDig = dig;
1283  np->dwInFlags = flags;
1284  return pVarParseNumFromStr( buff, lcid, LOCALE_NOUSEROVERRIDE, np, rgb);
1285 }
1286 
1288  INT d, INT e, INT f )
1289 {
1290  if (hres == (HRESULT)S_OK)
1291  {
1292  ok_(__FILE__,line)(np->cDig == a, "Expected cDig = %d, got %d\n", a, np->cDig);
1293  ok_(__FILE__,line)(np->dwInFlags == b, "Expected dwInFlags = 0x%x, got 0x%x\n", b, np->dwInFlags);
1294  ok_(__FILE__,line)(np->dwOutFlags == c, "Expected dwOutFlags = 0x%x, got 0x%x\n", c, np->dwOutFlags);
1295  ok_(__FILE__,line)(np->cchUsed == d, "Expected cchUsed = %d, got %d\n", d, np->cchUsed);
1296  ok_(__FILE__,line)(np->nBaseShift == e, "Expected nBaseShift = %d, got %d\n", e, np->nBaseShift);
1297  ok_(__FILE__,line)(np->nPwr10 == f, "Expected nPwr10 = %d, got %d\n", f, np->nPwr10);
1298  }
1299 }
1300 
1301 #define CONVERTN(str,dig,flags) hres = convert_str( str, dig, flags, &np, rgb, lcid )
1302 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
1303 #define EXPECT(a,b,c,d,e,f) expect_NumFromStr( __LINE__, hres, &np, a, b, c, d, e, f )
1304 #define EXPECTRGB(a,b) ok(rgb[a] == b, "Digit[%d], expected %d, got %d\n", a, b, rgb[a])
1305 #define EXPECTFAIL ok(hres == (HRESULT)DISP_E_TYPEMISMATCH, "Call succeeded, hres = %08x\n", hres)
1306 #define EXPECT2(a,b) EXPECTRGB(0,a); EXPECTRGB(1,b)
1307 
1308 static void test_VarParseNumFromStr(void)
1309 {
1310  HRESULT hres;
1311  /* Ensure all tests are using the same locale characters for '$', ',' etc */
1313  NUMPARSE np;
1314  BYTE rgb[128];
1315 
1319 
1320  /* Consume a single digit */
1321  CONVERT("7", 0);
1322  EXPECT(1,0,0,1,0,0);
1323  EXPECT2(7,FAILDIG);
1324 
1325  /* cDig is not literal digits - zeros are suppressed and nPwr10 is increased */
1326  CONVERT("10", 0);
1327  EXPECT(1,0,0,2,0,1);
1328  /* Note: Win32 writes the trailing zeros if they are within cDig's limits,
1329  * but then excludes them from the returned cDig count.
1330  * In our implementation we don't bother writing them at all.
1331  */
1332  EXPECTRGB(0, 1);
1333 
1334  /* if cDig is too small and numbers follow, sets INEXACT */
1335  CONVERTN("11",1, 0);
1336  EXPECT(1,0,NUMPRS_INEXACT,2,0,1);
1337  EXPECT2(1,FAILDIG);
1338 
1339  /* Strips leading zeros */
1340  CONVERT("01", 0);
1341  EXPECT(1,0,0,2,0,0);
1342  EXPECT2(1,FAILDIG);
1343 
1344  /* Strips leading zeros */
1345  CONVERTN("01",1, 0);
1346  EXPECT(1,0,0,2,0,0);
1347  EXPECT2(1,FAILDIG);
1348 
1349 
1350  /* Fails on non digits */
1351  CONVERT("a", 0);
1352  EXPECTFAIL;
1353  EXPECTRGB(0,FAILDIG);
1354 
1357  /* Without flag, fails on whitespace */
1358  CONVERT(" 0", 0);
1359  EXPECTFAIL;
1360  EXPECTRGB(0,FAILDIG);
1361 
1362 
1363  /* With flag, consumes whitespace */
1366  EXPECT2(0,FAILDIG);
1367 
1368  /* Test TAB once, then assume it acts as space for all cases */
1369  CONVERT("\t0", NUMPRS_LEADING_WHITE);
1371  EXPECT2(0,FAILDIG);
1372 
1373 
1374  /* Doesn't pick up trailing whitespace without flag */
1375  CONVERT("0 ", 0);
1376  EXPECT(1,0,0,1,0,0);
1377  EXPECT2(0,FAILDIG);
1378 
1379  /* With flag, consumes trailing whitespace */
1382  EXPECT2(0,FAILDIG);
1383 
1384  /* Leading flag only consumes leading */
1385  CONVERT(" 0 ", NUMPRS_LEADING_WHITE);
1387  EXPECT2(0,FAILDIG);
1388 
1389  /* Both flags consumes both */
1392  EXPECT2(0,FAILDIG);
1393 
1396  /* Without flag, fails on + */
1397  CONVERT("+0", 0);
1398  EXPECTFAIL;
1399  EXPECTRGB(0,FAILDIG);
1400 
1401  /* With flag, consumes + */
1404  EXPECT2(0,FAILDIG);
1405 
1406  /* Without flag, doesn't consume trailing + */
1407  CONVERT("0+", 0);
1408  EXPECT(1,0,0,1,0,0);
1409  EXPECT2(0,FAILDIG);
1410 
1411  /* With flag, consumes trailing + */
1414  EXPECT2(0,FAILDIG);
1415 
1416  /* With leading flag, doesn't consume trailing + */
1417  CONVERT("+0+", NUMPRS_LEADING_PLUS);
1419  EXPECT2(0,FAILDIG);
1420 
1421  /* Trailing + doesn't get consumed if we specify both (unlike whitespace) */
1424  EXPECT2(0,FAILDIG);
1425 
1428  /* Without flag, fails on - */
1429  CONVERT("-0", 0);
1430  EXPECTFAIL;
1431  EXPECTRGB(0,FAILDIG);
1432 
1433  /* With flag, consumes - */
1436  EXPECT2(0,FAILDIG);
1437 
1438  /* Without flag, doesn't consume trailing - */
1439  CONVERT("0-", 0);
1440  EXPECT(1,0,0,1,0,0);
1441  EXPECT2(0,FAILDIG);
1442 
1443  /* With flag, consumes trailing - */
1446  EXPECT2(0,FAILDIG);
1447 
1448  /* With leading flag, doesn't consume trailing - */
1449  CONVERT("-0-", NUMPRS_LEADING_MINUS);
1451  EXPECT2(0,FAILDIG);
1452 
1453  /* Trailing - doesn't get consumed if we specify both (unlike whitespace) */
1456  EXPECT2(0,FAILDIG);
1457 
1460  /* Could be hex, octal or decimal - With flag reads as decimal */
1461  CONVERT("0", NUMPRS_HEX_OCT);
1462  EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1463  EXPECT2(0,FAILDIG);
1464 
1465  /* Doesn't recognise hex in .asm syntax */
1466  CONVERT("0h", NUMPRS_HEX_OCT);
1467  EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1468  EXPECT2(0,FAILDIG);
1469 
1470  /* Doesn't fail with valid leading string but no digits */
1471  CONVERT("0x", NUMPRS_HEX_OCT);
1472  EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1473  EXPECT2(0,FAILDIG);
1474 
1475  /* Doesn't recognise hex format numbers at all! */
1476  CONVERT("0x0", NUMPRS_HEX_OCT);
1477  EXPECT(1,NUMPRS_HEX_OCT,0,1,0,0);
1478  EXPECT2(0,FAILDIG);
1479 
1480  /* Doesn't recognise plain hex digits either */
1481  CONVERT("FE", NUMPRS_HEX_OCT);
1482  EXPECTFAIL;
1483  EXPECTRGB(0,FAILDIG);
1484 
1485  /* Octal */
1486  CONVERT("0100", NUMPRS_HEX_OCT);
1487  EXPECT(1,NUMPRS_HEX_OCT,0,4,0,2);
1488  EXPECTRGB(0,1);
1489  EXPECTRGB(1,0);
1490  EXPECTRGB(2,0);
1491  EXPECTRGB(3,FAILDIG);
1492 
1493  /* VB hex */
1494  CONVERT("&HF800", NUMPRS_HEX_OCT);
1495  EXPECT(4,NUMPRS_HEX_OCT,0x40,6,4,0);
1496  EXPECTRGB(0,15);
1497  EXPECTRGB(1,8);
1498  EXPECTRGB(2,0);
1499  EXPECTRGB(3,0);
1500  EXPECTRGB(4,FAILDIG);
1501 
1502  /* VB hex lower case and leading zero */
1503  CONVERT("&h0abcdef", NUMPRS_HEX_OCT);
1504  EXPECT(6,NUMPRS_HEX_OCT,0x40,9,4,0);
1505  EXPECTRGB(0,10);
1506  EXPECTRGB(1,11);
1507  EXPECTRGB(2,12);
1508  EXPECTRGB(3,13);
1509  EXPECTRGB(4,14);
1510  EXPECTRGB(5,15);
1511  EXPECTRGB(6,FAILDIG);
1512 
1513  /* VB oct */
1514  CONVERT("&O300", NUMPRS_HEX_OCT);
1515  EXPECT(3,NUMPRS_HEX_OCT,0x40,5,3,0);
1516  EXPECTRGB(0,3);
1517  EXPECTRGB(1,0);
1518  EXPECTRGB(2,0);
1519  EXPECTRGB(3,FAILDIG);
1520 
1521  /* VB oct lower case and leading zero */
1522  CONVERT("&o0777", NUMPRS_HEX_OCT);
1523  EXPECT(3,NUMPRS_HEX_OCT,0x40,6,3,0);
1524  EXPECTRGB(0,7);
1525  EXPECTRGB(1,7);
1526  EXPECTRGB(2,7);
1527  EXPECTRGB(3,FAILDIG);
1528 
1529  /* VB oct char bigger than 7 */
1530  CONVERT("&o128", NUMPRS_HEX_OCT);
1531  EXPECT(2,NUMPRS_HEX_OCT,0x40,4,3,0);
1532  EXPECTRGB(0,1);
1533  EXPECTRGB(1,2);
1534  EXPECTRGB(3,FAILDIG);
1535 
1538  /* Empty parens = error */
1539  CONVERT("()", NUMPRS_PARENS);
1540  EXPECTFAIL;
1541  EXPECTRGB(0,FAILDIG);
1542 
1543  /* With flag, trailing parens not consumed */
1544  CONVERT("0()", NUMPRS_PARENS);
1545  EXPECT(1,NUMPRS_PARENS,0,1,0,0);
1546  EXPECT2(0,FAILDIG);
1547 
1548  /* With flag, Number in parens made negative and parens consumed */
1549  CONVERT("(0)", NUMPRS_PARENS);
1551  EXPECT2(0,FAILDIG);
1552 
1555  /* With flag, thousands sep. not needed */
1556  CONVERT("0", NUMPRS_THOUSANDS);
1557  EXPECT(1,NUMPRS_THOUSANDS,0,1,0,0);
1558  EXPECT2(0,FAILDIG);
1559 
1560  /* With flag, thousands sep. and following digits consumed */
1561  CONVERT("1,000", NUMPRS_THOUSANDS);
1563  EXPECTRGB(0,1);
1564 
1565  /* With flag and decimal point, thousands sep. but not decimals consumed */
1566  CONVERT("1,000.0", NUMPRS_THOUSANDS);
1568  EXPECTRGB(0,1);
1569 
1572  /* Without flag, chokes on currency sign */
1573  CONVERT("$11", 0);
1574  EXPECTFAIL;
1575  EXPECTRGB(0,FAILDIG);
1576 
1577  /* With flag, consumes currency sign */
1578  CONVERT("$11", NUMPRS_CURRENCY);
1580  EXPECT2(1,1);
1581  EXPECTRGB(2,FAILDIG);
1582 
1583  /* With flag only, doesn't consume decimal point */
1584  CONVERT("$11.1", NUMPRS_CURRENCY);
1586  EXPECT2(1,1);
1587  EXPECTRGB(2,FAILDIG);
1588 
1589  /* With flag and decimal flag, consumes decimal point and following digits */
1592  EXPECT2(1,1);
1593  EXPECTRGB(2,1);
1594  EXPECTRGB(3,FAILDIG);
1595 
1596  /* Thousands flag can only be used with currency */
1599  EXPECT2(1,2);
1600  EXPECTRGB(2,3);
1601  EXPECTRGB(3,4);
1602  EXPECTRGB(4,FAILDIG);
1603 
1606  /* With flag, consumes decimal point */
1607  CONVERT("1.1", NUMPRS_DECIMAL);
1609  EXPECT2(1,1);
1610  EXPECTRGB(2,FAILDIG);
1611 
1612  /* With flag, consumes decimal point. Skipping the decimal part is not an error */
1613  CONVERT("1.", NUMPRS_DECIMAL);
1615  EXPECT2(1,FAILDIG);
1616 
1617  /* Consumes only one decimal point */
1618  CONVERT("1.1.", NUMPRS_DECIMAL);
1620  EXPECT2(1,1);
1621  EXPECTRGB(2,FAILDIG);
1622 
1625  /* Without flag, doesn't consume exponent */
1626  CONVERT("1e1", 0);
1627  EXPECT(1,0,0,1,0,0);
1628  EXPECT2(1,FAILDIG);
1629 
1630  /* With flag, consumes exponent */
1631  CONVERT("1e1", NUMPRS_EXPONENT);
1633  EXPECT2(1,FAILDIG);
1634 
1635  /* Negative exponents are accepted without flags */
1636  CONVERT("1e-1", NUMPRS_EXPONENT);
1638  EXPECT2(1,FAILDIG);
1639 
1640  /* As are positive exponents and leading exponent 0s */
1641  CONVERT("1e+01", NUMPRS_EXPONENT);
1643  EXPECT2(1,FAILDIG);
1644 
1645  /* The same for zero exponents */
1646  CONVERT("1e0", NUMPRS_EXPONENT);
1648  EXPECT2(1,FAILDIG);
1649 
1650  /* Sign on a zero exponent doesn't matter */
1651  CONVERT("1e+0", NUMPRS_EXPONENT);
1653  EXPECT2(1,FAILDIG);
1654 
1655  CONVERT("1e-0", NUMPRS_EXPONENT);
1657  EXPECT2(1,FAILDIG);
1658 
1659  /* Doesn't consume a real number exponent */
1660  CONVERT("1e1.", NUMPRS_EXPONENT);
1662  EXPECT2(1,FAILDIG);
1663 
1664  /* Powers of 10 are calculated from the position of any decimal point */
1667  EXPECT2(1,5);
1668 
1671  EXPECT2(1,5);
1672 
1675  /* Flag expects all digits */
1676  CONVERT("0", NUMPRS_USE_ALL);
1677  EXPECT(1,NUMPRS_USE_ALL,0,1,0,0);
1678  EXPECT2(0,FAILDIG);
1679 
1680  /* Rejects anything trailing */
1681  CONVERT("0 ", NUMPRS_USE_ALL);
1682  EXPECTFAIL;
1683  EXPECT2(0,FAILDIG);
1684 
1685  /* Unless consumed by trailing flag */
1688  EXPECT2(0,FAILDIG);
1689 
1692  /* Leading whitespace and plus, doesn't consume trailing whitespace */
1695  EXPECT2(0,FAILDIG);
1696 
1697  /* Order of whitespace and plus is unimportant */
1700  EXPECT2(0,FAILDIG);
1701 
1702  /* Leading whitespace can be repeated */
1705  EXPECT2(0,FAILDIG);
1706 
1707  /* But plus/minus etc. cannot */
1709  EXPECTFAIL;
1710  EXPECTRGB(0,FAILDIG);
1711 
1712  /* Inexact is not set if trailing zeros are removed */
1713  CONVERTN("10", 1, 0);
1714  EXPECT(1,0,0,2,0,1);
1715  EXPECT2(1,FAILDIG);
1716 
1717  /* Make sure a leading 0 is stripped but decimals after it get read */
1718  CONVERT("-0.51", NUMPRS_STD);
1720  EXPECT2(5,1);
1721 
1722  /* Keep trailing zeros on whole number part of a decimal */
1723  CONVERT("10.1", NUMPRS_STD);
1724  EXPECT(3,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-1);
1725  EXPECT2(1,0);
1726  EXPECTRGB(2,1);
1727 
1728  /* Zeros after decimal sign */
1729  CONVERT("0.01", NUMPRS_STD);
1730  EXPECT(1,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-2);
1731  EXPECT2(1,FAILDIG);
1732 
1733  /* Trailing zeros after decimal part */
1734  CONVERT("0.10", NUMPRS_STD);
1735  EXPECT(1,NUMPRS_STD,NUMPRS_DECIMAL,4,0,-1);
1736  EXPECT2(1,0);
1737 }
1738 
1739 static HRESULT (WINAPI *pVarNumFromParseNum)(NUMPARSE*,BYTE*,ULONG,VARIANT*);
1740 
1741 /* Macros for converting and testing the result of VarNumFromParseNum */
1742 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
1743 #undef CONVERT
1744 #define CONVERT(a,b,c,d,e,f,bits) \
1745  np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
1746  np.nBaseShift = (e); np.nPwr10 = (f); hres = pVarNumFromParseNum(&np, rgb, bits, &vOut)
1747 static const char *szFailOverflow = "Expected overflow, hres = %08x\n";
1748 #define EXPECT_OVERFLOW ok(hres == (HRESULT)DISP_E_OVERFLOW, szFailOverflow, hres)
1749 static const char *szFailOk = "Call failed, hres = %08x\n";
1750 #define EXPECT_OK ok(hres == (HRESULT)S_OK, szFailOk, hres); \
1751  if (hres == (HRESULT)S_OK)
1752 #define EXPECT_TYPE(typ) ok(V_VT(&vOut) == typ,"Expected Type = " #typ ", got %d\n", V_VT(&vOut))
1753 #define EXPECT_I1(val) EXPECT_OK { EXPECT_TYPE(VT_I1); \
1754  ok(V_I1(&vOut) == val, "Expected i1 = %d, got %d\n", (signed char)val, V_I1(&vOut)); }
1755 #define EXPECT_UI1(val) EXPECT_OK { EXPECT_TYPE(VT_UI1); \
1756  ok(V_UI1(&vOut) == val, "Expected ui1 = %d, got %d\n", (BYTE)val, V_UI1(&vOut)); }
1757 #define EXPECT_I2(val) EXPECT_OK { EXPECT_TYPE(VT_I2); \
1758  ok(V_I2(&vOut) == val, "Expected i2 = %d, got %d\n", (SHORT)val, V_I2(&vOut)); }
1759 #define EXPECT_UI2(val) EXPECT_OK { EXPECT_TYPE(VT_UI2); \
1760  ok(V_UI2(&vOut) == val, "Expected ui2 = %d, got %d\n", (USHORT)val, V_UI2(&vOut)); }
1761 #define EXPECT_I4(val) EXPECT_OK { EXPECT_TYPE(VT_I4); \
1762  ok(V_I4(&vOut) == val, "Expected i4 = %d, got %d\n", (LONG)val, V_I4(&vOut)); }
1763 #define EXPECT_UI4(val) EXPECT_OK { EXPECT_TYPE(VT_UI4); \
1764  ok(V_UI4(&vOut) == val, "Expected ui4 = %d, got %d\n", (ULONG)val, V_UI4(&vOut)); }
1765 #define EXPECT_I8(high,low) EXPECT_OK { EXPECT_TYPE(VT_I8); \
1766  ok(V_I8(&vOut) == ((((ULONG64)(high))<<32)|(low)), "Expected i8 = %x%08x, got %x%08x\n", \
1767  (LONG)(high), (LONG)(low), (LONG)(V_I8(&vOut)>>32), (LONG)V_I8(&vOut) ); }
1768 #define EXPECT_UI8(val) EXPECT_OK { EXPECT_TYPE(VT_UI8); \
1769  ok(V_UI8(&vOut) == val, "Expected ui8 = 0x%x%08x, got 0x%x%08x\n", \
1770  (DWORD)((ULONG64)val >> 32), (DWORD)(ULONG64)val, (DWORD)(V_UI8(&vOut) >> 32), (DWORD)V_UI8(&vOut)); }
1771 #define EXPECT_R4(val) EXPECT_OK { EXPECT_TYPE(VT_R4); \
1772  ok(V_R4(&vOut) == val, "Expected r4 = %f, got %f\n", val, V_R4(&vOut)); }
1773 #define EXPECT_R8(val) EXPECT_OK { EXPECT_TYPE(VT_R8); \
1774  ok(V_R8(&vOut) == val, "Expected r8 = %g, got %g\n", val, V_R8(&vOut)); }
1775 #define CY_MULTIPLIER 10000
1776 #define EXPECT_CY(val) EXPECT_OK { EXPECT_TYPE(VT_CY); \
1777  ok(V_CY(&vOut).int64 == (LONG64)(val * CY_MULTIPLIER), "Expected r8 = 0x%x%08x, got 0x%x%08x\n", \
1778  (DWORD)((LONG64)val >> 23), (DWORD)(LONG64)val, (DWORD)(V_CY(&vOut).int64 >>32), (DWORD)V_CY(&vOut).int64); }
1779 #define EXPECT_DECIMAL(valHi, valMid, valLo) EXPECT_OK { EXPECT_TYPE(VT_DECIMAL); \
1780  ok((V_DECIMAL(&vOut).Hi32 == valHi) && (S1(U1(V_DECIMAL(&vOut))).Mid32 == valMid) && \
1781  (S1(U1(V_DECIMAL(&vOut))).Lo32 == valLo), \
1782  "Expected decimal = %x/0x%x%08x, got %x/0x%x%08x\n", valHi, valMid, valLo, \
1783  V_DECIMAL(&vOut).Hi32, S1(U1(V_DECIMAL(&vOut))).Mid32, S1(U1(V_DECIMAL(&vOut))).Lo32); }
1784 
1785 static void test_VarNumFromParseNum(void)
1786 {
1787  HRESULT hres;
1788  NUMPARSE np;
1789  BYTE rgb[128];
1790  VARIANT vOut;
1791 
1793 
1794  /* Convert the number 1 to different types */
1795  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1); EXPECT_I1(1);
1796  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1); EXPECT_UI1(1);
1797  /* Prefers a signed type to unsigned of the same size */
1798  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1|VTBIT_UI1); EXPECT_I1(1);
1799  /* But takes the smaller size if possible */
1800  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I2|VTBIT_UI1); EXPECT_UI1(1);
1801 
1802  /* Try different integer sizes */
1803 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
1804 
1805  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, INTEGER_VTBITS); EXPECT_I1(1);
1806  /* 127 */
1807  SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 7);
1808  CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I1(127);
1809  /* 128 */
1810  SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
1811  CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(128);
1812  /* 255 */
1813  SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 5);
1814  CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_UI1(255);
1815  /* 256 */
1816  SETRGB(0, 2); SETRGB(1, 5); SETRGB(2, 6);
1817  CONVERT(3,0,0,3,0,0, INTEGER_VTBITS); EXPECT_I2(256);
1818  /* 32767 */
1819  SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 7);
1820  CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_I2(32767);
1821  /* 32768 */
1822  SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
1823  CONVERT(5,0,0,5,0,0, INTEGER_VTBITS); EXPECT_UI2(32768);
1824 
1825  /* Assume the above pattern holds for remaining positive integers; test negative */
1826 
1827  /* -128 */
1828  SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 8);
1829  CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I1(-128);
1830  /* -129 */
1831  SETRGB(0, 1); SETRGB(1, 2); SETRGB(2, 9);
1832  CONVERT(3,0,NUMPRS_NEG,3,0,0, INTEGER_VTBITS); EXPECT_I2(-129);
1833  /* -32768 */
1834  SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 8);
1835  CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I2(-32768);
1836  /* -32768 */
1837  SETRGB(0, 3); SETRGB(1, 2); SETRGB(2, 7); SETRGB(3, 6); SETRGB(4, 9);
1838  CONVERT(5,0,NUMPRS_NEG,5,0,0, INTEGER_VTBITS); EXPECT_I4(-32769);
1839 
1840  /* Assume the above pattern holds for remaining negative integers */
1841 
1842  /* Test hexadecimal conversions */
1843  SETRGB(0, 1); CONVERT(1,0,0,1,4,0, INTEGER_VTBITS); EXPECT_I1(0x01);
1844  /* 0x7f */
1845  SETRGB(0, 7); SETRGB(1, 0xf);
1846  CONVERT(2,0,0,2,4,0, INTEGER_VTBITS); EXPECT_I1(0x7f);
1847  SETRGB(0, 7); SETRGB(1, 0xf);
1848  CONVERT(2,0,0,2,4,0, VTBIT_DECIMAL); EXPECT_DECIMAL(0,0,0x7f);
1849  /* 0x7fff */
1850  SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
1851  CONVERT(4,0,0,4,4,0, INTEGER_VTBITS); EXPECT_I2(0x7fff);
1852  /* 0x7fffffff */
1853  SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
1854  SETRGB(4, 0xf); SETRGB(5, 0xf); SETRGB(6, 0xf); SETRGB(7, 0xf);
1855  CONVERT(8,0,0,8,4,0, INTEGER_VTBITS); EXPECT_I4(0x7fffffffL);
1856  /* 0x7fffffffffffffff (64 bits) */
1857  SETRGB(0, 7); SETRGB(1, 0xf); SETRGB(2, 0xf); SETRGB(3, 0xf);
1858  SETRGB(4, 0xf); SETRGB(5, 0xf); SETRGB(6, 0xf); SETRGB(7, 0xf);
1859  SETRGB(8, 0xf); SETRGB(9, 0xf); SETRGB(10, 0xf); SETRGB(11, 0xf);
1860  SETRGB(12, 0xf); SETRGB(13, 0xf); SETRGB(14, 0xf); SETRGB(15, 0xf);
1861  if (has_i8)
1862  {
1863  /* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
1864  truncate the number to the smallest integer size requested:
1865  CONVERT(16,0,0,16,4,0, INTEGER_VTBITS); EXPECT_I1((signed char)0xff); */
1866  CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x7fffffff,0xffffffff);
1867  }
1868 
1869  /* Assume the above pattern holds for numbers without hi-bit set, test (preservation of) hi-bit */
1870  /* 0x82 */
1871  SETRGB(0, 8); SETRGB(1, 2);
1872  CONVERT(2,0,0,2,4,0, INTEGER_VTBITS);
1873  EXPECT_I1((signed char)0x82);
1874  /* 0x8002 */
1875  SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 2);
1876  CONVERT(4,0,0,4,4,0, INTEGER_VTBITS);
1877  EXPECT_I2((signed short)0x8002);
1878  /* 0x80000002 */
1879  SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
1880  SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 2);
1881  CONVERT(8,0,0,8,4,0, INTEGER_VTBITS); EXPECT_I4(0x80000002);
1882  /* 0x8000000000000002 (64 bits) */
1883  SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
1884  SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 0);
1885  SETRGB(8, 0); SETRGB(9, 0); SETRGB(10, 0); SETRGB(11, 0);
1886  SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
1887  if (has_i8)
1888  {
1889  /* We cannot use INTEGER_VTBITS as WinXP and Win2003 are broken(?). They
1890  truncate the number to the smallest integer size requested:
1891  CONVERT(16,0,0,16,4,0, INTEGER_VTBITS & ~VTBIT_I1);
1892  EXPECT_I2((signed short)0x0002); */
1893  CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
1894  }
1895 
1896  /* Test (preservation of) hi-bit with STRICT type requesting */
1897  /* 0x82 */
1898  SETRGB(0, 8); SETRGB(1, 2);
1899  CONVERT(2,0,0,2,4,0, VTBIT_I1);
1900  EXPECT_I1((signed char)0x82);
1901  /* 0x8002 */
1902  SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 2);
1903  CONVERT(4,0,0,4,4,0, VTBIT_I2);
1904  EXPECT_I2((signed short)0x8002);
1905  /* 0x80000002 */
1906  SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
1907  SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 2);
1908  CONVERT(8,0,0,8,4,0, VTBIT_I4); EXPECT_I4(0x80000002);
1909  /* 0x8000000000000002 (64 bits) */
1910  SETRGB(0, 8); SETRGB(1, 0); SETRGB(2, 0); SETRGB(3, 0);
1911  SETRGB(4, 0); SETRGB(5, 0); SETRGB(6, 0); SETRGB(7, 0);
1912  SETRGB(8, 0); SETRGB(9, 0); SETRGB(10, 0); SETRGB(11, 0);
1913  SETRGB(12, 0); SETRGB(13, 0); SETRGB(14, 0); SETRGB(15, 2);
1914  if (has_i8)
1915  {
1916  CONVERT(16,0,0,16,4,0, VTBIT_I8); EXPECT_I8(0x80000000,0x00000002);
1917  }
1918  /* Assume the above pattern holds for numbers with hi-bit set */
1919 
1920  /* Negative numbers overflow if we have only unsigned outputs */
1921  /* -1 */
1922  SETRGB(0, 1); CONVERT(1,0,NUMPRS_NEG,1,0,0, VTBIT_UI1); EXPECT_OVERFLOW;
1923  /* -0.6 */
1924  SETRGB(0, 6); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_OVERFLOW;
1925 
1926  /* Except that rounding is done first, so -0.5 to 0 are accepted as 0 */
1927  /* -0.5 */
1928  SETRGB(0, 5); CONVERT(1,0,NUMPRS_NEG,1,0,~0u, VTBIT_UI1); EXPECT_UI1(0);
1929 
1930  /* Floating point zero is OK */
1931  /* 0.00000000E0 */
1932  SETRGB(0, 0); CONVERT(1,0,NUMPRS_DECIMAL|NUMPRS_EXPONENT,12,0,-8, VTBIT_R8);
1933  EXPECT_R8(0.0);
1934 
1935  /* Float is acceptable for an integer input value */
1936  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4); EXPECT_R4(1.0f);
1937  /* As is double */
1938  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8); EXPECT_R8(1.0);
1939  /* As is currency */
1940  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY); EXPECT_CY(1);
1941 
1942  /* Float is preferred over double */
1943  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R4|VTBIT_R8); EXPECT_R4(1.0f);
1944 
1945  /* Double is preferred over currency */
1946  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_R8|VTBIT_CY); EXPECT_R8(1.0);
1947 
1948  /* Currency is preferred over decimal */
1949  SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_CY|VTBIT_DECIMAL); EXPECT_CY(1);
1950 
1951  /* Underflow test */
1952  SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R4); EXPECT_R4(0.0);
1953  SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_R8); EXPECT_R8(0.0);
1954  SETRGB(0, 1); CONVERT(1,0,NUMPRS_EXPONENT,1,0,-94938484, VTBIT_CY); EXPECT_CY(0);
1955 }
1956 
1957 
1959  WORD h, WORD mn, WORD s, WORD ms, WORD dw, WORD dy)
1960 {
1961  UDATE ud;
1962  HRESULT res;
1963 
1964  memset(&ud, 0, sizeof(ud));
1965  res = pVarUdateFromDate(dt, flags, &ud);
1966  ok_(__FILE__,line)(r == res && (res != S_OK || (ud.st.wYear == y && ud.st.wMonth == m && ud.st.wDay == d &&
1967  ud.st.wHour == h && ud.st.wMinute == mn && ud.st.wSecond == s &&
1968  ud.st.wMilliseconds == ms && ud.st.wDayOfWeek == dw && ud.wDayOfYear == dy)),
1969  "%.16g expected res(%x) %d,%d,%d,%d,%d,%d,%d %d %d, got res(%x) %d,%d,%d,%d,%d,%d,%d %d %d\n",
1970  dt, r, d, m, y, h, mn, s, ms, dw, dy,
1971  res, ud.st.wDay, ud.st.wMonth, ud.st.wYear, ud.st.wHour, ud.st.wMinute,
1972  ud.st.wSecond, ud.st.wMilliseconds, ud.st.wDayOfWeek, ud.wDayOfYear );
1973 }
1974 #define DT2UD(dt,flags,r,d,m,y,h,mn,s,ms,dw,dy) test_UdateFromDate(__LINE__,dt,flags,r,d,m,y,h,mn,s,ms,dw,dy)
1975 
1976 static void test_VarUdateFromDate(void)
1977 {
1979  DT2UD(29221.0,0,S_OK,1,1,1980,0,0,0,0,2,1); /* 1 Jan 1980 */
1980  DT2UD(29222.0,0,S_OK,2,1,1980,0,0,0,0,3,2); /* 2 Jan 1980 */
1981  DT2UD(33238.0,0,S_OK,31,12,1990,0,0,0,0,1,365); /* 31 Dec 1990 */
1982  DT2UD(0.0,0,S_OK,30,12,1899,0,0,0,0,6,364); /* 30 Dec 1899 - VT_DATE 0.0 */
1983  DT2UD(-657434.0,0,S_OK,1,1,100,0,0,0,0,5,1); /* 1 Jan 100 - Min */
1984  DT2UD(-657435.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* < 1 Jan 100 => err */
1985  DT2UD(2958465.0,0,S_OK,31,12,9999,0,0,0,0,5,365); /* 31 Dec 9999 - Max */
1986  DT2UD(2958466.0,0,E_INVALIDARG,0,0,0,0,0,0,0,0,0); /* > 31 Dec 9999 => err */
1987 
1988  /* VAR_VALIDDATE doesn't prevent upper and lower bounds being checked */
1989  DT2UD(-657435.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
1990  DT2UD(2958466.0,VAR_VALIDDATE,E_INVALIDARG,0,0,0,0,0,0,0,0,0);
1991 
1992  /* Times */
1993  DT2UD(29221.25,0,S_OK,1,1,1980,6,0,0,0,2,1); /* 6 AM */
1994  DT2UD(29221.33333333,0,S_OK,1,1,1980,8,0,0,0,2,1); /* 8 AM */
1995  DT2UD(29221.5,0,S_OK,1,1,1980,12,0,0,0,2,1); /* 12 AM */
1996  DT2UD(29221.9888884444,0,S_OK,1,1,1980,23,44,0,0,2,1); /* 11:44 PM */
1997  DT2UD(29221.7508765432,0,S_OK,1,1,1980,18,1,16,0,2,1); /* 6:18:02 PM */
1998 
1999  /* Test handling of times on dates prior to the epoch */
2000  DT2UD(-5.25,0,S_OK,25,12,1899,6,0,0,0,1,359);
2001  DT2UD(-5.9999884259259,0,S_OK,25,12,1899,23,59,59,0,1,359);
2002  /* This just demonstrates the non-linear nature of values prior to the epoch */
2003  DT2UD(-4.0,0,S_OK,26,12,1899,0,0,0,0,2,360);
2004  /* Numerical oddity: for 0.0 < x < 1.0, x and -x represent the same datetime */
2005  DT2UD(-0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
2006  DT2UD(0.25,0,S_OK,30,12,1899,6,0,0,0,6,364);
2007 }
2008 
2009 
2010 static void test_DateFromUDate( int line, WORD d, WORD m, WORD y, WORD h, WORD mn, WORD s, WORD ms,
2011  WORD dw, WORD dy, ULONG flags, HRESULT r, DATE dt )
2012 {
2013  UDATE ud;
2014  double out;
2015  HRESULT res;
2016 
2017  ud.st.wYear = y;
2018  ud.st.wMonth = m;
2019  ud.st.wDay = d;
2020  ud.st.wHour = h;
2021  ud.st.wMinute = mn;
2022  ud.st.wSecond = s;
2023  ud.st.wMilliseconds = ms;
2024  ud.st.wDayOfWeek = dw;
2025  ud.wDayOfYear = dy;
2026  res = pVarDateFromUdate(&ud, flags, &out);
2027  ok_(__FILE__,line)(r == res && (r != S_OK || EQ_DOUBLE(out, dt)),
2028  "expected %x, %.16g, got %x, %.16g\n", r, dt, res, out);
2029 }
2030 #define UD2T(d,m,y,h,mn,s,ms,dw,dy,flags,r,dt) test_DateFromUDate(__LINE__,d,m,y,h,mn,s,ms,dw,dy,flags,r,dt)
2031 
2032 static void test_VarDateFromUdate(void)
2033 {
2035  UD2T(1,1,1980,0,0,0,0,2,1,0,S_OK,29221.0); /* 1 Jan 1980 */
2036  UD2T(2,1,1980,0,0,0,0,3,2,0,S_OK,29222.0); /* 2 Jan 1980 */
2037  UD2T(2,1,1980,0,0,0,0,4,5,0,S_OK,29222.0); /* 2 Jan 1980 */
2038  UD2T(31,12,1990,0,0,0,0,0,0,0,S_OK,33238.0); /* 31 Dec 1990 */
2039  UD2T(31,12,90,0,0,0,0,0,0,0,S_OK,33238.0); /* year < 100 is 1900+year! */
2040  UD2T(30,12,1899,0,0,0,0,6,364,0,S_OK,0.0); /* 30 Dec 1899 - VT_DATE 0.0 */
2041  UD2T(1,1,100,0,0,0,0,0,0,0,S_OK,-657434.0); /* 1 Jan 100 - Min */
2042  UD2T(31,12,9999,0,0,0,0,0,0,0,S_OK,2958465.0); /* 31 Dec 9999 - Max */
2043  UD2T(1,1,10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0); /* > 31 Dec 9999 => err */
2044  UD2T(1,1,-10000,0,0,0,0,0,0,0,E_INVALIDARG,0.0);/* < -9999 => err */
2045 
2046  UD2T(30,12,1899,0,0,0,0,0,0,0,S_OK,0.0); /* 30 Dec 1899 0:00:00 */
2047  UD2T(30,12,1899,0,0,0,999,0,0,0,S_OK,0.0); /* Ignore milliseconds */
2048 
2049  UD2T(1,1,1980,18,1,16,0,2,1,0,S_OK,29221.75087962963); /* 6:18:02 PM */
2050  UD2T(1,300,1980,18,1,16,0,2,1,0,S_OK,38322.75087962963); /* Test fwdrolled month */
2051  UD2T(300,1,1980,18,1,16,0,2,1,0,S_OK,29520.75087962963); /* Test fwdrolled days */
2052  UD2T(0,1,1980,42,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled hours */
2053  UD2T(1,1,1980,17,61,16,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled minutes */
2054  UD2T(1,1,1980,18,0,76,0,2,1,0,S_OK,29221.75087962963); /* Test fwdrolled seconds */
2055  UD2T(1,-300,1980,18,1,16,0,2,1,0,S_OK,20059.75087962963); /* Test backrolled month */
2056  UD2T(-300,1,1980,18,1,16,0,2,1,0,S_OK,28920.75087962963); /* Test backrolled days */
2057  UD2T(3,1,1980,-30,1,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled hours */
2058  UD2T(1,1,1980,20,-119,16,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled minutes */
2059  UD2T(1,1,1980,18,3,-104,0,2,1,0,S_OK,29221.75087962963); /* Test backrolled seconds */
2060  UD2T(1,12001,-1020,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test rolled year and month */
2061  UD2T(1,-23,1982,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled month */
2062  UD2T(-59,3,1980,18,1,16,0,0,0,0,S_OK,29221.75087962963); /* Test backrolled days */
2063  UD2T(1,1,0,0,0,0,0,0,0,0,S_OK,36526); /* Test zero year */
2064  UD2T(0,0,1980,0,0,0,0,0,0,0,S_OK,29189); /* Test zero day and month */
2065  UD2T(0,1,1980,0,0,0,0,2,1,0,S_OK,29220.0); /* Test zero day = LastDayOfMonth */
2066  UD2T(-1,1,1980,18,1,16,0,0,0,0,S_OK,29219.75087962963); /* Test day -1 = LastDayOfMonth - 1 */
2067  UD2T(1,1,-1,18,1,16,0,0,0,0,S_OK,36161.75087962963); /* Test year -1 = 1999 */
2068  UD2T(1,-1,1980,18,1,16,0,0,0,0,S_OK,29160.7508796296); /* Test month -1 = 11 */
2069  UD2T(1,13,1980,0,0,0,0,2,1,0,S_OK,29587.0); /* Rolls fwd to 1/1/1981 */
2070 
2071  /* Test handling of times on dates prior to the epoch */
2072  UD2T(25,12,1899,6,0,0,0,1,359,0,S_OK,-5.25);
2073  UD2T(25,12,1899,23,59,59,0,1,359,0,S_OK,-5.9999884259259);
2074  /* This just demonstrates the non-linear nature of values prior to the epoch */
2075  UD2T(26,12,1899,0,0,0,0,2,360,0,S_OK,-4.0);
2076  /* for DATE values 0.0 < x < 1.0, x and -x represent the same datetime */
2077  /* but when converting to DATE, prefer the positive versions */
2078  UD2T(30,12,1899,6,0,0,0,6,364,0,S_OK,0.25);
2079 
2080  UD2T(1,1,1980,18,1,16,0,2,1,VAR_TIMEVALUEONLY,S_OK,0.7508796296296296);
2081  UD2T(1,1,1980,18,1,16,0,2,1,VAR_DATEVALUEONLY,S_OK,29221.0);
2082  UD2T(25,12,1899,6,0,0,0,1,359,VAR_TIMEVALUEONLY,S_OK,0.25);
2083  UD2T(25,12,1899,6,0,0,0,1,359,VAR_DATEVALUEONLY,S_OK,-5.0);
2084  UD2T(1,-1,1980,18,1,16,0,0,0,VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY,S_OK,0.7508796296296296);
2085 }
2086 
2087 static void test_st2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
2088  WORD s, WORD ms, INT r, double dt)
2089 {
2090  SYSTEMTIME st;
2091  double out;
2092  INT res;
2093 
2094  st.wYear = y;
2095  st.wMonth = m;
2096  st.wDay = d;
2097  st.wHour = h;
2098  st.wMinute = mn;
2099  st.wSecond = s;
2100  st.wMilliseconds = ms;
2101  st.wDayOfWeek = 0;
2102  res = pSystemTimeToVariantTime(&st, &out);
2103  ok_(__FILE__,line)(r == res && (!r || EQ_DOUBLE(out, dt)),
2104  "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out);
2105 }
2106 #define ST2DT(d,m,y,h,mn,s,ms,r,dt) test_st2dt(__LINE__,d,m,y,h,mn,s,ms,r,dt)
2107 
2109 {
2111  ST2DT(1,1,1980,0,0,0,0,TRUE,29221.0);
2112  ST2DT(2,1,1980,0,0,0,0,TRUE,29222.0);
2113  ST2DT(0,1,1980,0,0,0,0,TRUE,29220.0); /* Rolls back to 31 Dec 1899 */
2114  ST2DT(1,13,1980,0,0,0,0,FALSE,29587.0); /* Fails on invalid month */
2115  ST2DT(32,1,1980,0,0,0,0,FALSE,0.0); /* Fails on invalid day */
2116  ST2DT(1,1,-1,0,0,0,0,FALSE,0.0); /* Fails on invalid year */
2117  ST2DT(1,1,10000,0,0,0,0,FALSE,0.0); /* Fails on invalid year */
2118  ST2DT(1,1,9999,0,0,0,0,TRUE,2958101.0); /* 9999 is last valid year */
2119  ST2DT(31,12,90,0,0,0,0,TRUE,33238.0); /* 30 <= year < 100 is 1900+year */
2120  ST2DT(1,1,30,0,0,0,0,TRUE,10959.0); /* 30 <= year < 100 is 1900+year */
2121  ST2DT(1,1,29,0,0,0,0,TRUE,47119.0); /* 0 <= year < 30 is 2000+year */
2122  ST2DT(1,1,0,0,0,0,0,TRUE,36526.0); /* 0 <= year < 30 is 2000+year */
2123 }
2124 
2125 static void test_dt2st(int line, double dt, INT r, WORD d, WORD m, WORD y,
2126  WORD h, WORD mn, WORD s, WORD ms)
2127 {
2128  SYSTEMTIME st;
2129  INT res;
2130 
2131  memset(&st, 0, sizeof(st));
2132  res = pVariantTimeToSystemTime(dt, &st);
2133  ok_(__FILE__,line)(r == res &&
2134  (!r || (st.wYear == y && st.wMonth == m && st.wDay == d &&
2135  st.wHour == h && st.wMinute == mn &&
2136  st.wSecond == s && st.wMilliseconds == ms)),
2137  "%.16g expected %d, %d,%d,%d,%d,%d,%d,%d, got %d, %d,%d,%d,%d,%d,%d,%d\n",
2138  dt, r, d, m, y, h, mn, s, ms, res, st.wDay, st.wMonth,
2139  st.wYear, st.wHour, st.wMinute, st.wSecond,
2140  st.wMilliseconds);
2141 }
2142 #define DT2ST(dt,r,d,m,y,h,mn,s,ms) test_dt2st(__LINE__,dt,r,d,m,y,h,mn,s,ms)
2143 
2145 {
2147  DT2ST(29221.0,1,1,1,1980,0,0,0,0);
2148  DT2ST(29222.0,1,2,1,1980,0,0,0,0);
2149 }
2150 
2151 #define MKDOSDATE(d,m,y) ((d & 0x1f) | ((m & 0xf) << 5) | (((y-1980) & 0x7f) << 9))
2152 #define MKDOSTIME(h,m,s) (((s>>1) & 0x1f) | ((m & 0x3f) << 5) | ((h & 0x1f) << 11))
2153 
2154 static void test_dos2dt(int line, WORD d, WORD m, WORD y, WORD h, WORD mn,
2155  WORD s, INT r, double dt)
2156 {
2157  unsigned short dosDate, dosTime;
2158  double out;
2159  INT res;
2160 
2161  out = 0.0;
2162  dosDate = MKDOSDATE(d, m, y);
2163  dosTime = MKDOSTIME(h, mn, s);
2164  res = pDosDateTimeToVariantTime(dosDate, dosTime, &out);
2165  ok_(__FILE__,line)(r == res && (!r || EQ_DOUBLE(out, dt)),
2166  "expected %d, %.16g, got %d, %.16g\n", r, dt, res, out);
2167 }
2168 #define DOS2DT(d,m,y,h,mn,s,r,dt) test_dos2dt(__LINE__,d,m,y,h,mn,s,r,dt)
2169 
2171 {
2173 
2174  /* Date */
2175  DOS2DT(1,1,1980,0,0,0,1,29221.0); /* 1/1/1980 */
2176  DOS2DT(31,12,2099,0,0,0,1,73050.0); /* 31/12/2099 */
2177  /* Dates are limited to the dos date max of 31/12/2099 */
2178  DOS2DT(31,12,2100,0,0,0,0,0.0); /* 31/12/2100 */
2179  /* Days and months of 0 cause date to roll back 1 day or month */
2180  DOS2DT(0,1,1980,0,0,0,1,29220.0); /* 0 Day => 31/12/1979 */
2181  DOS2DT(1,0,1980,0,0,0,1,29190.0); /* 0 Mth => 1/12/1979 */
2182  DOS2DT(0,0,1980,0,0,0,1,29189.0); /* 0 D/M => 30/11/1979 */
2183  /* Days > days in the month cause date to roll forward 1 month */
2184  DOS2DT(29,2,1981,0,0,0,1,29646.0); /* 29/2/1981 -> 3/1/1980 */
2185  DOS2DT(30,2,1981,0,0,0,1,29647.0); /* 30/2/1981 -> 4/1/1980 */
2186  /* Takes leap years into account when rolling forward */
2187  DOS2DT(29,2,1980,0,0,0,1,29280.0); /* 2/29/1980 */
2188  /* Months > 12 cause an error */
2189  DOS2DT(2,13,1980,0,0,0,0,0.0);
2190 
2191  /* Time */
2192  DOS2DT(1,1,1980,0,0,29,1,29221.00032407407); /* 1/1/1980 12:00:28 AM */
2193  DOS2DT(1,1,1980,0,0,31,1,29221.00034722222); /* 1/1/1980 12:00:30 AM */
2194  DOS2DT(1,1,1980,0,59,0,1,29221.04097222222); /* 1/1/1980 12:59:00 AM */
2195  DOS2DT(1,1,1980,0,60,0,0,0.0); /* Invalid minutes */
2196  DOS2DT(1,1,1980,0,0,60,0,0.0); /* Invalid seconds */
2197  DOS2DT(1,1,1980,23,0,0,1,29221.95833333333); /* 1/1/1980 11:00:00 PM */
2198  DOS2DT(1,1,1980,24,0,0,0,0.0); /* Invalid hours */
2199 
2200  DOS2DT(1,1,1980,0,0,1,1,29221.0);
2201  DOS2DT(2,1,1980,0,0,0,1,29222.0);
2202  DOS2DT(2,1,1980,0,0,0,1,29222.0);
2203  DOS2DT(31,12,1990,0,0,0,1,33238.0);
2204  DOS2DT(31,12,90,0,0,0,1,40543.0);
2205  DOS2DT(30,12,1899,0,0,0,1,46751.0);
2206  DOS2DT(1,1,100,0,0,0,1,43831.0);
2207  DOS2DT(31,12,9999,0,0,0,1,59901.0);
2208  DOS2DT(1,1,10000,0,0,0,1,59902.0);
2209  DOS2DT(1,1,-10000,0,0,0,1,48214.0);
2210 
2211  DOS2DT(30,12,1899,0,0,0,1,46751.0);
2212  DOS2DT(30,12,1899,0,0,1,1,46751.0);
2213 
2214  DOS2DT(1,1,1980,18,1,16,1,29221.75087962963);
2215  DOS2DT(1,300,1980,18,1,16,1,29556.75087962963);
2216  DOS2DT(300,1,1980,18,1,16,1,29232.75087962963);
2217  DOS2DT(0,1,1980,42,1,16,1,29220.4175462963);
2218  DOS2DT(1,1,1980,17,61,16,0,0.0);
2219  DOS2DT(1,1,1980,18,0,76,1,29221.75013888889);
2220  DOS2DT(1,-300,1980,18,1,16,1,29312.75087962963);
2221  DOS2DT(-300,1,1980,18,1,16,1,29240.75087962963);
2222  DOS2DT(3,1,1980,-30,1,16,1,29223.08421296296);
2223  DOS2DT(1,1,1980,20,-119,16,1,29221.83976851852);
2224  DOS2DT(1,1,1980,18,3,-104,1,29221.75236111111);
2225  DOS2DT(1,12001,-1020,18,1,16,1,55519.75087962963);
2226  DOS2DT(1,-23,1982,18,1,16,1,30195.75087962963);
2227  DOS2DT(-59,3,1980,18,1,16,1,29285.75087962963);
2228  DOS2DT(1,1,0,0,0,0,1,54058.0);
2229  DOS2DT(0,0,1980,0,0,0,1,29189.0);
2230  DOS2DT(0,1,1980,0,0,0,1,29220.0);
2231  DOS2DT(-1,1,1980,18,1,16,1,29251.75087962963);
2232  DOS2DT(1,1,-1,18,1,16,1,53693.75087962963);
2233  DOS2DT(1,-1,1980,18,1,16,0,0);
2234 }
2235 
2236 static void test_dt2dos(int line, double dt, INT r, WORD d, WORD m, WORD y,
2237  WORD h, WORD mn, WORD s)
2238 {
2239  unsigned short dosDate, dosTime, expDosDate, expDosTime;
2240  INT res;
2241 
2242  dosTime = dosDate = 0;
2243  expDosDate = MKDOSDATE(d,m,y);
2244  expDosTime = MKDOSTIME(h,mn,s);
2245  res = pVariantTimeToDosDateTime(dt, &dosDate, &dosTime);
2246  ok_(__FILE__,line)(r == res && (!r || (dosTime == expDosTime && dosDate == expDosDate)),
2247  "%g: expected %d,%d(%d/%d/%d),%d(%d:%d:%d) got %d,%d(%d/%d/%d),%d(%d:%d:%d)\n",
2248  dt, r, expDosDate, expDosDate & 0x1f,
2249  (expDosDate >> 5) & 0xf, 1980 + (expDosDate >> 9),
2250  expDosTime, expDosTime >> 11, (expDosTime >> 5) & 0x3f,
2251  (expDosTime & 0x1f),
2252  res, dosDate, dosDate & 0x1f, (dosDate >> 5) & 0xf,
2253  1980 + (dosDate >> 9), dosTime, dosTime >> 11,
2254  (dosTime >> 5) & 0x3f, (dosTime & 0x1f));
2255 }
2256 #define DT2DOS(dt,r,d,m,y,h,mn,s) test_dt2dos(__LINE__,dt,r,d,m,y,h,mn,s)
2257 
2259 {
2261 
2262  /* Date */
2263  DT2DOS(29221.0,1,1,1,1980,0,0,0); /* 1/1/1980 */
2264  DT2DOS(73050.0,1,31,12,2099,0,0,0); /* 31/12/2099 */
2265  DT2DOS(29220.0,0,0,0,0,0,0,0); /* 31/12/1979 - out of range */
2266  DT2DOS(73415.0,0,0,0,0,0,0,0); /* 31/12/2100 - out of range */
2267 
2268  /* Time */
2269  DT2DOS(29221.00032407407,1,1,1,1980,0,0,29); /* 1/1/1980 12:00:28 AM */
2270  DT2DOS(29221.00034722222,1,1,1,1980,0,0,31); /* 1/1/1980 12:00:30 AM */
2271  DT2DOS(29221.04097222222,1,1,1,1980,0,59,0); /* 1/1/1980 12:59:00 AM */
2272  DT2DOS(29221.95833333333,1,1,1,1980,23,0,0); /* 1/1/1980 11:00:00 PM */
2273 }
2274 
2275 static HRESULT (WINAPI *pVarAbs)(LPVARIANT,LPVARIANT);
2276 
2277 #define VARABS(vt,val,rvt,rval) \
2278  V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2279  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
2280  test_var_call1( __LINE__, pVarAbs, &v, &exp )
2281 
2282 static void test_VarAbs(void)
2283 {
2284  static WCHAR szNum[] = {'-','1','.','1','\0' };
2285  char buff[8];
2286  HRESULT hres;
2287  VARIANT v, vDst, exp;
2288  size_t i;
2289 
2290  CHECKPTR(VarAbs);
2291 
2292  /* Test all possible V_VT values.
2293  */
2294  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
2295  {
2296  VARTYPE vt;
2297 
2298  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2299  {
2300  HRESULT hExpected = DISP_E_BADVARTYPE;
2301 
2302  SKIPTESTS(vt);
2303 
2304  memset(&v, 0, sizeof(v));
2305  V_VT(&v) = vt | ExtraFlags[i];
2306  V_VT(&vDst) = VT_EMPTY;
2307 
2308  hres = pVarAbs(&v,&vDst);
2309  if (ExtraFlags[i] & VT_ARRAY ||
2310  (!ExtraFlags[i] && (vt == VT_UNKNOWN || vt == VT_BSTR ||
2311  vt == VT_DISPATCH || vt == VT_ERROR || vt == VT_RECORD)))
2312  {
2313  hExpected = DISP_E_TYPEMISMATCH;
2314  }
2315  else if (ExtraFlags[i] || vt >= VT_CLSID || vt == VT_VARIANT)
2316  {
2317  hExpected = DISP_E_BADVARTYPE;
2318  }
2319  else if (IsValidVariantClearVT(vt, ExtraFlags[i]))
2320  hExpected = S_OK;
2321 
2322  /* Native always fails on some vartypes that should be valid. don't
2323  * check that Wine does the same; these are bugs in native.
2324  */
2325  if (vt == VT_I8 || vt == VT_UI8 || vt == VT_INT || vt == VT_UINT ||
2326  vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4)
2327  continue;
2328  ok(hres == hExpected, "VarAbs: expected 0x%X, got 0x%X for vt %d | 0x%X\n",
2329  hExpected, hres, vt, ExtraFlags[i]);
2330  }
2331  }
2332 
2333  /* BOOL->I2, BSTR->R8, all others remain the same */
2334  VARABS(BOOL,VARIANT_TRUE,I2,-VARIANT_TRUE);
2335  VARABS(BOOL,VARIANT_FALSE,I2,VARIANT_FALSE);
2336  VARABS(EMPTY,0,I2,0);
2337  VARABS(EMPTY,1,I2,0);
2338  VARABS(NULL,0,NULL,0);
2339  VARABS(NULL,1,NULL,0);
2340  VARABS(I2,1,I2,1);
2341  VARABS(I2,-1,I2,1);
2342  VARABS(I4,1,I4,1);
2343  VARABS(I4,-1,I4,1);
2344  VARABS(UI1,1,UI1,1);
2345  VARABS(R4,1,R4,1);
2346  VARABS(R4,-1,R4,1);
2347  VARABS(R8,1,R8,1);
2348  VARABS(R8,-1,R8,1);
2349  VARABS(DATE,1,DATE,1);
2350  VARABS(DATE,-1,DATE,1);
2351  V_VT(&v) = VT_CY;
2352  V_CY(&v).int64 = -10000;
2353  memset(&vDst,0,sizeof(vDst));
2354  hres = pVarAbs(&v,&vDst);
2355  ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
2356  "VarAbs(CY): expected 0x0 got 0x%X\n", hres);
2358  if (buff[1])
2359  {
2360  trace("Skipping VarAbs(BSTR) as decimal separator is '%s'\n", buff);
2361  return;
2362  } else {
2363  szNum[2] = buff[0];
2364  }
2365  V_VT(&v) = VT_BSTR;
2366  V_BSTR(&v) = (BSTR)szNum;
2367  memset(&vDst,0,sizeof(vDst));
2368  hres = pVarAbs(&v,&vDst);
2369  ok(hres == S_OK && V_VT(&vDst) == VT_R8 && V_R8(&vDst) == 1.1,
2370  "VarAbs: expected 0x0,%d,%g, got 0x%X,%d,%g\n", VT_R8, 1.1, hres, V_VT(&vDst), V_R8(&vDst));
2371 }
2372 
2373 static HRESULT (WINAPI *pVarNot)(LPVARIANT,LPVARIANT);
2374 
2375 #define VARNOT(vt,val,rvt,rval) \
2376  V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
2377  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
2378  test_var_call1( __LINE__, pVarNot, &v, &exp )
2379 
2380 static void test_VarNot(void)
2381 {
2382  static const WCHAR szNum0[] = {'0','\0' };
2383  static const WCHAR szNum1[] = {'1','\0' };
2384  static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
2385  static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
2386  HRESULT hres;
2387  VARIANT v, exp, vDst;
2388  DECIMAL *pdec = &V_DECIMAL(&v);
2389  CY *pcy = &V_CY(&v);
2390  size_t i;
2391 
2392  CHECKPTR(VarNot);
2393 
2394  /* Test all possible V_VT values */
2395  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
2396  {
2397  VARTYPE vt;
2398 
2399  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
2400  {
2401  HRESULT hExpected = DISP_E_BADVARTYPE;
2402 
2403  SKIPTESTS(vt);
2404 
2405  memset(&v, 0, sizeof(v));
2406  V_VT(&v) = vt | ExtraFlags[i];
2407  V_VT(&vDst) = VT_EMPTY;
2408 
2409  switch (V_VT(&v))
2410  {
2411  case VT_I1: case VT_UI1: case VT_I2: case VT_UI2:
2412  case VT_INT: case VT_UINT: case VT_I4: case VT_UI4:
2413  case VT_R4: case VT_R8:
2414  case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
2415  case VT_DATE: case VT_CY:
2416  hExpected = S_OK;
2417  break;
2418  case VT_I8: case VT_UI8:
2419  if (has_i8)
2420  hExpected = S_OK;
2421  break;
2422  case VT_RECORD:
2423  hExpected = DISP_E_TYPEMISMATCH;
2424  break;
2425  case VT_UNKNOWN: case VT_BSTR: case VT_DISPATCH: case VT_ERROR:
2426  hExpected = DISP_E_TYPEMISMATCH;
2427  break;
2428  default:
2430  hExpected = DISP_E_TYPEMISMATCH;
2431  break;
2432  }
2433 
2434  hres = pVarNot(&v,&vDst);
2435  ok(hres == hExpected, "VarNot: expected 0x%X, got 0x%X vt %d|0x%X\n",
2436  hExpected, hres, vt, ExtraFlags[i]);
2437  }
2438  }
2439  /* Test the values returned by all cases that can succeed */
2440  VARNOT(EMPTY,0,I2,-1);
2441  VARNOT(EMPTY,1,I2,-1);
2442  VARNOT(NULL,0,NULL,0);
2443  VARNOT(NULL,1,NULL,0);
2444  VARNOT(BOOL,VARIANT_TRUE,BOOL,VARIANT_FALSE);
2445  VARNOT(BOOL,VARIANT_FALSE,BOOL,VARIANT_TRUE);
2446  VARNOT(I1,-1,I4,0);
2447  VARNOT(I1,0,I4,-1);
2448  VARNOT(I2,-1,I2,0);
2449  VARNOT(I2,0,I2,-1);
2450  VARNOT(I2,1,I2,-2);
2451  VARNOT(I4,1,I4,-2);
2452  VARNOT(I4,0,I4,-1);
2453  VARNOT(UI1,1,UI1,254);
2454  VARNOT(UI1,0,UI1,255);
2455  VARNOT(UI2,0,I4,-1);
2456  VARNOT(UI2,1,I4,-2);
2457  VARNOT(UI4,0,I4,-1);
2458  VARNOT(UI4,1,I4,-2);
2459  VARNOT(INT,0,I4,-1);
2460  VARNOT(INT,1,I4,-2);
2461  VARNOT(UINT,0,I4,-1);
2462  VARNOT(UINT,1,I4,-2);
2463  if (has_i8)
2464  {
2465  VARNOT(I8,1,I8,-2);
2466  VARNOT(I8,0,I8,-1);
2467  VARNOT(UI8,0,I4,-1);
2468  VARNOT(UI8,1,I4,-2);
2469  }
2470  VARNOT(R4,1,I4,-2);
2471  VARNOT(R4,0,I4,-1);
2472  VARNOT(R8,1,I4,-2);
2473  VARNOT(R8,0,I4,-1);
2474  VARNOT(DATE,1,I4,-2);
2475  VARNOT(DATE,0,I4,-1);
2476  VARNOT(BSTR,(BSTR)szNum0,I4,-1);
2477  ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum0, "VarNot(0): changed input\n");
2478  VARNOT(BSTR,(BSTR)szNum1,I4,-2);
2479  ok(V_VT(&v) == VT_BSTR && V_BSTR(&v) == szNum1, "VarNot(1): changed input\n");
2480  VARNOT(BSTR, (BSTR)szTrue, BOOL, VARIANT_FALSE);
2481  VARNOT(BSTR, (BSTR)szFalse, BOOL, VARIANT_TRUE);
2482 
2483  S(U(*pdec)).sign = DECIMAL_NEG;
2484  S(U(*pdec)).scale = 0;
2485  pdec->Hi32 = 0;
2486  S1(U1(*pdec)).Mid32 = 0;
2487  S1(U1(*pdec)).Lo32 = 1;
2488  VARNOT(DECIMAL,*pdec,I4,0);
2489 
2490  pcy->int64 = 10000;
2491  VARNOT(CY,*pcy,I4,-2);
2492 
2493  pcy->int64 = 0;
2494  VARNOT(CY,*pcy,I4,-1);
2495 
2496  pcy->int64 = -1;
2497  VARNOT(CY,*pcy,I4,-1);
2498 }
2499 
2500 static HRESULT (WINAPI *pVarSub)(LPVARIANT,LPVARIANT,LPVARIANT);
2501 
2502 #define VARSUB(vt1,val1,vt2,val2,rvt,rval) \
2503  V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
2504  V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
2505  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
2506  test_var_call2( __LINE__, pVarSub, &left, &right, &exp )
2507 
2508 static void test_VarSub(void)
2509 {
2510  VARIANT left, right, exp, result, cy, dec;
2511  VARTYPE i;
2512  BSTR lbstr, rbstr;
2513  HRESULT hres, expectedhres;
2514  double r;
2515 
2516  CHECKPTR(VarSub);
2517 
2518  lbstr = SysAllocString(sz12);
2519  rbstr = SysAllocString(sz12);
2520 
2521  VariantInit(&left);
2522  VariantInit(&right);
2523  VariantInit(&result);
2524 
2525  /* Test all possible flag/vt combinations & the resulting vt type */
2526  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
2527  {
2528 
2529  VARTYPE leftvt, rightvt, resvt;
2530 
2531  for (leftvt = 0; leftvt <= VT_BSTR_BLOB; leftvt++)
2532  {
2533 
2534  SKIPTESTS(leftvt);
2535 
2536  for (rightvt = 0; rightvt <= VT_BSTR_BLOB; rightvt++)
2537  {
2538 
2539  SKIPTESTS(rightvt);
2540  expectedhres = S_OK;
2541 
2542  memset(&left, 0, sizeof(left));
2543  memset(&right, 0, sizeof(right));
2544  V_VT(&left) = leftvt | ExtraFlags[i];
2545  if (leftvt == VT_BSTR)
2546  V_BSTR(&left) = lbstr;
2547  V_VT(&right) = rightvt | ExtraFlags[i];
2548  if (rightvt == VT_BSTR)
2549  V_BSTR(&right) = rbstr;
2550  V_VT(&result) = VT_EMPTY;
2551 
2552  /* All extra flags produce errors */
2555  ExtraFlags[i] == (VT_VECTOR|VT_BYREF) ||
2556  ExtraFlags[i] == (VT_BYREF|VT_RESERVED) ||
2557  ExtraFlags[i] == VT_VECTOR ||
2558  ExtraFlags[i] == VT_BYREF ||
2559  ExtraFlags[i] == VT_RESERVED)
2560  {
2561  expectedhres = DISP_E_BADVARTYPE;
2562  resvt = VT_EMPTY;
2563  }
2564  else if (ExtraFlags[i] >= VT_ARRAY)
2565  {
2566  expectedhres = DISP_E_TYPEMISMATCH;
2567  resvt = VT_EMPTY;
2568  }
2569  /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
2570  VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
2571  else if (!IsValidVariantClearVT(leftvt, ExtraFlags[i]) ||
2572  !IsValidVariantClearVT(rightvt, ExtraFlags[i]) ||
2573  leftvt == VT_CLSID || rightvt == VT_CLSID ||
2574  leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
2575  leftvt == VT_I1 || rightvt == VT_I1 ||
2576  leftvt == VT_UI2 || rightvt == VT_UI2 ||
2577  leftvt == VT_UI4 || rightvt == VT_UI4 ||
2578  leftvt == VT_UI8 || rightvt == VT_UI8 ||
2579  leftvt == VT_INT || rightvt == VT_INT ||
2580  leftvt == VT_UINT || rightvt == VT_UINT ||
2581  leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
2582  leftvt == VT_RECORD || rightvt == VT_RECORD)
2583  {
2584  if (leftvt == VT_RECORD && rightvt == VT_I8)
2585  {
2586  if (has_i8)
2587  expectedhres = DISP_E_TYPEMISMATCH;
2588  else
2589  expectedhres = DISP_E_BADVARTYPE;
2590  }
2591  else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
2592  expectedhres = DISP_E_TYPEMISMATCH;
2593  else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
2594  expectedhres = DISP_E_TYPEMISMATCH;
2595  else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
2596  expectedhres = DISP_E_TYPEMISMATCH;
2597  else if (leftvt == VT_RECORD && rightvt > VT_UI1)
2598  expectedhres = DISP_E_BADVARTYPE;
2599  else
2600  expectedhres = DISP_E_BADVARTYPE;
2601  resvt = VT_EMPTY;
2602  }
2603  else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
2604  (leftvt == VT_DISPATCH && rightvt == VT_NULL))
2605  resvt = VT_NULL;
2606  else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
2607  leftvt == VT_ERROR || rightvt == VT_ERROR)
2608  {
2609  resvt = VT_EMPTY;
2610  expectedhres = DISP_E_TYPEMISMATCH;
2611  }
2612  else if (leftvt == VT_NULL || rightvt == VT_NULL)
2613  resvt = VT_NULL;
2614  else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
2615  (leftvt == VT_DATE && rightvt == VT_DATE) ||
2616  (leftvt == VT_BSTR && rightvt == VT_EMPTY) ||
2617  (leftvt == VT_BSTR && rightvt == VT_BSTR))
2618  resvt = VT_R8;
2619  else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
2620  resvt = VT_DECIMAL;
2621  else if (leftvt == VT_DATE || rightvt == VT_DATE)
2622  resvt = VT_DATE;
2623  else if (leftvt == VT_CY || rightvt == VT_CY)
2624  resvt = VT_CY;
2625  else if (leftvt == VT_R8 || rightvt == VT_R8)
2626  resvt = VT_R8;
2627  else if (leftvt == VT_BSTR || rightvt == VT_BSTR) {
2628  resvt = VT_R8;
2629  } else if (leftvt == VT_R4 || rightvt == VT_R4) {
2630  if (leftvt == VT_I4 || rightvt == VT_I4 ||
2631  leftvt == VT_I8 || rightvt == VT_I8)
2632  resvt = VT_R8;
2633  else
2634  resvt = VT_R4;
2635  }
2636  else if (leftvt == VT_I8 || rightvt == VT_I8)
2637  resvt = VT_I8;
2638  else if (leftvt == VT_I4 || rightvt == VT_I4)
2639  resvt = VT_I4;
2640  else if (leftvt == VT_I2 || rightvt == VT_I2 ||
2641  leftvt == VT_BOOL || rightvt == VT_BOOL ||
2642  (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
2643  resvt = VT_I2;
2644  else if (leftvt == VT_UI1 || rightvt == VT_UI1)
2645  resvt = VT_UI1;
2646  else
2647  {
2648  resvt = VT_EMPTY;
2649  expectedhres = DISP_E_TYPEMISMATCH;
2650  }
2651 
2652  hres = pVarSub(&left, &right, &result);
2653 
2654  ok(hres == expectedhres && V_VT(&result) == resvt,
2655  "VarSub: %d|0x%X, %d|0x%X: Expected failure 0x%X, "
2656  "got 0x%X, expected vt %d got vt %d\n",
2657  leftvt, ExtraFlags[i], rightvt, ExtraFlags[i],
2658  expectedhres, hres, resvt, V_VT(&result));
2659  }
2660  }
2661  }
2662 
2663  /* Test returned values */
2664  VARSUB(I4,4,I4,2,I4,2);
2665  VARSUB(I2,4,I2,2,I2,2);
2666  VARSUB(I2,-13,I4,5,I4,-18);
2667  VARSUB(I4,-13,I4,5,I4,-18);
2668  VARSUB(I2,7,R4,0.5f,R4,6.5f);
2669  VARSUB(R4,0.5f,I4,5,R8,-4.5);
2670  VARSUB(R8,7.1,BOOL,0,R8,7.1);
2671  VARSUB(BSTR,lbstr,I2,4,R8,8);
2672  VARSUB(BSTR,lbstr,BOOL,1,R8,11);
2673  VARSUB(BSTR,lbstr,R4,0.1f,R8,11.9);
2674  VARSUB(R4,0.2f,BSTR,rbstr,R8,-11.8);
2675  VARSUB(DATE,2.25,I4,7,DATE,-4.75);
2676  VARSUB(DATE,1.25,R4,-1.7f,DATE,2.95);
2677 
2678  VARSUB(UI1, UI1_MAX, UI1, UI1_MAX, UI1, 0);
2679  VARSUB(I2, I2_MAX, I2, I2_MAX, I2, 0);
2680  VARSUB(I2, I2_MIN, I2, I2_MIN, I2, 0);
2681  VARSUB(I4, I4_MAX, I4, I4_MAX, I4, 0);
2682  VARSUB(I4, I4_MIN, I4, I4_MIN, I4, 0);
2683  VARSUB(R4, R4_MAX, R4, R4_MAX, R4, 0.0f);
2684  VARSUB(R4, R4_MAX, R4, R4_MIN, R4, R4_MAX - R4_MIN);
2685  VARSUB(R4, R4_MIN, R4, R4_MIN, R4, 0.0f);
2686  VARSUB(R8, R8_MAX, R8, R8_MIN, R8, R8_MAX - R8_MIN);
2687  VARSUB(R8, R8_MIN, R8, R8_MIN, R8, 0.0);
2688 
2689  /* Manually test BSTR + BSTR */
2690  V_VT(&left) = VT_BSTR;
2691  V_BSTR(&left) = lbstr;
2692  V_VT(&right) = VT_BSTR;
2693  V_BSTR(&right) = rbstr;
2694  hres = pVarSub(&left, &right, &result);
2695  ok(hres == S_OK && V_VT(&result) == VT_R8,
2696  "VarSub: expected coerced type VT_R8, got %s!\n", vtstr(V_VT(&result)));
2697  ok(hres == S_OK && EQ_DOUBLE(V_R8(&result), 0.0),
2698  "VarSub: BSTR + BSTR, expected %f got %f\n", 0.0, V_R8(&result));
2699 
2700  /* Manually test some VT_CY and VT_DECIMAL variants */
2701  V_VT(&cy) = VT_CY;
2702  hres = VarCyFromI4(4711, &V_CY(&cy));
2703  ok(hres == S_OK, "VarCyFromI4 failed!\n");
2704  V_VT(&dec) = VT_DECIMAL;
2705  hres = VarDecFromR8(-4.2, &V_DECIMAL(&dec));
2706  ok(hres == S_OK, "VarDecFromR4 failed!\n");
2707  memset(&left, 0, sizeof(left));
2708  memset(&right, 0, sizeof(right));
2709  V_VT(&left) = VT_I4;
2710  V_I4(&left) = -11;
2711  V_VT(&right) = VT_UI1;
2712  V_UI1(&right) = 9;
2713 
2714  hres = pVarSub(&cy, &right, &result);
2715  ok(hres == S_OK && V_VT(&result) == VT_CY,
2716  "VarSub: expected coerced type VT_CY, got %s!\n", vtstr(V_VT(&result)));
2717  hres = VarR8FromCy(V_CY(&result), &r);
2718  ok(hres == S_OK && EQ_DOUBLE(r, 4702.0),
2719  "VarSub: CY value %f, expected %f\n", r, (double)4720);
2720 
2721  hres = pVarSub(&left, &dec, &result);
2722  ok(hres == S_OK && V_VT(&result) == VT_DECIMAL,
2723  "VarSub: expected coerced type VT_DECIMAL, got %s!\n", vtstr(V_VT(&result)));
2725  ok(hres == S_OK && EQ_DOUBLE(r, -6.8),
2726  "VarSub: DECIMAL value %f, expected %f\n", r, (double)-15.2);
2727 
2728  SysFreeString(lbstr);
2729  SysFreeString(rbstr);
2730 }
2731 
2732 static HRESULT (WINAPI *pVarMod)(LPVARIANT,LPVARIANT,LPVARIANT);
2733 
2734 static void test_Mod( int line, VARIANT *left, VARIANT *right, VARIANT *expected, HRESULT expres )
2735 {
2736  VARIANT result;
2737  HRESULT hres;
2738 
2739  memset( &result, 0, sizeof(result) );
2740  hres = pVarMod( left, right, &result );
2741  ok_(__FILE__,line)( hres == expres, "wrong result %x/%x\n", hres, expres );
2742  if (hres == S_OK)
2743  ok_(__FILE__,line)( is_expected_variant( &result, expected ),
2744  "got %s expected %s\n", variantstr(&result), variantstr(expected) );
2745 }
2746 
2747 #define VARMOD(vt1,vt2,val1,val2,rvt,rval) \
2748  V_VT(&left) = VT_##vt1; V_##vt1(&left) = val1; \
2749  V_VT(&right) = VT_##vt2; V_##vt2(&right) = val2; \
2750  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
2751  test_var_call2( __LINE__, pVarMod, &left, &right, &exp )
2752 
2753 #define VARMOD2(vt1,vt2,val1,val2,rvt,rval,hexpected) \
2754  V_VT(&left) = VT_##vt1; V_I4(&left) = val1; \
2755  V_VT(&right) = VT_##vt2; V_I4(&right) = val2; \
2756  V_VT(&exp) = VT_##rvt; V_I4(&exp) = rval; \
2757  test_Mod( __LINE__, &left, &right, &exp, hexpected )
2758 
2759 static void test_VarMod(void)
2760 {
2761  VARIANT v1, v2, vDst, left, right, exp;
2762  HRESULT hres;
2763  HRESULT hexpected = 0;
2764  static const WCHAR szNum0[] = {'1','2','5','\0'};
2765  static const WCHAR szNum1[] = {'1','0','\0'};
2766  int l, r;
2767  BOOL lFound, rFound;
2768  BOOL lValid;
2769  BSTR strNum0, strNum1;
2770 
2771  CHECKPTR(VarMod);
2772 
2773  VARMOD(I1,BOOL,100,10,I4,0);
2774  VARMOD(I1,I1,100,10,I4,0);
2775  VARMOD(I1,UI1,100,10,I4,0);
2776  VARMOD(I1,I2,100,10,I4,0);
2777  VARMOD(I1,UI2,100,10,I4,0);
2778  VARMOD(I1,I4,100,10,I4,0);
2779  VARMOD(I1,UI4,100,10,I4,0);
2780  VARMOD(I1,R4,100,10,I4,0);
2781  VARMOD(I1,R8,100,10,I4,0);
2782 
2783  VARMOD(UI1,BOOL,100,10,I2,0);
2784  VARMOD(UI1,I1,100,10,I4,0);
2785  VARMOD(UI1,UI1,100,10,UI1,0);
2786  VARMOD(UI1,I2,100,10,I2,0);
2787  VARMOD(UI1,UI2,100,10,I4,0);
2788  VARMOD(UI1,I4,100,10,I4,0);
2789  VARMOD(UI1,UI4,100,10,I4,0);
2790  VARMOD(UI1,R4,100,10,I4,0);
2791  VARMOD(UI1,R8,100,10,I4,0);
2792 
2793  VARMOD(I2,BOOL,100,10,I2,0);
2794  VARMOD(I2,I1,100,10,I4,0);
2795  VARMOD(I2,UI1,100,10,I2,0);
2796  VARMOD(I2,I2,100,10,I2,0);
2797  VARMOD(I2,UI2,100,10,I4,0);
2798  VARMOD(I2,I4,100,10,I4,0);
2799  VARMOD(I2,UI4,100,10,I4,0);
2800  VARMOD(I2,R4,100,10,I4,0);
2801  VARMOD(I2,R8,100,10,I4,0);
2802 
2803  VARMOD(I4,BOOL,100,10,I4,0);
2804  VARMOD(I4,I1,100,10,I4,0);
2805  VARMOD(I4,UI1,100,10,I4,0);
2806  VARMOD(I4,I2,100,10,I4,0);
2807  VARMOD(I4,UI2,100,10,I4,0);
2808  VARMOD(I4,I4,100,10,I4,0);
2809  VARMOD(I4,UI4,100,10,I4,0);
2810  VARMOD(I4,R4,100,10,I4,0);
2811  VARMOD(I4,R8,100,10,I4,0);
2812  VARMOD(UI4,BOOL,100,10,I4,0);
2813  VARMOD(UI4,I1,100,10,I4,0);
2814  VARMOD(UI4,UI1,100,10,I4,0);
2815  VARMOD(UI4,I2,100,10,I4,0);
2816  VARMOD(UI4,UI2,100,10,I4,0);
2817  VARMOD(UI4,I4,100,10,I4,0);
2818  VARMOD(UI4,UI4,100,10,I4,0);
2819  VARMOD(UI4,R4,100,10,I4,0);
2820  VARMOD(UI4,R8,100,10,I4,0);
2821  VARMOD(R4,BOOL,100,10,I4,0);
2822  VARMOD(R4,I1,100,10,I4,0);
2823  VARMOD(R4,UI1,100,10,I4,0);
2824  VARMOD(R4,I2,100,10,I4,0);
2825  VARMOD(R4,UI2,100,10,I4,0);
2826  VARMOD(R4,I4,100,10,I4,0);
2827  VARMOD(R4,UI4,100,10,I4,0);
2828  VARMOD(R4,R4,100,10,I4,0);
2829  VARMOD(R4,R8,100,10,I4,0);
2830  VARMOD(R8,BOOL,100,10,I4,0);
2831  VARMOD(R8,I1,100,10,I4,0);
2832  VARMOD(R8,UI1,100,10,I4,0);
2833  VARMOD(R8,I2,100,10,I4,0);
2834  VARMOD(R8,UI2,100,10,I4,0);
2835  VARMOD(R8,I4,100,10,I4,0);
2836  VARMOD(R8,UI4,100,10,I4,0);
2837  VARMOD(R8,R4,100,10,I4,0);
2838  VARMOD(R8,R8,100,10,I4,0);
2839 
2840  VARMOD(INT,INT,100,10,I4,0);
2841  VARMOD(INT,UINT,100,10,I4,0);
2842 
2843  VARMOD(BOOL,BOOL,100,10,I2,0);
2844  VARMOD(BOOL,I1,100,10,I4,0);
2845  VARMOD(BOOL,UI1,100,10,I2,0);
2846  VARMOD(BOOL,I2,100,10,I2,0);
2847  VARMOD(BOOL,UI2,100,10,I4,0);
2848  VARMOD(BOOL,I4,100,10,I4,0);
2849  VARMOD(BOOL,UI4,100,10,I4,0);
2850  VARMOD(BOOL,R4,100,10,I4,0);
2851  VARMOD(BOOL,R8,100,10,I4,0);
2852  VARMOD(BOOL,DATE,100,10,I4,0);
2853 
2854  VARMOD(DATE,BOOL,100,10,I4,0);
2855  VARMOD(DATE,I1,100,10,I4,0);
2856  VARMOD(DATE,UI1,100,10,I4,0);
2857  VARMOD(DATE,I2,100,10,I4,0);
2858  VARMOD(DATE,UI2,100,10,I4,0);
2859  VARMOD(DATE,I4,100,10,I4,0);
2860  VARMOD(DATE,UI4,100,10,I4,0);
2861  VARMOD(DATE,R4,100,10,I4,0);
2862  VARMOD(DATE,R8,100,10,I4,0);
2863  VARMOD(DATE,DATE,100,10,I4,0);
2864 
2865  strNum0 = SysAllocString(szNum0);
2866  strNum1 = SysAllocString(szNum1);
2867  VARMOD(BSTR,BSTR,strNum0,strNum1,I4,5);
2868  VARMOD(BSTR,I1,strNum0,10,I4,5);
2869  VARMOD(BSTR,I2,strNum0,10,I4,5);
2870  VARMOD(BSTR,I4,strNum0,10,I4,5);
2871  VARMOD(BSTR,R4,strNum0,10,I4,5);
2872  VARMOD(BSTR,R8,strNum0,10,I4,5);
2873  VARMOD(I4,BSTR,125,strNum1,I4,5);
2874 
2875  if (has_i8)
2876  {
2877  VARMOD(BOOL,I8,100,10,I8,0);
2878  VARMOD(I1,I8,100,10,I8,0);
2879  VARMOD(UI1,I8,100,10,I8,0);
2880  VARMOD(I2,I8,100,10,I8,0);
2881  VARMOD(I4,I8,100,10,I8,0);
2882  VARMOD(UI4,I8,100,10,I8,0);
2883  VARMOD(R4,I8,100,10,I8,0);
2884  VARMOD(R8,I8,100,10,I8,0);
2885  VARMOD(DATE,I8,100,10,I8,0);
2886 
2887  VARMOD(I8,BOOL,100,10,I8,0);
2888  VARMOD(I8,I1,100,10,I8,0);
2889  VARMOD(I8,UI1,100,10,I8,0);
2890  VARMOD(I8,I2,100,10,I8,0);
2891  VARMOD(I8,UI2,100,10,I8,0);
2892  VARMOD(I8,I4,100,10,I8,0);
2893  VARMOD(I8,UI4,100,10,I8,0);
2894  VARMOD(I8,R4,100,10,I8,0);
2895  VARMOD(I8,R8,100,10,I8,0);
2896  VARMOD(I8,I8,100,10,I8,0);
2897 
2898  VARMOD(BSTR,I8,strNum0,10,I8,5);
2899  }
2900 
2901  /* test all combinations of types */
2902  for(l = 0; l < VT_BSTR_BLOB; l++)
2903  {
2904  SKIPTESTS(l);
2905 
2906  for(r = 0; r < VT_BSTR_BLOB; r++)
2907  {
2908  SKIPTESTS(r);
2909 
2910  if(l == VT_BSTR) continue;
2911  if(l == VT_DISPATCH) continue;
2912  if(r == VT_BSTR) continue;
2913  if(r == VT_DISPATCH) continue;
2914 
2915  lFound = TRUE;
2916  lValid = TRUE;
2917  switch(l)
2918  {
2919  case VT_EMPTY:
2920  case VT_NULL:
2921  case VT_I1:
2922  case VT_UI1:
2923  case VT_I2:
2924  case VT_UI2:
2925  case VT_I4:
2926  case VT_I8:
2927  case VT_UI4:
2928  case VT_UI8:
2929  case VT_INT:
2930  case VT_UINT:
2931  case VT_R4:
2932  case VT_R8:
2933  case VT_BOOL:
2934  case VT_DATE:
2935  case VT_CY:
2936  case VT_DECIMAL:
2937  hexpected = S_OK;
2938  break;
2939  case VT_ERROR:
2940  case VT_VARIANT:
2941  case VT_UNKNOWN:
2942  case VT_RECORD:
2943  lValid = FALSE;
2944  break;
2945  default:
2946  lFound = FALSE;
2947  hexpected = DISP_E_BADVARTYPE;
2948  break;
2949  }
2950 
2951  rFound = TRUE;
2952  switch(r)
2953  {
2954  case VT_EMPTY:
2955  case VT_NULL:
2956  case VT_I1:
2957  case VT_UI1:
2958  case VT_I2:
2959  case VT_UI2:
2960  case VT_I4:
2961  case VT_I8:
2962  case VT_UI4:
2963  case VT_UI8:
2964  case VT_INT:
2965  case VT_UINT:
2966  case VT_R4:
2967  case VT_R8:
2968  case VT_BOOL:
2969  case VT_DATE:
2970  case VT_DECIMAL:
2971  case VT_CY:
2972  hexpected = S_OK;
2973  break;
2974  case VT_ERROR:
2975  case VT_VARIANT:
2976  case VT_UNKNOWN:
2977  case VT_RECORD:
2978  break;
2979  default:
2980  rFound = FALSE;
2981  break;
2982  }
2983 
2984  if(((l == VT_I8) && (r == VT_INT)) || ((l == VT_INT) && (r == VT_I8)))
2985  {
2986  hexpected = DISP_E_TYPEMISMATCH;
2987  } else if((l == VT_EMPTY) && (r == VT_NULL))
2988  {
2989  hexpected = S_OK;
2990  } else if((l == VT_NULL) && (r == VT_EMPTY))
2991  {
2992  hexpected = S_OK;
2993  } else if((l == VT_EMPTY) && (r == VT_CY))
2994  {
2995  hexpected = S_OK;
2996  } else if((l == VT_EMPTY) && (r == VT_RECORD))
2997  {
2998  hexpected = DISP_E_TYPEMISMATCH;
2999  } else if((r == VT_EMPTY) && lFound && lValid)
3000  {
3001  hexpected = DISP_E_DIVBYZERO;
3002  } else if((l == VT_ERROR) || ((r == VT_ERROR) && lFound && lValid))
3003  {
3004  hexpected = DISP_E_TYPEMISMATCH;
3005  } else if((l == VT_NULL) && (r == VT_NULL))
3006  {
3007  hexpected = S_OK;
3008  } else if((l == VT_VARIANT) || ((r == VT_VARIANT) && lFound && lValid))
3009  {
3010  hexpected = DISP_E_TYPEMISMATCH;
3011  } else if((l == VT_NULL) && (r == VT_RECORD))
3012  {
3013  hexpected = DISP_E_TYPEMISMATCH;
3014  } else if((l == VT_I8) && (r == VT_DECIMAL))
3015  {
3016  hexpected = S_OK;
3017  } else if((l == VT_DECIMAL) && (r == VT_I8))
3018  {
3019  hexpected = S_OK;
3020  } else if((l == VT_UNKNOWN) || ((r == VT_UNKNOWN) && lFound && lValid))
3021  {
3022  hexpected = DISP_E_TYPEMISMATCH;
3023  } else if((l == VT_NULL) && rFound)
3024  {
3025  hexpected = S_OK;
3026  } else if(l == VT_RECORD)
3027  {
3028  hexpected = DISP_E_TYPEMISMATCH;
3029  } else if((r == VT_RECORD) && lValid && lFound)
3030  {
3031  hexpected = DISP_E_TYPEMISMATCH;
3032  } else if((l == VT_EMPTY) && (r == VT_EMPTY))
3033  {
3034  hexpected = DISP_E_DIVBYZERO;
3035  } else if((l == VT_CY) && !rFound)
3036  {
3037  hexpected = DISP_E_BADVARTYPE;
3038  } else if(lFound && !rFound)
3039  {
3040  hexpected = DISP_E_BADVARTYPE;
3041  } else if(!lFound && rFound)
3042  {
3043  hexpected = DISP_E_BADVARTYPE;
3044  } else if((r == VT_NULL) && lFound && lValid)
3045  {
3046  hexpected = S_OK;
3047  } else if((l == VT_NULL) || (r == VT_NULL))
3048  {
3049  hexpected = DISP_E_BADVARTYPE;
3050  } else if((l == VT_VARIANT) || (r == VT_VARIANT))
3051  {
3052  hexpected = DISP_E_BADVARTYPE;
3053  } else if(!lFound && !rFound)
3054  {
3055  hexpected = DISP_E_BADVARTYPE;
3056  }
3057 
3058  V_VT(&v1) = l;
3059  V_VT(&v2) = r;
3060 
3061  if(l == VT_CY)
3062  V_CY(&v1).int64 = 1000000;
3063  else if(l == VT_R4)
3064  V_R4(&v1) = 100;
3065  else if(l == VT_R8)
3066  V_R8(&v1) = 100;
3067  else if(l == VT_UI8)
3068  V_UI8(&v1) = 100;
3069  else if(l == VT_I8)
3070  V_I8(&v1) = 100;
3071  else if(l == VT_DATE)
3072  V_DATE(&v1) = 1000;
3073  else if (l == VT_DECIMAL)
3074  {
3075  V_DECIMAL(&v1).Hi32 = 0;
3076  U1(V_DECIMAL(&v1)).Lo64 = 100;
3077  U(V_DECIMAL(&v1)).signscale = 0;
3078  }
3079  else
3080  V_I4(&v1) = 10000;
3081 
3082  if(r == VT_CY)
3083  V_CY(&v2).int64 = 10000;
3084  else if(r == VT_R4)
3085  V_R4(&v2) = 100;
3086  else if(r == VT_R8)
3087  V_R8(&v2) = 100;
3088  else if(r == VT_UI8)
3089  V_UI8(&v2) = 100;
3090  else if(r == VT_I8)
3091  V_I8(&v2) = 100;
3092  else if(r == VT_DATE)
3093  V_DATE(&v2) = 1000;
3094  else if (r == VT_DECIMAL)
3095  {
3096  V_DECIMAL(&v2).Hi32 = 0;
3097  U1(V_DECIMAL(&v2)).Lo64 = 100;
3098  U(V_DECIMAL(&v2)).signscale = 0;
3099  }
3100  else
3101  V_I4(&v2) = 10000;
3102 
3103  if ((l != VT_I8 && l != VT_UI8 && r != VT_I8 && r != VT_UI8) || has_i8)
3104  {
3105  hres = pVarMod(&v1,&v2,&vDst);
3106  ok(hres == hexpected,
3107  "VarMod: expected 0x%x, got 0x%X for l type of %d, r type of %d,\n", hexpected, hres, l, r);
3108  }
3109  }
3110  }
3111 
3112 
3113  /****************************/
3114  /* test some bad parameters */
3115  VARMOD(I4,I4,-1,-1,I4,0);
3116 
3117  /* test modulus with zero */
3118  VARMOD2(I4,I4,100,0,EMPTY,0,DISP_E_DIVBYZERO);
3119 
3120  VARMOD(I4,I4,0,10,I4,0); /* test 0 mod 10 */
3121 
3122  /* right parameter is type empty */
3123  VARMOD2(I4,EMPTY,100,10,EMPTY,0,DISP_E_DIVBYZERO);
3124 
3125  /* left parameter is type empty */
3126  VARMOD2(EMPTY,I4,100,10,I4,0,S_OK);
3127 
3128  /* mod with a null left value */
3129  VARMOD2(NULL,I4,125,10,NULL,0,S_OK);
3130 
3131  /* mod with a null right value */
3132  VARMOD2(I4,NULL,100,10,NULL,0,S_OK);
3133 
3134  /* void left value */
3135  VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3136 
3137  /* void right value */
3138  VARMOD2(I4,VOID,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3139 
3140  /* null left value, void right value */
3141  VARMOD2(NULL,VOID,100,10,EMPTY, 0, DISP_E_BADVARTYPE);
3142 
3143  /* void left value, null right value */
3145 
3146  /* some currencies */
3147  V_VT(&v1) = VT_CY;
3148  V_VT(&v2) = VT_CY;
3149  V_CY(&v1).int64 = 100000;
3150  V_CY(&v2).int64 = 100000;
3151  hres = pVarMod(&v1,&v2,&vDst);
3152  ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3153  "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3154 
3155  V_VT(&v1) = VT_I4;
3156  V_VT(&v2) = VT_CY;
3157  V_I4(&v1) = 100;
3158  V_CY(&v2).int64 = 100000;
3159  hres = pVarMod(&v1,&v2,&vDst);
3160  ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3161  "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3162 
3163  /* some decimals */
3164  V_VT(&v1) = VT_DECIMAL;
3165  V_VT(&v2) = VT_DECIMAL;
3166  VarDecFromI4(100, &V_DECIMAL(&v1));
3167  VarDecFromI4(10, &V_DECIMAL(&v2));
3168  hres = pVarMod(&v1,&v2,&vDst);
3169  ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3170  "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3171 
3172  V_VT(&v1) = VT_I4;
3173  V_VT(&v2) = VT_DECIMAL;
3174  V_I4(&v1) = 100;
3175  VarDecFromI4(10, &V_DECIMAL(&v2));
3176  hres = pVarMod(&v1,&v2,&vDst);
3177  ok(hres == S_OK && V_VT(&vDst) == VT_I4 && V_I4(&vDst) == 0,
3178  "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", S_OK, VT_I4, 0, hres, V_VT(&vDst), V_I4(&vDst));
3179 
3180  VARMOD2(UINT,I4,100,10,I4,0,S_OK);
3181 
3182  /* test that an error results in the type of the result changing but not its value */
3183  V_VT(&v1) = VT_UNKNOWN;
3184  V_VT(&v2) = VT_EMPTY;
3185  V_I4(&v1) = 100;
3186  V_CY(&v2).int64 = 100000;
3187  V_VT(&vDst) = VT_I4;
3188  V_I4(&vDst) = 1231;
3189  hres = pVarMod(&v1,&v2,&vDst);
3190  ok(hres == DISP_E_TYPEMISMATCH && V_VT(&vDst) == VT_EMPTY && V_I4(&vDst) == 1231,
3191  "VarMod: expected 0x%x,%d,%d, got 0x%X,%d,%d\n", DISP_E_TYPEMISMATCH, VT_EMPTY, 1231, hres, V_VT(&vDst), V_I4(&vDst));
3192 
3193 
3194  /* test some invalid types */
3195  /*TODO: not testing VT_DISPATCH */
3196  if (has_i8)
3197  {
3198  VARMOD2(I8,INT,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3199  }
3200  VARMOD2(ERROR,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3203  VARMOD2(VOID,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3204  VARMOD2(HRESULT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3205  VARMOD2(PTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3207  VARMOD2(CARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3208  VARMOD2(USERDEFINED,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3209  VARMOD2(LPSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3210  VARMOD2(LPWSTR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3211  VARMOD2(RECORD,I4,100,10,EMPTY,0,DISP_E_TYPEMISMATCH);
3212  VARMOD2(FILETIME,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3213  VARMOD2(BLOB,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3214  VARMOD2(STREAM,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3215  VARMOD2(STORAGE,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3216  VARMOD2(STREAMED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3217  VARMOD2(STORED_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3218  VARMOD2(BLOB_OBJECT,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3219  VARMOD2(CF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3221  VARMOD2(VECTOR,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3222  VARMOD2(ARRAY,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3223  VARMOD2(BYREF,I4,100,10,EMPTY,0,DISP_E_BADVARTYPE);
3224 
3225  /* test some more invalid types */
3226  V_VT(&v1) = 456;
3227  V_VT(&v2) = 234;
3228  V_I4(&v1) = 100;
3229  V_I4(&v2)= 10;
3230  hres = pVarMod(&v1,&v2,&vDst);
3231  ok(hres == DISP_E_BADVARTYPE && V_VT(&vDst) == VT_EMPTY,
3232  "VarMod: expected 0x%x,%d, got 0x%X,%d\n", DISP_E_BADVARTYPE, VT_EMPTY, hres, V_VT(&vDst));
3233 
3234  SysFreeString(strNum0);
3235  SysFreeString(strNum1);
3236 }
3237 
3238 static HRESULT (WINAPI *pVarFix)(LPVARIANT,LPVARIANT);
3239 
3240 #define VARFIX(vt,val,rvt,rval) \
3241  V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3242  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3243  test_var_call1( __LINE__, pVarFix, &v, &exp )
3244 
3245 static void test_VarFix(void)
3246 {
3247  static const WCHAR szNumMinus1[] = {'-','1','\0' };
3248  HRESULT hres;
3249  VARIANT v, exp, vDst;
3250  DECIMAL *pdec = &V_DECIMAL(&v);
3251  CY *pcy = &V_CY(&v);
3252  size_t i;
3253 
3254  CHECKPTR(VarFix);
3255 
3256  /* Test all possible V_VT values */
3257  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3258  {
3259  VARTYPE vt;
3260 
3261  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3262  {
3263  BOOL bFail = TRUE;
3264 
3265  SKIPTESTS(vt);
3266 
3267  memset(&v, 0, sizeof(v));
3268  V_VT(&v) = vt | ExtraFlags[i];
3269  V_VT(&vDst) = VT_EMPTY;
3270 
3271  switch (V_VT(&v))
3272  {
3273  case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8:
3274  case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
3275  case VT_DATE: case VT_CY:
3276  bFail = FALSE;
3277  break;
3278  case VT_I8:
3279  if (has_i8)
3280  bFail = FALSE;
3281  break;
3282  }
3283 
3284  hres = pVarFix(&v,&vDst);
3285  if (bFail)
3287  "VarFix: expected failure, got 0x%X vt %d|0x%X\n",
3288  hres, vt, ExtraFlags[i]);
3289  else
3290  ok(hres == S_OK, "VarFix: expected S_OK, got 0x%X vt %d|0x%X\n",
3291  hres, vt, ExtraFlags[i]);
3292  }
3293  }
3294 
3295  VARFIX(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
3296  VARFIX(BOOL,VARIANT_FALSE,I2,0);
3297  VARFIX(BOOL,1,I2,1);
3298  VARFIX(UI1,1,UI1,1);
3299  VARFIX(I2,-1,I2,-1);
3300  VARFIX(I4,-1,I4,-1);
3301  if (has_i8)
3302  {
3303  VARFIX(I8,-1,I8,-1);
3304  }
3305  VARFIX(R4,1.4f,R4,1);
3306  VARFIX(R4,1.5f,R4,1);
3307  VARFIX(R4,1.6f,R4,1);
3308  VARFIX(R4,-1.4f,R4,-1);
3309  VARFIX(R4,-1.5f,R4,-1);
3310  VARFIX(R4,-1.6f,R4,-1);
3311  /* DATE & R8 round as for R4 */
3312  VARFIX(DATE,-1,DATE,-1);
3313  VARFIX(R8,-1,R8,-1);
3314  VARFIX(BSTR,(BSTR)szNumMinus1,R8,-1);
3315 
3316  V_VT(&v) = VT_EMPTY;
3317  hres = pVarFix(&v,&vDst);
3318  ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
3319  "VarFix: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
3320  hres, V_VT(&vDst), V_I2(&vDst));
3321 
3322  V_VT(&v) = VT_NULL;
3323  hres = pVarFix(&v,&vDst);
3324  ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
3325  "VarFix: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
3326 
3327  V_VT(&v) = VT_DECIMAL;
3328  S(U(*pdec)).sign = DECIMAL_NEG;
3329  S(U(*pdec)).scale = 0;
3330  pdec->Hi32 = 0;
3331  S1(U1(*pdec)).Mid32 = 0;
3332  S1(U1(*pdec)).Lo32 = 1;
3333  hres = pVarFix(&v,&vDst);
3334  ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&V_DECIMAL(&v), &V_DECIMAL(&vDst), sizeof(DECIMAL)),
3335  "VarFix: expected 0x0,%d,identical, got 0x%X,%d\n", VT_DECIMAL,
3336  hres, V_VT(&vDst));
3337 
3338  /* FIXME: Test some fractional decimals when VarDecFix is implemented */
3339 
3340  V_VT(&v) = VT_CY;
3341  pcy->int64 = -10000;
3342  hres = pVarFix(&v,&vDst);
3343  ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
3344  "VarFix: VT_CY wrong, hres=0x%X\n", hres);
3345 
3346  V_VT(&v) = VT_CY;
3347  pcy->int64 = -16000;
3348  hres = pVarFix(&v,&vDst);
3349  ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
3350  "VarFix: VT_CY wrong, hres=0x%X\n", hres);
3351 }
3352 
3353 static HRESULT (WINAPI *pVarInt)(LPVARIANT,LPVARIANT);
3354 
3355 #define VARINT(vt,val,rvt,rval) \
3356  V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3357  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3358  test_var_call1( __LINE__, pVarInt, &v, &exp )
3359 
3360 static void test_VarInt(void)
3361 {
3362  static const WCHAR szNumMinus1[] = {'-','1','\0' };
3363  HRESULT hres;
3364  VARIANT v, exp, vDst;
3365  DECIMAL *pdec = &V_DECIMAL(&v);
3366  CY *pcy = &V_CY(&v);
3367  size_t i;
3368 
3369  CHECKPTR(VarInt);
3370 
3371  /* Test all possible V_VT values */
3372  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3373  {
3374  VARTYPE vt;
3375 
3376  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3377  {
3378  BOOL bFail = TRUE;
3379 
3380  SKIPTESTS(vt);
3381 
3382  memset(&v, 0, sizeof(v));
3383  V_VT(&v) = vt | ExtraFlags[i];
3384  V_VT(&vDst) = VT_EMPTY;
3385 
3386  switch (V_VT(&v))
3387  {
3388  case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8:
3389  case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
3390  case VT_DATE: case VT_CY:
3391  bFail = FALSE;
3392  break;
3393  case VT_I8:
3394  if (has_i8)
3395  bFail = FALSE;
3396  break;
3397  }
3398 
3399  hres = pVarInt(&v,&vDst);
3400  if (bFail)
3402  "VarInt: expected failure, got 0x%X vt %d|0x%X\n",
3403  hres, vt, ExtraFlags[i]);
3404  else
3405  ok(hres == S_OK, "VarInt: expected S_OK, got 0x%X vt %d|0x%X\n",
3406  hres, vt, ExtraFlags[i]);
3407  }
3408  }
3409 
3410  VARINT(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
3411  VARINT(BOOL,VARIANT_FALSE,I2,0);
3412  VARINT(BOOL,1,I2,1);
3413  VARINT(UI1,1,UI1,1);
3414  VARINT(I2,-1,I2,-1);
3415  VARINT(I4,-1,I4,-1);
3416  if (has_i8)
3417  {
3418  VARINT(I8,-1,I8,-1);
3419  }
3420  VARINT(R4,1.4f,R4,1);
3421  VARINT(R4,1.5f,R4,1);
3422  VARINT(R4,1.6f,R4,1);
3423  VARINT(R4,-1.4f,R4,-2); /* Note these 3 are different from VarFix */
3424  VARINT(R4,-1.5f,R4,-2);
3425  VARINT(R4,-1.6f,R4,-2);
3426  /* DATE & R8 round as for R4 */
3427  VARINT(DATE,-1,DATE,-1);
3428  VARINT(R8,-1,R8,-1);
3429  VARINT(BSTR,(BSTR)szNumMinus1,R8,-1);
3430 
3431  V_VT(&v) = VT_EMPTY;
3432  hres = pVarInt(&v,&vDst);
3433  ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
3434  "VarInt: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
3435  hres, V_VT(&vDst), V_I2(&vDst));
3436 
3437  V_VT(&v) = VT_NULL;
3438  hres = pVarInt(&v,&vDst);
3439  ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
3440  "VarInt: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
3441 
3442  V_VT(&v) = VT_DECIMAL;
3443  S(U(*pdec)).sign = DECIMAL_NEG;
3444  S(U(*pdec)).scale = 0;
3445  pdec->Hi32 = 0;
3446  S1(U1(*pdec)).Mid32 = 0;
3447  S1(U1(*pdec)).Lo32 = 1;
3448  hres = pVarInt(&v,&vDst);
3449  ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&V_DECIMAL(&v), &V_DECIMAL(&vDst), sizeof(DECIMAL)),
3450  "VarInt: expected 0x0,%d,identical, got 0x%X,%d\n", VT_DECIMAL,
3451  hres, V_VT(&vDst));
3452 
3453  /* FIXME: Test some fractional decimals when VarDecInt is implemented */
3454 
3455  V_VT(&v) = VT_CY;
3456  pcy->int64 = -10000;
3457  hres = pVarInt(&v,&vDst);
3458  ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
3459  "VarInt: VT_CY wrong, hres=0x%X\n", hres);
3460 
3461  V_VT(&v) = VT_CY;
3462  pcy->int64 = -11000;
3463  hres = pVarInt(&v,&vDst);
3464  ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -20000,
3465  "VarInt: VT_CY wrong, hres=0x%X 0x%x%08x\n",
3466  hres, (DWORD)(V_CY(&vDst).int64 >> 32), (DWORD)V_CY(&vDst).int64);
3467 }
3468 
3469 static HRESULT (WINAPI *pVarNeg)(LPVARIANT,LPVARIANT);
3470 
3471 #define VARNEG(vt,val,rvt,rval) \
3472  V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3473  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3474  test_var_call1( __LINE__, pVarNeg, &v, &exp )
3475 
3476 static void test_VarNeg(void)
3477 {
3478  static const WCHAR szNumMinus1[] = {'-','1','\0' };
3479  static const WCHAR szNum1[] = {'1','\0' };
3480  HRESULT hres;
3481  VARIANT v, exp, vDst;
3482  DECIMAL *pdec = &V_DECIMAL(&v);
3483  CY *pcy = &V_CY(&v);
3484  size_t i;
3485 
3486  CHECKPTR(VarNeg);
3487 
3488  /* Test all possible V_VT values. But don't test the exact return values
3489  * except for success/failure, since M$ made a hash of them in the
3490  * native version. This at least ensures (as with all tests here) that
3491  * we will notice if/when new vtypes/flags are added in native.
3492  */
3493  for (i = 0; i < ARRAY_SIZE(ExtraFlags); i++)
3494  {
3495  VARTYPE vt;
3496 
3497  for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
3498  {
3499  BOOL bFail = TRUE;
3500 
3501  SKIPTESTS(vt);
3502 
3503  memset(&v, 0, sizeof(v));
3504  V_VT(&v) = vt | ExtraFlags[i];
3505  V_VT(&vDst) = VT_EMPTY;
3506 
3507  switch (V_VT(&v))
3508  {
3509  case VT_UI1: case VT_I2: case VT_I4:
3510  case VT_R4: case VT_R8:
3511  case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
3512  case VT_DATE: case VT_CY:
3513  bFail = FALSE;
3514  break;
3515  case VT_I8:
3516  if (has_i8)
3517  bFail = FALSE;
3518  }
3519 
3520  hres = pVarNeg(&v,&vDst);
3521  if (bFail)
3523  "VarNeg: expected failure, got 0x%X vt %d|0x%X\n",
3524  hres, vt, ExtraFlags[i]);
3525  else
3526  ok(hres == S_OK, "VarNeg: expected S_OK, got 0x%X vt %d|0x%X\n",
3527  hres, vt, ExtraFlags[i]);
3528  }
3529  }
3530 
3531  VARNEG(BOOL,VARIANT_TRUE,I2,1);
3532  VARNEG(BOOL,VARIANT_FALSE,I2,0);
3533  VARNEG(BOOL,1,I2,-1);
3534  VARNEG(UI1,1,I2,-1);
3535  VARNEG(UI1,254,I2,-254);
3536  VARNEG(I2,-32768,I4,32768);
3537  VARNEG(I2,-1,I2,1);
3538  VARNEG(I2,1,I2,-1);
3539  VARNEG(I4,-((int)(~0u >> 1)) - 1,R8,-2147483648u);
3540  VARNEG(I4,-1,I4,1);
3541  VARNEG(I4,1,I4,-1);
3542  if (has_i8)
3543  {
3544  VARNEG(I8,1,I8,-1);
3545  VARNEG(I8,-1,I8,1);
3546  }
3547  VARNEG(R4,1,R4,-1);
3548  VARNEG(R4,-1,R4,1);
3549  VARNEG(DATE,1,DATE,-1);
3550  VARNEG(DATE,-1,DATE,1);
3551  VARNEG(R8,1,R8,-1);
3552  VARNEG(R8,-1,R8,1);
3553  VARNEG(BSTR,(BSTR)szNumMinus1,R8,1);
3554  VARNEG(BSTR,(BSTR)szNum1,R8,-1);
3555 
3556  V_VT(&v) = VT_EMPTY;
3557  hres = pVarNeg(&v,&vDst);
3558  ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
3559  "VarNeg: expected 0x0,%d,0 got 0x%X,%d,%d\n", VT_EMPTY,
3560  hres, V_VT(&vDst), V_I2(&vDst));
3561 
3562  V_VT(&v) = VT_NULL;
3563  hres = pVarNeg(&v,&vDst);
3564  ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
3565  "VarNeg: expected 0x0,%d got 0x%X,%d\n", VT_NULL, hres, V_VT(&vDst));
3566 
3567  V_VT(&v) = VT_DECIMAL;
3568  S(U(*pdec)).sign = DECIMAL_NEG;
3569  S(U(*pdec)).scale = 0;
3570  pdec->Hi32 = 0;
3571  S1(U1(*pdec)).Mid32 = 0;
3572  S1(U1(*pdec)).Lo32 = 1;
3573  hres = pVarNeg(&v,&vDst);
3574  ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
3575  S(U(V_DECIMAL(&vDst))).sign == 0,
3576  "VarNeg: expected 0x0,%d,0x00, got 0x%X,%d,%02x\n", VT_DECIMAL,
3577  hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
3578 
3579  S(U(*pdec)).sign = 0;
3580  hres = pVarNeg(&v,&vDst);
3581  ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
3582  S(U(V_DECIMAL(&vDst))).sign == DECIMAL_NEG,
3583  "VarNeg: expected 0x0,%d,0x7f, got 0x%X,%d,%02x\n", VT_DECIMAL,
3584  hres, V_VT(&vDst), S(U(V_DECIMAL(&vDst))).sign);
3585 
3586  V_VT(&v) = VT_CY;
3587  pcy->int64 = -10000;
3588  hres = pVarNeg(&v,&vDst);
3589  ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
3590  "VarNeg: VT_CY wrong, hres=0x%X\n", hres);
3591 }
3592 
3593 static HRESULT (WINAPI *pVarRound)(LPVARIANT,int,LPVARIANT);
3594 
3595 static void test_Round( int line, VARIANT *arg, int deci, VARIANT *expected )
3596 {
3597  VARIANT result;
3598  HRESULT hres;
3599 
3600  memset( &result, 0, sizeof(result) );
3601  hres = pVarRound( arg, deci, &result );
3602  ok_(__FILE__,line)( hres == S_OK, "wrong result %x\n", hres );
3603  if (hres == S_OK)
3604  ok_(__FILE__,line)( is_expected_variant( &result, expected ),
3605  "got %s expected %s\n", variantstr(&result), variantstr(expected) );
3606 }
3607 #define VARROUND(vt,val,deci,rvt,rval) \
3608  V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
3609  V_VT(&exp) = VT_##rvt; V_##rvt(&exp) = rval; \
3610  test_Round( __LINE__, &v, deci, &exp )
3611 
3612 struct decimal_t {