4 * Copyright 1998 Jean-Claude Cote
6 * The purpose of this program is validate the implementation
7 * of the APIs related to VARIANTs. The validation is done
8 * by comparing the results given by the Windows implementation
9 * versus the Wine implementation.
11 * This program tests the creation/coercion/destruction of VARIANTs.
13 * The program does not currently test any API that takes
14 * arguments of type: IDispatch, IUnknown, DECIMAL, CURRENCY.
16 * Since the purpose of this program is to compare the results
17 * from Windows and Wine it is written so that with a simple
18 * define it can be compiled either in Windows or Linux.
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
25 * This library is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 * - The Variant structure in Windows has a non-named union. This means
36 * the member of the union are accessible simply by doing
37 * pVariant->pfltVal. With gcc it is not possible to have non-named
38 * union so it has been named 'u'. So it's members are accessible
39 * using this name like so pVariant->u.pfltVal. So if this program is
40 * compiled in Windows the references to 'u' will need to be take out
43 * - Also the printf is a little different so the format specifiers may
44 * need to be tweaked if this file is compile in Windows.
45 * Printf is also different in that it continues printing numbers
46 * even after there is no more significative digits left to print. These
47 * number are garbage and in windows they are set to zero but not
50 * - The VarDateFromStr is not implemented yet.
52 * - The date and floating point format may not be the exact same
53 * format has the one inwindows depending on what the Internatinal
54 * setting are in windows.
68 #include "wine/test.h"
79 static HRESULT (WINAPI
*pVarBstrFromI1
)(CHAR
,LCID
,ULONG
,BSTR
*)=NULL
;
81 static HRESULT (WINAPI
*pVarI1FromBool
)(VARIANT_BOOL
,CHAR
*)=NULL
;
82 static HRESULT (WINAPI
*pVarI1FromDate
)(DATE
,CHAR
*)=NULL
;
83 static HRESULT (WINAPI
*pVarI1FromI4
)(LONG
,CHAR
*)=NULL
;
84 static HRESULT (WINAPI
*pVarI1FromR8
)(double,CHAR
*)=NULL
;
85 static HRESULT (WINAPI
*pVarI1FromStr
)(OLECHAR
*,LCID
,ULONG
,CHAR
*);
86 static HRESULT (WINAPI
*pVarI1FromUI1
)(BYTE
,CHAR
*)=NULL
;
88 static HRESULT (WINAPI
*pVarI2FromUI2
)(USHORT
,short*)=NULL
;
90 static HRESULT (WINAPI
*pVarUI2FromBool
)(VARIANT_BOOL
,USHORT
*)=NULL
;
91 static HRESULT (WINAPI
*pVarUI2FromDate
)(DATE
,USHORT
*)=NULL
;
92 static HRESULT (WINAPI
*pVarUI2FromI2
)(short,USHORT
*)=NULL
;
93 static HRESULT (WINAPI
*pVarUI2FromI4
)(LONG
,USHORT
*);
94 static HRESULT (WINAPI
*pVarUI2FromR8
)(double,USHORT
*)=NULL
;
95 static HRESULT (WINAPI
*pVarUI2FromStr
)(OLECHAR
*,LCID
,ULONG
,USHORT
*)=NULL
;
97 static HRESULT (WINAPI
*pVarUI4FromBool
)(VARIANT_BOOL
,ULONG
*)=NULL
;
98 static HRESULT (WINAPI
*pVarUI4FromDate
)(DATE
,ULONG
*)=NULL
;
99 static HRESULT (WINAPI
*pVarUI4FromI2
)(short,ULONG
*)=NULL
;
100 static HRESULT (WINAPI
*pVarUI4FromR8
)(double,ULONG
*)=NULL
;
101 static HRESULT (WINAPI
*pVarUI4FromStr
)(OLECHAR
*,LCID
,ULONG
,ULONG
*)=NULL
;
103 /* When comparing floating point values we cannot expect an exact match
104 * because the rounding errors depend on the exact algorithm.
106 #define EQ_DOUBLE(a,b) (fabs((a)-(b))<1e-14)
108 #define MAX_BUFFER 1024
110 static char* WtoA( OLECHAR
* p
)
112 static char buffer
[MAX_BUFFER
];
113 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, p
, -1, buffer
+1, sizeof(buffer
)-3, NULL
, NULL
);
120 static OLECHAR
* AtoW( char* p
)
123 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, p
, -1, NULL
, 0 );
124 buffer
= malloc( len
* sizeof(OLECHAR
) );
125 MultiByteToWideChar( CP_ACP
, 0, p
, -1, buffer
, len
);
129 static const struct _vartypes
{
131 HRESULT vcind1
,vcind2
,vcex1
,vcex2
;
132 int todoind1
,todoind2
,todowcex1
,todowcex2
;
134 {0, 0, 0x80070057, 0, 0x80020008,0,1 },
135 {1, 0, 0x80070057, 0, 0x80020008,0,1 },
136 {2, 0, 0, 0, 0x80020005 },
137 {3, 0, 0, 0, 0x80020005 },
138 {4, 0, 0, 0, 0x80020005 },
139 {5, 0, 0, 0, 0x80020005 },
140 {6, 0, 0, 0, 0x80020005 },
141 {7, 0, 0, 0, 0x80020005 },
142 {77,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
143 {78,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
144 {79,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
145 {80,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
146 {81,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
147 {82,0x80020008, 0x80070057, 0x80020005, 0x80020005,0,1 },
148 {83,0x80020008, 0x80070057, 0, 0x80020005,0,1,1 },
149 {84,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
150 {85,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
151 {86,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
152 {87,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
153 {88,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
154 {89,0x80020008, 0x80070057, 0, 0x80020005,0,1,1 },
155 {90,0x80020008, 0x80070057, 0, 0x80020005,0,1,1 },
156 {91,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
157 {92,0x80020008, 0x80070057, 0, 0x80020005,0,1 },
158 {93,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
159 {94,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
160 {95,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
161 {96,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
162 {97,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
163 {98,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
164 {99,0x80020008, 0x80070057, 0x80020008, 0x80020008,0,1,1,1 },
167 static const char *strfromr8
[] = {
198 "7.65432198765432E+15",
199 "-7.65432198765432E+15",
200 "8.76543219876543E+16",
201 "-8.76543219876543E+16",
202 "9.87654321987654E+17",
203 "-9.87654321987654E+17",
204 "1.98765432198765E+18",
205 "-1.98765432198765E+18",
206 "2.19876543219877E+19",
207 "-2.19876543219877E+19",
298 "7.65432198765432E+15",
299 "-7.65432198765432E+15",
300 "8.76543219876543E+16",
301 "-8.76543219876543E+16",
302 "9.87654321987654E+17",
303 "-9.87654321987654E+17",
304 "1.98765432198765E+18",
305 "-1.98765432198765E+18",
306 "2.19876543219877E+19",
307 "-2.19876543219877E+19",
381 /* These are the strings we use for the XxxFromStr tests.
382 * The arrays that follow define the expected results for each type.
384 static char* _pTestStrA
[] = {
437 "1000000000000000000000000000000000000000000000000000000000000000",
438 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
439 "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
440 "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
441 "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
455 "11/11/1999:11:11:1134",
456 "11/11/1999 11:11:11:1",
457 "\t1999/\t11/21 11 :11:11am",
459 "11/11/1999 11:11:11Am",
460 "11/11/1999 11:11:11PM",
461 "11/11/199911:11:11PM",
462 "11/11/1999 0:0:11am",
463 "11/11/1999 11,11:11am",
464 "11/11/1999 11:11:11am",
465 "11/11/1999 11/11:11am",
466 "11/11/1999 11:11AM",
470 "11/11/1999 11:11:11",
478 "1999 January 3 9AM",
479 "1 January 1999 11AM",
482 "4:22 11/11/1999 AM",
484 "11-11/1999 11:11:11.12AM",
485 "1999 January 3, 9AM",
486 "December, 31, 2078",
487 "December, 31, 2078,",
507 #define NB_OLE_STRINGS (sizeof(_pTestStrA)/sizeof(*_pTestStrA))
509 static const struct _strret_date
{
514 } strrets_DATE
[NB_OLE_STRINGS
] = {
522 { 0, 0.03402777777777, 1 },
523 { 0, 0.00347222222222, 1 },
524 { 0, 0.03541666666666, 1 },
536 { 0x80020005, 0.0, 1 },
537 { 0x80020005, 0.0, 1 },
539 { 0x80020005, 0.0, 1 },
553 { 0x80020005, 0.0, 1 },
554 { 0, 0.04309027777777, 0, 1 },
557 { 0x80020005, 0.0, 1 },
558 { 0x80020005, 0.0, 1 },
560 { 0x80020005, 0.0, 1 },
579 { 0x80020005, 0.0, 1 },
584 { 0, 36485.466099537036, 1 },
585 { 0, 36475.466099537036 },
586 { 0, 36475.966099537036 },
587 { 0x80020005, 0.0, 1 },
588 { 0, 36475.000127314815 },
590 { 0, 36475.466099537036 },
592 { 0, 36475.465972222222 },
593 { 0, 36475.041666666664, 1 },
595 { 0, 36475.466099537036 },
600 { 0x80020005, 0.0, 1 },
603 { 0, 36163.375000000000, 1 },
604 { 0, 36161.458333333336, 1 },
605 { 0, 36475.166666666664, 1 },
606 { 0x80020005, 0.0, 1 },
608 { 0x80020005, 0.0, 1 },
611 { 0x80020005, 0.0, 1 },
624 { 0, 0.045138888888889, 1 },
625 { 0, 0.086805555555556, 1 },
626 { 0, 0.128472222222222, 1 },
627 { 0, 0.170138888888889, 1 },
629 static const struct _strret_b
{
632 } strrets_B
[NB_OLE_STRINGS
] = {
638 { 0, VARIANT_FALSE
},
639 { 0, VARIANT_FALSE
},
673 { 0, VARIANT_FALSE
},
674 { 0, VARIANT_FALSE
},
739 { 0, VARIANT_FALSE
},
747 static const struct _strret_r8
{
750 } strrets_R8
[NB_OLE_STRINGS
] = {
770 { 0, -32768.000000 },
771 { 0, -32769.000000 },
772 { 0, 16777216.000000 },
773 { 0, 16777217.000000 },
774 { 0, -16777216.000000 },
775 { 0, 16777217.000000 },
776 { 0, 2147483647.000000 },
777 { 0, 2147483648.000000 },
778 { 0, -2147483647.000000 },
779 { 0, -2147483648.000000 },
793 { 0, 100000000000.000000 },
804 { 0, 99999999999999997e183
},
809 { 0, 4294967295.000000 },
810 { 0, 4294967296.000000 },
865 static const struct _strret_r4
{
868 } strrets_R4
[NB_OLE_STRINGS
] = {
886 { 0, 32767.000000F
},
887 { 0, 32768.000000F
},
888 { 0, -32768.000000F
},
889 { 0, -32769.000000F
},
890 { 0, 16777216.000000F
},
891 { 0, 16777216.000000F
},
892 { 0, -16777216.000000F
},
893 { 0, 16777216.000000F
},
894 { 0, 2147483648.000000F
},
895 { 0, 2147483648.000000F
},
896 { 0, -2147483648.000000F
},
897 { 0, -2147483648.000000F
},
911 { 0, 99999997952.000000F
},
924 { 0, 65535.000000F
},
925 { 0, 65535.500000F
},
926 { 0, 65536.000000F
},
927 { 0, 4294967296.000000F
},
928 { 0, 4294967296.000000F
},
983 static const struct _strret_i4
{
986 } strrets_I4
[NB_OLE_STRINGS
] = {
1014 { 0, -2147483647L },
1101 static const struct _strret_i2
{
1104 } strrets_I2
[NB_OLE_STRINGS
] = {
1219 static const struct _strret_i1
{
1222 } strrets_I1
[NB_OLE_STRINGS
] = {
1337 static const struct _strret_u1
{
1340 } strrets_U1
[NB_OLE_STRINGS
] = {
1456 static const struct _strret_U2
{
1459 } strrets_U2
[NB_OLE_STRINGS
] = {
1575 static const struct _strret_U4
{
1578 } strrets_U4
[NB_OLE_STRINGS
] = {
1706 int* pInt
= &theInt
;
1708 VARIANT_BOOL
* pBool
= &b
;
1709 unsigned short uShort
= 0;
1710 unsigned short* pUShort
= &uShort
;
1711 unsigned long uLong
= 0;
1712 unsigned long* pULong
= &uLong
;
1714 CHAR
* pChar
= &theChar
;
1716 BYTE
* pByte
= &byte
;
1720 long* pLong
= &Long
;
1724 double* pDouble
= &d
;
1728 OLECHAR
* pOleChar
[NB_OLE_STRINGS
];
1730 for (i
=0; i
<NB_OLE_STRINGS
;i
++) {
1731 pOleChar
[i
]=AtoW(_pTestStrA
[i
]);
1733 lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
, SUBLANG_ENGLISH_US
), SORT_DEFAULT
);
1735 /* Start testing the Low-Level API ( the coercions )
1737 hdll
=LoadLibraryA("netapi32.dll");
1738 pVarI1FromBool
=(void*)GetProcAddress(hdll
,"VarI1FromBool");
1739 pVarI1FromDate
=(void*)GetProcAddress(hdll
,"VarI1FromDate");
1740 pVarI1FromI4
=(void*)GetProcAddress(hdll
,"VarI1FromI4");
1741 pVarI1FromR8
=(void*)GetProcAddress(hdll
,"VarI1FromR8");
1742 pVarI1FromStr
=(void*)GetProcAddress(hdll
,"VarI1FromStr");
1743 pVarI1FromUI1
=(void*)GetProcAddress(hdll
,"VarI1FromUI1");
1745 pVarI2FromUI2
=(void*)GetProcAddress(hdll
,"VarI2FromUI2");
1747 pVarUI2FromBool
=(void*)GetProcAddress(hdll
,"VarUI2FromBool");
1748 pVarUI2FromDate
=(void*)GetProcAddress(hdll
,"VarUI2FromDate");
1749 pVarUI2FromI2
=(void*)GetProcAddress(hdll
,"VarUI2FromI2");
1750 pVarUI2FromI4
=(void*)GetProcAddress(hdll
,"VarUI2FromI4");
1751 pVarUI2FromR8
=(void*)GetProcAddress(hdll
,"VarUI2FromR8");
1752 pVarUI2FromStr
=(void*)GetProcAddress(hdll
,"VarUI2FromStr");
1754 pVarUI4FromBool
=(void*)GetProcAddress(hdll
,"VarUI4FromBool");
1755 pVarUI4FromDate
=(void*)GetProcAddress(hdll
,"VarUI4FromDate");
1756 pVarUI4FromI2
=(void*)GetProcAddress(hdll
,"VarUI4FromI2");
1757 pVarUI4FromR8
=(void*)GetProcAddress(hdll
,"VarUI4FromR8");
1758 pVarUI4FromStr
=(void*)GetProcAddress(hdll
,"VarUI4FromStr");
1760 /* unsigned char from...
1762 trace( "======== Testing VarUI1FromXXX ========\n");
1764 #define XOK "should return S_OK"
1765 #define XOV "should return DISP_E_OVERFLOW"
1766 /* Crashes on Win95: VarUI1FromI2( 0, NULL ) */
1768 ok(VarUI1FromStr(NULL
, lcid
, 0, pByte
) == DISP_E_TYPEMISMATCH
,"should return DISP_E_TYPEMISMATCH");
1769 ok(S_OK
== VarUI1FromI2( 0, pByte
), XOK
);
1770 ok(*pByte
== 0,"should give 0 byte value");
1772 ok(S_OK
== VarUI1FromI2( 69, pByte
), XOK
);
1773 ok(*pByte
== 69,"should give 69 byte value");
1775 ok(S_OK
== VarUI1FromI2( 70, pByte
), XOK
);
1776 ok(*pByte
== 70,"should give 70 byte value");
1778 ok(S_OK
== VarUI1FromI2( 128, pByte
), XOK
);
1779 ok(*pByte
== 128,"should give 128 byte value");
1781 ok(S_OK
== VarUI1FromI2( 255, pByte
), XOK
);
1782 ok(*pByte
== 255,"should give 255 byte value");
1784 ok(DISP_E_OVERFLOW
== VarUI1FromI2( 256, pByte
), XOV
);
1785 ok(DISP_E_OVERFLOW
== VarUI1FromI2( 257, pByte
), XOV
);
1787 ok(S_OK
== VarUI1FromR8( 0.0, pByte
), XOK
);
1788 ok(*pByte
== 0,"0.0 float should be converted to 0");
1790 ok(S_OK
== VarUI1FromR8( 69.33, pByte
), XOK
);
1791 ok(*pByte
== 0x45, "expected 69 (hex 0x45) as byte value");
1793 ok(S_OK
== VarUI1FromR8( 69.66, pByte
), XOK
);
1794 ok(*pByte
== 0x46, "expected 70 (hex 0x46) as byte value");
1796 ok(DISP_E_OVERFLOW
== VarUI1FromR8( -69.33, pByte
), XOV
);
1797 ok(DISP_E_OVERFLOW
== VarUI1FromR8( -69.66, pByte
), XOV
);
1799 ok(S_OK
== VarUI1FromR8( -0.5, pByte
), XOK
);
1800 ok(*pByte
== 0,"-0.5 should give return 0");
1802 ok(DISP_E_OVERFLOW
== VarUI1FromR8( -0.51, pByte
), XOV
);
1804 ok(S_OK
== VarUI1FromR8( -0.49, pByte
), XOK
);
1805 ok(*pByte
== 0,"-0.49 should give return 0");
1807 ok(S_OK
== VarUI1FromR8( 0.5, pByte
), XOK
);
1808 ok(*pByte
== 0,"0.5 should give return 0");
1810 ok(S_OK
== VarUI1FromR8( 0.51, pByte
), XOK
);
1811 ok(*pByte
== 1,"0.51 should give return 1");
1813 ok(S_OK
== VarUI1FromR8( 0.49, pByte
), XOK
);
1814 ok(*pByte
== 0,"0.49 should give return 0");
1816 ok(S_OK
== VarUI1FromDate( 0.0, pByte
), XOK
);
1817 ok(*pByte
== 0,"0.0 date should give return 0");
1819 ok(S_OK
== VarUI1FromDate( 69.33, pByte
), XOK
);
1820 ok(*pByte
== 0x45,"69.33 date should give return 0x45");
1822 ok(S_OK
== VarUI1FromDate( 69.66, pByte
), XOK
);
1823 ok(*pByte
== 0x46,"69.66 date should give return 0x46");
1825 ok(DISP_E_OVERFLOW
== VarUI1FromDate( -69.33, pByte
), XOV
);
1827 ok(DISP_E_OVERFLOW
== VarUI1FromDate( -69.66, pByte
), XOV
);
1829 ok(S_OK
== VarUI1FromBool( VARIANT_TRUE
, pByte
), XOK
);
1830 ok(*pByte
== 0xff, "true should be converted to 0xff");
1832 ok(S_OK
== VarUI1FromBool( VARIANT_FALSE
, pByte
), XOK
);
1833 ok(*pByte
== 0, "false should be converted to 0");
1835 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
1838 rc
=VarUI1FromStr( pOleChar
[i
], lcid
, 0, pByte
);
1839 ok(rc
== strrets_U1
[i
].error
,
1840 "VarUI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1841 i
,_pTestStrA
[i
],rc
,strrets_U1
[i
].error
);
1842 if (rc
== 0 && strrets_U1
[i
].error
== 0) {
1843 ok(*pByte
== strrets_U1
[i
].retval
,
1844 "VarUI1FromStr([%d]=\"%s\") got %02x instead of %02x",
1845 i
,_pTestStrA
[i
],*pByte
,strrets_U1
[i
].retval
);
1849 /* unsigned short from ... */
1850 trace( "======== Testing VarUI2FromXXX ========\n");
1852 if (pVarUI2FromI2
) {
1853 ok(DISP_E_OVERFLOW
== pVarUI2FromI2( -1, pUShort
), XOV
);
1854 ok(S_OK
== pVarUI2FromI2( 0, NULL
), XOK
);
1856 ok(S_OK
== pVarUI2FromI2( 0, pUShort
), XOK
);
1857 ok(*pUShort
== 0,"0 should be 0");
1858 ok(S_OK
== pVarUI2FromI2( 69, pUShort
), XOK
);
1859 ok(*pUShort
== 69,"69 should be 69");
1860 ok(S_OK
== pVarUI2FromI2( 70, pUShort
), XOK
);
1861 ok(*pUShort
== 70,"70 should be 70");
1863 ok(S_OK
== pVarUI2FromI2( 128, pUShort
), XOK
);
1864 ok(*pUShort
== 128,"128 should be 128");
1867 if (pVarUI2FromI4
) {
1868 ok(S_OK
== pVarUI2FromI4( 65535, pUShort
), XOK
);
1869 ok(*pUShort
== 65535,"65535 should be 65535");
1870 ok(DISP_E_OVERFLOW
== pVarUI2FromI4( 65536, pUShort
), XOV
);
1871 ok(DISP_E_OVERFLOW
== pVarUI2FromI4( 65537, pUShort
), XOV
);
1874 if (pVarUI2FromR8
) {
1875 ok(S_OK
== pVarUI2FromR8( 0.0, pUShort
), XOK
);
1876 ok(*pUShort
== 0,"0.0 should be 0");
1877 ok(S_OK
== pVarUI2FromR8( 69.33, pUShort
), XOK
);
1878 ok(*pUShort
== 69,"69.33 should be 69");
1879 ok(S_OK
== pVarUI2FromR8( 69.66, pUShort
), XOK
);
1880 ok(*pUShort
== 70,"69.66 should be 70");
1882 ok(DISP_E_OVERFLOW
== pVarUI2FromR8( -69.33, pUShort
), XOV
);
1883 ok(DISP_E_OVERFLOW
== pVarUI2FromR8( -69.66, pUShort
), XOV
);
1885 ok(S_OK
== pVarUI2FromR8( -0.5, pUShort
), XOK
);
1886 ok(*pUShort
== 0, "-0.5 -> 0");
1887 ok(DISP_E_OVERFLOW
== pVarUI2FromR8( -0.51, pUShort
), XOV
);
1888 ok(S_OK
== pVarUI2FromR8( -0.49, pUShort
), XOK
);
1889 ok(*pUShort
== 0, "-0.49 -> 0");
1891 ok(S_OK
== pVarUI2FromR8( 0.5, pUShort
), XOK
);
1892 ok(*pUShort
== 0,"0.5 should be 0");
1893 ok(S_OK
== pVarUI2FromR8( 0.51, pUShort
), XOK
);
1894 ok(*pUShort
== 1,"0.51 should be 1");
1895 ok(S_OK
== pVarUI2FromR8( 0.49, pUShort
), XOK
);
1896 ok(*pUShort
== 0,"0.49 should be 0");
1899 if (pVarUI2FromDate
) {
1900 ok(S_OK
== pVarUI2FromDate( 0.0, pUShort
), XOK
);
1901 ok(*pUShort
== 0,"0.0 should be 0");
1902 ok(S_OK
== pVarUI2FromDate( 69.33, pUShort
), XOK
);
1903 ok(*pUShort
== 69,"69.33 should be 69");
1904 ok(S_OK
== pVarUI2FromDate( 69.66, pUShort
), XOK
);
1905 ok(*pUShort
== 70,"69.66 should be 70");
1906 ok(DISP_E_OVERFLOW
== pVarUI2FromDate( -69.33, pUShort
), XOV
);
1907 ok(DISP_E_OVERFLOW
== pVarUI2FromDate( -69.66, pUShort
), XOV
);
1910 if (pVarUI2FromBool
) {
1911 ok(S_OK
== pVarUI2FromBool( VARIANT_TRUE
, pUShort
), XOK
);
1912 ok(*pUShort
== 65535,"TRUE should be 65535");
1913 ok(S_OK
== pVarUI2FromBool( VARIANT_FALSE
, pUShort
), XOK
);
1914 ok(*pUShort
== 0,"FALSE should be 0");
1917 if (pVarUI2FromStr
) {
1918 ok(DISP_E_TYPEMISMATCH
== pVarUI2FromStr( NULL
, lcid
, 0, pUShort
), "should return DISP_E_TYPEMISMATCH");
1920 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
1923 rc
=pVarUI2FromStr( pOleChar
[i
], lcid
, 0, pUShort
);
1924 ok(rc
== strrets_U2
[i
].error
,
1925 "VarUI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
1926 i
,_pTestStrA
[i
],rc
,strrets_U2
[i
].error
);
1927 if (rc
== 0 && strrets_U2
[i
].error
== 0) {
1928 ok(*pUShort
== strrets_U2
[i
].retval
,
1929 "VarUI2FromStr([%d]=\"%s\") got %u instead of %u",
1930 i
,_pTestStrA
[i
],*pUShort
,strrets_U2
[i
].retval
);
1935 /* unsigned long from ...
1937 trace( "======== Testing VarUI4FromXXX ========\n");
1939 if (pVarUI4FromI2
) {
1940 ok(S_OK
== pVarUI4FromI2( 0, NULL
), XOK
);
1942 ok(S_OK
== pVarUI4FromI2( 0, pULong
), XOK
);
1943 ok(*pULong
== 0,"0 should be 0");
1944 ok(S_OK
== pVarUI4FromI2( 69, pULong
), XOK
);
1945 ok(*pULong
== 69,"69 should be 69");
1947 ok(S_OK
== pVarUI4FromI2( 70, pULong
), XOK
);
1948 ok(*pULong
== 70,"70 should be 70");
1950 ok(S_OK
== pVarUI4FromI2( 128, pULong
), XOK
);
1951 ok(*pULong
== 128,"128 should be 128");
1952 ok(S_OK
== pVarUI4FromI2( 255, pULong
), XOK
);
1953 ok(*pULong
== 255,"255 should be 255");
1956 if (pVarUI4FromR8
) {
1957 ok(S_OK
== pVarUI4FromR8( 4294967295.0, pULong
), XOK
);
1958 ok(*pULong
== 4294967295U,"4294967295.0 should be 4294967295");
1959 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( 4294967296.0, pULong
), XOV
);
1961 ok(S_OK
== pVarUI4FromR8( 0.0, pULong
), XOK
);
1962 ok(*pULong
== 0,"0 should be 0");
1963 ok(S_OK
== pVarUI4FromR8( 69.33, pULong
), XOK
);
1964 ok(*pULong
== 69,"69.33 should be 69");
1965 ok(S_OK
== pVarUI4FromR8( 69.66, pULong
), XOK
);
1966 ok(*pULong
== 70,"69.66 should be 70");
1967 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( -69.33, pULong
), XOV
);
1968 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( -69.66, pULong
), XOV
);
1970 ok(S_OK
== pVarUI4FromR8( -0.5, pULong
), XOK
);
1971 ok(*pULong
== 0,"-0.5 should be 0");
1973 ok(DISP_E_OVERFLOW
== pVarUI4FromR8( -0.51, pULong
), XOV
);
1975 ok(S_OK
== pVarUI4FromR8( -0.49, pULong
), XOK
);
1976 ok(*pULong
== 0,"-0.49 should be 0");
1978 ok(S_OK
== pVarUI4FromR8( 0.5, pULong
), XOK
);
1979 ok(*pULong
== 0,"0.5 should be 0");
1980 ok(S_OK
== pVarUI4FromR8( 0.51, pULong
), XOK
);
1981 ok(*pULong
== 1,"0.51 should be 1");
1982 ok(S_OK
== pVarUI4FromR8( 0.49, pULong
), XOK
);
1983 ok(*pULong
== 0,"0.49 should be 0");
1986 if (pVarUI4FromDate
) {
1987 ok(S_OK
== pVarUI4FromDate( 0.0, pULong
), XOK
);
1988 ok(*pULong
== 0,"0.0 should be 0");
1989 ok(S_OK
== pVarUI4FromDate( 69.33, pULong
), XOK
);
1990 ok(*pULong
== 69,"69.33 should be 69");
1991 ok(S_OK
== pVarUI4FromDate( 69.66, pULong
), XOK
);
1992 ok(*pULong
== 70,"69.66 should be 70");
1993 ok(DISP_E_OVERFLOW
== pVarUI4FromDate( -69.33, pULong
), XOV
);
1994 ok(DISP_E_OVERFLOW
== pVarUI4FromDate( -69.66, pULong
), XOV
);
1997 if (pVarUI4FromBool
) {
1998 ok(S_OK
== pVarUI4FromBool( VARIANT_TRUE
, pULong
), XOK
);
1999 ok(*pULong
== 4294967295U, "TRUE should be 4294967295");
2000 ok(S_OK
== pVarUI4FromBool( VARIANT_FALSE
, pULong
), XOK
);
2001 ok(*pULong
== 0, "FALSE should be 0");
2004 if (pVarUI4FromStr
) {
2005 ok(DISP_E_TYPEMISMATCH
== pVarUI4FromStr( NULL
, lcid
, 0, pULong
), "should erturn DISP_E_TYPEMISMATCH");
2006 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2009 rc
=pVarUI4FromStr( pOleChar
[i
], lcid
, 0, pULong
);
2010 ok(rc
== strrets_U4
[i
].error
,
2011 "VarUI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2012 i
,_pTestStrA
[i
],rc
,strrets_U4
[i
].error
);
2013 if (rc
== 0 && strrets_U4
[i
].error
== 0) {
2014 ok(*pULong
== strrets_U4
[i
].retval
,
2015 "VarUI4FromStr([%d]=\"%s\") got %lu instead of %lu",
2016 i
,_pTestStrA
[i
],*pULong
,strrets_U4
[i
].retval
);
2023 trace( "======== Testing VarI1FromXXX ========\n");
2025 if (pVarI1FromBool
) {
2026 ok(S_OK
== pVarI1FromBool( VARIANT_TRUE
, pByte
), XOK
);
2027 ok(*pByte
== 0xff,"true should be 0xff");
2029 ok(S_OK
== pVarI1FromBool( VARIANT_TRUE
, pChar
), XOK
);
2030 ok(*pChar
== -1, "TRUE should be -1");
2032 ok(S_OK
== pVarI1FromBool( VARIANT_FALSE
, pChar
), XOK
);
2033 ok(*pChar
== 0, "FALSE should be 0");
2036 if (pVarI1FromUI1
) {
2037 ok(DISP_E_OVERFLOW
== pVarI1FromUI1( (unsigned char)32767, pChar
), XOV
);
2038 ok(*pChar
== 0, "should still be 0");
2039 ok(DISP_E_OVERFLOW
== pVarI1FromUI1( (unsigned char)65535, pChar
), XOV
);
2040 ok(*pChar
== 0, "should still be 0");
2044 ok(DISP_E_OVERFLOW
== pVarI1FromI4( 32767, pChar
), XOV
);
2045 ok(*pChar
== 0, "should still be 0");
2046 ok(DISP_E_OVERFLOW
== pVarI1FromI4( 32768, pChar
), XOV
);
2047 ok(*pChar
== 0, "should still be 0");
2048 ok(DISP_E_OVERFLOW
== pVarI1FromI4( -32768, pChar
), XOV
);
2049 ok(*pChar
== 0, "should still be 0");
2050 ok(DISP_E_OVERFLOW
== pVarI1FromI4( -32769, pChar
), XOV
);
2051 ok(*pChar
== 0, "should still be 0");
2055 ok(S_OK
== pVarI1FromR8( 69.33, pChar
), XOK
);
2056 ok(*pChar
== 69, "69.33 should be 69");
2057 ok(S_OK
== pVarI1FromR8( 69.66, pChar
), XOK
);
2058 ok(*pChar
== 70, "69.66 should be 70");
2060 ok(S_OK
== pVarI1FromR8( -69.33, pChar
), XOK
);
2061 ok(*pChar
== -69, "-69.33 should be -69");
2062 ok(S_OK
== pVarI1FromR8( -69.66, pChar
), XOK
);
2063 ok(*pChar
== -70, "-69.66 should be -70");
2066 if (pVarI1FromDate
) {
2067 ok(S_OK
== pVarI1FromDate( -69.66, pChar
), XOK
);
2068 ok(*pChar
== -70, "-69.66 should be -70");
2071 if (pVarI1FromStr
) {
2072 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2075 rc
=pVarI1FromStr( pOleChar
[i
], lcid
, 0, pChar
);
2076 ok(rc
== strrets_I1
[i
].error
,
2077 "VarI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2078 i
,_pTestStrA
[i
],rc
,strrets_I1
[i
].error
);
2079 if (rc
== 0 && strrets_I1
[i
].error
== 0) {
2080 ok(*pChar
== strrets_I1
[i
].retval
,
2081 "VarI1FromStr([%d]=\"%s\") got %d instead of %d",
2082 i
,_pTestStrA
[i
],*pChar
,strrets_I1
[i
].retval
);
2089 trace( "======== Testing VarI2FromXXX ========\n");
2091 if (pVarI2FromUI2
) {
2092 ok(S_OK
== pVarI2FromUI2( 32767, pShort
), XOK
);
2093 ok(*pShort
== 32767, "should be 32767");
2094 ok(DISP_E_OVERFLOW
== pVarI2FromUI2( 65535, pShort
), XOV
);
2095 ok(*pShort
== 32767, "pShort should be unchanged");
2098 ok(S_OK
== VarI2FromI4( 32767, pShort
), XOK
);
2099 ok(*pShort
== 32767, "should be 32767");
2100 ok(DISP_E_OVERFLOW
== VarI2FromI4( 32768, pShort
), XOV
);
2101 ok(*pShort
== 32767, "should still be 32767");
2102 ok(S_OK
== VarI2FromI4( -32768, pShort
), XOK
);
2103 ok(*pShort
== -32768, "should be -32768");
2104 ok(DISP_E_OVERFLOW
== VarI2FromI4( -32769, pShort
), XOV
);
2105 ok(*pShort
== -32768, "should still be -32768");
2107 ok(S_OK
== VarI2FromR8( 69.33, pShort
), XOK
);
2108 ok(*pShort
== 69, "should be 69");
2109 ok(S_OK
== VarI2FromR8( 69.66, pShort
), XOK
);
2110 ok(*pShort
== 70, "should be 70");
2111 ok(S_OK
== VarI2FromR8( -69.33, pShort
), XOK
);
2112 ok(*pShort
== -69, "should be -69");
2113 ok(S_OK
== VarI2FromR8( -69.66, pShort
), XOK
);
2114 ok(*pShort
== -70, "should be -70");
2115 ok(S_OK
== VarI2FromDate( -69.66, pShort
), XOK
);
2116 ok(*pShort
== -70, "should be -70");
2118 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2121 rc
=VarI2FromStr( pOleChar
[i
], lcid
, 0, pShort
);
2122 ok(rc
== strrets_I2
[i
].error
,
2123 "VarI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2124 i
,_pTestStrA
[i
],rc
,strrets_I2
[i
].error
);
2125 if (rc
== 0 && strrets_I2
[i
].error
== 0) {
2126 ok(*pShort
== strrets_I2
[i
].retval
,
2127 "VarI2FromStr([%d]=\"%s\") got %d instead of %d",
2128 i
,_pTestStrA
[i
],*pShort
,strrets_I2
[i
].retval
);
2134 trace( "======== Testing VarI4FromXXX ========\n");
2136 ok(S_OK
== VarI4FromI2( 3, (long*)pInt
), XOK
);
2137 ok(*pInt
== 3,"should be 3");
2139 ok(S_OK
== VarI4FromR8( 69.33, pLong
), XOK
);
2140 ok(*pLong
== 69,"should be 69");
2141 ok(S_OK
== VarI4FromR8( 69.66, pLong
), XOK
);
2142 ok(*pLong
== 70,"should be 70");
2143 ok(S_OK
== VarI4FromR8( -69.33, pLong
), XOK
);
2144 ok(*pLong
== -69,"should be -69");
2145 ok(S_OK
== VarI4FromR8( -69.66, pLong
), XOK
);
2146 ok(*pLong
== -70,"should be -70");
2148 ok(S_OK
== VarI4FromR8( 2147483647.0, pLong
), XOK
);
2149 ok(*pLong
== 2147483647,"should be 2147483647");
2150 ok(DISP_E_OVERFLOW
== VarI4FromR8( 2147483648.0, pLong
), XOV
);
2151 ok(*pLong
== 2147483647,"should still be 2147483647");
2153 ok(S_OK
== VarI4FromR8( -2147483647.0, pLong
), XOK
);
2154 ok(*pLong
== -2147483647,"should be -2147483647");
2155 ok(S_OK
== VarI4FromR8( -2147483648.0, pLong
), XOK
);
2156 ok(*pLong
== 0x80000000L
,"should be -2147483648");
2157 ok(DISP_E_OVERFLOW
== VarI4FromR8( -2147483649.0, pLong
), XOV
);
2158 ok(*pLong
== 0x80000000L
,"should still be -2147483648");
2159 ok(DISP_E_OVERFLOW
== VarI4FromDate( -2147483649.0, pLong
), XOV
);
2160 ok(*pLong
== 0x80000000L
,"should still be -2147483648");
2162 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2165 rc
=VarI4FromStr( pOleChar
[i
], lcid
, 0, pLong
);
2166 ok(rc
== strrets_I4
[i
].error
,
2167 "VarI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2168 i
,_pTestStrA
[i
],rc
,strrets_I4
[i
].error
);
2169 if (rc
== 0 && strrets_I4
[i
].error
== 0) {
2170 ok(*pLong
== strrets_I4
[i
].retval
,
2171 "VarI4FromStr([%d]=\"%s\") got %ld instead of %ld",
2172 i
,_pTestStrA
[i
],*pLong
,strrets_I4
[i
].retval
);
2178 trace( "======== Testing VarR4FromXXX ========\n");
2180 ok(S_OK
== VarR4FromI4( 16777216, pFloat
), XOK
);
2181 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2183 ok(S_OK
== VarR4FromI4( 16777217, pFloat
), XOK
);
2184 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2185 ok(S_OK
== VarR4FromI4( -16777216, pFloat
), XOK
);
2186 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2187 ok(S_OK
== VarR4FromI4( -16777217, pFloat
), XOK
);
2188 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2190 ok(S_OK
== VarR4FromR8( 16777216.0, pFloat
), XOK
);
2191 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2192 ok(S_OK
== VarR4FromR8( 16777217.0, pFloat
), XOK
);
2193 ok(16777216.0 == *pFloat
,"should be 16777216.0");
2194 ok(S_OK
== VarR4FromR8( -16777216.0, pFloat
), XOK
);
2195 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2196 ok(S_OK
== VarR4FromR8( -16777217.0, pFloat
), XOK
);
2197 ok(-16777216.0 == *pFloat
,"should be -16777216.0");
2199 ok(S_OK
== VarR4FromR8( 16777218e31
, pFloat
), XOK
);
2200 ok(*pFloat
== 167772177736353110000000000000000000000.000000,
2201 "should be 167772177736353110000000000000000000000.000000");
2202 ok(DISP_E_OVERFLOW
== VarR4FromR8( 16777218e32
, pFloat
), XOV
);
2203 ok(*pFloat
== 167772177736353110000000000000000000000.000000,
2204 "should still be 167772177736353110000000000000000000000.000000");
2205 ok(S_OK
== VarR4FromDate( 16777218e31
, pFloat
), XOK
);
2206 ok(*pFloat
== 167772177736353110000000000000000000000.000000,
2207 "should be 167772177736353110000000000000000000000.000000");
2209 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2212 rc
=VarR4FromStr( pOleChar
[i
], lcid
, 0, pFloat
);
2213 ok(rc
== strrets_R4
[i
].error
,
2214 "VarR4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2215 i
,_pTestStrA
[i
],rc
,strrets_R4
[i
].error
);
2216 if (rc
== 0 && strrets_R4
[i
].error
== 0) {
2217 ok(*pFloat
== strrets_R4
[i
].retval
,
2218 "VarR4FromStr([%d]=\"%s\") got %f instead of %f",
2219 i
,_pTestStrA
[i
],*pFloat
,strrets_R4
[i
].retval
);
2225 trace( "======== Testing VarR8FromXXX ========\n");
2227 ok(S_OK
== VarR8FromDate( 900719925474099.0, pDouble
), XOK
);
2228 ok(*pDouble
== 900719925474099.000000,"should be 900719925474099.000000\n");
2229 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2232 rc
=VarR8FromStr( pOleChar
[i
], lcid
, 0, pDouble
);
2233 ok(rc
== strrets_R8
[i
].error
,
2234 "VarR8FromStr([%d]=\"%s\") rc=%lx instead of %lx",
2235 i
,_pTestStrA
[i
],rc
,strrets_R8
[i
].error
);
2236 if (rc
== 0 && strrets_R8
[i
].error
== 0) {
2237 ok(*pDouble
== strrets_R8
[i
].retval
,
2238 "VarR8FromStr([%d]=\"%s\") got %.15f instead of %.15f",
2239 i
,_pTestStrA
[i
],*pDouble
,strrets_R8
[i
].retval
);
2245 trace( "======== Testing VarDateFromXXX ========\n");
2247 ok(S_OK
== VarDateFromI4( 2958465, pDouble
), XOK
);
2248 ok(*pDouble
== 2958465.000000,"should be 2958465.000000");
2249 rc
=VarDateFromI4( 2958466, pDouble
);
2250 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2252 ok(*pDouble
== 2958465.000000,"should still be 2958465.000000");
2253 ok(S_OK
== VarDateFromI4( -657434, pDouble
), XOK
);
2254 ok(*pDouble
== -657434.000000,"should be -657434.000000");
2255 rc
=VarDateFromI4( -657435, pDouble
);
2256 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2258 ok(*pDouble
== -657434.000000,"should still be -657434.000000");
2260 ok(S_OK
== VarDateFromR8( 2958465.9999, pDouble
), XOK
);
2261 ok(*pDouble
== 2958465.999900, "should be 2958465.999900");
2262 rc
=VarDateFromR8( 2958466, pDouble
);
2263 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2265 ok(*pDouble
== 2958465.999900, "should still be 2958465.999900");
2266 ok(S_OK
== VarDateFromR8( -657434.9999, pDouble
), XOK
);
2267 ok(*pDouble
== -657434.999900,"should be -657434.999900");
2268 rc
=VarDateFromR8( -657435, pDouble
);
2269 ok(rc
==DISP_E_OVERFLOW
|| rc
==DISP_E_TYPEMISMATCH
/* Win95 */,
2271 ok(*pDouble
== -657434.999900,"should still be -657434.999900");
2273 ok(S_OK
== VarDateFromR8( 0.0, pDouble
), XOK
);
2274 ok(*pDouble
== 0.0,"0.0 should be 0.0");
2275 ok(S_OK
== VarDateFromR8( 1.0, pDouble
), XOK
);
2276 ok(*pDouble
== 1.0,"1.0 should be 1.0");
2277 ok(S_OK
== VarDateFromR8( 2.25, pDouble
), XOK
);
2278 ok(*pDouble
== 2.25,"2.25 should be 2.25");
2279 ok(S_OK
== VarDateFromR8( -2.0, pDouble
), XOK
);
2280 ok(*pDouble
== -2.0,"-2.0 should be -2.0");
2282 /* Need some parsing function in Linux to emulate this...
2285 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2288 rc
=VarDateFromStr( pOleChar
[i
], lcid
, 0, pDouble
);
2289 if (strrets_DATE
[i
].todo_rc
) {
2291 ok(rc
== strrets_DATE
[i
].error
,
2292 "VarDateFromStr([%d]=\"%s\") rc= %lx instead of %lx",
2293 i
,_pTestStrA
[i
],rc
,strrets_DATE
[i
].error
);
2296 ok(rc
== strrets_DATE
[i
].error
,
2297 "VarDateFromStr([%d]=\"%s\") rc= %lx instead of %lx",
2298 i
,_pTestStrA
[i
],rc
,strrets_DATE
[i
].error
);
2300 if (rc
== 0 && strrets_DATE
[i
].error
== 0) {
2301 if (strrets_DATE
[i
].todo_rc
|| strrets_DATE
[i
].todo_val
) {
2303 ok(EQ_DOUBLE(*pDouble
,strrets_DATE
[i
].retval
),
2304 "VarDateFromStr([%d]=\"%s\") got %.15f instead of %.15f",
2305 i
,_pTestStrA
[i
],*pDouble
,strrets_DATE
[i
].retval
);
2308 ok(EQ_DOUBLE(*pDouble
,strrets_DATE
[i
].retval
),
2309 "VarDateFromStr([%d]=\"%s\") got %.15f instead of %.15f",
2310 i
,_pTestStrA
[i
],*pDouble
,strrets_DATE
[i
].retval
);
2316 trace( "======== Testing VarBoolFromXXX ========\n");
2318 ok(S_OK
== VarBoolFromI4( 0, pBool
), XOK
);
2319 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2320 ok(S_OK
== VarBoolFromI4( 1, pBool
), XOK
);
2321 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2322 ok(S_OK
== VarBoolFromI4( -1, pBool
), XOK
);
2323 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2324 ok(S_OK
== VarBoolFromI4( 2, pBool
), XOK
);
2325 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2327 ok(S_OK
== VarBoolFromUI1( ' ', pBool
), XOK
);
2328 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2329 ok(S_OK
== VarBoolFromUI1( '\0', pBool
), XOK
);
2330 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2331 ok(S_OK
== VarBoolFromUI1( 0x0000, pBool
), XOK
);
2332 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2333 ok(S_OK
== VarBoolFromUI1( (unsigned char)0xFFF, pBool
), XOK
);
2334 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2335 ok(S_OK
== VarBoolFromUI1( (unsigned char)0xFFFF, pBool
), XOK
);
2336 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2338 ok(S_OK
== VarBoolFromR8( 0.0, pBool
), XOK
);
2339 ok(VARIANT_FALSE
== *pBool
, "expected FALSE");
2340 ok(S_OK
== VarBoolFromR8( 1.1, pBool
), XOK
);
2341 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2342 ok(S_OK
== VarBoolFromR8( 0.5, pBool
), XOK
);
2343 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2344 ok(S_OK
== VarBoolFromR8( 0.49, pBool
), XOK
);
2345 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2346 ok(S_OK
== VarBoolFromR8( 0.51, pBool
), XOK
);
2347 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2348 ok(S_OK
== VarBoolFromR8( -0.5, pBool
), XOK
);
2349 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2350 ok(S_OK
== VarBoolFromR8( -0.49, pBool
), XOK
);
2351 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2352 ok(S_OK
== VarBoolFromR8( -0.51, pBool
), XOK
);
2353 ok(VARIANT_TRUE
== *pBool
, "expected TRUE");
2356 for (i
= 0; i
< NB_OLE_STRINGS
; i
++)
2359 rc
=VarBoolFromStr( pOleChar
[i
], lcid
, 0, pBool
);
2360 ok(rc
== strrets_B
[i
].error
,
2361 "VarBoolFromStr([%d]=\"%s\") rc=%lx instead of %lx",
2362 i
,_pTestStrA
[i
],rc
,strrets_B
[i
].error
);
2363 if (rc
== 0 && strrets_B
[i
].error
== 0) {
2364 ok(*pBool
== strrets_B
[i
].retval
,
2365 "VarBoolFromStr([%d]=\"%s\") got %x instead of %x",
2366 i
,_pTestStrA
[i
],*pBool
,strrets_B
[i
].retval
);
2372 trace( "======== Testing VarBSTRFromXXX ========\n");
2376 if (pVarBstrFromI1
) {
2377 ok(S_OK
== pVarBstrFromI1( -100, 0, 0, &bstr
), XOK
);
2378 ok(!strcmp(WtoA(bstr
),"\"-100\""),"should be string -100");
2381 ok(S_OK
== VarBstrFromUI1( 0x5A, 0, 0, &bstr
), XOK
);
2382 ok(!strcmp(WtoA(bstr
),"\"90\""),"should be string 90");
2383 ok(S_OK
== VarBstrFromI4( 2958465, 0, 0, &bstr
), XOK
);
2384 ok(!strcmp(WtoA(bstr
),"\"2958465\""),"should be string 2958465");
2390 for( i
=0; i
<20; i
++ )
2393 /* add an integer to the real number
2395 d
+= ((i
%9)+1) * pow( 10, i
);
2397 ok(S_OK
== VarBstrFromR8( d
, lcid
, 0, &bstr
), XOK
);
2398 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2399 ok(!strcmp(xval
,WtoA(bstr
)),
2400 "d is %.15f, should be cvt. to %s, but return val is %s",
2401 d
,strfromr8
[off
],WtoA(bstr
));
2404 ok(S_OK
== VarBstrFromR8( -d
, lcid
, 0, &bstr
), XOK
);
2405 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2406 ok(!strcmp(xval
,WtoA(bstr
)),
2407 "d is %.15f, should be cvt. to %s, but return val is %s",
2408 -d
,strfromr8
[off
],WtoA(bstr
));
2412 for( i
=0; i
<20; i
++ )
2415 /* add a decimal to the real number
2417 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2418 ok(S_OK
== VarBstrFromR8( d
, lcid
, 0, &bstr
), XOK
);
2419 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2420 ok(!strcmp(xval
,WtoA(bstr
)),
2421 "d is %.15f, should be cvt. to %s, but return val is %s",
2422 d
,strfromr8
[off
],WtoA(bstr
));
2424 ok(S_OK
== VarBstrFromR8( d
-1, lcid
, 0, &bstr
), XOK
);
2425 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2426 ok(!strcmp(xval
,WtoA(bstr
)),
2427 "d is %.15f, should be cvt. to %s, but return val is %s",
2428 d
-1,strfromr8
[off
],WtoA(bstr
));
2430 ok(S_OK
== VarBstrFromR8( -d
, lcid
, 0, &bstr
), XOK
);
2431 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2432 ok(!strcmp(xval
,WtoA(bstr
)),
2433 "d is %.15f, should be cvt. to %s, but return val is %s",
2434 -d
,strfromr8
[off
],WtoA(bstr
));
2439 for( i
=0; i
<20; i
++ )
2442 /* add an integer to the real number
2444 d
+= ((i
%9)+1) * pow( 10, i
);
2445 /* add a decimal to the real number
2447 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2448 ok(S_OK
== VarBstrFromR8( d
, lcid
, 0, &bstr
), XOK
);
2449 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2450 ok(!strcmp(xval
,WtoA(bstr
)),
2451 "d is %.15f, should be cvt. to %s, but return val is %s",
2452 d
,strfromr8
[off
],WtoA(bstr
));
2454 ok(S_OK
== VarBstrFromR8( -d
, lcid
, 0, &bstr
), XOK
);
2455 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2456 ok(!strcmp(xval
,WtoA(bstr
)),
2457 "d is %.15f, should be cvt. to %s, but return val is %s",
2458 -d
,strfromr8
[off
],WtoA(bstr
));
2463 for( i
=0; i
<10; i
++ )
2466 /* add an integer to the real number
2468 d
+= ((i
%9)+1) * pow( 10, i
);
2469 ok(S_OK
== VarBstrFromR4( (float)d
, lcid
, 0, &bstr
), XOK
);
2470 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2471 ok(!strcmp(xval
,WtoA(bstr
)),
2472 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2473 i
,d
,strfromr8
[off
],WtoA(bstr
));
2475 ok(S_OK
== VarBstrFromR4( (float)-d
, lcid
, 0, &bstr
), XOK
);
2476 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2477 ok(!strcmp(xval
,WtoA(bstr
)),
2478 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2479 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2483 for( i
=0; i
<10; i
++ )
2486 /* add a decimal to the real number
2488 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2489 ok(S_OK
== VarBstrFromR4( (float)d
, lcid
, 0, &bstr
), XOK
);
2490 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2491 ok(!strcmp(xval
,WtoA(bstr
)),
2492 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2493 i
,d
,strfromr8
[off
],WtoA(bstr
));
2495 ok(S_OK
== VarBstrFromR4( (float)(d
-1), lcid
, 0, &bstr
), XOK
);
2496 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2497 ok(!strcmp(xval
,WtoA(bstr
)),
2498 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2499 i
,d
-1,strfromr8
[off
],WtoA(bstr
));
2501 ok(S_OK
== VarBstrFromR4( (float)-d
, lcid
, 0, &bstr
), XOK
);
2502 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2503 ok(!strcmp(xval
,WtoA(bstr
)),
2504 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2505 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2510 for( i
=0; i
<10; i
++ )
2512 static int istodo
[10]={0,0,0,0,0,1,0,0,0,0};
2514 /* add an integer to the real number
2516 d
+= ((i
%9)+1) * pow( 10, i
);
2517 /* add a decimal to the real number
2519 d
+= ((i
%9)+1) * pow( 10, (i
*-1) );
2520 ok(S_OK
== VarBstrFromR4( (float)d
, lcid
, 0, &bstr
), XOK
);
2521 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2524 ok(!strcmp(xval
,WtoA(bstr
)),
2525 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2526 i
,d
,strfromr8
[off
],WtoA(bstr
));
2529 ok(!strcmp(xval
,WtoA(bstr
)),
2530 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2531 i
,d
,strfromr8
[off
],WtoA(bstr
));
2534 ok(S_OK
== VarBstrFromR4( (float)-d
, lcid
, 0, &bstr
), XOK
);
2535 sprintf(xval
,"\"%s\"",strfromr8
[off
]);
2538 ok(!strcmp(xval
,WtoA(bstr
)),
2539 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2540 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2543 ok(!strcmp(xval
,WtoA(bstr
)),
2544 "%d: d is %.8f, should be cvt. to %s, but return val is %s",
2545 i
,-d
,strfromr8
[off
],WtoA(bstr
));
2550 ok(S_OK
== VarBstrFromBool( 0x00, lcid
, 0, &bstr
), XOK
);
2551 ok(!strcmp(WtoA(bstr
),"\"False\""),"should be 'False'");
2552 ok(S_OK
== VarBstrFromBool( 0xFF, lcid
, 0, &bstr
), XOK
);
2553 ok(!strcmp(WtoA(bstr
),"\"True\""),"should be 'True'");
2555 ok(S_OK
== VarBstrFromDate( 0.0, lcid
, 0, &bstr
), XOK
);
2557 ok(!strcmp(WtoA(bstr
),"\"12:00:00 AM\""),
2558 "should be '12:00:00 AM', but is %s\n",WtoA(bstr
));
2561 ok(S_OK
== VarBstrFromDate( 3.34, lcid
, 0, &bstr
), XOK
);
2563 ok(strcmp(WtoA(bstr
),"\"1/2/1900 8:09:36 AM\"")==0 ||
2564 strcmp(WtoA(bstr
),"\"1/2/00 8:09:36 AM\"")==0 /* Win95 */,
2565 "should be '1/2/1900 8:09:36 AM', but is %s\n",WtoA(bstr
));
2568 ok(S_OK
== VarBstrFromDate( 3339.34, lcid
, 0, &bstr
), XOK
);
2570 ok(strcmp(WtoA(bstr
),"\"2/20/1909 8:09:36 AM\"")==0 ||
2571 strcmp(WtoA(bstr
),"\"2/20/09 8:09:36 AM\"")==0 /* Win95 */,
2572 "should be '2/20/1909 8:09:36 AM', but is %s\n",WtoA(bstr
));
2575 ok(S_OK
== VarBstrFromDate( 365.00, lcid
, 0, &bstr
), XOK
);
2577 ok(strcmp(WtoA(bstr
),"\"12/30/1900\"")==0 ||
2578 strcmp(WtoA(bstr
),"\"12/30/00\"")==0 /* Win95 */,
2579 "should be '12/30/1900', but is %s\n",WtoA(bstr
));
2582 ok(S_OK
== VarBstrFromDate( 365.25, lcid
, 0, &bstr
), XOK
);
2584 ok(strcmp(WtoA(bstr
),"\"12/30/1900 6:00:00 AM\"")==0 ||
2585 strcmp(WtoA(bstr
),"\"12/30/00 6:00:00 AM\"")==0 /* Win95 */,
2586 "should be '12/30/1900 6:00:00 AM', but is %s\n",WtoA(bstr
));
2589 ok(S_OK
== VarBstrFromDate( 1461.0, lcid
, 0, &bstr
), XOK
);
2591 ok(strcmp(WtoA(bstr
),"\"12/31/1903\"")==0 ||
2592 strcmp(WtoA(bstr
),"\"12/31/03\"")==0 /* Win95 */,
2593 "should be '12/31/1903', but is %s\n",WtoA(bstr
));
2596 ok(S_OK
== VarBstrFromDate( 1461.5, lcid
, 0, &bstr
), XOK
);
2598 ok(strcmp(WtoA(bstr
),"\"12/31/1903 12:00:00 PM\"")==0 ||
2599 strcmp(WtoA(bstr
),"\"12/31/03 12:00:00 PM\"")==0 /* Win95 */,
2600 "should be '12/31/1903 12:00:00 PM', but is %s\n",WtoA(bstr
));
2603 /* Test variant API...
2605 trace( "======== Testing Hi-Level Variant API ========\n");
2607 bstr
= SysAllocString( pOleChar
[4] );
2609 VariantClear( &va
);
2617 V_VT(&va
) = VT_BSTR
;
2618 V_UNION(&va
,bstrVal
) = bstr
;
2619 ok(S_OK
== VariantClear( &va
), XOK
);
2620 SysFreeString( bstr
);
2621 SysFreeString( bstr
);
2623 ok(S_OK
== VariantCopy( &vb
, &va
), XOK
);
2624 ok(S_OK
== VariantClear( &vb
), XOK
);
2625 ok(S_OK
== VariantClear( &va
), XOK
);
2629 V_UNION(&va
,dblVal
) = d
;
2630 ok(S_OK
== VariantCopy( &va
, &va
), XOK
);
2631 ok(V_R8(&va
) == 4.123,"should be 4.123");
2633 V_VT(&va
) = VT_R8
| VT_BYREF
;
2635 V_UNION(&va
,pdblVal
) = &d
;
2636 ok(S_OK
== VariantCopyInd( &va
, &va
), XOK
);
2637 ok(V_R8(&va
) == 31.123,"should be 31.123");
2641 V_UNION(&va
,dblVal
) = d
;
2642 ok(S_OK
== VariantCopy( &vb
, &va
), XOK
);
2643 ok(V_R8(&vb
) == 1.123,"should be 1.123");
2645 V_VT(&va
) = VT_R8
| VT_BYREF
;
2647 V_UNION(&va
,pdblVal
) = &d
;
2648 ok(S_OK
== VariantCopy( &vb
, &va
), XOK
);
2649 ok(*(V_R8REF(&vb
)) == 123.123,"should be 123.123");
2651 V_VT(&va
) = VT_R8
| VT_BYREF
;
2653 V_UNION(&va
,pdblVal
) = &d
;
2654 ok(S_OK
== VariantCopyInd( &vb
, &va
), XOK
);
2655 ok(V_R8(&vb
) == 111.2,"should be 111.2");
2657 V_VT(&va
) = VT_R8
| VT_BYREF
;
2659 V_UNION(&va
,pdblVal
) = &d
;
2660 ok(S_OK
== VariantChangeTypeEx( &va
, &va
, lcid
, 0, VT_I2
), XOK
);
2661 ok(V_VT(&va
) == VT_I2
,"should be type VT_I2");
2664 V_UNION(&va
,intVal
) = 4;
2665 ok(S_OK
== VariantChangeTypeEx(&vb
, &va
, lcid
, 0, VT_BSTR
), XOK
);
2666 ok(!strcmp(WtoA(V_BSTR(&vb
)),"\"4\""),"should be 4");
2668 V_VT(&va
) = VT_DATE
;
2669 V_UNION(&va
,date
) = 34465.332431;
2670 ok(S_OK
== VariantChangeTypeEx(&vb
, &va
, lcid
, 0, VT_BSTR
), XOK
);
2672 ok(strcmp(WtoA(V_BSTR(&vb
)),"\"5/11/1994 7:58:42 AM\"")==0 ||
2673 strcmp(WtoA(V_BSTR(&vb
)),"\"5/11/94 7:58:42 AM\"")==0 /* Win95 */,
2674 "should be 5/11/94 7:58:42 AM got %s",WtoA(V_BSTR(&vb
)));
2678 V_VT(&va
) = VT_BSTR
;
2679 V_UNION(&va
,bstrVal
) = bstr
;
2680 ok(S_OK
== VariantChangeTypeEx(&vb
, &va
, lcid
, 0, VT_R8
), XOK
);
2681 ok(V_R8(&vb
) == -0.490000,"should be -0.49");
2683 V_VT(&vc
) = VT_BSTR
| VT_BYREF
;
2684 V_UNION(&vc
,pbstrVal
) = &bstr
;
2685 V_VT(&vb
) = VT_VARIANT
| VT_BYREF
;
2686 V_UNION(&vb
,pvarVal
) = &vc
;
2687 V_VT(&va
) = VT_VARIANT
| VT_BYREF
;
2688 V_UNION(&va
,pvarVal
) = &vb
;
2689 ok(E_INVALIDARG
== VariantCopyInd( &vd
, &va
), "expect E_INVALIDARG");
2691 /* test what happens when bad vartypes are passed in */
2692 trace( "======== Testing different VARTYPES ========\n" );
2694 for( i
=0; i
<sizeof(vartypes
)/sizeof(vartypes
[0]); i
++ )
2696 /* Trying to use variants that are set to be BSTR but
2697 * do not contain a valid pointer makes the program crash
2698 * in Windows so we will skip those. We do not need them
2699 * anyway to illustrate the behavior.
2701 V_VT(&va
) = vartypes
[i
].ind
;
2703 V_UNION(&va
,dblVal
) = d
;
2704 rc
= VariantCopyInd( &vb
, &va
);
2705 if (vartypes
[i
].todoind1
) {
2707 ok(vartypes
[i
].vcind1
== rc
,
2708 "%d: vt %d, return value %lx, expected was %lx",
2709 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind1
);
2712 ok(vartypes
[i
].vcind1
== rc
,
2713 "%d: vt %d, return value %lx, expected was %lx",
2714 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind1
);
2716 V_VT(&va
) = vartypes
[i
].ind
| VT_BYREF
;
2718 V_UNION(&va
,pdblVal
) = &d
;
2719 rc
= VariantCopyInd( &vb
, &va
);
2720 if (vartypes
[i
].todoind2
) {
2722 ok(vartypes
[i
].vcind2
== rc
,
2723 "%d: vt %d, return value %lx, expected was %lx",
2724 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind2
);
2727 ok(vartypes
[i
].vcind2
== rc
,
2728 "%d: vt %d, return value %lx, expected was %lx",
2729 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcind2
);
2733 V_UNION(&va
,dblVal
) = d
;
2734 rc
= VariantChangeTypeEx( &vb
, &va
, lcid
, 0, (VARTYPE
)i
);
2735 if (vartypes
[i
].todowcex1
) {
2737 ok(vartypes
[i
].vcex1
== rc
|| rc
== DISP_E_BADVARTYPE
,
2738 "%d: vt %d, return value %lx, expected was %lx",
2739 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex1
);
2742 ok(vartypes
[i
].vcex1
== rc
|| rc
== DISP_E_BADVARTYPE
,
2743 "%d: vt %d, return value %lx, expected was %lx",
2744 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex1
);
2748 V_UNION(&va
,dblVal
) = d
;
2749 rc
= VariantChangeTypeEx( &vb
, &va
, lcid
, 0, (VARTYPE
)(i
| VT_BYREF
) );
2750 if (vartypes
[i
].todowcex2
) {
2752 ok(vartypes
[i
].vcex2
== rc
|| rc
== DISP_E_BADVARTYPE
,
2753 "%d: vt %d, return value %lx, expected was %lx",
2754 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex2
);
2757 ok(vartypes
[i
].vcex2
== rc
|| rc
== DISP_E_BADVARTYPE
,
2758 "%d: vt %d, return value %lx, expected was %lx",
2759 i
,vartypes
[i
].ind
,rc
,vartypes
[i
].vcex2
);
2764 V_UNION(&va
,dblVal
) = d
;
2765 ok(DISP_E_BADVARTYPE
== VariantClear( &va
), "should give DISP_E_BADVARTYPE");
2767 VariantClear( &va
);
2768 VariantClear( &vb
);
2769 VariantClear( &vc
);
2770 VariantClear( &vd
);
2771 VariantClear( &ve
);
2772 /* There is alot of memory leaks but this is simply a test program.