Remove tests that are covered by vartype.c.
authorJon Griffiths <jon_p_griffiths@yahoo.com>
Tue, 20 Jan 2004 23:38:38 +0000 (23:38 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 20 Jan 2004 23:38:38 +0000 (23:38 +0000)
Call by pointer for more functions not available in early versions.
Add tests for VarFix/VarInt/VarNeg, VarFormat "on/off/yes/no".
Fix tests that assumed relative dates.
Make BSTR copy test separate.

dlls/oleaut32/tests/vartest.c
dlls/oleaut32/tests/vartype.c

index f596125532a53667d93323da666aac10940dcc83..caf83a63add8c33eb2362ff77f60eb51e65c3071 100644 (file)
@@ -16,9 +16,6 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * NOTES
- * - Does not test IDispatch, IUnknown, IRecordInfo, DECIMAL, CY, I8/UI8
  */
 
 #include <stdarg.h>
 
 static HMODULE hOleaut32;
 
-static HRESULT (WINAPI *pVarBstrFromI1)(CHAR,LCID,ULONG,BSTR*)=NULL;
-
-static HRESULT (WINAPI *pVarI1FromBool)(VARIANT_BOOL,CHAR*)=NULL;
-static HRESULT (WINAPI *pVarI1FromDate)(DATE,CHAR*)=NULL;
-static HRESULT (WINAPI *pVarI1FromI4)(LONG,CHAR*)=NULL;
-static HRESULT (WINAPI *pVarI1FromR8)(double,CHAR*)=NULL;
-static HRESULT (WINAPI *pVarI1FromStr)(OLECHAR*,LCID,ULONG,CHAR*);
-static HRESULT (WINAPI *pVarI1FromUI1)(BYTE,CHAR*)=NULL;
-
-static HRESULT (WINAPI *pVarI2FromUI2)(USHORT,short*)=NULL;
-
-static HRESULT (WINAPI *pVarUI2FromBool)(VARIANT_BOOL,USHORT*)=NULL;
-static HRESULT (WINAPI *pVarUI2FromDate)(DATE,USHORT*)=NULL;
-static HRESULT (WINAPI *pVarUI2FromI2)(short,USHORT*)=NULL;
-static HRESULT (WINAPI *pVarUI2FromI4)(LONG,USHORT*);
-static HRESULT (WINAPI *pVarUI2FromR8)(double,USHORT*)=NULL;
-static HRESULT (WINAPI *pVarUI2FromStr)(OLECHAR*,LCID,ULONG,USHORT*)=NULL;
-
-static HRESULT (WINAPI *pVarUI4FromBool)(VARIANT_BOOL,ULONG*)=NULL;
-static HRESULT (WINAPI *pVarUI4FromDate)(DATE,ULONG*)=NULL;
-static HRESULT (WINAPI *pVarUI4FromI2)(short,ULONG*)=NULL;
-static HRESULT (WINAPI *pVarUI4FromR8)(double,ULONG*)=NULL;
-static HRESULT (WINAPI *pVarUI4FromStr)(OLECHAR*,LCID,ULONG,ULONG*)=NULL;
-
 static HRESULT (WINAPI *pVarUdateFromDate)(DATE,ULONG,UDATE*);
 static HRESULT (WINAPI *pVarDateFromUdate)(UDATE*,ULONG,DATE*);
 static INT (WINAPI *pSystemTimeToVariantTime)(LPSYSTEMTIME,double*);
@@ -91,2617 +64,23 @@ static HRESULT (WINAPI *pVarFormat)(LPVARIANT,LPOLESTR,int,int,ULONG,BSTR*);
 #define HAVE_OLEAUT32_CY      HAVE_FUNC(VarCyAdd)
 /* Have I8/UI8 data type? */
 #define HAVE_OLEAUT32_I8      HAVE_FUNC(VarI8FromI1)
+/* Is this an ancient version with support for only I2/I4/R4/R8/DATE? */
+#define IS_ANCIENT (!HAVE_FUNC(VarI1FromI2))
+/* Is vt a type unavailable to ancient versions? */
+#define IS_MODERN_VTYPE(vt) (vt==VT_VARIANT||vt==VT_DECIMAL|| \
+    vt==VT_I1||vt==VT_UI2||vt==VT_UI4||vt == VT_INT||vt == VT_UINT)
 
 /* When comparing floating point values we cannot expect an exact match
  * because the rounding errors depend on the exact algorithm.
  */
 #define EQ_DOUBLE(a,b)     (fabs((a)-(b))<1e-14)
 
-#define MAX_BUFFER  1024
-
-static char* WtoA( OLECHAR* p )
-{
-    static char buffer[MAX_BUFFER];
-    DWORD len = WideCharToMultiByte( CP_ACP, 0, p, -1, buffer+1, sizeof(buffer)-3, NULL, NULL );
-    buffer[0] = '\"';
-    buffer[len] = '\"';
-    buffer[len+1] = 0;
-    return buffer;
-}
-
-static OLECHAR* AtoW( const char* p )
-{
-    OLECHAR *buffer;
-    DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
-    buffer = malloc( len * sizeof(OLECHAR) );
-    MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
-    return buffer;
-}
-
 static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
 {
     while (*str1 && (*str1 == *str2)) { str1++; str2++; }
     return *str1 - *str2;
 }
 
-static const struct _vartypes {
-    int ind;
-    HRESULT vcind1,vcind2,vcex1,vcex2;
-} vartypes[] = {
-    {0, 0,          0x80070057, 0,          0x80020008 },
-    {1, 0,          0x80070057, 0,          0x80020008 },
-    {2, 0,          0,          0,          0x80020005 },
-    {3, 0,          0,          0,          0x80020005 },
-    {4, 0,          0,          0,          0x80020005 },
-    {5, 0,          0,          0,          0x80020005 },
-    {6, 0,          0,          0,          0x80020005 },
-    {7, 0,          0,          0,          0x80020005 },
-    {77,0x80020008, 0x80070057, 0,          0x80020005 },
-    {78,0x80020008, 0x80070057, 0x80020005, 0x80020005 },
-    {79,0x80020008, 0x80070057, 0x80020005, 0x80020005 },
-    {80,0x80020008, 0x80070057, 0,          0x80020005 },
-    {81,0x80020008, 0x80070057, 0x80020005, 0x80020005 },
-    {82,0x80020008, 0x80070057, 0x80020005, 0x80020005 },
-    {83,0x80020008, 0x80070057, 0,          0x80020005 },
-    {84,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {85,0x80020008, 0x80070057, 0,          0x80020005 },
-    {86,0x80020008, 0x80070057, 0,          0x80020005 },
-    {87,0x80020008, 0x80070057, 0,          0x80020005 },
-    {88,0x80020008, 0x80070057, 0,          0x80020005 },
-    {89,0x80020008, 0x80070057, 0,          0x80020005 },
-    {90,0x80020008, 0x80070057, 0,          0x80020005 },
-    {91,0x80020008, 0x80070057, 0,          0x80020005 },
-    {92,0x80020008, 0x80070057, 0,          0x80020005 },
-    {93,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {94,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {95,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {96,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {97,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {98,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-    {99,0x80020008, 0x80070057, 0x80020008, 0x80020008 },
-};
-
-static const char *strfromr8[] = {
-"1",
-"-1",
-"21",
-"-21",
-"321",
-"-321",
-"4321",
-"-4321",
-"54321",
-"-54321",
-"654321",
-"-654321",
-"7654321",
-"-7654321",
-"87654321",
-"-87654321",
-"987654321",
-"-987654321",
-"1987654321",
-"-1987654321",
-"21987654321",
-"-21987654321",
-"321987654321",
-"-321987654321",
-"4321987654321",
-"-4321987654321",
-"54321987654321",
-"-54321987654321",
-"654321987654321",
-"-654321987654321",
-"7.65432198765432E+15",
-"-7.65432198765432E+15",
-"8.76543219876543E+16",
-"-8.76543219876543E+16",
-"9.87654321987654E+17",
-"-9.87654321987654E+17",
-"1.98765432198765E+18",
-"-1.98765432198765E+18",
-"2.19876543219877E+19",
-"-2.19876543219877E+19",
-"1",
-"0",
-"-1",
-"1.2",
-"0.2",
-"-1.2",
-"1.23",
-"0.23",
-"-1.23",
-"1.234",
-"0.234",
-"-1.234",
-"1.2345",
-"0.2345",
-"-1.2345",
-"1.23456",
-"0.23456",
-"-1.23456",
-"1.234567",
-"0.234567",
-"-1.234567",
-"1.2345678",
-"0.2345678",
-"-1.2345678",
-"1.23456789",
-"0.23456789",
-"-1.23456789",
-"1.234567891",
-"0.234567891",
-"-1.234567891",
-"1.2345678912",
-"0.2345678912",
-"-1.2345678912",
-"1.23456789123",
-"0.23456789123",
-"-1.23456789123",
-"1.234567891234",
-"0.234567891234",
-"-1.234567891234",
-"1.2345678912345",
-"0.2345678912345",
-"-1.2345678912345",
-"1.23456789123456",
-"0.23456789123456",
-"-1.23456789123456",
-"1.23456789123457",
-"0.234567891234567",
-"-1.23456789123457",
-"1.23456789123457",
-"0.234567891234568",
-"-1.23456789123457",
-"1.23456789123457",
-"0.234567891234568",
-"-1.23456789123457",
-"1.23456789123457",
-"0.234567891234568",
-"-1.23456789123457",
-"1.23456789123457",
-"0.234567891234568",
-"-1.23456789123457",
-"2",
-"-2",
-"22.2",
-"-22.2",
-"322.23",
-"-322.23",
-"4322.234",
-"-4322.234",
-"54322.2345",
-"-54322.2345",
-"654322.23456",
-"-654322.23456",
-"7654322.234567",
-"-7654322.234567",
-"87654322.2345678",
-"-87654322.2345678",
-"987654322.234568",
-"-987654322.234568",
-"1987654322.23457",
-"-1987654322.23457",
-"21987654322.2346",
-"-21987654322.2346",
-"321987654322.235",
-"-321987654322.235",
-"4321987654322.23",
-"-4321987654322.23",
-"54321987654322.2",
-"-54321987654322.2",
-"654321987654322",
-"-654321987654322",
-"7.65432198765432E+15",
-"-7.65432198765432E+15",
-"8.76543219876543E+16",
-"-8.76543219876543E+16",
-"9.87654321987654E+17",
-"-9.87654321987654E+17",
-"1.98765432198765E+18",
-"-1.98765432198765E+18",
-"2.19876543219877E+19",
-"-2.19876543219877E+19",
-/* r4 tests */
-"1",
-"-1",
-"21",
-"-21",
-"321",
-"-321",
-"4321",
-"-4321",
-"54321",
-"-54321",
-"654321",
-"-654321",
-"7654321",
-"-7654321",
-"8.765432E+07",
-"-8.765432E+07",
-"9.876543E+08",
-"-9.876543E+08",
-"1.987654E+09",
-"-1.987654E+09",
-"1",
-"0",
-"-1",
-"1.2",
-"0.2",
-"-1.2",
-"1.23",
-"0.23",
-"-1.23",
-"1.234",
-"0.234",
-"-1.234",
-"1.2345",
-"0.2345",
-"-1.2345",
-"1.23456",
-"0.23456",
-"-1.23456",
-"1.234567",
-"0.234567",
-"-1.234567",
-"1.234568",
-"0.2345678",
-"-1.234568",
-"1.234568",
-"0.2345679",
-"-1.234568",
-"1.234568",
-"0.2345679",
-"-1.234568",
-"2",
-"-2",
-"22.2",
-"-22.2",
-"322.23",
-"-322.23",
-"4322.234",
-"-4322.234",
-"54322.23",
-"-54322.23",
-"654322.3",
-"-654322.3",
-"7654322",
-"-7654322",
-"8.765432E+07",
-"-8.765432E+07",
-"9.876543E+08",
-"-9.876543E+08",
-"1.987654E+09",
-"-1.987654E+09",
-};
-
-/* These are the strings we use for the XxxFromStr tests.
- * The arrays that follow define the expected results for each type.
- */
-static const char* _pTestStrA[] = {
-    "-2",
-    "-1",
-    "-0.51",
-    "-0.5",
-    "-0.49",
-    "-0.0",
-    "0.0",
-    "0.49",
-    "0.5",
-    "0.51",
-    "1",
-    "127",
-    "128",
-    "129",
-    "255",
-    "256",
-    "257",
-    "32767",
-    "32768",
-    "-32768",
-    "-32769",
-    "16777216",
-    "16777217",
-    "-16777216",
-    "16777217",
-    "2147483647",
-    "2147483648",
-    "-2147483647",
-    "-2147483648",
-
-    "",
-    " ",
-    "1F",
-    "1G",
-    " 1 ",
-    " 1 2 ",
-    "1,2,3",
-    "1 2 3",
-    "1,2, 3",
-    "1;2;3",
-    "1.2.3",
-
-    "0.",
-    ".0",
-    "0.1E12",
-    "2.4,E1",
-    "  +3.2,E1",
-    "4E2.5",
-    "  2E+2",
-    "1 E+2",
-    ".",
-    ".E2",
-    "1000000000000000000000000000000000000000000000000000000000000000",
-    "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-    "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-    "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-    "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
-    "65535",
-    "65535.5",
-    "65536",
-    "4294967295",
-    "4294967296",
-
-    "1 January 99",
-    "December 31, 2078",
-    "January 1, 1900",
-    "January 2 1900",
-    "11.11.1999",
-    "11/11/1999",
-    " 11 / 11 / 1999",
-    "11/11/1999:11:11:1134",
-    "11/11/1999 11:11:11:1",
-    "\t1999/\t11/21 11 :11:11am",
-
-    "11/11/1999 11:11:11Am",
-    "11/11/1999 11:11:11PM",
-    "11/11/199911:11:11PM",
-    "11/11/1999 0:0:11am",
-    "11/11/1999 11,11:11am",
-    "11/11/1999 11:11:11am",
-    "11/11/1999 11/11:11am",
-    "11/11/1999 11:11AM",
-    "11/11/1999 1AM",
-    "11/11/1999 0AM",
-
-    "11/11/1999 11:11:11",
-    "11/13/1999 0AM",
-    "13/13/1999 0AM",
-    "13/11/1999 0AM",
-    "11/33/1999 0AM",
-    "11/11/1999 AM",
-    "1/1/0 0AM",
-    "1/1/-1 0AM",
-    "1999 January 3 9AM",
-    "1 January 1999 11AM",
-
-    "4AM 11/11/1999",
-    "4:22 11/11/1999 AM",
-    " 1 1 /11/1999",
-    "11-11/1999 11:11:11.12AM",
-    "1999 January 3, 9AM",
-    "December, 31, 2078",
-    "December, 31, 2078,",
-    "December, 31 2078",
-    "11/99",
-    "11-1999",
-
-    "true",
-    "True",
-    "TRue",
-    "TRUE",
-    " TRUE",
-    "FALSE ",
-    "False",
-    "JustSomeText",
-    "Just Some Text",
-
-    "1.5",
-    "2.5",
-    "3.5",
-    "4.5",
-};
-#define NB_OLE_STRINGS (sizeof(_pTestStrA)/sizeof(*_pTestStrA))
-
-static const struct _strret_date {
-    HRESULT error;
-    DATE retval;
-    BOOL todo_rc;
-    BOOL todo_val;
-} strrets_DATE[NB_OLE_STRINGS] = {
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0.0, 1 },
-    { 0,           0.03402777777777, 1 },
-    { 0,           0.00347222222222, 1 },
-    { 0,           0.03541666666666, 1 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           37623.0, 1 },
-    { 0,           37623.0 },
-    { 0,           37623.0 },
-    { 0,           37623.0 },
-    { 0x80020005,  0.0, 1 },
-    { 0,           0.04309027777777, 0, 1 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           36161.0, 1 },
-    { 0,           65380.0 },
-    { 0,           2.0},
-    { 0,           3.0 },
-    { 0x80020005,  0.0, 1 },
-    { 0,           36475.0 },
-    { 0,           36475.0 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           36485.466099537036, 1 },
-    { 0,           36475.466099537036 },
-    { 0,           36475.966099537036 },
-    { 0x80020005,  0.0, 1 },
-    { 0,           36475.000127314815 },
-    { 0x80020005 },
-    { 0,           36475.466099537036 },
-    { 0x80020005 },
-    { 0,           36475.465972222222 },
-    { 0,           36475.041666666664, 1 },
-    { 0,           36475.0, 1 },
-    { 0,           36475.466099537036 },
-    { 0,           36477.0, 1 },
-    { 0x80020005 },
-    { 0,           36477.0, 1 },
-    { 0x80020005 },
-    { 0x80020005,  0.0, 1 },
-    { 0,           36526.0, 1 },
-    { 0x80020005 },
-    { 0,           36163.375000000000, 1 },
-    { 0,           36161.458333333336, 1 },
-    { 0,           36475.166666666664, 1 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005 },
-    { 0x80020005,  0.0, 1 },
-    { 0x80020005 },
-    { 0,           65380.0 },
-    { 0x80020005,  0.0, 1 },
-    { 0,           65380.0 },
-    { 0,           36465.0, 1 },
-    { 0,           36465.0, 1 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0.045138888888889, 1 },
-    { 0,           0.086805555555556, 1 },
-    { 0,           0.128472222222222, 1 },
-    { 0,           0.170138888888889, 1 },
-};
-static const struct _strret_b {
-    HRESULT error;
-    BOOL retval;
-} strrets_B[NB_OLE_STRINGS] = {
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_FALSE },
-    { 0,           VARIANT_FALSE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           VARIANT_FALSE },
-    { 0,           VARIANT_FALSE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           VARIANT_FALSE },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-    { 0,           VARIANT_TRUE },
-};
-static const struct _strret_r8 {
-    HRESULT error;
-    DOUBLE retval;
-} strrets_R8[NB_OLE_STRINGS] = {
-    { 0,           -2.000000 },
-    { 0,           -1.000000 },
-    { 0,           -0.510000 },
-    { 0,           -0.500000 },
-    { 0,           -0.490000 },
-    { 0,           0.000000 },
-    { 0,           0.000000 },
-    { 0,           0.490000 },
-    { 0,           0.500000 },
-    { 0,           0.510000 },
-    { 0,           1.000000 },
-    { 0,           127.000000 },
-    { 0,           128.000000 },
-    { 0,           129.000000 },
-    { 0,           255.000000 },
-    { 0,           256.000000 },
-    { 0,           257.000000 },
-    { 0,           32767.000000 },
-    { 0,           32768.000000 },
-    { 0,           -32768.000000 },
-    { 0,           -32769.000000 },
-    { 0,           16777216.000000 },
-    { 0,           16777217.000000 },
-    { 0,           -16777216.000000 },
-    { 0,           16777217.000000 },
-    { 0,           2147483647.000000 },
-    { 0,           2147483648.000000 },
-    { 0,           -2147483647.000000 },
-    { 0,           -2147483648.000000 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1.000000 },
-    { 0x80020005 },
-    { 0,           123.000000 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0.000000 },
-    { 0,           0.000000 },
-    { 0,           100000000000.000000 },
-    { 0,           24.000000 },
-    { 0,           32.000000 },
-    { 0x80020005 },
-    { 0,           200.000000 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1e63 },
-    { 0,           1.000000 },
-    { 0,           1.000000 },
-    { 0,           99999999999999997e183 },
-    { 0,           1.000000 },
-    { 0,           65535.000000 },
-    { 0,           65535.500000 },
-    { 0,           65536.000000 },
-    { 0,           4294967295.000000 },
-    { 0,           4294967296.000000 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1.500000 },
-    { 0,           2.500000 },
-    { 0,           3.500000 },
-    { 0,           4.500000 },
-};
-static const struct _strret_r4 {
-    HRESULT error;
-    FLOAT retval;
-} strrets_R4[NB_OLE_STRINGS] = {
-    { 0,           -2.000000F },
-    { 0,           -1.000000F },
-    { 0,           -0.510000F },
-    { 0,           -0.500000F },
-    { 0,           -0.490000F },
-    { 0,           0.000000F },
-    { 0,           0.000000F },
-    { 0,           0.490000F },
-    { 0,           0.500000F },
-    { 0,           0.510000F },
-    { 0,           1.000000F },
-    { 0,           127.000000F },
-    { 0,           128.000000F },
-    { 0,           129.000000F },
-    { 0,           255.000000F },
-    { 0,           256.000000F },
-    { 0,           257.000000F },
-    { 0,           32767.000000F },
-    { 0,           32768.000000F },
-    { 0,           -32768.000000F },
-    { 0,           -32769.000000F },
-    { 0,           16777216.000000F },
-    { 0,           16777216.000000F },
-    { 0,           -16777216.000000F },
-    { 0,           16777216.000000F },
-    { 0,           2147483648.000000F },
-    { 0,           2147483648.000000F },
-    { 0,           -2147483648.000000F },
-    { 0,           -2147483648.000000F },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1.000000F },
-    { 0x80020005 },
-    { 0,           123.000000F },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0.000000F },
-    { 0,           0.000000F },
-    { 0,           99999997952.000000F },
-    { 0,           24.000000F },
-    { 0,           32.000000F },
-    { 0x80020005 },
-    { 0,           200.000000F },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1.000000F },
-    { 0,           1.000000F },
-    { 0x8002000A },
-    { 0,           1.000000F },
-    { 0,           65535.000000F },
-    { 0,           65535.500000F },
-    { 0,           65536.000000F },
-    { 0,           4294967296.000000F },
-    { 0,           4294967296.000000F },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1.500000F },
-    { 0,           2.500000F },
-    { 0,           3.500000F },
-    { 0,           4.500000F },
-};
-static const struct _strret_i4 {
-    HRESULT error;
-    LONG retval;
-} strrets_I4[NB_OLE_STRINGS] = {
-    { 0,           -2L },
-    { 0,           -1L },
-    { 0,           -1L },
-    { 0,           0L },
-    { 0,           0L },
-    { 0,           0L },
-    { 0,           0L },
-    { 0,           0L },
-    { 0,           0L },
-    { 0,           1L },
-    { 0,           1L },
-    { 0,           127L },
-    { 0,           128L },
-    { 0,           129L },
-    { 0,           255L },
-    { 0,           256L },
-    { 0,           257L },
-    { 0,           32767L },
-    { 0,           32768L },
-    { 0,           -32768L },
-    { 0,           -32769L },
-    { 0,           16777216L },
-    { 0,           16777217L },
-    { 0,           -16777216L },
-    { 0,           16777217L },
-    { 0,           2147483647L },
-    { 0x8002000A },
-    { 0,           -2147483647L },
-    { 0,           0x80000000L },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1L },
-    { 0x80020005 },
-    { 0,           123L },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0L },
-    { 0,           0L },
-    { 0x8002000A },
-    { 0,           24L },
-    { 0,           32L },
-    { 0x80020005 },
-    { 0,           200L },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1L },
-    { 0,           1L },
-    { 0x8002000A },
-    { 0,           1L },
-    { 0,           65535L },
-    { 0,           65536L },
-    { 0,           65536L },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           2L },
-    { 0,           2L },
-    { 0,           4L },
-    { 0,           4L },
-};
-static const struct _strret_i2 {
-    HRESULT error;
-    SHORT retval;
-} strrets_I2[NB_OLE_STRINGS] = {
-    { 0,           -2 },
-    { 0,           -1 },
-    { 0,           -1 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           1 },
-    { 0,           1 },
-    { 0,           127 },
-    { 0,           128 },
-    { 0,           129 },
-    { 0,           255 },
-    { 0,           256 },
-    { 0,           257 },
-    { 0,           32767 },
-    { 0x8002000A },
-    { 0,           -32768 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1 },
-    { 0x80020005 },
-    { 0,           123 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0x8002000A },
-    { 0,           24 },
-    { 0,           32 },
-    { 0x80020005 },
-    { 0,           200 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           2 },
-    { 0,           2 },
-    { 0,           4 },
-    { 0,           4 },
-};
-static const struct _strret_i1 {
-    HRESULT error;
-    CHAR retval;
-} strrets_I1[NB_OLE_STRINGS] = {
-    { 0,           -2 },
-    { 0,           -1 },
-    { 0,           -1 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           1 },
-    { 0,           1 },
-    { 0,           127 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1 },
-    { 0x80020005 },
-    { 0,           123 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0x8002000A },
-    { 0,           24 },
-    { 0,           32 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           2 },
-    { 0,           2 },
-    { 0,           4 },
-    { 0,           4 },
-};
-static const struct _strret_u1 {
-    HRESULT error;
-    BYTE retval;
-} strrets_U1[NB_OLE_STRINGS] = {
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           1 },
-    { 0,           1 },
-    { 0,           0x7F },
-    { 0,           0x80 },
-    { 0,           0x81 },
-    { 0,           0xFF },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1 },
-    { 0x80020005 },
-    { 0,           0x7B },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0x8002000A },
-    { 0,           0x18 },
-    { 0,           0x20 },
-    { 0x80020005 },
-    { 0,           0xC8 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           2 },
-    { 0,           2 },
-    { 0,           4 },
-    { 0,           4 },
-};
-
-static const struct _strret_U2 {
-    HRESULT error;
-    WORD retval;
-} strrets_U2[NB_OLE_STRINGS] = {
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           1 },
-    { 0,           1 },
-    { 0,           127 },
-    { 0,           128 },
-    { 0,           129 },
-    { 0,           255 },
-    { 0,           256 },
-    { 0,           257 },
-    { 0,           32767 },
-    { 0,           32768 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1 },
-    { 0x80020005 },
-    { 0,           123 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0x8002000A },
-    { 0,           24 },
-    { 0,           32 },
-    { 0x80020005 },
-    { 0,           200 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           65535 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           2 },
-    { 0,           2 },
-    { 0,           4 },
-    { 0,           4 },
-};
-
-static const struct _strret_U4 {
-    HRESULT error;
-    DWORD retval;
-} strrets_U4[NB_OLE_STRINGS] = {
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0,           1 },
-    { 0,           1 },
-    { 0,           127 },
-    { 0,           128 },
-    { 0,           129 },
-    { 0,           255 },
-    { 0,           256 },
-    { 0,           257 },
-    { 0,           32767 },
-    { 0,           32768 },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0,           16777216 },
-    { 0,           16777217 },
-    { 0x8002000A },
-    { 0,           16777217 },
-    { 0,           2147483647 },
-    { 0,           2147483648U },
-    { 0x8002000A },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           1 },
-    { 0x80020005 },
-    { 0,           123 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           0 },
-    { 0,           0 },
-    { 0x8002000A },
-    { 0,           24 },
-    { 0,           32 },
-    { 0x80020005 },
-    { 0,           200 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           1 },
-    { 0x8002000A },
-    { 0,           1 },
-    { 0,           65535 },
-    { 0,           65536 },
-    { 0,           65536 },
-    { 0,           4294967295U },
-    { 0x8002000A },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0x80020005 },
-    { 0,           2 },
-    { 0,           2 },
-    { 0,           4 },
-    { 0,           4 },
-};
-
-static void test_variant(void)
-{
-       HMODULE hdll;
-       VARIANTARG va;
-       VARIANTARG vb;
-       VARIANTARG vc;
-       VARIANTARG vd;
-       VARIANTARG ve;
-
-       HRESULT rc;
-       LCID lcid;
-       int theInt = 0;
-       int* pInt = &theInt;
-       VARIANT_BOOL b = 0;
-       VARIANT_BOOL* pBool = &b;
-       unsigned short uShort = 0;
-       unsigned short* pUShort = &uShort;
-       unsigned long uLong = 0;
-       unsigned long* pULong = &uLong;
-       CHAR theChar;
-       CHAR* pChar = &theChar;
-       BYTE byte;
-       BYTE* pByte = &byte;
-       short s = 0;
-       short* pShort = &s;
-       long Long = 0;
-       long* pLong = &Long;
-       float f = 0;
-       float* pFloat = &f;
-       double d = 0;
-       double* pDouble = &d;
-
-       BSTR bstr = NULL;
-       int off, i = 0;
-       OLECHAR* pOleChar[NB_OLE_STRINGS];
-
-       for (i=0; i<NB_OLE_STRINGS;i++) {
-               pOleChar[i]=AtoW(_pTestStrA[i]);
-       }
-       lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT );
-
-       /* Start testing the Low-Level API ( the coercions )
-        */
-    hdll=LoadLibraryA("netapi32.dll");
-    pVarI1FromBool=(void*)GetProcAddress(hdll,"VarI1FromBool");
-    pVarI1FromDate=(void*)GetProcAddress(hdll,"VarI1FromDate");
-    pVarI1FromI4=(void*)GetProcAddress(hdll,"VarI1FromI4");
-    pVarI1FromR8=(void*)GetProcAddress(hdll,"VarI1FromR8");
-    pVarI1FromStr=(void*)GetProcAddress(hdll,"VarI1FromStr");
-    pVarI1FromUI1=(void*)GetProcAddress(hdll,"VarI1FromUI1");
-
-    pVarI2FromUI2=(void*)GetProcAddress(hdll,"VarI2FromUI2");
-
-    pVarUI2FromBool=(void*)GetProcAddress(hdll,"VarUI2FromBool");
-    pVarUI2FromDate=(void*)GetProcAddress(hdll,"VarUI2FromDate");
-    pVarUI2FromI2=(void*)GetProcAddress(hdll,"VarUI2FromI2");
-    pVarUI2FromI4=(void*)GetProcAddress(hdll,"VarUI2FromI4");
-    pVarUI2FromR8=(void*)GetProcAddress(hdll,"VarUI2FromR8");
-    pVarUI2FromStr=(void*)GetProcAddress(hdll,"VarUI2FromStr");
-
-    pVarUI4FromBool=(void*)GetProcAddress(hdll,"VarUI4FromBool");
-    pVarUI4FromDate=(void*)GetProcAddress(hdll,"VarUI4FromDate");
-    pVarUI4FromI2=(void*)GetProcAddress(hdll,"VarUI4FromI2");
-    pVarUI4FromR8=(void*)GetProcAddress(hdll,"VarUI4FromR8");
-    pVarUI4FromStr=(void*)GetProcAddress(hdll,"VarUI4FromStr");
-
-       /* unsigned char from...
-        */
-       trace( "======== Testing VarUI1FromXXX ========\n");
-
-#define XOK "should return S_OK\n"
-#define XOV "should return DISP_E_OVERFLOW\n"
-       /* Crashes on Win95: VarUI1FromI2( 0, NULL ) */
-
-       ok(VarUI1FromStr(NULL, lcid, 0, pByte) == DISP_E_TYPEMISMATCH,"should return DISP_E_TYPEMISMATCH");
-       ok(S_OK == VarUI1FromI2( 0, pByte ), XOK);
-       ok(*pByte == 0,"should give 0 byte value");
-
-       ok(S_OK == VarUI1FromI2( 69, pByte ), XOK);
-       ok(*pByte == 69,"should give 69 byte value");
-
-       ok(S_OK == VarUI1FromI2( 70, pByte ), XOK);
-       ok(*pByte == 70,"should give 70 byte value");
-
-       ok(S_OK == VarUI1FromI2( 128, pByte ), XOK);
-       ok(*pByte == 128,"should give 128 byte value");
-
-       ok(S_OK == VarUI1FromI2( 255, pByte ), XOK);
-       ok(*pByte == 255,"should give 255 byte value");
-
-       ok(DISP_E_OVERFLOW == VarUI1FromI2( 256, pByte ), XOV);
-       ok(DISP_E_OVERFLOW == VarUI1FromI2( 257, pByte ), XOV);
-
-       ok(S_OK == VarUI1FromR8( 0.0, pByte ), XOK);
-       ok(*pByte == 0,"0.0 float should be converted to 0");
-
-       ok(S_OK == VarUI1FromR8( 69.33, pByte ), XOK);
-       ok(*pByte == 0x45, "expected 69 (hex 0x45) as byte value");
-
-       ok(S_OK == VarUI1FromR8( 69.66, pByte ), XOK);
-       ok(*pByte == 0x46, "expected 70 (hex 0x46) as byte value");
-
-       ok(DISP_E_OVERFLOW == VarUI1FromR8( -69.33, pByte ), XOV);
-       ok(DISP_E_OVERFLOW == VarUI1FromR8( -69.66, pByte ), XOV);
-
-       ok(S_OK == VarUI1FromR8( -0.5, pByte ), XOK);
-       ok(*pByte == 0,"-0.5 should give return 0");
-
-       ok(DISP_E_OVERFLOW == VarUI1FromR8( -0.51, pByte ), XOV);
-
-       ok(S_OK == VarUI1FromR8( -0.49, pByte ), XOK);
-       ok(*pByte == 0,"-0.49 should give return 0");
-
-       ok(S_OK == VarUI1FromR8( 0.5, pByte ), XOK);
-       ok(*pByte == 0,"0.5 should give return 0");
-
-       ok(S_OK == VarUI1FromR8( 0.51, pByte ), XOK);
-       ok(*pByte == 1,"0.51 should give return 1");
-
-       ok(S_OK == VarUI1FromR8( 0.49, pByte ), XOK);
-       ok(*pByte == 0,"0.49 should give return 0");
-
-       ok(S_OK == VarUI1FromDate( 0.0, pByte ), XOK);
-       ok(*pByte == 0,"0.0 date should give return 0");
-
-       ok(S_OK == VarUI1FromDate( 69.33, pByte ), XOK);
-       ok(*pByte == 0x45,"69.33 date should give return 0x45");
-
-       ok(S_OK == VarUI1FromDate( 69.66, pByte ), XOK);
-       ok(*pByte == 0x46,"69.66 date should give return 0x46");
-
-       ok(DISP_E_OVERFLOW == VarUI1FromDate( -69.33, pByte ), XOV);
-
-       ok(DISP_E_OVERFLOW == VarUI1FromDate( -69.66, pByte ), XOV);
-
-       ok(S_OK == VarUI1FromBool( VARIANT_TRUE, pByte ), XOK);
-       ok(*pByte == 0xff, "true should be converted to 0xff");
-
-       ok(S_OK == VarUI1FromBool( VARIANT_FALSE, pByte ), XOK);
-       ok(*pByte == 0, "false should be converted to 0");
-
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pByte= 42;
-            rc=VarUI1FromStr( pOleChar[i], lcid, 0, pByte );
-            ok(rc == strrets_U1[i].error,
-               "VarUI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_U1[i].error);
-            if (rc == 0 && strrets_U1[i].error == 0) {
-                ok(*pByte == strrets_U1[i].retval,
-                   "VarUI1FromStr([%d]=\"%s\") got %02x instead of %02x",
-                   i,_pTestStrA[i],*pByte,strrets_U1[i].retval);
-            }
-       }
-
-       /* unsigned short from ... */
-       trace( "======== Testing VarUI2FromXXX ========\n");
-
-    if (pVarUI2FromI2) {
-        ok(DISP_E_OVERFLOW == pVarUI2FromI2( -1, pUShort ), XOV);
-        ok(S_OK == pVarUI2FromI2( 0, NULL ), XOK);
-
-        ok(S_OK == pVarUI2FromI2( 0, pUShort ), XOK);
-        ok(*pUShort == 0,"0 should be 0");
-        ok(S_OK == pVarUI2FromI2( 69, pUShort ), XOK);
-        ok(*pUShort == 69,"69 should be 69");
-        ok(S_OK == pVarUI2FromI2( 70, pUShort ), XOK);
-        ok(*pUShort == 70,"70 should be 70");
-
-        ok(S_OK == pVarUI2FromI2( 128, pUShort ), XOK);
-        ok(*pUShort == 128,"128 should be 128");
-    }
-
-    if (pVarUI2FromI4) {
-        ok(S_OK == pVarUI2FromI4( 65535, pUShort ), XOK);
-        ok(*pUShort == 65535,"65535 should be 65535");
-        ok(DISP_E_OVERFLOW == pVarUI2FromI4( 65536, pUShort ), XOV);
-        ok(DISP_E_OVERFLOW == pVarUI2FromI4( 65537, pUShort ), XOV);
-    }
-
-    if (pVarUI2FromR8) {
-        ok(S_OK == pVarUI2FromR8( 0.0, pUShort ), XOK);
-        ok(*pUShort == 0,"0.0 should be 0");
-        ok(S_OK == pVarUI2FromR8( 69.33, pUShort ), XOK);
-        ok(*pUShort == 69,"69.33 should be 69");
-        ok(S_OK == pVarUI2FromR8( 69.66, pUShort ), XOK);
-        ok(*pUShort == 70,"69.66 should be 70");
-
-        ok(DISP_E_OVERFLOW == pVarUI2FromR8( -69.33, pUShort ), XOV);
-        ok(DISP_E_OVERFLOW == pVarUI2FromR8( -69.66, pUShort ), XOV);
-
-        ok(S_OK == pVarUI2FromR8( -0.5, pUShort ), XOK);
-        ok(*pUShort == 0, "-0.5 -> 0");
-        ok(DISP_E_OVERFLOW == pVarUI2FromR8( -0.51, pUShort ), XOV);
-        ok(S_OK == pVarUI2FromR8( -0.49, pUShort ), XOK);
-        ok(*pUShort == 0, "-0.49 -> 0");
-
-        ok(S_OK == pVarUI2FromR8( 0.5, pUShort ), XOK);
-        ok(*pUShort == 0,"0.5 should be 0");
-        ok(S_OK == pVarUI2FromR8( 0.51, pUShort ), XOK);
-        ok(*pUShort == 1,"0.51 should be 1");
-        ok(S_OK == pVarUI2FromR8( 0.49, pUShort ), XOK);
-        ok(*pUShort == 0,"0.49 should be 0");
-    }
-
-    if (pVarUI2FromDate) {
-        ok(S_OK == pVarUI2FromDate( 0.0, pUShort ), XOK);
-        ok(*pUShort == 0,"0.0 should be 0");
-        ok(S_OK == pVarUI2FromDate( 69.33, pUShort ), XOK);
-        ok(*pUShort == 69,"69.33 should be 69");
-        ok(S_OK == pVarUI2FromDate( 69.66, pUShort ), XOK);
-        ok(*pUShort == 70,"69.66 should be 70");
-        ok(DISP_E_OVERFLOW == pVarUI2FromDate( -69.33, pUShort ), XOV);
-        ok(DISP_E_OVERFLOW == pVarUI2FromDate( -69.66, pUShort ), XOV);
-    }
-
-    if (pVarUI2FromBool) {
-        ok(S_OK == pVarUI2FromBool( VARIANT_TRUE, pUShort ), XOK);
-        ok(*pUShort == 65535,"TRUE should be 65535");
-        ok(S_OK == pVarUI2FromBool( VARIANT_FALSE, pUShort ), XOK);
-        ok(*pUShort == 0,"FALSE should be 0");
-    }
-
-    if (pVarUI2FromStr) {
-        ok(DISP_E_TYPEMISMATCH == pVarUI2FromStr( NULL, lcid, 0, pUShort ), "should return DISP_E_TYPEMISMATCH");
-
-        for (i = 0; i < NB_OLE_STRINGS; i++)
-        {
-            *pUShort=42;
-            rc=pVarUI2FromStr( pOleChar[i], lcid, 0, pUShort );
-            ok(rc == strrets_U2[i].error,
-               "VarUI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_U2[i].error);
-            if (rc == 0 && strrets_U2[i].error == 0) {
-                ok(*pUShort == strrets_U2[i].retval,
-                   "VarUI2FromStr([%d]=\"%s\") got %u instead of %u",
-                   i,_pTestStrA[i],*pUShort,strrets_U2[i].retval);
-            }
-        }
-    }
-
-       /* unsigned long from ...
-        */
-       trace( "======== Testing VarUI4FromXXX ========\n");
-
-    if (pVarUI4FromI2) {
-        ok(S_OK == pVarUI4FromI2( 0, NULL ), XOK);
-
-        ok(S_OK == pVarUI4FromI2( 0, pULong ), XOK);
-        ok(*pULong == 0,"0 should be 0");
-        ok(S_OK == pVarUI4FromI2( 69, pULong ), XOK);
-        ok(*pULong == 69,"69 should be 69");
-
-        ok(S_OK == pVarUI4FromI2( 70, pULong ), XOK);
-        ok(*pULong == 70,"70 should be 70");
-
-        ok(S_OK == pVarUI4FromI2( 128, pULong ), XOK);
-        ok(*pULong == 128,"128 should be 128");
-        ok(S_OK == pVarUI4FromI2( 255, pULong ), XOK);
-        ok(*pULong == 255,"255 should be 255");
-    }
-
-    if (pVarUI4FromR8) {
-        ok(S_OK == pVarUI4FromR8( 4294967295.0, pULong ), XOK);
-        ok(*pULong == 4294967295U,"4294967295.0 should be 4294967295");
-        ok(DISP_E_OVERFLOW == pVarUI4FromR8( 4294967296.0, pULong ), XOV);
-
-        ok(S_OK == pVarUI4FromR8( 0.0, pULong ), XOK);
-        ok(*pULong == 0,"0 should be 0");
-        ok(S_OK == pVarUI4FromR8( 69.33, pULong ), XOK);
-        ok(*pULong == 69,"69.33 should be 69");
-        ok(S_OK == pVarUI4FromR8( 69.66, pULong ), XOK);
-        ok(*pULong == 70,"69.66 should be 70");
-        ok(DISP_E_OVERFLOW == pVarUI4FromR8( -69.33, pULong ), XOV);
-        ok(DISP_E_OVERFLOW == pVarUI4FromR8( -69.66, pULong ), XOV);
-
-        ok(S_OK == pVarUI4FromR8( -0.5, pULong ), XOK);
-        ok(*pULong == 0,"-0.5 should be 0");
-
-        ok(DISP_E_OVERFLOW == pVarUI4FromR8( -0.51, pULong ), XOV);
-
-        ok(S_OK == pVarUI4FromR8( -0.49, pULong ), XOK);
-        ok(*pULong == 0,"-0.49 should be 0");
-
-        ok(S_OK == pVarUI4FromR8( 0.5, pULong ), XOK);
-        ok(*pULong == 0,"0.5 should be 0");
-        ok(S_OK == pVarUI4FromR8( 0.51, pULong ), XOK);
-        ok(*pULong == 1,"0.51 should be 1");
-        ok(S_OK == pVarUI4FromR8( 0.49, pULong ), XOK);
-        ok(*pULong == 0,"0.49 should be 0");
-    }
-
-    if (pVarUI4FromDate) {
-        ok(S_OK == pVarUI4FromDate( 0.0, pULong ), XOK);
-        ok(*pULong == 0,"0.0 should be 0");
-        ok(S_OK == pVarUI4FromDate( 69.33, pULong ), XOK);
-        ok(*pULong == 69,"69.33 should be 69");
-        ok(S_OK == pVarUI4FromDate( 69.66, pULong ), XOK);
-        ok(*pULong == 70,"69.66 should be 70");
-        ok(DISP_E_OVERFLOW == pVarUI4FromDate( -69.33, pULong ), XOV);
-        ok(DISP_E_OVERFLOW == pVarUI4FromDate( -69.66, pULong ), XOV);
-    }
-
-    if (pVarUI4FromBool) {
-        ok(S_OK == pVarUI4FromBool( VARIANT_TRUE, pULong ), XOK);
-        ok(*pULong == 4294967295U, "TRUE should be 4294967295");
-        ok(S_OK == pVarUI4FromBool( VARIANT_FALSE, pULong ), XOK);
-        ok(*pULong == 0, "FALSE should be 0");
-    }
-
-    if (pVarUI4FromStr) {
-        ok(DISP_E_TYPEMISMATCH == pVarUI4FromStr( NULL, lcid, 0, pULong ), "should erturn DISP_E_TYPEMISMATCH");
-        for (i = 0; i < NB_OLE_STRINGS; i++)
-        {
-            *pULong=42;
-            rc=pVarUI4FromStr( pOleChar[i], lcid, 0, pULong );
-            ok(rc == strrets_U4[i].error,
-               "VarUI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_U4[i].error);
-            if (rc == 0 && strrets_U4[i].error == 0) {
-                ok(*pULong == strrets_U4[i].retval,
-                   "VarUI4FromStr([%d]=\"%s\") got %lu instead of %lu",
-                   i,_pTestStrA[i],*pULong,strrets_U4[i].retval);
-            }
-        }
-    }
-
-       /* CHAR from ...
-        */
-       trace( "======== Testing VarI1FromXXX ========\n");
-
-    if (pVarI1FromBool) {
-        ok(S_OK == pVarI1FromBool( VARIANT_TRUE, pByte ), XOK);
-        ok(*pByte == 0xff,"true should be 0xff");
-
-        ok(S_OK == pVarI1FromBool( VARIANT_TRUE, pChar ), XOK);
-        ok(*pChar == -1, "TRUE should be -1");
-
-        ok(S_OK == pVarI1FromBool( VARIANT_FALSE, pChar ), XOK);
-        ok(*pChar == 0, "FALSE should be 0");
-    }
-
-    if (pVarI1FromUI1) {
-        ok(DISP_E_OVERFLOW == pVarI1FromUI1( (unsigned char)32767, pChar ), XOV);
-        ok(*pChar == 0, "should still be 0");
-        ok(DISP_E_OVERFLOW == pVarI1FromUI1( (unsigned char)65535, pChar ), XOV);
-        ok(*pChar == 0, "should still be 0");
-    }
-
-    if (pVarI1FromI4) {
-        ok(DISP_E_OVERFLOW == pVarI1FromI4( 32767, pChar ), XOV);
-        ok(*pChar == 0, "should still be 0");
-        ok(DISP_E_OVERFLOW == pVarI1FromI4( 32768, pChar ), XOV);
-        ok(*pChar == 0, "should still be 0");
-        ok(DISP_E_OVERFLOW == pVarI1FromI4( -32768, pChar ), XOV);
-        ok(*pChar == 0, "should still be 0");
-        ok(DISP_E_OVERFLOW == pVarI1FromI4( -32769, pChar ), XOV);
-        ok(*pChar == 0, "should still be 0");
-    }
-
-    if (pVarI1FromR8) {
-        ok(S_OK == pVarI1FromR8( 69.33, pChar ), XOK);
-        ok(*pChar == 69, "69.33 should be 69");
-        ok(S_OK == pVarI1FromR8( 69.66, pChar ), XOK);
-        ok(*pChar == 70, "69.66 should be 70");
-
-        ok(S_OK == pVarI1FromR8( -69.33, pChar ), XOK);
-        ok(*pChar == -69, "-69.33 should be -69");
-        ok(S_OK == pVarI1FromR8( -69.66, pChar ), XOK);
-        ok(*pChar == -70, "-69.66 should be -70");
-    }
-
-    if (pVarI1FromDate) {
-        ok(S_OK == pVarI1FromDate( -69.66, pChar ), XOK);
-        ok(*pChar == -70, "-69.66 should be -70");
-    }
-
-    if (pVarI1FromStr) {
-        for (i = 0; i < NB_OLE_STRINGS; i++)
-        {
-            *pChar=42;
-            rc=pVarI1FromStr( pOleChar[i], lcid, 0, pChar );
-            ok(rc == strrets_I1[i].error,
-               "VarI1FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_I1[i].error);
-            if (rc == 0 && strrets_I1[i].error == 0) {
-                ok(*pChar == strrets_I1[i].retval,
-                   "VarI1FromStr([%d]=\"%s\") got %d instead of %d",
-                   i,_pTestStrA[i],*pChar,strrets_I1[i].retval);
-            }
-        }
-    }
-
-       /* short from ...
-        */
-       trace( "======== Testing VarI2FromXXX ========\n");
-
-    if (pVarI2FromUI2) {
-        ok(S_OK == pVarI2FromUI2( 32767, pShort ), XOK);
-        ok(*pShort == 32767, "should be 32767");
-        ok(DISP_E_OVERFLOW == pVarI2FromUI2( 65535, pShort ), XOV);
-        ok(*pShort == 32767, "pShort should be unchanged");
-    }
-
-       ok(S_OK == VarI2FromI4( 32767, pShort ), XOK);
-       ok(*pShort == 32767, "should be 32767");
-       ok(DISP_E_OVERFLOW == VarI2FromI4( 32768, pShort ), XOV);
-       ok(*pShort == 32767, "should still be 32767");
-       ok(S_OK == VarI2FromI4( -32768, pShort ), XOK);
-       ok(*pShort == -32768, "should be -32768");
-       ok(DISP_E_OVERFLOW == VarI2FromI4( -32769, pShort ), XOV);
-       ok(*pShort == -32768, "should still be -32768");
-
-       ok(S_OK == VarI2FromR8( 69.33, pShort ), XOK);
-       ok(*pShort == 69, "should be 69");
-       ok(S_OK == VarI2FromR8( 69.66, pShort ), XOK);
-       ok(*pShort == 70, "should be 70");
-       ok(S_OK == VarI2FromR8( -69.33, pShort ), XOK);
-       ok(*pShort == -69, "should be -69");
-       ok(S_OK == VarI2FromR8( -69.66, pShort ), XOK);
-       ok(*pShort == -70, "should be -70");
-       ok(S_OK == VarI2FromDate( -69.66, pShort ), XOK);
-       ok(*pShort == -70, "should be -70");
-
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pShort=42;
-            rc=VarI2FromStr( pOleChar[i], lcid, 0, pShort );
-            ok(rc == strrets_I2[i].error,
-               "VarI2FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_I2[i].error);
-            if (rc == 0 && strrets_I2[i].error == 0) {
-                ok(*pShort == strrets_I2[i].retval,
-                   "VarI2FromStr([%d]=\"%s\") got %d instead of %d",
-                   i,_pTestStrA[i],*pShort,strrets_I2[i].retval);
-            }
-       }
-
-       /* long from ...
-        */
-       trace( "======== Testing VarI4FromXXX ========\n");
-
-       ok(S_OK == VarI4FromI2( 3, (long*)pInt ), XOK);
-       ok(*pInt == 3,"should be 3");
-
-       ok(S_OK == VarI4FromR8( 69.33, pLong ), XOK);
-       ok(*pLong == 69,"should be 69");
-       ok(S_OK == VarI4FromR8( 69.66, pLong ), XOK);
-       ok(*pLong == 70,"should be 70");
-       ok(S_OK == VarI4FromR8( -69.33, pLong ), XOK);
-       ok(*pLong == -69,"should be -69");
-       ok(S_OK == VarI4FromR8( -69.66, pLong ), XOK);
-       ok(*pLong == -70,"should be -70");
-
-       ok(S_OK == VarI4FromR8( 2147483647.0, pLong ), XOK);
-       ok(*pLong == 2147483647,"should be 2147483647");
-       ok(DISP_E_OVERFLOW == VarI4FromR8( 2147483648.0, pLong ), XOV);
-       ok(*pLong == 2147483647,"should still be 2147483647");
-
-       ok(S_OK == VarI4FromR8( -2147483647.0, pLong ), XOK);
-       ok(*pLong == -2147483647,"should be -2147483647");
-       ok(S_OK == VarI4FromR8( -2147483648.0, pLong ), XOK);
-       ok(*pLong == 0x80000000L,"should be -2147483648");
-       ok(DISP_E_OVERFLOW == VarI4FromR8( -2147483649.0, pLong ), XOV);
-       ok(*pLong == 0x80000000L,"should still be -2147483648");
-       ok(DISP_E_OVERFLOW == VarI4FromDate( -2147483649.0, pLong ), XOV);
-       ok(*pLong == 0x80000000L,"should still be -2147483648");
-
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pLong=42;
-            rc=VarI4FromStr( pOleChar[i], lcid, 0, pLong );
-            ok(rc == strrets_I4[i].error,
-               "VarI4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_I4[i].error);
-            if (rc == 0 && strrets_I4[i].error == 0) {
-                ok(*pLong == strrets_I4[i].retval,
-                   "VarI4FromStr([%d]=\"%s\") got %ld instead of %ld",
-                   i,_pTestStrA[i],*pLong,strrets_I4[i].retval);
-            }
-       }
-
-       /* float from ...
-        */
-       trace( "======== Testing VarR4FromXXX ========\n");
-
-       ok(S_OK == VarR4FromI4( 16777216, pFloat ), XOK);
-       ok(16777216.0 == *pFloat,"should be 16777216.0");
-
-       ok(S_OK == VarR4FromI4( 16777217, pFloat ), XOK);
-       ok(16777216.0 == *pFloat,"should be 16777216.0");
-       ok(S_OK == VarR4FromI4( -16777216, pFloat ), XOK);
-       ok(-16777216.0 == *pFloat,"should be -16777216.0");
-       ok(S_OK == VarR4FromI4( -16777217, pFloat ), XOK);
-       ok(-16777216.0 == *pFloat,"should be -16777216.0");
-
-       ok(S_OK == VarR4FromR8( 16777216.0, pFloat ), XOK);
-       ok(16777216.0 == *pFloat,"should be 16777216.0");
-       ok(S_OK == VarR4FromR8( 16777217.0, pFloat ), XOK);
-       ok(16777216.0 == *pFloat,"should be 16777216.0");
-       ok(S_OK == VarR4FromR8( -16777216.0, pFloat ), XOK);
-       ok(-16777216.0 == *pFloat,"should be -16777216.0");
-       ok(S_OK == VarR4FromR8( -16777217.0, pFloat ), XOK);
-       ok(-16777216.0 == *pFloat,"should be -16777216.0");
-
-       ok(S_OK == VarR4FromR8( 16777218e31, pFloat ), XOK);
-       ok(*pFloat == 167772177736353110000000000000000000000.000000,
-               "should be 167772177736353110000000000000000000000.000000");
-       ok(DISP_E_OVERFLOW == VarR4FromR8( 16777218e32, pFloat ), XOV);
-       ok(*pFloat == 167772177736353110000000000000000000000.000000,
-               "should still be 167772177736353110000000000000000000000.000000");
-       ok(S_OK == VarR4FromDate( 16777218e31, pFloat ), XOK);
-       ok(*pFloat == 167772177736353110000000000000000000000.000000,
-               "should be 167772177736353110000000000000000000000.000000");
-
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pFloat=42.0;
-            rc=VarR4FromStr( pOleChar[i], lcid, 0, pFloat );
-            ok(rc == strrets_R4[i].error,
-                   "VarR4FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-                   i,_pTestStrA[i],rc,strrets_R4[i].error);
-            if (rc == 0 && strrets_R4[i].error == 0) {
-                ok(*pFloat == strrets_R4[i].retval,
-                   "VarR4FromStr([%d]=\"%s\")  got %f instead of %f",
-                   i,_pTestStrA[i],*pFloat,strrets_R4[i].retval);
-            }
-       }
-
-       /* double from ...
-        */
-       trace( "======== Testing VarR8FromXXX ========\n");
-
-       ok(S_OK == VarR8FromDate( 900719925474099.0, pDouble ), XOK);
-       ok(*pDouble == 900719925474099.000000,"should be 900719925474099.000000\n");
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pDouble=42.0;
-            rc=VarR8FromStr( pOleChar[i], lcid, 0, pDouble );
-            ok(rc == strrets_R8[i].error,
-               "VarR8FromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_R8[i].error);
-            if (rc == 0 && strrets_R8[i].error == 0) {
-                ok(*pDouble == strrets_R8[i].retval,
-                   "VarR8FromStr([%d]=\"%s\") got %.15f instead of %.15f",
-                   i,_pTestStrA[i],*pDouble,strrets_R8[i].retval);
-            }
-       }
-
-       /* date from ...
-        */
-       trace( "======== Testing VarDateFromXXX ========\n");
-
-       ok(S_OK == VarDateFromI4( 2958465, pDouble ), XOK);
-       ok(*pDouble == 2958465.000000,"should be 2958465.000000");
-    rc=VarDateFromI4( 2958466, pDouble );
-    ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
-       "got %lx",rc);
-       ok(*pDouble == 2958465.000000,"should still be 2958465.000000");
-       ok(S_OK == VarDateFromI4( -657434, pDouble ), XOK);
-       ok(*pDouble == -657434.000000,"should be -657434.000000");
-    rc=VarDateFromI4( -657435, pDouble );
-    ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
-       "got %lx",rc);
-       ok(*pDouble == -657434.000000,"should still be -657434.000000");
-
-       ok(S_OK == VarDateFromR8( 2958465.9999, pDouble ), XOK);
-       ok(*pDouble == 2958465.999900, "should be 2958465.999900");
-    rc=VarDateFromR8( 2958466, pDouble );
-    ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
-       "got %lx",rc);
-       ok(*pDouble == 2958465.999900, "should still be 2958465.999900");
-       ok(S_OK == VarDateFromR8( -657434.9999, pDouble ), XOK);
-       ok(*pDouble == -657434.999900,"should be -657434.999900");
-    rc=VarDateFromR8( -657435, pDouble );
-    ok(rc==DISP_E_OVERFLOW || rc==DISP_E_TYPEMISMATCH /* Win95 */,
-       "got %lx",rc);
-       ok(*pDouble == -657434.999900,"should still be -657434.999900");
-
-       ok(S_OK == VarDateFromR8( 0.0, pDouble ), XOK);
-       ok(*pDouble == 0.0,"0.0 should be 0.0");
-       ok(S_OK == VarDateFromR8( 1.0, pDouble ), XOK);
-       ok(*pDouble == 1.0,"1.0 should be 1.0");
-       ok(S_OK == VarDateFromR8( 2.25, pDouble ), XOK);
-       ok(*pDouble == 2.25,"2.25 should be 2.25");
-       ok(S_OK == VarDateFromR8( -2.0, pDouble ), XOK);
-       ok(*pDouble == -2.0,"-2.0 should be -2.0");
-
-       /* Need some parsing function in Linux to emulate this...
-        * Still in progess.
-        */
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pDouble=42.0;
-            if (i == 34) continue;  /* result for this one depends on the current year */
-            rc=VarDateFromStr( pOleChar[i], lcid, LOCALE_NOUSEROVERRIDE, pDouble );
-            ok(i == 94 /* FIXME: Bug in native */ || rc == strrets_DATE[i].error,
-               "VarDateFromStr([%d]=\"%s\") rc= %lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_DATE[i].error);
-            if (rc == 0 && strrets_DATE[i].error == 0) {
-               ok(EQ_DOUBLE(*pDouble,strrets_DATE[i].retval),
-                  "VarDateFromStr([%d]=\"%s\") got %.15f instead of %.15f",
-                  i,_pTestStrA[i],*pDouble,strrets_DATE[i].retval);
-            }
-       }
-       /* bool from ...
-        */
-       trace( "======== Testing VarBoolFromXXX ========\n");
-
-       ok(S_OK == VarBoolFromI4( 0, pBool ), XOK);
-       ok(VARIANT_FALSE == *pBool, "expected FALSE");
-       ok(S_OK == VarBoolFromI4( 1, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromI4( -1, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromI4( 2, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-
-       ok(S_OK == VarBoolFromUI1( ' ', pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromUI1( '\0', pBool ), XOK);
-       ok(VARIANT_FALSE == *pBool, "expected FALSE");
-       ok(S_OK == VarBoolFromUI1( 0x0000, pBool ), XOK);
-       ok(VARIANT_FALSE == *pBool, "expected FALSE");
-       ok(S_OK == VarBoolFromUI1( (unsigned char)0xFFF, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromUI1( (unsigned char)0xFFFF, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-
-       ok(S_OK == VarBoolFromR8( 0.0, pBool ), XOK);
-       ok(VARIANT_FALSE == *pBool, "expected FALSE");
-       ok(S_OK == VarBoolFromR8( 1.1, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromR8( 0.5, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromR8( 0.49, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromR8( 0.51, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromR8( -0.5, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromR8( -0.49, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-       ok(S_OK == VarBoolFromR8( -0.51, pBool ), XOK);
-       ok(VARIANT_TRUE == *pBool, "expected TRUE");
-
-
-       for (i = 0; i < NB_OLE_STRINGS; i++)
-       {
-            *pBool=42;
-            rc=VarBoolFromStr( pOleChar[i], lcid, 0, pBool );
-            ok(rc == strrets_B[i].error,
-               "VarBoolFromStr([%d]=\"%s\") rc=%lx instead of %lx",
-               i,_pTestStrA[i],rc,strrets_B[i].error);
-            if (rc == 0 && strrets_B[i].error == 0) {
-                ok(*pBool == strrets_B[i].retval,
-                   "VarBoolFromStr([%d]=\"%s\") got %x instead of %x",
-                   i,_pTestStrA[i],*pBool,strrets_B[i].retval);
-            }
-       }
-
-       /* BSTR from ...
-        */
-       trace( "======== Testing VarBSTRFromXXX ========\n");
-
-       /* integers...
-        */
-    if (pVarBstrFromI1) {
-        ok(S_OK == pVarBstrFromI1( -100, 0, 0, &bstr ), XOK);
-        ok(!strcmp(WtoA(bstr),"\"-100\""),"should be string -100");
-    }
-
-       ok(S_OK == VarBstrFromUI1( 0x5A, 0, 0, &bstr ), XOK);
-       ok(!strcmp(WtoA(bstr),"\"90\""),"should be string 90");
-       ok(S_OK == VarBstrFromI4( 2958465, 0, 0, &bstr ), XOK);
-       ok(!strcmp(WtoA(bstr),"\"2958465\""),"should be string 2958465");
-
-       /* reals...
-        */
-       off = 0;
-       d=0;
-       for( i=0; i<20; i++ )
-       {
-               char xval[80];
-               /* add an integer to the real number
-                */
-               d += ((i%9)+1) * pow( 10, i );
-
-               ok(S_OK == VarBstrFromR8( d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   d,strfromr8[off],WtoA(bstr));
-                off++;
-
-               ok(S_OK == VarBstrFromR8( -d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   -d,strfromr8[off],WtoA(bstr));
-                off++;
-       }
-       d=0;
-       for( i=0; i<20; i++ )
-       {
-               char xval[80];
-               /* add a decimal to the real number
-                */
-               d += ((i%9)+1) * pow( 10, (i*-1) );
-               ok(S_OK == VarBstrFromR8( d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   d,strfromr8[off],WtoA(bstr));
-                off++;
-               ok(S_OK == VarBstrFromR8( d-1, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   d-1,strfromr8[off],WtoA(bstr));
-                off++;
-               ok(S_OK == VarBstrFromR8( -d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   -d,strfromr8[off],WtoA(bstr));
-                off++;
-       }
-
-       d=0;
-       for( i=0; i<20; i++ )
-       {
-               char xval[80];
-               /* add an integer to the real number
-                */
-               d += ((i%9)+1) * pow( 10, i );
-               /* add a decimal to the real number
-                */
-               d += ((i%9)+1) * pow( 10, (i*-1) );
-               ok(S_OK == VarBstrFromR8( d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   d,strfromr8[off],WtoA(bstr));
-                        off++;
-               ok(S_OK == VarBstrFromR8( -d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "d is %.15f, should be cvt. to %s, but return val is %s",
-                   -d,strfromr8[off],WtoA(bstr));
-                        off++;
-       }
-
-       d=0;
-       for( i=0; i<10; i++ )
-       {
-               char xval[80];
-               /* add an integer to the real number
-                */
-               d += ((i%9)+1) * pow( 10, i );
-               ok(S_OK == VarBstrFromR4( (float)d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                   i,d,strfromr8[off],WtoA(bstr));
-                off++;
-               ok(S_OK == VarBstrFromR4( (float)-d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                   i,-d,strfromr8[off],WtoA(bstr));
-                off++;
-       }
-       d=0;
-       for( i=0; i<10; i++ )
-       {
-               char xval[80];
-               /* add a decimal to the real number
-                */
-               d += ((i%9)+1) * pow( 10, (i*-1) );
-               ok(S_OK == VarBstrFromR4( (float)d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                   i,d,strfromr8[off],WtoA(bstr));
-                off++;
-               ok(S_OK == VarBstrFromR4( (float)(d-1), lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-               ok(!strcmp(xval,WtoA(bstr)),
-                   "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                   i,d-1,strfromr8[off],WtoA(bstr));
-                off++;
-               ok(S_OK == VarBstrFromR4( (float)-d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-                ok(!strcmp(xval,WtoA(bstr)),
-                   "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                   i,-d,strfromr8[off],WtoA(bstr));
-                off++;
-       }
-
-       d=0;
-       for( i=0; i<10; i++ )
-       {
-        static int istodo[10]={0,0,0,0,0,1,0,0,0,0};
-           char xval[80];
-               /* add an integer to the real number
-                */
-               d += ((i%9)+1) * pow( 10, i );
-               /* add a decimal to the real number
-                */
-               d += ((i%9)+1) * pow( 10, (i*-1) );
-               ok(S_OK == VarBstrFromR4( (float)d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-        if (istodo[i]) {
-        /* Skip this test: The input value is 654322.23456.
-         * Native converts this to 654322.3, Wine to 654322.2
-         * I consider Wines behaviour to be correct and Native buggy.
-         */
-        } else {
-            ok(!strcmp(xval,WtoA(bstr)),
-                   "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                   i,d,strfromr8[off],WtoA(bstr));
-        }
-        off++;
-               ok(S_OK == VarBstrFromR4( (float)-d, lcid, 0, &bstr ), XOK);
-               sprintf(xval,"\"%s\"",strfromr8[off]);
-        if (istodo[i]) {
-        /* Skip this test, as above */
-        } else {
-                   ok(!strcmp(xval,WtoA(bstr)),
-                       "%d: d is %.8f, should be cvt. to %s, but return val is %s",
-                       i,-d,strfromr8[off],WtoA(bstr));
-        }
-        off++;
-       }
-
-       ok(S_OK == VarBstrFromBool( 0x00, lcid, 0, &bstr ), XOK);
-       ok(!strcmp(WtoA(bstr),"\"False\""),"should be 'False'");
-       ok(S_OK == VarBstrFromBool( 0xFF, lcid, 0, &bstr ), XOK);
-       ok(!strcmp(WtoA(bstr),"\"True\""),"should be 'True'");
-
-       ok(S_OK == VarBstrFromDate( 0.0, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(!strcmp(WtoA(bstr),"\"12:00:00 AM\""),
-       "should be '12:00:00 AM', but is %s\n",WtoA(bstr));
-
-       ok(S_OK == VarBstrFromDate( 3.34, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(strcmp(WtoA(bstr),"\"1/2/1900 8:09:36 AM\"")==0 ||
-       strcmp(WtoA(bstr),"\"1/2/00 8:09:36 AM\"")==0 /* Win95 */,
-       "should be '1/2/1900 8:09:36 AM', but is %s\n",WtoA(bstr));
-
-       ok(S_OK == VarBstrFromDate( 3339.34, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(strcmp(WtoA(bstr),"\"2/20/1909 8:09:36 AM\"")==0 ||
-       strcmp(WtoA(bstr),"\"2/20/09 8:09:36 AM\"")==0 /* Win95 */,
-       "should be '2/20/1909 8:09:36 AM', but is %s\n",WtoA(bstr));
-
-       ok(S_OK == VarBstrFromDate( 365.00, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(strcmp(WtoA(bstr),"\"12/30/1900\"")==0 ||
-       strcmp(WtoA(bstr),"\"12/30/00\"")==0 /* Win95 */,
-       "should be '12/30/1900', but is %s\n",WtoA(bstr));
-
-       ok(S_OK == VarBstrFromDate( 365.25, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(strcmp(WtoA(bstr),"\"12/30/1900 6:00:00 AM\"")==0 ||
-       strcmp(WtoA(bstr),"\"12/30/00 6:00:00 AM\"")==0 /* Win95 */,
-       "should be '12/30/1900 6:00:00 AM', but is %s\n",WtoA(bstr));
-
-       ok(S_OK == VarBstrFromDate( 1461.0, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(strcmp(WtoA(bstr),"\"12/31/1903\"")==0 ||
-       strcmp(WtoA(bstr),"\"12/31/03\"")==0 /* Win95 */,
-       "should be '12/31/1903', but is %s\n",WtoA(bstr));
-
-       ok(S_OK == VarBstrFromDate( 1461.5, lcid, LOCALE_NOUSEROVERRIDE, &bstr ), XOK);
-       ok(strcmp(WtoA(bstr),"\"12/31/1903 12:00:00 PM\"")==0 ||
-       strcmp(WtoA(bstr),"\"12/31/03 12:00:00 PM\"")==0 /* Win95 */,
-       "should be '12/31/1903 12:00:00 PM', but is %s\n",WtoA(bstr));
-
-       /* Test variant API...
-        */
-       trace( "======== Testing Hi-Level Variant API ========\n");
-
-       bstr = SysAllocString( pOleChar[4] );
-
-       VariantClear( &va );
-
-       VariantInit( &va );
-       VariantInit( &vb );
-       VariantInit( &vc );
-       VariantInit( &vd );
-       VariantInit( &ve );
-
-       V_VT(&va) = VT_BSTR;
-       V_UNION(&va,bstrVal) = bstr;
-       ok(S_OK == VariantClear( &va ), XOK);
-       SysFreeString( bstr );
-       SysFreeString( bstr );
-
-       ok(S_OK == VariantCopy( &vb, &va ), XOK);
-       ok(S_OK == VariantClear( &vb ), XOK);
-       ok(S_OK == VariantClear( &va ), XOK);
-
-       V_VT(&va) = VT_R8;
-       d = 4.123;
-       V_UNION(&va,dblVal) = d;
-       ok(S_OK == VariantCopy( &va, &va ), XOK);
-       ok(V_R8(&va) == 4.123,"should be 4.123");
-
-       V_VT(&va) = VT_R8 | VT_BYREF;
-       d = 31.123;
-       V_UNION(&va,pdblVal) = &d;
-       ok(S_OK == VariantCopyInd( &va, &va ), XOK);
-       ok(V_R8(&va) == 31.123,"should be 31.123");
-
-       V_VT(&va) = VT_R8;
-       d = 1.123;
-       V_UNION(&va,dblVal) = d;
-       ok(S_OK == VariantCopy( &vb, &va ), XOK);
-       ok(V_R8(&vb) == 1.123,"should be 1.123");
-
-       V_VT(&va) = VT_R8 | VT_BYREF;
-       d = 123.123;
-       V_UNION(&va,pdblVal) = &d;
-       ok(S_OK == VariantCopy( &vb, &va ), XOK);
-       ok(*(V_R8REF(&vb)) == 123.123,"should be 123.123");
-
-       V_VT(&va) = VT_R8 | VT_BYREF;
-       d = 111.2;
-       V_UNION(&va,pdblVal) = &d;
-       ok(S_OK == VariantCopyInd( &vb, &va ), XOK);
-       ok(V_R8(&vb) == 111.2,"should be 111.2");
-
-       V_VT(&va) = VT_R8 | VT_BYREF;
-       d = 1211.123453;
-       V_UNION(&va,pdblVal) = &d;
-       ok(S_OK == VariantChangeTypeEx( &va, &va, lcid, 0, VT_I2 ), XOK);
-       ok(V_VT(&va) == VT_I2,"should be type VT_I2");
-
-       V_VT(&va) = VT_I4;
-       V_UNION(&va,intVal) = 4;
-       ok(S_OK == VariantChangeTypeEx(&vb, &va, lcid, 0, VT_BSTR ), XOK);
-       ok(!strcmp(WtoA(V_BSTR(&vb)),"\"4\""),"should be 4");
-
-       V_VT(&va) = VT_DATE;
-       V_UNION(&va,date) = 34465.332431;
-       ok(S_OK == VariantChangeTypeEx(&vb, &va, lcid, VARIANT_NOUSEROVERRIDE, VT_BSTR ), XOK);
-       ok(strcmp(WtoA(V_BSTR(&vb)),"\"5/11/1994 7:58:42 AM\"")==0 ||
-       strcmp(WtoA(V_BSTR(&vb)),"\"5/11/94 7:58:42 AM\"")==0 /* Win95 */,
-       "should be 5/11/94 7:58:42 AM got %s",WtoA(V_BSTR(&vb)));
-
-       bstr = pOleChar[4];
-       V_VT(&va) = VT_BSTR;
-       V_UNION(&va,bstrVal) = bstr;
-       ok(S_OK == VariantChangeTypeEx(&vb, &va, lcid, 0, VT_R8 ), XOK);
-       ok(V_R8(&vb) == -0.490000,"should be -0.49");
-
-       V_VT(&vc) = VT_BSTR | VT_BYREF;
-       V_UNION(&vc,pbstrVal) = &bstr;
-       V_VT(&vb) = VT_VARIANT | VT_BYREF;
-       V_UNION(&vb,pvarVal) = &vc;
-       V_VT(&va) = VT_VARIANT | VT_BYREF;
-       V_UNION(&va,pvarVal) = &vb;
-       ok(E_INVALIDARG == VariantCopyInd( &vd, &va ), "expect E_INVALIDARG");
-
-       /* test what happens when bad vartypes are passed in */
-       trace( "======== Testing different VARTYPES ========\n" );
-
-       for( i=0; i<sizeof(vartypes)/sizeof(vartypes[0]); i++ )
-       {
-                   /* Trying to use variants that are set to be BSTR but
-                    * do not contain a valid pointer makes the program crash
-                    * in Windows so we will skip those. We do not need them
-                    * anyway to illustrate the behavior.
-                    */
-                   V_VT(&va) = vartypes[i].ind;
-                   d = 4.123;
-                   V_UNION(&va,dblVal) = d;
-                   rc = VariantCopyInd( &vb, &va );
-                       ok(vartypes[i].vcind1 == rc,
-                           "%d: vt %d, return value %lx, expected was %lx",
-                           i,vartypes[i].ind,rc,vartypes[i].vcind1);
-                   V_VT(&va) = vartypes[i].ind | VT_BYREF;
-                   d = 4.123;
-                   V_UNION(&va,pdblVal) = &d;
-                   rc = VariantCopyInd( &vb, &va );
-                       ok(vartypes[i].vcind2 == rc,
-                           "%d: vt %d, return value %lx, expected was %lx",
-                           i,vartypes[i].ind,rc,vartypes[i].vcind2);
-                   V_VT(&va) = VT_R8;
-                   d = 4.123;
-                   V_UNION(&va,dblVal) = d;
-                   rc = VariantChangeTypeEx( &vb, &va, lcid, 0, (VARTYPE)i );
-                       ok(vartypes[i].vcex1 == rc || rc == DISP_E_BADVARTYPE,
-                           "%d: vt %d, return value %lx, expected was %lx",
-                           i,vartypes[i].ind,rc,vartypes[i].vcex1);
-                   V_VT(&va) = VT_R8;
-                   d = 4.123;
-                   V_UNION(&va,dblVal) = d;
-                   rc = VariantChangeTypeEx( &vb, &va, lcid, 0, (VARTYPE)(i | VT_BYREF) );
-                       ok(vartypes[i].vcex2 == rc || rc == DISP_E_BADVARTYPE,
-                           "%d: vt %d, return value %lx, expected was %lx",
-                           i,vartypes[i].ind,rc,vartypes[i].vcex2);
-
-               V_VT(&va) = 99;
-               d = 4.123;
-               V_UNION(&va,dblVal) = d;
-               ok(DISP_E_BADVARTYPE == VariantClear( &va ), "should give DISP_E_BADVARTYPE");
-       }
-       VariantClear( &va );
-       VariantClear( &vb );
-       VariantClear( &vc );
-       VariantClear( &vd );
-       VariantClear( &ve );
-       /* There is alot of memory leaks but this is simply a test program.
-        */
-}
-
 static void test_VariantInit(void)
 {
   VARIANTARG v1, v2;
@@ -2770,14 +149,16 @@ static void test_VariantClear(void)
   V_VT(&v) = VT_UI4;
   V_UI4(&v) = ~0u;
   hres = VariantClear(&v);
-  ok(hres == S_OK && V_VT(&v) == VT_EMPTY, "VariantClear: Type set to %d\n", V_VT(&v));
+  ok((hres == S_OK && V_VT(&v) == VT_EMPTY) ||
+     (IS_ANCIENT && hres == DISP_E_BADVARTYPE && V_VT(&v) == VT_UI4),
+     "VariantClear: Type set to %d, res %08lx\n", V_VT(&v), hres);
   ok(V_UI4(&v) == ~0u, "VariantClear: Overwrote value\n");
 
   /* Test all possible V_VT values.
    * Also demonstrates that null pointers in 'v' are not dereferenced.
    * Individual variant tests should test VariantClear() with non-NULL values.
    */
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     VARTYPE vt;
 
@@ -2812,7 +193,7 @@ static void test_VariantCopy(void)
    */
 
   /* vSrc == vDst */
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
     {
@@ -2838,7 +219,7 @@ static void test_VariantCopy(void)
   memset(&vSrc, 0, sizeof(vSrc));
   V_VT(&vSrc) = VT_UI1;
 
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
     {
@@ -2862,7 +243,7 @@ static void test_VariantCopy(void)
   }
 
   /* Test that VariantClear() checks vSrc for validity before copying */
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
     {
@@ -2916,7 +297,7 @@ static void test_VariantCopyInd(void)
   memset(buffer, 0, sizeof(buffer));
 
   /* vSrc == vDst */
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     if (ExtraFlags[i] & VT_ARRAY)
       continue; /* Native crashes on NULL safearray */
@@ -2965,7 +346,7 @@ static void test_VariantCopyInd(void)
   V_VT(&vSrc) = VT_UI1|VT_BYREF;
   V_BYREF(&vSrc) = &buffer;
 
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
     {
@@ -2989,7 +370,7 @@ static void test_VariantCopyInd(void)
   }
 
   /* bad src */
-  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+  for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]) && !IS_ANCIENT; i++)
   {
     if (ExtraFlags[i] & VT_ARRAY)
       continue; /* Native crashes on NULL safearray */
@@ -3095,11 +476,13 @@ static void test_VariantCopyInd(void)
      "CopyInd(ref->ref): expected E_INVALIDARG, got 0x%08lx\n", hres);
 }
 
+static HRESULT (WINAPI *pVarParseNumFromStr)(OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
+
 /* Macros for converting and testing the result of VarParseNumFromStr */
 #define FAILDIG 255
 #define CONVERTN(str,dig,flags) MultiByteToWideChar(CP_ACP,0,str,-1,buff,sizeof(buff)); \
   memset(rgb, FAILDIG, sizeof(rgb)); memset(&np,-1,sizeof(np)); np.cDig = dig; np.dwInFlags = flags; \
-  hres = VarParseNumFromStr(buff,lcid,LOCALE_NOUSEROVERRIDE,&np,rgb)
+  hres = pVarParseNumFromStr(buff,lcid,LOCALE_NOUSEROVERRIDE,&np,rgb)
 #define CONVERT(str,flags) CONVERTN(str,sizeof(rgb),flags)
 #define EXPECT(a,b,c,d,e,f) ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
   if (hres == (HRESULT)S_OK) { \
@@ -3125,6 +508,8 @@ static void test_VarParseNumFromStr(void)
 
   /** No flags **/
 
+  CHECKPTR(VarParseNumFromStr);
+
   /* Consume a single digit */
   CONVERT("7", 0);
   EXPECT(1,0,0,1,0,0);
@@ -3474,12 +859,14 @@ static void test_VarParseNumFromStr(void)
   EXPECT2(5,1);
 }
 
+static HRESULT (WINAPI *pVarNumFromParseNum)(NUMPARSE*,BYTE*,ULONG,VARIANT*);
+
 /* Macros for converting and testing the result of VarNumFromParseNum */
 #define SETRGB(indx,val) if (!indx) memset(rgb, FAILDIG, sizeof(rgb)); rgb[indx] = val
 #undef CONVERT
 #define CONVERT(a,b,c,d,e,f,bits) \
     np.cDig = (a); np.dwInFlags = (b); np.dwOutFlags = (c); np.cchUsed = (d); \
-    np.nBaseShift = (e); np.nPwr10 = (f); hres = VarNumFromParseNum(&np, rgb, bits, &vOut)
+    np.nBaseShift = (e); np.nPwr10 = (f); hres = pVarNumFromParseNum(&np, rgb, bits, &vOut)
 #define EXPECT_OVERFLOW ok(hres == (HRESULT)DISP_E_OVERFLOW, "Expected overflow, hres = %08lx\n", hres)
 #define EXPECT_OK ok(hres == (HRESULT)S_OK, "Call failed, hres = %08lx\n", hres); \
   if (hres == (HRESULT)S_OK)
@@ -3515,6 +902,8 @@ static void test_VarNumFromParseNum(void)
   BYTE rgb[128];
   VARIANT vOut;
 
+  CHECKPTR(VarNumFromParseNum);
+    
   /* Convert the number 1 to different types */
   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_I1); EXPECT_I1(1);
   SETRGB(0, 1); CONVERT(1,0,0,1,0,0, VTBIT_UI1); EXPECT_UI1(1);
@@ -3867,8 +1256,8 @@ static const FMTRES VarFormat_results[] =
   { "Standard", "1.00", "0.00" },
   { "Scientific","1.00E+00", "0.00E+00" },
   { "True/False", "True", "False" },
-/*  { "On/Off", "On", "Off" },
-  { "Yes/No", "Yes", "No")}, */
+  { "On/Off", "On", "Off" },
+  { "Yes/No", "Yes", "No" },
   { "#", "1", "" },
   { "##", "1", "" },
   { "#.#", "1.", "." },
@@ -4121,7 +1510,7 @@ static void test_VarAbs(void)
     VARABS(R8,-1,R8,1);
     GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buff, sizeof(buff)/sizeof(char));
     if (buff[0] != '.' || buff[1])
-    { 
+    {
         trace("Skipping VarAbs(BSTR) as decimal separator is '%s'\n", buff);
         return;
     }
@@ -4166,7 +1555,6 @@ static void test_VarNot(void)
             V_VT(&v) = vt | ExtraFlags[i];
             V_VT(&vDst) = VT_EMPTY;
 
-            hres = pVarNot(&v,&vDst);
             switch (V_VT(&v))
             {
             case VT_I1:  case VT_UI1: case VT_I2:  case VT_UI2:
@@ -4227,29 +1615,382 @@ static void test_VarNot(void)
     VARNOT(CY,*pcy,I4,-2);
     }
 }
+static HRESULT (WINAPI *pVarSub)(LPVARIANT,LPVARIANT,LPVARIANT);
 
 static void test_VarSub(void)
 {
     VARIANT va, vb, vc;
     HRESULT hr;
 
+    CHECKPTR(VarSub);
+    
     V_VT(&va) = VT_DATE;
     V_DATE(&va) = 200000.0;
     V_VT(&vb) = VT_DATE;
     V_DATE(&vb) = 100000.0;
-    
-    hr = VarSub(&va, &vb, &vc);
+
+    hr = pVarSub(&va, &vb, &vc);
     ok(hr == S_OK,"VarSub of VT_DATE - VT_DATE failed with %lx\n", hr);
     ok(V_VT(&vc) == VT_R8,"VarSub of VT_DATE - VT_DATE returned vt 0x%x\n", V_VT(&vc));
     ok(((V_R8(&vc) >  99999.9) && (V_R8(&vc) < 100000.1)),"VarSub of VT_DATE - VT_DATE  should return 100000.0, but returned %g\n", V_R8(&vc));
     /* fprintf(stderr,"VarSub of 10000-20000 returned: %g\n", V_R8(&vc)); */
 }
 
+static HRESULT (WINAPI *pVarFix)(LPVARIANT,LPVARIANT);
+
+#define VARFIX(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
+        memset(&vDst,0,sizeof(vDst)); hres = pVarFix(&v,&vDst); \
+        ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
+        "VarFix: expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##rvt, (int)(rval), \
+        hres, V_VT(&vDst), (int)V_##rvt(&vDst))
+
+static void test_VarFix(void)
+{
+    static const WCHAR szNumMinus1[] = {'-','1','\0' };
+    HRESULT hres;
+    VARIANT v, vDst;
+    DECIMAL *pdec = &V_DECIMAL(&v);
+    CY *pcy = &V_CY(&v);
+    size_t i;
+
+    CHECKPTR(VarFix);
+
+    /* Test all possible V_VT values */
+    for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+    {
+        VARTYPE vt;
+
+        for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
+        {
+            HRESULT bFail = TRUE;
+
+            memset(&v, 0, sizeof(v));
+            V_VT(&v) = vt | ExtraFlags[i];
+            V_VT(&vDst) = VT_EMPTY;
+
+            switch (V_VT(&v))
+            {
+              case VT_UI1: case VT_I2: case VT_I4: case VT_R4:  case VT_R8:
+              case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
+              case VT_DATE: case VT_CY:
+                bFail = FALSE;
+                break;
+              case VT_I8:
+                if (HAVE_OLEAUT32_I8)
+                  bFail = FALSE;
+                break;
+            }
+
+            hres = pVarFix(&v,&vDst);
+            if (bFail)
+              ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
+                 "VarFix: expected failure, got 0x%lX vt %d|0x%X\n",
+                 hres, vt, ExtraFlags[i]);
+            else
+                 ok(hres == S_OK, "VarFix: expected S_OK, got 0x%lX vt %d|0x%X\n",
+                    hres, vt, ExtraFlags[i]);
+        }
+    }
+
+    VARFIX(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
+    VARFIX(BOOL,VARIANT_FALSE,I2,0);
+    VARFIX(BOOL,1,I2,1);
+    VARFIX(UI1,1,UI1,1);
+    VARFIX(I2,-1,I2,-1);
+    VARFIX(I4,-1,I4,-1);
+    if (HAVE_OLEAUT32_I8)
+    {
+        VARFIX(I8,-1,I8,-1);
+    }
+    VARFIX(R4,1.4,R4,1);
+    VARFIX(R4,1.5,R4,1);
+    VARFIX(R4,1.6,R4,1);
+    VARFIX(R4,-1.4,R4,-1);
+    VARFIX(R4,-1.5,R4,-1);
+    VARFIX(R4,-1.6,R4,-1);
+    /* DATE & R8 round as for R4 */
+    VARFIX(DATE,-1,DATE,-1);
+    VARFIX(R8,-1,R8,-1);
+    VARFIX(BSTR,(BSTR)szNumMinus1,R8,-1);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = pVarFix(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
+       "VarFix: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
+       hres, V_VT(&vDst), V_I2(&vDst));
+
+    V_VT(&v) = VT_NULL;
+    hres = pVarFix(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
+       "VarFix: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
+
+    V_VT(&v) = VT_DECIMAL;
+    pdec->u.s.sign = DECIMAL_NEG;
+    pdec->u.s.scale = 0;
+    pdec->Hi32 = 0;
+    pdec->u1.s1.Mid32 = 0;
+    pdec->u1.s1.Lo32 = 1;
+    hres = pVarFix(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&v, &vDst, sizeof(v)),
+       "VarFix: expected 0x0,%d,identical, got 0x%lX,%d\n", VT_DECIMAL,
+       hres, V_VT(&vDst));
+
+    /* FIXME: Test some fractional decimals when VarDecFix is implemented */
+
+    V_VT(&v) = VT_CY;
+    pcy->int64 = -10000;
+    hres = pVarFix(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
+       "VarFix: VT_CY wrong, hres=0x%lX\n", hres);
+
+    V_VT(&v) = VT_CY;
+    pcy->int64 = -16000;
+    hres = pVarFix(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
+       "VarFix: VT_CY wrong, hres=0x%lX\n", hres);
+}
+
+static HRESULT (WINAPI *pVarInt)(LPVARIANT,LPVARIANT);
+
+#define VARINT(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
+        memset(&vDst,0,sizeof(vDst)); hres = pVarInt(&v,&vDst); \
+        ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
+        "VarInt: expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##rvt, (int)(rval), \
+        hres, V_VT(&vDst), (int)V_##rvt(&vDst))
+
+static void test_VarInt(void)
+{
+    static const WCHAR szNumMinus1[] = {'-','1','\0' };
+    HRESULT hres;
+    VARIANT v, vDst;
+    DECIMAL *pdec = &V_DECIMAL(&v);
+    CY *pcy = &V_CY(&v);
+    size_t i;
+
+    CHECKPTR(VarInt);
+
+    /* Test all possible V_VT values */
+    for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+    {
+        VARTYPE vt;
+
+        for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
+        {
+            HRESULT bFail = TRUE;
+
+            memset(&v, 0, sizeof(v));
+            V_VT(&v) = vt | ExtraFlags[i];
+            V_VT(&vDst) = VT_EMPTY;
+
+            switch (V_VT(&v))
+            {
+              case VT_UI1: case VT_I2: case VT_I4: case VT_R4:  case VT_R8:
+              case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
+              case VT_DATE: case VT_CY:
+                bFail = FALSE;
+                break;
+              case VT_I8:
+                if (HAVE_OLEAUT32_I8)
+                  bFail = FALSE;
+                break;
+            }
+
+            hres = pVarInt(&v,&vDst);
+            if (bFail)
+              ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
+                 "VarInt: expected failure, got 0x%lX vt %d|0x%X\n",
+                 hres, vt, ExtraFlags[i]);
+            else
+                 ok(hres == S_OK, "VarInt: expected S_OK, got 0x%lX vt %d|0x%X\n",
+                    hres, vt, ExtraFlags[i]);
+        }
+    }
+
+    VARINT(BOOL,VARIANT_TRUE,I2,VARIANT_TRUE);
+    VARINT(BOOL,VARIANT_FALSE,I2,0);
+    VARINT(BOOL,1,I2,1);
+    VARINT(UI1,1,UI1,1);
+    VARINT(I2,-1,I2,-1);
+    VARINT(I4,-1,I4,-1);
+    if (HAVE_OLEAUT32_I8)
+    {
+        VARINT(I8,-1,I8,-1);
+    }
+    VARINT(R4,1.4,R4,1);
+    VARINT(R4,1.5,R4,1);
+    VARINT(R4,1.6,R4,1);
+    VARINT(R4,-1.4,R4,-2); /* Note these 3 are different from VarFix */
+    VARINT(R4,-1.5,R4,-2);
+    VARINT(R4,-1.6,R4,-2);
+    /* DATE & R8 round as for R4 */
+    VARINT(DATE,-1,DATE,-1);
+    VARINT(R8,-1,R8,-1);
+    VARINT(BSTR,(BSTR)szNumMinus1,R8,-1);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = pVarInt(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
+       "VarInt: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
+       hres, V_VT(&vDst), V_I2(&vDst));
+
+    V_VT(&v) = VT_NULL;
+    hres = pVarInt(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
+       "VarInt: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
+
+    V_VT(&v) = VT_DECIMAL;
+    pdec->u.s.sign = DECIMAL_NEG;
+    pdec->u.s.scale = 0;
+    pdec->Hi32 = 0;
+    pdec->u1.s1.Mid32 = 0;
+    pdec->u1.s1.Lo32 = 1;
+    hres = pVarInt(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL && !memcmp(&v, &vDst, sizeof(v)),
+       "VarInt: expected 0x0,%d,identical, got 0x%lX,%d\n", VT_DECIMAL,
+       hres, V_VT(&vDst));
+
+    /* FIXME: Test some fractional decimals when VarDecInt is implemented */
+
+    V_VT(&v) = VT_CY;
+    pcy->int64 = -10000;
+    hres = pVarInt(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -10000,
+       "VarInt: VT_CY wrong, hres=0x%lX\n", hres);
+
+    V_VT(&v) = VT_CY;
+    pcy->int64 = -11000;
+    hres = pVarInt(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == -20000,
+       "VarInt: VT_CY wrong, hres=0x%lX %lld\n", hres,V_CY(&vDst).int64);
+}
+
+static HRESULT (WINAPI *pVarNeg)(LPVARIANT,LPVARIANT);
+
+#define VARNEG(vt,val,rvt,rval) V_VT(&v) = VT_##vt; V_##vt(&v) = val; \
+        memset(&vDst,0,sizeof(vDst)); hres = pVarNeg(&v,&vDst); \
+        ok(hres == S_OK && V_VT(&vDst) == VT_##rvt && V_##rvt(&vDst) == (rval), \
+        "VarNeg: expected 0x0,%d,%d, got 0x%lX,%d,%d\n", VT_##rvt, (int)(rval), \
+        hres, V_VT(&vDst), (int)V_##rvt(&vDst))
+
+static void test_VarNeg(void)
+{
+    static const WCHAR szNumMinus1[] = {'-','1','\0' };
+    static const WCHAR szNum1[] = {'1','\0' };
+    HRESULT hres;
+    VARIANT v, vDst;
+    DECIMAL *pdec = &V_DECIMAL(&v);
+    CY *pcy = &V_CY(&v);
+    size_t i;
+
+    CHECKPTR(VarNeg);
+
+    /* Test all possible V_VT values. But don't test the exact return values
+     * except for success/failure, since M$ made a hash of them in the
+     * native version. This at least ensures (as with all tests here) that
+     * we will notice if/when new vtypes/flags are added in native.
+     */
+    for (i = 0; i < sizeof(ExtraFlags)/sizeof(ExtraFlags[0]); i++)
+    {
+        VARTYPE vt;
+
+        for (vt = 0; vt <= VT_BSTR_BLOB; vt++)
+        {
+            HRESULT bFail = TRUE;
+
+            memset(&v, 0, sizeof(v));
+            V_VT(&v) = vt | ExtraFlags[i];
+            V_VT(&vDst) = VT_EMPTY;
+
+            switch (V_VT(&v))
+            {
+            case VT_UI1: case VT_I2: case VT_I4:
+            case VT_R4:  case VT_R8:
+            case VT_DECIMAL: case VT_BOOL: case VT_NULL: case VT_EMPTY:
+            case VT_DATE: case VT_CY:
+                bFail = FALSE;
+                break;
+            case VT_I8:
+                if (HAVE_OLEAUT32_I8)
+                    bFail = FALSE;
+            }
+
+            hres = pVarNeg(&v,&vDst);
+            if (bFail)
+                ok(hres == DISP_E_TYPEMISMATCH || hres == DISP_E_BADVARTYPE,
+                   "VarNeg: expected failure, got 0x%lX vt %d|0x%X\n",
+                   hres, vt, ExtraFlags[i]);
+            else
+                ok(hres == S_OK, "VarNeg: expected S_OK, got 0x%lX vt %d|0x%X\n",
+                    hres, vt, ExtraFlags[i]);
+        }
+    }
+
+    VARNEG(BOOL,VARIANT_TRUE,I2,1);
+    VARNEG(BOOL,VARIANT_FALSE,I2,0);
+    VARNEG(BOOL,1,I2,-1);
+    VARNEG(UI1,1,I2,-1);
+    VARNEG(UI1,254,I2,-254);
+    VARNEG(I2,-32768,I4,32768);
+    VARNEG(I2,-1,I2,1);
+    VARNEG(I2,1,I2,-1);
+    VARNEG(I4,-((int)(~0u >> 1)) - 1,R8,-2147483648u);
+    VARNEG(I4,-1,I4,1);
+    VARNEG(I4,1,I4,-1);
+    if (HAVE_OLEAUT32_I8)
+    {
+        VARNEG(I8,1,I8,-1);
+        VARNEG(I8,-1,I8,1);
+    }
+    VARNEG(R4,1,R4,-1);
+    VARNEG(R4,-1,R4,1);
+    VARNEG(DATE,1,DATE,-1);
+    VARNEG(DATE,-1,DATE,1);
+    VARNEG(R8,1,R8,-1);
+    VARNEG(R8,-1,R8,1);
+    VARNEG(BSTR,(BSTR)szNumMinus1,R8,1);
+    VARNEG(BSTR,(BSTR)szNum1,R8,-1);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = pVarNeg(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_I2 && V_I2(&vDst) == 0,
+       "VarNeg: expected 0x0,%d,0 got 0x%lX,%d,%d\n", VT_EMPTY,
+       hres, V_VT(&vDst), V_I2(&vDst));
+
+    V_VT(&v) = VT_NULL;
+    hres = pVarNeg(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_NULL,
+       "VarNeg: expected 0x0,%d got 0x%lX,%d\n", VT_NULL, hres, V_VT(&vDst));
+
+    V_VT(&v) = VT_DECIMAL;
+    pdec->u.s.sign = DECIMAL_NEG;
+    pdec->u.s.scale = 0;
+    pdec->Hi32 = 0;
+    pdec->u1.s1.Mid32 = 0;
+    pdec->u1.s1.Lo32 = 1;
+    hres = pVarNeg(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
+       V_DECIMAL(&vDst).u.s.sign == 0,
+       "VarNeg: expected 0x0,%d,0x00, got 0x%lX,%d,%02x\n", VT_DECIMAL,
+       hres, V_VT(&vDst), V_DECIMAL(&vDst).u.s.sign);
+
+    pdec->u.s.sign = 0;
+    hres = pVarNeg(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_DECIMAL &&
+       V_DECIMAL(&vDst).u.s.sign == DECIMAL_NEG,
+       "VarNeg: expected 0x0,%d,0x7f, got 0x%lX,%d,%02x\n", VT_DECIMAL,
+       hres, V_VT(&vDst), V_DECIMAL(&vDst).u.s.sign);
+
+    V_VT(&v) = VT_CY;
+    pcy->int64 = -10000;
+    hres = pVarNeg(&v,&vDst);
+    ok(hres == S_OK && V_VT(&vDst) == VT_CY && V_CY(&vDst).int64 == 10000,
+       "VarNeg: VT_CY wrong, hres=0x%lX\n", hres);
+}
+
 START_TEST(vartest)
 {
   hOleaut32 = LoadLibraryA("oleaut32.dll");
 
-  test_variant();
   test_VariantInit();
   test_VariantClear();
   test_VariantCopy();
@@ -4267,4 +2008,7 @@ START_TEST(vartest)
   test_VarAbs();
   test_VarNot();
   test_VarSub();
+  test_VarFix();
+  test_VarInt();
+  test_VarNeg();
 }
index fa2fc4566c17c0aef1502e924bc3e0eca595594f..221c838a67f26824b38afb3197745f8d6688bc28 100644 (file)
@@ -34,8 +34,6 @@ static HMODULE hOleaut32;
 /* Is a given function exported from oleaut32? */
 #define HAVE_FUNC(func) ((void*)GetProcAddress(hOleaut32, #func) != NULL)
 
-/* Have proper locale conversions? */
-#define HAVE_OLEAUT32_LOCALES HAVE_FUNC(GetVarConversionLocaleSetting)
 /* Have IRecordInfo data type? */
 #define HAVE_OLEAUT32_RECORD  HAVE_FUNC(SafeArraySetRecordInfo)
 /* Have DECIMAL data type with new error checking? */
@@ -44,6 +42,13 @@ static HMODULE hOleaut32;
 #define HAVE_OLEAUT32_CY      HAVE_FUNC(VarCyAdd)
 /* Have I8/UI8 data type? */
 #define HAVE_OLEAUT32_I8      HAVE_FUNC(VarI8FromI1)
+/* Have proper locale conversions? */
+#define HAVE_OLEAUT32_LOCALES (HAVE_FUNC(GetVarConversionLocaleSetting) && HAVE_OLEAUT32_I8)
+/* Is this an ancient version with support for only I2/I4/R4/R8/DATE? */
+#define IS_ANCIENT (!HAVE_FUNC(VarI1FromI2))
+/* Is vt a type unavailable to ancient versions? */
+#define IS_MODERN_VTYPE(vt) (vt==VT_VARIANT||vt==VT_DECIMAL|| \
+    vt==VT_I1||vt==VT_UI2||vt==VT_UI4||vt == VT_INT||vt == VT_UINT)
 
 /* Macros for converting and testing results */
 #define CONVVARS(typ) HRESULT hres; CONV_TYPE out; typ in
@@ -60,7 +65,7 @@ static HMODULE hOleaut32;
 #define EXPECT_GT       EXPECTRES(VARCMP_GT, VARCMP_GT)
 #define EXPECT_EQ       EXPECTRES(VARCMP_EQ, VARCMP_EQ)
 #define EXPECT_DBL(x)   \
-  ok(hres == S_OK && fabs(out-(x))<1e-14, "expected " #x ", got %g; hres=0x%08lx", out, hres)
+  ok(hres == S_OK && fabs(out-(x))<1e-14, "expected " #x ", got %16.16g; hres=0x%08lx", out, hres)
 
 #define CONVERT(func, val) in = val; hres = p##func(in, &out)
 #define CONVERTRANGE(func,start,end) for (i = start; i < end; i+=1) { CONVERT(func, i); EXPECT(i); };
@@ -135,14 +140,19 @@ static HMODULE hOleaut32;
   VariantInit(&vDst); \
   V_VT(&vSrc) = vt; \
   (val(&vSrc)) = in; \
-  TYPETEST(VT_I1, V_I1(&vDst), fs); \
+  if (!IS_ANCIENT) { \
+    TYPETEST(VT_I1, V_I1(&vDst), fs); \
+    TYPETEST(VT_UI2, V_UI2(&vDst), fs); \
+    TYPETEST(VT_UI4, V_UI4(&vDst), fs); \
+    TYPETEST(VT_INT, V_INT(&vDst), fs); \
+    TYPETEST(VT_UINT, V_UINT(&vDst), fs); \
+  } else {  \
+    BADVAR(VT_I1); BADVAR(VT_UI2); BADVAR(VT_UI4); \
+    BADVAR(VT_INT); BADVAR(VT_UINT); \
+  } \
   TYPETEST(VT_UI1, V_UI1(&vDst), fs); \
   TYPETEST(VT_I2, V_I2(&vDst), fs); \
-  TYPETEST(VT_UI2, V_UI2(&vDst), fs); \
   TYPETEST(VT_I4, V_I4(&vDst), fs); \
-  TYPETEST(VT_UI4, V_UI4(&vDst), fs); \
-  TYPETEST(VT_INT, V_INT(&vDst), fs); \
-  TYPETEST(VT_UINT, V_UINT(&vDst), fs); \
   TYPETEST(VT_R4, V_R4(&vDst), fs); \
   TYPETEST(VT_R8, V_R8(&vDst), fs); \
   TYPETEST(VT_DATE, V_DATE(&vDst), fs); \
@@ -209,7 +219,7 @@ static HMODULE hOleaut32;
   MISMATCH(VT_DISPATCH); \
   MISMATCH(VT_ERROR); \
   MISMATCH(VT_UNKNOWN); \
-  MISMATCH(VT_VARIANT); \
+  if (!IS_ANCIENT) { MISMATCH(VT_VARIANT); } else { BADVAR(VT_VARIANT); } \
   if (HAVE_OLEAUT32_RECORD) \
   { \
     MISMATCH(VT_RECORD); \
@@ -787,7 +797,10 @@ static void test_VarI1FromStr(void)
 
 static void test_VarI1Copy(void)
 {
-  COPYTEST(1, VT_I1, V_I1(&vSrc), V_I1(&vDst), V_I1REF(&vSrc), V_I1REF(&vDst), "%d");
+  if (!IS_ANCIENT)
+  {
+      COPYTEST(1, VT_I1, V_I1(&vSrc), V_I1(&vDst), V_I1REF(&vSrc), V_I1REF(&vDst), "%d");
+  }
 }
 
 static void test_VarI1ChangeTypeEx(void)
@@ -797,8 +810,11 @@ static void test_VarI1ChangeTypeEx(void)
 
   in = 1;
 
-  INITIAL_TYPETEST(VT_I1, V_I1, "%d");
-  COMMON_TYPETEST;
+  if (!IS_ANCIENT)
+  {
+      INITIAL_TYPETEST(VT_I1, V_I1, "%d");
+      COMMON_TYPETEST;
+  }
 }
 
 #undef CONV_TYPE
@@ -1550,7 +1566,10 @@ static void test_VarUI2FromStr(void)
 
 static void test_VarUI2Copy(void)
 {
-  COPYTEST(1, VT_UI2, V_UI2(&vSrc), V_UI2(&vDst), V_UI2REF(&vSrc), V_UI2REF(&vDst), "%d");
+  if (!IS_ANCIENT)
+  {
+      COPYTEST(1, VT_UI2, V_UI2(&vSrc), V_UI2(&vDst), V_UI2REF(&vSrc), V_UI2REF(&vDst), "%d");
+  }
 }
 
 static void test_VarUI2ChangeTypeEx(void)
@@ -1560,8 +1579,11 @@ static void test_VarUI2ChangeTypeEx(void)
 
   in = 1;
 
-  INITIAL_TYPETEST(VT_UI2, V_UI2, "%d");
-  COMMON_TYPETEST;
+  if (!IS_ANCIENT)
+  {
+    INITIAL_TYPETEST(VT_UI2, V_UI2, "%d");
+    COMMON_TYPETEST;
+  }
 }
 
 /*
@@ -2031,7 +2053,10 @@ static void test_VarUI4FromStr(void)
 
 static void test_VarUI4Copy(void)
 {
-  COPYTEST(1ul, VT_UI4, V_UI4(&vSrc), V_UI4(&vDst), V_UI4REF(&vSrc), V_UI4REF(&vDst), "%lu");
+  if (!IS_ANCIENT)
+  {
+      COPYTEST(1ul, VT_UI4, V_UI4(&vSrc), V_UI4(&vDst), V_UI4REF(&vSrc), V_UI4REF(&vDst), "%lu");
+  }
 }
 
 static void test_VarUI4ChangeTypeEx(void)
@@ -2041,8 +2066,11 @@ static void test_VarUI4ChangeTypeEx(void)
 
   in = 1;
 
-  INITIAL_TYPETEST(VT_UI4, V_UI4, "%lu");
-  COMMON_TYPETEST;
+  if (!IS_ANCIENT)
+  {
+    INITIAL_TYPETEST(VT_UI4, V_UI4, "%lu");
+    COMMON_TYPETEST;
+  }
 }
 
 /*
@@ -3269,16 +3297,16 @@ static void test_VarDateFromStr(void)
   /* After 30, two digit dates are expected to be in the 1900's */
   DFS("1 2 30"); EXPECT_DBL(10960.0);
   DFS("1 2 31"); EXPECT_DBL(11325.0);
-  /* DFS("3 am 1 2"); EXPECT_DBL(37623.125); FIXME: assumes year is 2003 */
-  /* DFS("1 2 3 am"); EXPECT_DBL(37623.125); FIXME: assumes year is 2003 */
+  DFS("3 am 1 2"); MKRELDATE(2,1); relative += 0.125; EXPECT_DBL(relative);
+  DFS("1 2 3 am"); EXPECT_DBL(relative);
 
   /* 4 elements -interpreted as 2 digit date & time */
   DFS("1.2 3 4");   MKRELDATE(4,3); relative += 0.04305555556; EXPECT_DBL(relative);
   DFS("3 4 1.2");   EXPECT_DBL(relative);
   /* 5 elements - interpreted as 2 & 3 digit date/times */
-  /* DFS("1.2.3 4 5"); EXPECT_DBL(37716.04309027778); FIXME: assumes year is 2003 */
+  DFS("1.2.3 4 5"); MKRELDATE(5,4); relative += 0.04309027778; EXPECT_DBL(relative);
   DFS("1.2 3 4 5"); EXPECT_DBL(38415.04305555556);
-  /* DFS("1 2 3.4.5"); EXPECT_DBL(37623.12783564815); FIXME: assumes year is 2003 */
+  DFS("1 2 3.4.5"); MKRELDATE(2,1); relative += 0.12783564815; EXPECT_DBL(relative);
   DFS("1 2 3 4.5"); EXPECT_DBL(37623.17013888889);
   /* 6 elements - interpreted as 3 digit date/times */
   DFS("1.2.3 4 5 6"); EXPECT_DBL(38812.04309027778);
@@ -4442,9 +4470,12 @@ static void test_VarBoolChangeTypeEx(void)
   V_VT(&vSrc) = VT_BOOL;
   V_BOOL(&vSrc) = 1;
 
-  BOOL_STR(VARIANT_ALPHABOOL, szTrue);
-  V_BOOL(&vSrc) = 0;
-  BOOL_STR(VARIANT_ALPHABOOL, szFalse);
+  if (!IS_ANCIENT)
+  {
+      BOOL_STR(VARIANT_ALPHABOOL, szTrue);
+      V_BOOL(&vSrc) = 0;
+      BOOL_STR(VARIANT_ALPHABOOL, szFalse);
+  }
 
   if (HAVE_OLEAUT32_LOCALES)
   {
@@ -4574,10 +4605,13 @@ static void test_SysAllocStringLen()
   const OLECHAR szTest[5] = { 'T','e','s','t','\0' };
   BSTR str;
 
+  /* Very early native dlls do not limit the size of strings, so skip this test */
+#if 0
   str = SysAllocStringLen(szTest, 0x80000000);
   todo_wine {
   ok (str == NULL, "Expected NULL, got %p\n", str);
   }
+#endif
   
   str = SysAllocStringLen(NULL, 0);
   ok (str != NULL, "Expected non-NULL\n");
@@ -4607,7 +4641,6 @@ static void test_SysAllocStringByteLen()
   const OLECHAR szTest[10] = { 'T','e','s','t','\0' };
   const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
   BSTR str;
-  HRESULT hres;
 
   str = SysAllocStringByteLen(szTestA, 0x80000000);
   ok (str == NULL, "Expected NULL, got %p\n", str);
@@ -4641,20 +4674,9 @@ static void test_SysAllocStringByteLen()
   {
     const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
     LPINTERNAL_BSTR bstr = Get(str);
-    VARIANT vt1, vt2;
 
     ok (bstr->dwLen == 3, "Expected 3, got %ld\n", bstr->dwLen);
     ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
-
-    V_VT(&vt1) = VT_BSTR;
-    V_BSTR(&vt1) = str;
-    V_VT(&vt2) = VT_EMPTY;
-    hres = VariantCopy(&vt2, &vt1);
-    ok (hres == S_OK,"Failed to copy binary bstring with hres 0x%08lx\n", hres);
-    bstr = Get(V_BSTR(&vt2));
-    ok (bstr->dwLen == 3, "Expected 3, got %ld\n", bstr->dwLen);
-    ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
-
     SysFreeString(str);
   }
 
@@ -4748,6 +4770,30 @@ static void test_SysReAllocStringLen()
   }
 }
 
+static void test_BstrCopy()
+{
+  const CHAR szTestA[6] = { 'T','e','s','t','\0','?' };
+  const CHAR szTestTruncA[4] = { 'T','e','s','\0' };
+  LPINTERNAL_BSTR bstr;
+  BSTR str;
+  HRESULT hres;
+  VARIANT vt1, vt2;
+
+  str = SysAllocStringByteLen(szTestA, 3);
+  ok (str != NULL, "Expected non-NULL\n");
+  if (str)
+  {
+    V_VT(&vt1) = VT_BSTR;
+    V_BSTR(&vt1) = str;
+    V_VT(&vt2) = VT_EMPTY;
+    hres = VariantCopy(&vt2, &vt1);
+    ok (hres == S_OK,"Failed to copy binary bstring with hres 0x%08lx\n", hres);
+    bstr = Get(V_BSTR(&vt2));
+    ok (bstr->dwLen == 3, "Expected 3, got %ld\n", bstr->dwLen);
+    ok (!lstrcmpA((LPCSTR)bstr->szString, szTestTruncA), "String different\n");
+  }
+}
+
 /* IUnknown */
 
 static void test_IUnknownClear(void)
@@ -4880,6 +4926,9 @@ static void test_IUnknownChangeTypeEx(void)
       else if (vt  >= VT_I2 && vt <= VT_UINT && vt != (VARTYPE)15)
         hExpected = DISP_E_TYPEMISMATCH;
     }
+    if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
+        hExpected = DISP_E_BADVARTYPE;
+
     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
     ok(hres == hExpected,
        "change unk(badvar): vt %d expected 0x%08lx, got 0x%08lx\n",
@@ -5030,6 +5079,8 @@ static void test_ErrorChangeTypeEx(void)
       else if (vt <= VT_UINT && vt != (VARTYPE)15)
         hExpected = DISP_E_TYPEMISMATCH;
     }
+    if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
+        hExpected = DISP_E_BADVARTYPE;
 
     ok(hres == hExpected,
      "change err: vt %d expected 0x%08lx, got 0x%08lx\n", vt, hExpected, hres);
@@ -5072,10 +5123,13 @@ static void test_EmptyChangeTypeEx(void)
     else if (vt <= VT_UINT && vt != (VARTYPE)15)
       hExpected = S_OK;
 
+    if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
+        hExpected = DISP_E_BADVARTYPE;
+
     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
 
     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
-       "change err: vt %d expected 0x%08lx, got 0x%08lx, vt %d\n",
+       "change empty: vt %d expected 0x%08lx, got 0x%08lx, vt %d\n",
        vt, hExpected, hres, V_VT(&vDst));
   }
 }
@@ -5118,6 +5172,9 @@ static void test_NullChangeTypeEx(void)
               (vt <= VT_UINT && vt != (VARTYPE)15))
       hExpected = DISP_E_TYPEMISMATCH;
 
+    if (IS_ANCIENT && IS_MODERN_VTYPE(vt))
+        hExpected = DISP_E_BADVARTYPE;
+
     hres = VariantChangeTypeEx(&vDst, &vSrc, lcid, 0, vt);
 
     ok(hres == hExpected && (hres != S_OK || V_VT(&vDst) == vt),
@@ -5395,6 +5452,7 @@ START_TEST(vartype)
   test_SysAllocStringByteLen();
   test_SysReAllocString();
   test_SysReAllocStringLen();
+  test_BstrCopy();
 
   test_IUnknownClear();
   test_IUnknownCopy();