Fix segmentation fault caused by incorrect referencing of client audio
[wine] / dlls / oleaut32 / variant.c
1 /*
2  * VARIANT
3  *
4  * Copyright 1998 Jean-Claude Cote
5  * Copyright 2003 Jon Griffiths
6  * Copyright 2005 Daniel Remenak
7  *
8  * The alorithm for conversion from Julian days to day/month/year is based on
9  * that devised by Henry Fliegel, as implemented in PostgreSQL, which is
10  * Copyright 1994-7 Regents of the University of California
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27 #include "config.h"
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32
33 #define COBJMACROS
34 #define NONAMELESSUNION
35 #define NONAMELESSSTRUCT
36
37 #include "windef.h"
38 #include "winbase.h"
39 #include "wine/unicode.h"
40 #include "winerror.h"
41 #include "variant.h"
42 #include "wine/debug.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(variant);
45
46 const char* wine_vtypes[VT_CLSID] =
47 {
48   "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
49   "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
50   "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8",
51   "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY",
52   "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR""32","33","34","35",
53   "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
54   "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
55   "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
56   "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID"
57 };
58
59 const char* wine_vflags[16] =
60 {
61  "",
62  "|VT_VECTOR",
63  "|VT_ARRAY",
64  "|VT_VECTOR|VT_ARRAY",
65  "|VT_BYREF",
66  "|VT_VECTOR|VT_ARRAY",
67  "|VT_ARRAY|VT_BYREF",
68  "|VT_VECTOR|VT_ARRAY|VT_BYREF",
69  "|VT_HARDTYPE",
70  "|VT_VECTOR|VT_HARDTYPE",
71  "|VT_ARRAY|VT_HARDTYPE",
72  "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
73  "|VT_BYREF|VT_HARDTYPE",
74  "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
75  "|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
76  "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
77 };
78
79 /* Convert a variant from one type to another */
80 static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
81                                      VARIANTARG* ps, VARTYPE vt)
82 {
83   HRESULT res = DISP_E_TYPEMISMATCH;
84   VARTYPE vtFrom =  V_TYPE(ps);
85   BOOL bIgnoreOverflow = FALSE;
86   DWORD dwFlags = 0;
87
88   TRACE("(%p->(%s%s),0x%08lx,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd),
89         debugstr_VF(pd), lcid, wFlags, ps, debugstr_VT(ps), debugstr_VF(ps),
90         debugstr_vt(vt), debugstr_vf(vt));
91
92   if (vt == VT_BSTR || vtFrom == VT_BSTR)
93   {
94     /* All flags passed to low level function are only used for
95      * changing to or from strings. Map these here.
96      */
97     if (wFlags & VARIANT_LOCALBOOL)
98       dwFlags |= VAR_LOCALBOOL;
99     if (wFlags & VARIANT_CALENDAR_HIJRI)
100       dwFlags |= VAR_CALENDAR_HIJRI;
101     if (wFlags & VARIANT_CALENDAR_THAI)
102       dwFlags |= VAR_CALENDAR_THAI;
103     if (wFlags & VARIANT_CALENDAR_GREGORIAN)
104       dwFlags |= VAR_CALENDAR_GREGORIAN;
105     if (wFlags & VARIANT_NOUSEROVERRIDE)
106       dwFlags |= LOCALE_NOUSEROVERRIDE;
107     if (wFlags & VARIANT_USE_NLS)
108       dwFlags |= LOCALE_USE_NLS;
109   }
110
111   /* Map int/uint to i4/ui4 */
112   if (vt == VT_INT)
113     vt = VT_I4;
114   else if (vt == VT_UINT)
115     vt = VT_UI4;
116
117   if (vtFrom == VT_INT)
118     vtFrom = VT_I4;
119   else if (vtFrom == VT_UINT)
120   {
121     vtFrom = VT_UI4;
122     if (vt == VT_I4)
123       bIgnoreOverflow = TRUE;
124   }
125
126   if (vt == vtFrom)
127      return VariantCopy(pd, ps);
128
129   if (wFlags & VARIANT_NOVALUEPROP && vtFrom == VT_DISPATCH && vt != VT_UNKNOWN)
130   {
131     /* VARIANT_NOVALUEPROP prevents IDispatch objects from being coerced by
132      * accessing the default object property.
133      */
134     return DISP_E_TYPEMISMATCH;
135   }
136
137   switch (vt)
138   {
139   case VT_EMPTY:
140     if (vtFrom == VT_NULL)
141       return DISP_E_TYPEMISMATCH;
142     /* ... Fall through */
143   case VT_NULL:
144     if (vtFrom <= VT_UINT && vtFrom != (VARTYPE)15 && vtFrom != VT_ERROR)
145     {
146       res = VariantClear( pd );
147       if (vt == VT_NULL && SUCCEEDED(res))
148         V_VT(pd) = VT_NULL;
149     }
150     return res;
151
152   case VT_I1:
153     switch (vtFrom)
154     {
155     case VT_EMPTY:    V_I1(pd) = 0; return S_OK;
156     case VT_I2:       return VarI1FromI2(V_I2(ps), &V_I1(pd));
157     case VT_I4:       return VarI1FromI4(V_I4(ps), &V_I1(pd));
158     case VT_UI1:      return VarI1FromUI1(V_UI1(ps), &V_I1(pd));
159     case VT_UI2:      return VarI1FromUI2(V_UI2(ps), &V_I1(pd));
160     case VT_UI4:      return VarI1FromUI4(V_UI4(ps), &V_I1(pd));
161     case VT_I8:       return VarI1FromI8(V_I8(ps), &V_I1(pd));
162     case VT_UI8:      return VarI1FromUI8(V_UI8(ps), &V_I1(pd));
163     case VT_R4:       return VarI1FromR4(V_R4(ps), &V_I1(pd));
164     case VT_R8:       return VarI1FromR8(V_R8(ps), &V_I1(pd));
165     case VT_DATE:     return VarI1FromDate(V_DATE(ps), &V_I1(pd));
166     case VT_BOOL:     return VarI1FromBool(V_BOOL(ps), &V_I1(pd));
167     case VT_CY:       return VarI1FromCy(V_CY(ps), &V_I1(pd));
168     case VT_DECIMAL:  return VarI1FromDec(&V_DECIMAL(ps), &V_I1(pd) );
169     case VT_DISPATCH: return VarI1FromDisp(V_DISPATCH(ps), lcid, &V_I1(pd) );
170     case VT_BSTR:     return VarI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_I1(pd) );
171     }
172     break;
173
174   case VT_I2:
175     switch (vtFrom)
176     {
177     case VT_EMPTY:    V_I2(pd) = 0; return S_OK;
178     case VT_I1:       return VarI2FromI1(V_I1(ps), &V_I2(pd));
179     case VT_I4:       return VarI2FromI4(V_I4(ps), &V_I2(pd));
180     case VT_UI1:      return VarI2FromUI1(V_UI1(ps), &V_I2(pd));
181     case VT_UI2:      return VarI2FromUI2(V_UI2(ps), &V_I2(pd));
182     case VT_UI4:      return VarI2FromUI4(V_UI4(ps), &V_I2(pd));
183     case VT_I8:       return VarI2FromI8(V_I8(ps), &V_I2(pd));
184     case VT_UI8:      return VarI2FromUI8(V_UI8(ps), &V_I2(pd));
185     case VT_R4:       return VarI2FromR4(V_R4(ps), &V_I2(pd));
186     case VT_R8:       return VarI2FromR8(V_R8(ps), &V_I2(pd));
187     case VT_DATE:     return VarI2FromDate(V_DATE(ps), &V_I2(pd));
188     case VT_BOOL:     return VarI2FromBool(V_BOOL(ps), &V_I2(pd));
189     case VT_CY:       return VarI2FromCy(V_CY(ps), &V_I2(pd));
190     case VT_DECIMAL:  return VarI2FromDec(&V_DECIMAL(ps), &V_I2(pd));
191     case VT_DISPATCH: return VarI2FromDisp(V_DISPATCH(ps), lcid, &V_I2(pd));
192     case VT_BSTR:     return VarI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_I2(pd));
193     }
194     break;
195
196   case VT_I4:
197     switch (vtFrom)
198     {
199     case VT_EMPTY:    V_I4(pd) = 0; return S_OK;
200     case VT_I1:       return VarI4FromI1(V_I1(ps), &V_I4(pd));
201     case VT_I2:       return VarI4FromI2(V_I2(ps), &V_I4(pd));
202     case VT_UI1:      return VarI4FromUI1(V_UI1(ps), &V_I4(pd));
203     case VT_UI2:      return VarI4FromUI2(V_UI2(ps), &V_I4(pd));
204     case VT_UI4:      
205           if (bIgnoreOverflow)
206           {
207             V_VT(pd) = VT_I4;
208             V_I4(pd) = V_I4(ps);
209             return S_OK;
210           }
211           return VarI4FromUI4(V_UI4(ps), &V_I4(pd));
212     case VT_I8:       return VarI4FromI8(V_I8(ps), &V_I4(pd));
213     case VT_UI8:      return VarI4FromUI8(V_UI8(ps), &V_I4(pd));
214     case VT_R4:       return VarI4FromR4(V_R4(ps), &V_I4(pd));
215     case VT_R8:       return VarI4FromR8(V_R8(ps), &V_I4(pd));
216     case VT_DATE:     return VarI4FromDate(V_DATE(ps), &V_I4(pd));
217     case VT_BOOL:     return VarI4FromBool(V_BOOL(ps), &V_I4(pd));
218     case VT_CY:       return VarI4FromCy(V_CY(ps), &V_I4(pd));
219     case VT_DECIMAL:  return VarI4FromDec(&V_DECIMAL(ps), &V_I4(pd));
220     case VT_DISPATCH: return VarI4FromDisp(V_DISPATCH(ps), lcid, &V_I4(pd));
221     case VT_BSTR:     return VarI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_I4(pd));
222     }
223     break;
224
225   case VT_UI1:
226     switch (vtFrom)
227     {
228     case VT_EMPTY:    V_UI1(pd) = 0; return S_OK;
229     case VT_I1:       return VarUI1FromI1(V_I1(ps), &V_UI1(pd));
230     case VT_I2:       return VarUI1FromI2(V_I2(ps), &V_UI1(pd));
231     case VT_I4:       return VarUI1FromI4(V_I4(ps), &V_UI1(pd));
232     case VT_UI2:      return VarUI1FromUI2(V_UI2(ps), &V_UI1(pd));
233     case VT_UI4:      return VarUI1FromUI4(V_UI4(ps), &V_UI1(pd));
234     case VT_I8:       return VarUI1FromI8(V_I8(ps), &V_UI1(pd));
235     case VT_UI8:      return VarUI1FromUI8(V_UI8(ps), &V_UI1(pd));
236     case VT_R4:       return VarUI1FromR4(V_R4(ps), &V_UI1(pd));
237     case VT_R8:       return VarUI1FromR8(V_R8(ps), &V_UI1(pd));
238     case VT_DATE:     return VarUI1FromDate(V_DATE(ps), &V_UI1(pd));
239     case VT_BOOL:     return VarUI1FromBool(V_BOOL(ps), &V_UI1(pd));
240     case VT_CY:       return VarUI1FromCy(V_CY(ps), &V_UI1(pd));
241     case VT_DECIMAL:  return VarUI1FromDec(&V_DECIMAL(ps), &V_UI1(pd));
242     case VT_DISPATCH: return VarUI1FromDisp(V_DISPATCH(ps), lcid, &V_UI1(pd));
243     case VT_BSTR:     return VarUI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI1(pd));
244     }
245     break;
246
247   case VT_UI2:
248     switch (vtFrom)
249     {
250     case VT_EMPTY:    V_UI2(pd) = 0; return S_OK;
251     case VT_I1:       return VarUI2FromI1(V_I1(ps), &V_UI2(pd));
252     case VT_I2:       return VarUI2FromI2(V_I2(ps), &V_UI2(pd));
253     case VT_I4:       return VarUI2FromI4(V_I4(ps), &V_UI2(pd));
254     case VT_UI1:      return VarUI2FromUI1(V_UI1(ps), &V_UI2(pd));
255     case VT_UI4:      return VarUI2FromUI4(V_UI4(ps), &V_UI2(pd));
256     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
257     case VT_UI8:      return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
258     case VT_R4:       return VarUI2FromR4(V_R4(ps), &V_UI2(pd));
259     case VT_R8:       return VarUI2FromR8(V_R8(ps), &V_UI2(pd));
260     case VT_DATE:     return VarUI2FromDate(V_DATE(ps), &V_UI2(pd));
261     case VT_BOOL:     return VarUI2FromBool(V_BOOL(ps), &V_UI2(pd));
262     case VT_CY:       return VarUI2FromCy(V_CY(ps), &V_UI2(pd));
263     case VT_DECIMAL:  return VarUI2FromDec(&V_DECIMAL(ps), &V_UI2(pd));
264     case VT_DISPATCH: return VarUI2FromDisp(V_DISPATCH(ps), lcid, &V_UI2(pd));
265     case VT_BSTR:     return VarUI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI2(pd));
266     }
267     break;
268
269   case VT_UI4:
270     switch (vtFrom)
271     {
272     case VT_EMPTY:    V_UI4(pd) = 0; return S_OK;
273     case VT_I1:       return VarUI4FromI1(V_I1(ps), &V_UI4(pd));
274     case VT_I2:       return VarUI4FromI2(V_I2(ps), &V_UI4(pd));
275     case VT_I4:       return VarUI4FromI4(V_I4(ps), &V_UI4(pd));
276     case VT_UI1:      return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd));
277     case VT_UI2:      return VarUI4FromUI2(V_UI2(ps), &V_UI4(pd));
278     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
279     case VT_UI8:      return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
280     case VT_R4:       return VarUI4FromR4(V_R4(ps), &V_UI4(pd));
281     case VT_R8:       return VarUI4FromR8(V_R8(ps), &V_UI4(pd));
282     case VT_DATE:     return VarUI4FromDate(V_DATE(ps), &V_UI4(pd));
283     case VT_BOOL:     return VarUI4FromBool(V_BOOL(ps), &V_UI4(pd));
284     case VT_CY:       return VarUI4FromCy(V_CY(ps), &V_UI4(pd));
285     case VT_DECIMAL:  return VarUI4FromDec(&V_DECIMAL(ps), &V_UI4(pd));
286     case VT_DISPATCH: return VarUI4FromDisp(V_DISPATCH(ps), lcid, &V_UI4(pd));
287     case VT_BSTR:     return VarUI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI4(pd));
288     }
289     break;
290
291   case VT_UI8:
292     switch (vtFrom)
293     {
294     case VT_EMPTY:    V_UI8(pd) = 0; return S_OK;
295     case VT_I4:       if (V_I4(ps) < 0) return DISP_E_OVERFLOW; V_UI8(pd) = V_I4(ps); return S_OK;
296     case VT_I1:       return VarUI8FromI1(V_I1(ps), &V_UI8(pd));
297     case VT_I2:       return VarUI8FromI2(V_I2(ps), &V_UI8(pd));
298     case VT_UI1:      return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd));
299     case VT_UI2:      return VarUI8FromUI2(V_UI2(ps), &V_UI8(pd));
300     case VT_UI4:      return VarUI8FromUI4(V_UI4(ps), &V_UI8(pd));
301     case VT_I8:       return VarUI8FromI8(V_I8(ps), &V_UI8(pd));
302     case VT_R4:       return VarUI8FromR4(V_R4(ps), &V_UI8(pd));
303     case VT_R8:       return VarUI8FromR8(V_R8(ps), &V_UI8(pd));
304     case VT_DATE:     return VarUI8FromDate(V_DATE(ps), &V_UI8(pd));
305     case VT_BOOL:     return VarUI8FromBool(V_BOOL(ps), &V_UI8(pd));
306     case VT_CY:       return VarUI8FromCy(V_CY(ps), &V_UI8(pd));
307     case VT_DECIMAL:  return VarUI8FromDec(&V_DECIMAL(ps), &V_UI8(pd));
308     case VT_DISPATCH: return VarUI8FromDisp(V_DISPATCH(ps), lcid, &V_UI8(pd));
309     case VT_BSTR:     return VarUI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI8(pd));
310     }
311     break;
312
313   case VT_I8:
314     switch (vtFrom)
315     {
316     case VT_EMPTY:    V_I8(pd) = 0; return S_OK;
317     case VT_I4:       V_I8(pd) = V_I4(ps); return S_OK;
318     case VT_I1:       return VarI8FromI1(V_I1(ps), &V_I8(pd));
319     case VT_I2:       return VarI8FromI2(V_I2(ps), &V_I8(pd));
320     case VT_UI1:      return VarI8FromUI1(V_UI1(ps), &V_I8(pd));
321     case VT_UI2:      return VarI8FromUI2(V_UI2(ps), &V_I8(pd));
322     case VT_UI4:      return VarI8FromUI4(V_UI4(ps), &V_I8(pd));
323     case VT_UI8:      return VarI8FromUI8(V_I8(ps), &V_I8(pd));
324     case VT_R4:       return VarI8FromR4(V_R4(ps), &V_I8(pd));
325     case VT_R8:       return VarI8FromR8(V_R8(ps), &V_I8(pd));
326     case VT_DATE:     return VarI8FromDate(V_DATE(ps), &V_I8(pd));
327     case VT_BOOL:     return VarI8FromBool(V_BOOL(ps), &V_I8(pd));
328     case VT_CY:       return VarI8FromCy(V_CY(ps), &V_I8(pd));
329     case VT_DECIMAL:  return VarI8FromDec(&V_DECIMAL(ps), &V_I8(pd));
330     case VT_DISPATCH: return VarI8FromDisp(V_DISPATCH(ps), lcid, &V_I8(pd));
331     case VT_BSTR:     return VarI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_I8(pd));
332     }
333     break;
334
335   case VT_R4:
336     switch (vtFrom)
337     {
338     case VT_EMPTY:    V_R4(pd) = 0.0f; return S_OK;
339     case VT_I1:       return VarR4FromI1(V_I1(ps), &V_R4(pd));
340     case VT_I2:       return VarR4FromI2(V_I2(ps), &V_R4(pd));
341     case VT_I4:       return VarR4FromI4(V_I4(ps), &V_R4(pd));
342     case VT_UI1:      return VarR4FromUI1(V_UI1(ps), &V_R4(pd));
343     case VT_UI2:      return VarR4FromUI2(V_UI2(ps), &V_R4(pd));
344     case VT_UI4:      return VarR4FromUI4(V_UI4(ps), &V_R4(pd));
345     case VT_I8:       return VarR4FromI8(V_I8(ps), &V_R4(pd));
346     case VT_UI8:      return VarR4FromUI8(V_UI8(ps), &V_R4(pd));
347     case VT_R8:       return VarR4FromR8(V_R8(ps), &V_R4(pd));
348     case VT_DATE:     return VarR4FromDate(V_DATE(ps), &V_R4(pd));
349     case VT_BOOL:     return VarR4FromBool(V_BOOL(ps), &V_R4(pd));
350     case VT_CY:       return VarR4FromCy(V_CY(ps), &V_R4(pd));
351     case VT_DECIMAL:  return VarR4FromDec(&V_DECIMAL(ps), &V_R4(pd));
352     case VT_DISPATCH: return VarR4FromDisp(V_DISPATCH(ps), lcid, &V_R4(pd));
353     case VT_BSTR:     return VarR4FromStr(V_BSTR(ps), lcid, dwFlags, &V_R4(pd));
354     }
355     break;
356
357   case VT_R8:
358     switch (vtFrom)
359     {
360     case VT_EMPTY:    V_R8(pd) = 0.0; return S_OK;
361     case VT_I1:       return VarR8FromI1(V_I1(ps), &V_R8(pd));
362     case VT_I2:       return VarR8FromI2(V_I2(ps), &V_R8(pd));
363     case VT_I4:       return VarR8FromI4(V_I4(ps), &V_R8(pd));
364     case VT_UI1:      return VarR8FromUI1(V_UI1(ps), &V_R8(pd));
365     case VT_UI2:      return VarR8FromUI2(V_UI2(ps), &V_R8(pd));
366     case VT_UI4:      return VarR8FromUI4(V_UI4(ps), &V_R8(pd));
367     case VT_I8:       return VarR8FromI8(V_I8(ps), &V_R8(pd));
368     case VT_UI8:      return VarR8FromUI8(V_UI8(ps), &V_R8(pd));
369     case VT_R4:       return VarR8FromR4(V_R4(ps), &V_R8(pd));
370     case VT_DATE:     return VarR8FromDate(V_DATE(ps), &V_R8(pd));
371     case VT_BOOL:     return VarR8FromBool(V_BOOL(ps), &V_R8(pd));
372     case VT_CY:       return VarR8FromCy(V_CY(ps), &V_R8(pd));
373     case VT_DECIMAL:  return VarR8FromDec(&V_DECIMAL(ps), &V_R8(pd));
374     case VT_DISPATCH: return VarR8FromDisp(V_DISPATCH(ps), lcid, &V_R8(pd));
375     case VT_BSTR:     return VarR8FromStr(V_BSTR(ps), lcid, dwFlags, &V_R8(pd));
376     }
377     break;
378
379   case VT_DATE:
380     switch (vtFrom)
381     {
382     case VT_EMPTY:    V_DATE(pd) = 0.0; return S_OK;
383     case VT_I1:       return VarDateFromI1(V_I1(ps), &V_DATE(pd));
384     case VT_I2:       return VarDateFromI2(V_I2(ps), &V_DATE(pd));
385     case VT_I4:       return VarDateFromI4(V_I4(ps), &V_DATE(pd));
386     case VT_UI1:      return VarDateFromUI1(V_UI1(ps), &V_DATE(pd));
387     case VT_UI2:      return VarDateFromUI2(V_UI2(ps), &V_DATE(pd));
388     case VT_UI4:      return VarDateFromUI4(V_UI4(ps), &V_DATE(pd));
389     case VT_I8:       return VarDateFromI8(V_I8(ps), &V_DATE(pd));
390     case VT_UI8:      return VarDateFromUI8(V_UI8(ps), &V_DATE(pd));
391     case VT_R4:       return VarDateFromR4(V_R4(ps), &V_DATE(pd));
392     case VT_R8:       return VarDateFromR8(V_R8(ps), &V_DATE(pd));
393     case VT_BOOL:     return VarDateFromBool(V_BOOL(ps), &V_DATE(pd));
394     case VT_CY:       return VarDateFromCy(V_CY(ps), &V_DATE(pd));
395     case VT_DECIMAL:  return VarDateFromDec(&V_DECIMAL(ps), &V_DATE(pd));
396     case VT_DISPATCH: return VarDateFromDisp(V_DISPATCH(ps), lcid, &V_DATE(pd));
397     case VT_BSTR:     return VarDateFromStr(V_BSTR(ps), lcid, dwFlags, &V_DATE(pd));
398     }
399     break;
400
401   case VT_BOOL:
402     switch (vtFrom)
403     {
404     case VT_EMPTY:    V_BOOL(pd) = 0; return S_OK;
405     case VT_I1:       return VarBoolFromI1(V_I1(ps), &V_BOOL(pd));
406     case VT_I2:       return VarBoolFromI2(V_I2(ps), &V_BOOL(pd));
407     case VT_I4:       return VarBoolFromI4(V_I4(ps), &V_BOOL(pd));
408     case VT_UI1:      return VarBoolFromUI1(V_UI1(ps), &V_BOOL(pd));
409     case VT_UI2:      return VarBoolFromUI2(V_UI2(ps), &V_BOOL(pd));
410     case VT_UI4:      return VarBoolFromUI4(V_UI4(ps), &V_BOOL(pd));
411     case VT_I8:       return VarBoolFromI8(V_I8(ps), &V_BOOL(pd));
412     case VT_UI8:      return VarBoolFromUI8(V_UI8(ps), &V_BOOL(pd));
413     case VT_R4:       return VarBoolFromR4(V_R4(ps), &V_BOOL(pd));
414     case VT_R8:       return VarBoolFromR8(V_R8(ps), &V_BOOL(pd));
415     case VT_DATE:     return VarBoolFromDate(V_DATE(ps), &V_BOOL(pd));
416     case VT_CY:       return VarBoolFromCy(V_CY(ps), &V_BOOL(pd));
417     case VT_DECIMAL:  return VarBoolFromDec(&V_DECIMAL(ps), &V_BOOL(pd));
418     case VT_DISPATCH: return VarBoolFromDisp(V_DISPATCH(ps), lcid, &V_BOOL(pd));
419     case VT_BSTR:     return VarBoolFromStr(V_BSTR(ps), lcid, dwFlags, &V_BOOL(pd));
420     }
421     break;
422
423   case VT_BSTR:
424     switch (vtFrom)
425     {
426     case VT_EMPTY:
427       V_BSTR(pd) = SysAllocStringLen(NULL, 0);
428       return V_BSTR(pd) ? S_OK : E_OUTOFMEMORY;
429     case VT_BOOL:
430       if (wFlags & (VARIANT_ALPHABOOL|VARIANT_LOCALBOOL))
431          return VarBstrFromBool(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
432       return VarBstrFromI2(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
433     case VT_I1:       return VarBstrFromI1(V_I1(ps), lcid, dwFlags, &V_BSTR(pd));
434     case VT_I2:       return VarBstrFromI2(V_I2(ps), lcid, dwFlags, &V_BSTR(pd));
435     case VT_I4:       return VarBstrFromI4(V_I4(ps), lcid, dwFlags, &V_BSTR(pd));
436     case VT_UI1:      return VarBstrFromUI1(V_UI1(ps), lcid, dwFlags, &V_BSTR(pd));
437     case VT_UI2:      return VarBstrFromUI2(V_UI2(ps), lcid, dwFlags, &V_BSTR(pd));
438     case VT_UI4:      return VarBstrFromUI4(V_UI4(ps), lcid, dwFlags, &V_BSTR(pd));
439     case VT_I8:       return VarBstrFromI8(V_I8(ps), lcid, dwFlags, &V_BSTR(pd));
440     case VT_UI8:      return VarBstrFromUI8(V_UI8(ps), lcid, dwFlags, &V_BSTR(pd));
441     case VT_R4:       return VarBstrFromR4(V_R4(ps), lcid, dwFlags, &V_BSTR(pd));
442     case VT_R8:       return VarBstrFromR8(V_R8(ps), lcid, dwFlags, &V_BSTR(pd));
443     case VT_DATE:     return VarBstrFromDate(V_DATE(ps), lcid, dwFlags, &V_BSTR(pd));
444     case VT_CY:       return VarBstrFromCy(V_CY(ps), lcid, dwFlags, &V_BSTR(pd));
445     case VT_DECIMAL:  return VarBstrFromDec(&V_DECIMAL(ps), lcid, dwFlags, &V_BSTR(pd));
446 /*  case VT_DISPATCH: return VarBstrFromDisp(V_DISPATCH(ps), lcid, dwFlags, &V_BSTR(pd)); */
447     }
448     break;
449
450   case VT_CY:
451     switch (vtFrom)
452     {
453     case VT_EMPTY:    V_CY(pd).int64 = 0; return S_OK;
454     case VT_I1:       return VarCyFromI1(V_I1(ps), &V_CY(pd));
455     case VT_I2:       return VarCyFromI2(V_I2(ps), &V_CY(pd));
456     case VT_I4:       return VarCyFromI4(V_I4(ps), &V_CY(pd));
457     case VT_UI1:      return VarCyFromUI1(V_UI1(ps), &V_CY(pd));
458     case VT_UI2:      return VarCyFromUI2(V_UI2(ps), &V_CY(pd));
459     case VT_UI4:      return VarCyFromUI4(V_UI4(ps), &V_CY(pd));
460     case VT_I8:       return VarCyFromI8(V_I8(ps), &V_CY(pd));
461     case VT_UI8:      return VarCyFromUI8(V_UI8(ps), &V_CY(pd));
462     case VT_R4:       return VarCyFromR4(V_R4(ps), &V_CY(pd));
463     case VT_R8:       return VarCyFromR8(V_R8(ps), &V_CY(pd));
464     case VT_DATE:     return VarCyFromDate(V_DATE(ps), &V_CY(pd));
465     case VT_BOOL:     return VarCyFromBool(V_BOOL(ps), &V_CY(pd));
466     case VT_DECIMAL:  return VarCyFromDec(&V_DECIMAL(ps), &V_CY(pd));
467     case VT_DISPATCH: return VarCyFromDisp(V_DISPATCH(ps), lcid, &V_CY(pd));
468     case VT_BSTR:     return VarCyFromStr(V_BSTR(ps), lcid, dwFlags, &V_CY(pd));
469     }
470     break;
471
472   case VT_DECIMAL:
473     switch (vtFrom)
474     {
475     case VT_EMPTY:
476     case VT_BOOL:
477        DEC_SIGNSCALE(&V_DECIMAL(pd)) = SIGNSCALE(DECIMAL_POS,0);
478        DEC_HI32(&V_DECIMAL(pd)) = 0;
479        DEC_MID32(&V_DECIMAL(pd)) = 0;
480         /* VarDecFromBool() coerces to -1/0, ChangeTypeEx() coerces to 1/0.
481          * VT_NULL and VT_EMPTY always give a 0 value.
482          */
483        DEC_LO32(&V_DECIMAL(pd)) = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0;
484        return S_OK;
485     case VT_I1:       return VarDecFromI1(V_I1(ps), &V_DECIMAL(pd));
486     case VT_I2:       return VarDecFromI2(V_I2(ps), &V_DECIMAL(pd));
487     case VT_I4:       return VarDecFromI4(V_I4(ps), &V_DECIMAL(pd));
488     case VT_UI1:      return VarDecFromUI1(V_UI1(ps), &V_DECIMAL(pd));
489     case VT_UI2:      return VarDecFromUI2(V_UI2(ps), &V_DECIMAL(pd));
490     case VT_UI4:      return VarDecFromUI4(V_UI4(ps), &V_DECIMAL(pd));
491     case VT_I8:       return VarDecFromI8(V_I8(ps), &V_DECIMAL(pd));
492     case VT_UI8:      return VarDecFromUI8(V_UI8(ps), &V_DECIMAL(pd));
493     case VT_R4:       return VarDecFromR4(V_R4(ps), &V_DECIMAL(pd));
494     case VT_R8:       return VarDecFromR8(V_R8(ps), &V_DECIMAL(pd));
495     case VT_DATE:     return VarDecFromDate(V_DATE(ps), &V_DECIMAL(pd));
496     case VT_CY:       return VarDecFromCy(V_CY(pd), &V_DECIMAL(ps));
497     case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(ps));
498     case VT_BSTR:     return VarDecFromStr(V_BSTR(ps), lcid, dwFlags, &V_DECIMAL(pd));
499     }
500     break;
501
502   case VT_UNKNOWN:
503     switch (vtFrom)
504     {
505     case VT_DISPATCH:
506       if (V_DISPATCH(ps) == NULL)
507         V_UNKNOWN(pd) = NULL;
508       else
509         res = IDispatch_QueryInterface(V_DISPATCH(ps), &IID_IUnknown, (LPVOID*)&V_UNKNOWN(pd));
510       break;
511     }
512     break;
513
514   case VT_DISPATCH:
515     switch (vtFrom)
516     {
517     case VT_UNKNOWN:
518       if (V_UNKNOWN(ps) == NULL)
519         V_DISPATCH(pd) = NULL;
520       else
521         res = IUnknown_QueryInterface(V_UNKNOWN(ps), &IID_IDispatch, (LPVOID*)&V_DISPATCH(pd));
522       break;
523     }
524     break;
525
526   case VT_RECORD:
527     break;
528   }
529   return res;
530 }
531
532 /* Coerce to/from an array */
533 static inline HRESULT VARIANT_CoerceArray(VARIANTARG* pd, VARIANTARG* ps, VARTYPE vt)
534 {
535   if (vt == VT_BSTR && V_VT(ps) == (VT_ARRAY|VT_UI1))
536     return BstrFromVector(V_ARRAY(ps), &V_BSTR(pd));
537
538   if (V_VT(ps) == VT_BSTR && vt == (VT_ARRAY|VT_UI1))
539     return VectorFromBstr(V_BSTR(ps), &V_ARRAY(ps));
540
541   if (V_VT(ps) == vt)
542     return SafeArrayCopy(V_ARRAY(ps), &V_ARRAY(pd));
543
544   return DISP_E_TYPEMISMATCH;
545 }
546
547 /******************************************************************************
548  * Check if a variants type is valid.
549  */
550 static inline HRESULT VARIANT_ValidateType(VARTYPE vt)
551 {
552   VARTYPE vtExtra = vt & VT_EXTRA_TYPE;
553
554   vt &= VT_TYPEMASK;
555
556   if (!(vtExtra & (VT_VECTOR|VT_RESERVED)))
557   {
558     if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID)
559     {
560       if ((vtExtra & (VT_BYREF|VT_ARRAY)) && vt <= VT_NULL)
561         return DISP_E_BADVARTYPE;
562       if (vt != (VARTYPE)15)
563         return S_OK;
564     }
565   }
566   return DISP_E_BADVARTYPE;
567 }
568
569 /******************************************************************************
570  *              VariantInit     [OLEAUT32.8]
571  *
572  * Initialise a variant.
573  *
574  * PARAMS
575  *  pVarg [O] Variant to initialise
576  *
577  * RETURNS
578  *  Nothing.
579  *
580  * NOTES
581  *  This function simply sets the type of the variant to VT_EMPTY. It does not
582  *  free any existing value, use VariantClear() for that.
583  */
584 void WINAPI VariantInit(VARIANTARG* pVarg)
585 {
586   TRACE("(%p)\n", pVarg);
587
588   V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
589 }
590
591 /******************************************************************************
592  *              VariantClear    [OLEAUT32.9]
593  *
594  * Clear a variant.
595  *
596  * PARAMS
597  *  pVarg [I/O] Variant to clear
598  *
599  * RETURNS
600  *  Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
601  *  Failure: DISP_E_BADVARTYPE, if the variant is a not a valid variant type.
602  */
603 HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
604 {
605   HRESULT hres = S_OK;
606
607   TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
608
609   hres = VARIANT_ValidateType(V_VT(pVarg));
610
611   if (SUCCEEDED(hres))
612   {
613     if (!V_ISBYREF(pVarg))
614     {
615       if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY)
616       {
617         if (V_ARRAY(pVarg))
618           hres = SafeArrayDestroy(V_ARRAY(pVarg));
619       }
620       else if (V_VT(pVarg) == VT_BSTR)
621       {
622         if (V_BSTR(pVarg))
623           SysFreeString(V_BSTR(pVarg));
624       }
625       else if (V_VT(pVarg) == VT_RECORD)
626       {
627         struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
628         if (pBr->pRecInfo)
629         {
630           IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
631           IRecordInfo_Release(pBr->pRecInfo);
632         }
633       }
634       else if (V_VT(pVarg) == VT_DISPATCH ||
635                V_VT(pVarg) == VT_UNKNOWN)
636       {
637         if (V_UNKNOWN(pVarg))
638           IUnknown_Release(V_UNKNOWN(pVarg));
639       }
640       else if (V_VT(pVarg) == VT_VARIANT)
641       {
642         if (V_VARIANTREF(pVarg))
643           VariantClear(V_VARIANTREF(pVarg));
644       }
645     }
646     V_VT(pVarg) = VT_EMPTY;
647   }
648   return hres;
649 }
650
651 /******************************************************************************
652  * Copy an IRecordInfo object contained in a variant.
653  */
654 static HRESULT VARIANT_CopyIRecordInfo(struct __tagBRECORD* pBr)
655 {
656   HRESULT hres = S_OK;
657
658   if (pBr->pRecInfo)
659   {
660     ULONG ulSize;
661
662     hres = IRecordInfo_GetSize(pBr->pRecInfo, &ulSize);
663     if (SUCCEEDED(hres))
664     {
665       PVOID pvRecord = HeapAlloc(GetProcessHeap(), 0, ulSize);
666       if (!pvRecord)
667         hres = E_OUTOFMEMORY;
668       else
669       {
670         memcpy(pvRecord, pBr->pvRecord, ulSize);
671         pBr->pvRecord = pvRecord;
672
673         hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord);
674         if (SUCCEEDED(hres))
675           IRecordInfo_AddRef(pBr->pRecInfo);
676       }
677     }
678   }
679   else if (pBr->pvRecord)
680     hres = E_INVALIDARG;
681   return hres;
682 }
683
684 /******************************************************************************
685  *    VariantCopy  [OLEAUT32.10]
686  *
687  * Copy a variant.
688  *
689  * PARAMS
690  *  pvargDest [O] Destination for copy
691  *  pvargSrc  [I] Source variant to copy
692  *
693  * RETURNS
694  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
695  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid type.
696  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
697  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
698  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
699  *
700  * NOTES
701  *  - If pvargSrc == pvargDest, this function does nothing, and succeeds if
702  *    pvargSrc is valid. Otherwise, pvargDest is always cleared using
703  *    VariantClear() before pvargSrc is copied to it. If clearing pvargDest
704  *    fails, so does this function.
705  *  - VT_CLSID is a valid type type for pvargSrc, but not for pvargDest.
706  *  - For by-value non-intrinsic types, a deep copy is made, i.e. The whole value
707  *    is copied rather than just any pointers to it.
708  *  - For by-value object types the object pointer is copied and the objects
709  *    reference count increased using IUnknown_AddRef().
710  *  - For all by-reference types, only the referencing pointer is copied.
711  */
712 HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
713 {
714   HRESULT hres = S_OK;
715
716   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
717         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
718         debugstr_VF(pvargSrc));
719
720   if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */
721       FAILED(VARIANT_ValidateType(V_VT(pvargSrc))))
722     return DISP_E_BADVARTYPE;
723
724   if (pvargSrc != pvargDest &&
725       SUCCEEDED(hres = VariantClear(pvargDest)))
726   {
727     *pvargDest = *pvargSrc; /* Shallow copy the value */
728
729     if (!V_ISBYREF(pvargSrc))
730     {
731       if (V_ISARRAY(pvargSrc))
732       {
733         if (V_ARRAY(pvargSrc))
734           hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest));
735       }
736       else if (V_VT(pvargSrc) == VT_BSTR)
737       {
738         if (V_BSTR(pvargSrc))
739         {
740           V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc)));
741           if (!V_BSTR(pvargDest))
742           {
743             TRACE("!V_BSTR(pvargDest), SysAllocStringByteLen() failed to allocate %d bytes\n", SysStringByteLen(V_BSTR(pvargSrc)));
744             hres = E_OUTOFMEMORY;
745           }
746         }
747       }
748       else if (V_VT(pvargSrc) == VT_RECORD)
749       {
750         hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
751       }
752       else if (V_VT(pvargSrc) == VT_DISPATCH ||
753                V_VT(pvargSrc) == VT_UNKNOWN)
754       {
755         if (V_UNKNOWN(pvargSrc))
756           IUnknown_AddRef(V_UNKNOWN(pvargSrc));
757       }
758     }
759   }
760   return hres;
761 }
762
763 /* Return the byte size of a variants data */
764 static inline size_t VARIANT_DataSize(const VARIANT* pv)
765 {
766   switch (V_TYPE(pv))
767   {
768   case VT_I1:
769   case VT_UI1:   return sizeof(BYTE);
770   case VT_I2:
771   case VT_UI2:   return sizeof(SHORT);
772   case VT_INT:
773   case VT_UINT:
774   case VT_I4:
775   case VT_UI4:   return sizeof(LONG);
776   case VT_I8:
777   case VT_UI8:   return sizeof(LONGLONG);
778   case VT_R4:    return sizeof(float);
779   case VT_R8:    return sizeof(double);
780   case VT_DATE:  return sizeof(DATE);
781   case VT_BOOL:  return sizeof(VARIANT_BOOL);
782   case VT_DISPATCH:
783   case VT_UNKNOWN:
784   case VT_BSTR:  return sizeof(void*);
785   case VT_CY:    return sizeof(CY);
786   case VT_ERROR: return sizeof(SCODE);
787   }
788   TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv));
789   return 0;
790 }
791
792 /******************************************************************************
793  *    VariantCopyInd  [OLEAUT32.11]
794  *
795  * Copy a variant, dereferencing it it is by-reference.
796  *
797  * PARAMS
798  *  pvargDest [O] Destination for copy
799  *  pvargSrc  [I] Source variant to copy
800  *
801  * RETURNS
802  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
803  *  Failure: An HRESULT error code indicating the error.
804  *
805  * NOTES
806  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid by-value type.
807  *           E_INVALIDARG, if pvargSrc  is an invalid by-reference type.
808  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
809  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
810  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
811  *
812  * NOTES
813  *  - If pvargSrc is by-value, this function behaves exactly as VariantCopy().
814  *  - If pvargSrc is by-reference, the value copied to pvargDest is the pointed-to
815  *    value.
816  *  - if pvargSrc == pvargDest, this function dereferences in place. Otherwise,
817  *    pvargDest is always cleared using VariantClear() before pvargSrc is copied
818  *    to it. If clearing pvargDest fails, so does this function.
819  */
820 HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
821 {
822   VARIANTARG vTmp, *pSrc = pvargSrc;
823   VARTYPE vt;
824   HRESULT hres = S_OK;
825
826   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
827         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
828         debugstr_VF(pvargSrc));
829
830   if (!V_ISBYREF(pvargSrc))
831     return VariantCopy(pvargDest, pvargSrc);
832
833   /* Argument checking is more lax than VariantCopy()... */
834   vt = V_TYPE(pvargSrc);
835   if (V_ISARRAY(pvargSrc) ||
836      (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
837      !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED))))
838   {
839     /* OK */
840   }
841   else
842     return E_INVALIDARG; /* ...And the return value for invalid types differs too */
843
844   if (pvargSrc == pvargDest)
845   {
846     /* In place copy. Use a shallow copy of pvargSrc & init pvargDest.
847      * This avoids an expensive VariantCopy() call - e.g. SafeArrayCopy().
848      */
849     vTmp = *pvargSrc;
850     pSrc = &vTmp;
851     V_VT(pvargDest) = VT_EMPTY;
852   }
853   else
854   {
855     /* Copy into another variant. Free the variant in pvargDest */
856     if (FAILED(hres = VariantClear(pvargDest)))
857     {
858       TRACE("VariantClear() of destination failed\n");
859       return hres;
860     }
861   }
862
863   if (V_ISARRAY(pSrc))
864   {
865     /* Native doesn't check that *V_ARRAYREF(pSrc) is valid */
866     hres = SafeArrayCopy(*V_ARRAYREF(pSrc), &V_ARRAY(pvargDest));
867   }
868   else if (V_VT(pSrc) == (VT_BSTR|VT_BYREF))
869   {
870     /* Native doesn't check that *V_BSTRREF(pSrc) is valid */
871     V_BSTR(pvargDest) = SysAllocStringByteLen((char*)*V_BSTRREF(pSrc), SysStringByteLen(*V_BSTRREF(pSrc)));
872   }
873   else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF))
874   {
875     V_UNION(pvargDest,brecVal) = V_UNION(pvargSrc,brecVal);
876     hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
877   }
878   else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) ||
879            V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF))
880   {
881     /* Native doesn't check that *V_UNKNOWNREF(pSrc) is valid */
882     V_UNKNOWN(pvargDest) = *V_UNKNOWNREF(pSrc);
883     if (*V_UNKNOWNREF(pSrc))
884       IUnknown_AddRef(*V_UNKNOWNREF(pSrc));
885   }
886   else if (V_VT(pSrc) == (VT_VARIANT|VT_BYREF))
887   {
888     /* Native doesn't check that *V_VARIANTREF(pSrc) is valid */
889     if (V_VT(V_VARIANTREF(pSrc)) == (VT_VARIANT|VT_BYREF))
890       hres = E_INVALIDARG; /* Don't dereference more than one level */
891     else
892       hres = VariantCopyInd(pvargDest, V_VARIANTREF(pSrc));
893
894     /* Use the dereferenced variants type value, not VT_VARIANT */
895     goto VariantCopyInd_Return;
896   }
897   else if (V_VT(pSrc) == (VT_DECIMAL|VT_BYREF))
898   {
899     memcpy(&DEC_SCALE(&V_DECIMAL(pvargDest)), &DEC_SCALE(V_DECIMALREF(pSrc)),
900            sizeof(DECIMAL) - sizeof(USHORT));
901   }
902   else
903   {
904     /* Copy the pointed to data into this variant */
905     memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(pSrc));
906   }
907
908   V_VT(pvargDest) = V_VT(pSrc) & ~VT_BYREF;
909
910 VariantCopyInd_Return:
911
912   if (pSrc != pvargSrc)
913     VariantClear(pSrc);
914
915   TRACE("returning 0x%08lx, %p->(%s%s)\n", hres, pvargDest,
916         debugstr_VT(pvargDest), debugstr_VF(pvargDest));
917   return hres;
918 }
919
920 /******************************************************************************
921  *    VariantChangeType  [OLEAUT32.12]
922  *
923  * Change the type of a variant.
924  *
925  * PARAMS
926  *  pvargDest [O] Destination for the converted variant
927  *  pvargSrc  [O] Source variant to change the type of
928  *  wFlags    [I] VARIANT_ flags from "oleauto.h"
929  *  vt        [I] Variant type to change pvargSrc into
930  *
931  * RETURNS
932  *  Success: S_OK. pvargDest contains the converted value.
933  *  Failure: An HRESULT error code describing the failure.
934  *
935  * NOTES
936  *  The LCID used for the conversion is LOCALE_USER_DEFAULT.
937  *  See VariantChangeTypeEx.
938  */
939 HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
940                                  USHORT wFlags, VARTYPE vt)
941 {
942   return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
943 }
944
945 /******************************************************************************
946  *    VariantChangeTypeEx  [OLEAUT32.147]
947  *
948  * Change the type of a variant.
949  *
950  * PARAMS
951  *  pvargDest [O] Destination for the converted variant
952  *  pvargSrc  [O] Source variant to change the type of
953  *  lcid      [I] LCID for the conversion
954  *  wFlags    [I] VARIANT_ flags from "oleauto.h"
955  *  vt        [I] Variant type to change pvargSrc into
956  *
957  * RETURNS
958  *  Success: S_OK. pvargDest contains the converted value.
959  *  Failure: An HRESULT error code describing the failure.
960  *
961  * NOTES
962  *  pvargDest and pvargSrc can point to the same variant to perform an in-place
963  *  conversion. If the conversion is successful, pvargSrc will be freed.
964  */
965 HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
966                                    LCID lcid, USHORT wFlags, VARTYPE vt)
967 {
968   HRESULT res = S_OK;
969
970   TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%04x,%s%s)\n", pvargDest,
971         debugstr_VT(pvargDest), debugstr_VF(pvargDest), pvargSrc,
972         debugstr_VT(pvargSrc), debugstr_VF(pvargSrc), lcid, wFlags,
973         debugstr_vt(vt), debugstr_vf(vt));
974
975   if (vt == VT_CLSID)
976     res = DISP_E_BADVARTYPE;
977   else
978   {
979     res = VARIANT_ValidateType(V_VT(pvargSrc));
980
981     if (SUCCEEDED(res))
982     {
983       res = VARIANT_ValidateType(vt);
984
985       if (SUCCEEDED(res))
986       {
987         VARIANTARG vTmp, vSrcDeref;
988
989         if(V_ISBYREF(pvargSrc) && !V_BYREF(pvargSrc))
990           res = DISP_E_TYPEMISMATCH;
991         else
992         {
993           V_VT(&vTmp) = VT_EMPTY;
994           V_VT(&vSrcDeref) = VT_EMPTY;
995           VariantClear(&vTmp);
996           VariantClear(&vSrcDeref);
997         }
998
999         if (SUCCEEDED(res))
1000         {
1001           res = VariantCopyInd(&vSrcDeref, pvargSrc);
1002           if (SUCCEEDED(res))
1003           {
1004             if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY))
1005               res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt);
1006             else
1007               res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt);
1008
1009             if (SUCCEEDED(res)) {
1010                 V_VT(&vTmp) = vt;
1011                 VariantCopy(pvargDest, &vTmp);
1012             }
1013             VariantClear(&vTmp);
1014             VariantClear(&vSrcDeref);
1015           }
1016         }
1017       }
1018     }
1019   }
1020
1021   TRACE("returning 0x%08lx, %p->(%s%s)\n", res, pvargDest,
1022         debugstr_VT(pvargDest), debugstr_VF(pvargDest));
1023   return res;
1024 }
1025
1026 /* Date Conversions */
1027
1028 #define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
1029
1030 /* Convert a VT_DATE value to a Julian Date */
1031 static inline int VARIANT_JulianFromDate(int dateIn)
1032 {
1033   int julianDays = dateIn;
1034
1035   julianDays -= DATE_MIN; /* Convert to + days from 1 Jan 100 AD */
1036   julianDays += 1757585;  /* Convert to + days from 23 Nov 4713 BC (Julian) */
1037   return julianDays;
1038 }
1039
1040 /* Convert a Julian Date to a VT_DATE value */
1041 static inline int VARIANT_DateFromJulian(int dateIn)
1042 {
1043   int julianDays = dateIn;
1044
1045   julianDays -= 1757585;  /* Convert to + days from 1 Jan 100 AD */
1046   julianDays += DATE_MIN; /* Convert to +/- days from 1 Jan 1899 AD */
1047   return julianDays;
1048 }
1049
1050 /* Convert a Julian date to Day/Month/Year - from PostgreSQL */
1051 static inline void VARIANT_DMYFromJulian(int jd, USHORT *year, USHORT *month, USHORT *day)
1052 {
1053   int j, i, l, n;
1054
1055   l = jd + 68569;
1056   n = l * 4 / 146097;
1057   l -= (n * 146097 + 3) / 4;
1058   i = (4000 * (l + 1)) / 1461001;
1059   l += 31 - (i * 1461) / 4;
1060   j = (l * 80) / 2447;
1061   *day = l - (j * 2447) / 80;
1062   l = j / 11;
1063   *month = (j + 2) - (12 * l);
1064   *year = 100 * (n - 49) + i + l;
1065 }
1066
1067 /* Convert Day/Month/Year to a Julian date - from PostgreSQL */
1068 static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day)
1069 {
1070   int m12 = (month - 14) / 12;
1071
1072   return ((1461 * (year + 4800 + m12)) / 4 + (367 * (month - 2 - 12 * m12)) / 12 -
1073            (3 * ((year + 4900 + m12) / 100)) / 4 + day - 32075);
1074 }
1075
1076 /* Macros for accessing DOS format date/time fields */
1077 #define DOS_YEAR(x)   (1980 + (x >> 9))
1078 #define DOS_MONTH(x)  ((x >> 5) & 0xf)
1079 #define DOS_DAY(x)    (x & 0x1f)
1080 #define DOS_HOUR(x)   (x >> 11)
1081 #define DOS_MINUTE(x) ((x >> 5) & 0x3f)
1082 #define DOS_SECOND(x) ((x & 0x1f) << 1)
1083 /* Create a DOS format date/time */
1084 #define DOS_DATE(d,m,y) (d | (m << 5) | ((y-1980) << 9))
1085 #define DOS_TIME(h,m,s) ((s >> 1) | (m << 5) | (h << 11))
1086
1087 /* Roll a date forwards or backwards to correct it */
1088 static HRESULT VARIANT_RollUdate(UDATE *lpUd)
1089 {
1090   static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1091
1092   TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
1093         lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
1094
1095   /* Years < 100 are treated as 1900 + year */
1096   if (lpUd->st.wYear < 100)
1097     lpUd->st.wYear += 1900;
1098
1099   if (!lpUd->st.wMonth)
1100   {
1101     /* Roll back to December of the previous year */
1102     lpUd->st.wMonth = 12;
1103     lpUd->st.wYear--;
1104   }
1105   else while (lpUd->st.wMonth > 12)
1106   {
1107     /* Roll forward the correct number of months */
1108     lpUd->st.wYear++;
1109     lpUd->st.wMonth -= 12;
1110   }
1111
1112   if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 ||
1113       lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59)
1114     return E_INVALIDARG; /* Invalid values */
1115
1116   if (!lpUd->st.wDay)
1117   {
1118     /* Roll back the date one day */
1119     if (lpUd->st.wMonth == 1)
1120     {
1121       /* Roll back to December 31 of the previous year */
1122       lpUd->st.wDay   = 31;
1123       lpUd->st.wMonth = 12;
1124       lpUd->st.wYear--;
1125     }
1126     else
1127     {
1128       lpUd->st.wMonth--; /* Previous month */
1129       if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
1130         lpUd->st.wDay = 29; /* Februaury has 29 days on leap years */
1131       else
1132         lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */
1133     }
1134   }
1135   else if (lpUd->st.wDay > 28)
1136   {
1137     int rollForward = 0;
1138
1139     /* Possibly need to roll the date forward */
1140     if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
1141       rollForward = lpUd->st.wDay - 29; /* Februaury has 29 days on leap years */
1142     else
1143       rollForward = lpUd->st.wDay - days[lpUd->st.wMonth];
1144
1145     if (rollForward > 0)
1146     {
1147       lpUd->st.wDay = rollForward;
1148       lpUd->st.wMonth++;
1149       if (lpUd->st.wMonth > 12)
1150       {
1151         lpUd->st.wMonth = 1; /* Roll forward into January of the next year */
1152         lpUd->st.wYear++;
1153       }
1154     }
1155   }
1156   TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
1157         lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
1158   return S_OK;
1159 }
1160
1161 /**********************************************************************
1162  *              DosDateTimeToVariantTime [OLEAUT32.14]
1163  *
1164  * Convert a Dos format date and time into variant VT_DATE format.
1165  *
1166  * PARAMS
1167  *  wDosDate [I] Dos format date
1168  *  wDosTime [I] Dos format time
1169  *  pDateOut [O] Destination for VT_DATE format
1170  *
1171  * RETURNS
1172  *  Success: TRUE. pDateOut contains the converted time.
1173  *  Failure: FALSE, if wDosDate or wDosTime are invalid (see notes).
1174  *
1175  * NOTES
1176  * - Dos format dates can only hold dates from 1-Jan-1980 to 31-Dec-2099.
1177  * - Dos format times are accurate to only 2 second precision.
1178  * - The format of a Dos Date is:
1179  *| Bits   Values  Meaning
1180  *| ----   ------  -------
1181  *| 0-4    1-31    Day of the week. 0 rolls back one day. A value greater than
1182  *|                the days in the month rolls forward the extra days.
1183  *| 5-8    1-12    Month of the year. 0 rolls back to December of the previous
1184  *|                year. 13-15 are invalid.
1185  *| 9-15   0-119   Year based from 1980 (Max 2099). 120-127 are invalid.
1186  * - The format of a Dos Time is:
1187  *| Bits   Values  Meaning
1188  *| ----   ------  -------
1189  *| 0-4    0-29    Seconds/2. 30 and 31 are invalid.
1190  *| 5-10   0-59    Minutes. 60-63 are invalid.
1191  *| 11-15  0-23    Hours (24 hour clock). 24-32 are invalid.
1192  */
1193 INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
1194                                     double *pDateOut)
1195 {
1196   UDATE ud;
1197
1198   TRACE("(0x%x(%d/%d/%d),0x%x(%d:%d:%d),%p)\n",
1199         wDosDate, DOS_YEAR(wDosDate), DOS_MONTH(wDosDate), DOS_DAY(wDosDate),
1200         wDosTime, DOS_HOUR(wDosTime), DOS_MINUTE(wDosTime), DOS_SECOND(wDosTime),
1201         pDateOut);
1202
1203   ud.st.wYear = DOS_YEAR(wDosDate);
1204   ud.st.wMonth = DOS_MONTH(wDosDate);
1205   if (ud.st.wYear > 2099 || ud.st.wMonth > 12)
1206     return FALSE;
1207   ud.st.wDay = DOS_DAY(wDosDate);
1208   ud.st.wHour = DOS_HOUR(wDosTime);
1209   ud.st.wMinute = DOS_MINUTE(wDosTime);
1210   ud.st.wSecond = DOS_SECOND(wDosTime);
1211   ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
1212
1213   return !VarDateFromUdate(&ud, 0, pDateOut);
1214 }
1215
1216 /**********************************************************************
1217  *              VariantTimeToDosDateTime [OLEAUT32.13]
1218  *
1219  * Convert a variant format date into a Dos format date and time.
1220  *
1221  *  dateIn    [I] VT_DATE time format
1222  *  pwDosDate [O] Destination for Dos format date
1223  *  pwDosTime [O] Destination for Dos format time
1224  *
1225  * RETURNS
1226  *  Success: TRUE. pwDosDate and pwDosTime contains the converted values.
1227  *  Failure: FALSE, if dateIn cannot be represented in Dos format.
1228  *
1229  * NOTES
1230  *   See DosDateTimeToVariantTime() for Dos format details and bugs.
1231  */
1232 INT WINAPI VariantTimeToDosDateTime(double dateIn, USHORT *pwDosDate, USHORT *pwDosTime)
1233 {
1234   UDATE ud;
1235
1236   TRACE("(%g,%p,%p)\n", dateIn, pwDosDate, pwDosTime);
1237
1238   if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1239     return FALSE;
1240
1241   if (ud.st.wYear < 1980 || ud.st.wYear > 2099)
1242     return FALSE;
1243
1244   *pwDosDate = DOS_DATE(ud.st.wDay, ud.st.wMonth, ud.st.wYear);
1245   *pwDosTime = DOS_TIME(ud.st.wHour, ud.st.wMinute, ud.st.wSecond);
1246
1247   TRACE("Returning 0x%x(%d/%d/%d), 0x%x(%d:%d:%d)\n",
1248         *pwDosDate, DOS_YEAR(*pwDosDate), DOS_MONTH(*pwDosDate), DOS_DAY(*pwDosDate),
1249         *pwDosTime, DOS_HOUR(*pwDosTime), DOS_MINUTE(*pwDosTime), DOS_SECOND(*pwDosTime));
1250   return TRUE;
1251 }
1252
1253 /***********************************************************************
1254  *              SystemTimeToVariantTime [OLEAUT32.184]
1255  *
1256  * Convert a System format date and time into variant VT_DATE format.
1257  *
1258  * PARAMS
1259  *  lpSt     [I] System format date and time
1260  *  pDateOut [O] Destination for VT_DATE format date
1261  *
1262  * RETURNS
1263  *  Success: TRUE. *pDateOut contains the converted value.
1264  *  Failure: FALSE, if lpSt cannot be represented in VT_DATE format.
1265  */
1266 INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut)
1267 {
1268   UDATE ud;
1269
1270   TRACE("(%p->%d/%d/%d %d:%d:%d,%p)\n", lpSt, lpSt->wDay, lpSt->wMonth,
1271         lpSt->wYear, lpSt->wHour, lpSt->wMinute, lpSt->wSecond, pDateOut);
1272
1273   if (lpSt->wMonth > 12)
1274     return FALSE;
1275
1276   memcpy(&ud.st, lpSt, sizeof(ud.st));
1277   return !VarDateFromUdate(&ud, 0, pDateOut);
1278 }
1279
1280 /***********************************************************************
1281  *              VariantTimeToSystemTime [OLEAUT32.185]
1282  *
1283  * Convert a variant VT_DATE into a System format date and time.
1284  *
1285  * PARAMS
1286  *  datein [I] Variant VT_DATE format date
1287  *  lpSt   [O] Destination for System format date and time
1288  *
1289  * RETURNS
1290  *  Success: TRUE. *lpSt contains the converted value.
1291  *  Failure: FALSE, if dateIn is too large or small.
1292  */
1293 INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt)
1294 {
1295   UDATE ud;
1296
1297   TRACE("(%g,%p)\n", dateIn, lpSt);
1298
1299   if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1300     return FALSE;
1301
1302   memcpy(lpSt, &ud.st, sizeof(ud.st));
1303   return TRUE;
1304 }
1305
1306 /***********************************************************************
1307  *              VarDateFromUdateEx [OLEAUT32.319]
1308  *
1309  * Convert an unpacked format date and time to a variant VT_DATE.
1310  *
1311  * PARAMS
1312  *  pUdateIn [I] Unpacked format date and time to convert
1313  *  lcid     [I] Locale identifier for the conversion
1314  *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1315  *  pDateOut [O] Destination for variant VT_DATE.
1316  *
1317  * RETURNS
1318  *  Success: S_OK. *pDateOut contains the converted value.
1319  *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
1320  */
1321 HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut)
1322 {
1323   UDATE ud;
1324   double dateVal;
1325
1326   TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08lx,0x%08lx,%p)\n", pUdateIn,
1327         pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
1328         pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond,
1329         pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek,
1330         pUdateIn->wDayOfYear, lcid, dwFlags, pDateOut);
1331
1332   if (lcid != MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT))
1333     FIXME("lcid possibly not handled, treating as en-us\n");
1334       
1335   memcpy(&ud, pUdateIn, sizeof(ud));
1336
1337   if (dwFlags & VAR_VALIDDATE)
1338     WARN("Ignoring VAR_VALIDDATE\n");
1339
1340   if (FAILED(VARIANT_RollUdate(&ud)))
1341     return E_INVALIDARG;
1342
1343   /* Date */
1344   dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay));
1345
1346   /* Time */
1347   dateVal += ud.st.wHour / 24.0;
1348   dateVal += ud.st.wMinute / 1440.0;
1349   dateVal += ud.st.wSecond / 86400.0;
1350   dateVal += ud.st.wMilliseconds / 86400000.0;
1351
1352   TRACE("Returning %g\n", dateVal);
1353   *pDateOut = dateVal;
1354   return S_OK;
1355 }
1356
1357 /***********************************************************************
1358  *              VarDateFromUdate [OLEAUT32.330]
1359  *
1360  * Convert an unpacked format date and time to a variant VT_DATE.
1361  *
1362  * PARAMS
1363  *  pUdateIn [I] Unpacked format date and time to convert
1364  *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1365  *  pDateOut [O] Destination for variant VT_DATE.
1366  *
1367  * RETURNS
1368  *  Success: S_OK. *pDateOut contains the converted value.
1369  *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
1370  *
1371  * NOTES
1372  *  This function uses the United States English locale for the conversion. Use
1373  *  VarDateFromUdateEx() for alternate locales.
1374  */
1375 HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
1376 {
1377   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
1378   
1379   return VarDateFromUdateEx(pUdateIn, lcid, dwFlags, pDateOut);
1380 }
1381
1382 /***********************************************************************
1383  *              VarUdateFromDate [OLEAUT32.331]
1384  *
1385  * Convert a variant VT_DATE into an unpacked format date and time.
1386  *
1387  * PARAMS
1388  *  datein    [I] Variant VT_DATE format date
1389  *  dwFlags   [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1390  *  lpUdate   [O] Destination for unpacked format date and time
1391  *
1392  * RETURNS
1393  *  Success: S_OK. *lpUdate contains the converted value.
1394  *  Failure: E_INVALIDARG, if dateIn is too large or small.
1395  */
1396 HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
1397 {
1398   /* Cumulative totals of days per month */
1399   static const USHORT cumulativeDays[] =
1400   {
1401     0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
1402   };
1403   double datePart, timePart;
1404   int julianDays;
1405
1406   TRACE("(%g,0x%08lx,%p)\n", dateIn, dwFlags, lpUdate);
1407
1408   if (dateIn <= (DATE_MIN - 1.0) || dateIn >= (DATE_MAX + 1.0))
1409     return E_INVALIDARG;
1410
1411   datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn);
1412   /* Compensate for int truncation (always downwards) */
1413   timePart = dateIn - datePart + 0.00000000001;
1414   if (timePart >= 1.0)
1415     timePart -= 0.00000000001;
1416
1417   /* Date */
1418   julianDays = VARIANT_JulianFromDate(dateIn);
1419   VARIANT_DMYFromJulian(julianDays, &lpUdate->st.wYear, &lpUdate->st.wMonth,
1420                         &lpUdate->st.wDay);
1421
1422   datePart = (datePart + 1.5) / 7.0;
1423   lpUdate->st.wDayOfWeek = (datePart - floor(datePart)) * 7;
1424   if (lpUdate->st.wDayOfWeek == 0)
1425     lpUdate->st.wDayOfWeek = 5;
1426   else if (lpUdate->st.wDayOfWeek == 1)
1427     lpUdate->st.wDayOfWeek = 6;
1428   else
1429     lpUdate->st.wDayOfWeek -= 2;
1430
1431   if (lpUdate->st.wMonth > 2 && IsLeapYear(lpUdate->st.wYear))
1432     lpUdate->wDayOfYear = 1; /* After February, in a leap year */
1433   else
1434     lpUdate->wDayOfYear = 0;
1435
1436   lpUdate->wDayOfYear += cumulativeDays[lpUdate->st.wMonth];
1437   lpUdate->wDayOfYear += lpUdate->st.wDay;
1438
1439   /* Time */
1440   timePart *= 24.0;
1441   lpUdate->st.wHour = timePart;
1442   timePart -= lpUdate->st.wHour;
1443   timePart *= 60.0;
1444   lpUdate->st.wMinute = timePart;
1445   timePart -= lpUdate->st.wMinute;
1446   timePart *= 60.0;
1447   lpUdate->st.wSecond = timePart;
1448   timePart -= lpUdate->st.wSecond;
1449   lpUdate->st.wMilliseconds = 0;
1450   if (timePart > 0.5)
1451   {
1452     /* Round the milliseconds, adjusting the time/date forward if needed */
1453     if (lpUdate->st.wSecond < 59)
1454       lpUdate->st.wSecond++;
1455     else
1456     {
1457       lpUdate->st.wSecond = 0;
1458       if (lpUdate->st.wMinute < 59)
1459         lpUdate->st.wMinute++;
1460       else
1461       {
1462         lpUdate->st.wMinute = 0;
1463         if (lpUdate->st.wHour < 23)
1464           lpUdate->st.wHour++;
1465         else
1466         {
1467           lpUdate->st.wHour = 0;
1468           /* Roll over a whole day */
1469           if (++lpUdate->st.wDay > 28)
1470             VARIANT_RollUdate(lpUdate);
1471         }
1472       }
1473     }
1474   }
1475   return S_OK;
1476 }
1477
1478 #define GET_NUMBER_TEXT(fld,name) \
1479   buff[0] = 0; \
1480   if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \
1481     WARN("buffer too small for " #fld "\n"); \
1482   else \
1483     if (buff[0]) lpChars->name = buff[0]; \
1484   TRACE("lcid 0x%lx, " #name "=%d '%c'\n", lcid, lpChars->name, lpChars->name)
1485
1486 /* Get the valid number characters for an lcid */
1487 void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
1488 {
1489   static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',',','$',0,'.',',' };
1490   LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE;
1491   WCHAR buff[4];
1492
1493   memcpy(lpChars, &defaultChars, sizeof(defaultChars));
1494   GET_NUMBER_TEXT(LOCALE_SNEGATIVESIGN, cNegativeSymbol);
1495   GET_NUMBER_TEXT(LOCALE_SPOSITIVESIGN, cPositiveSymbol);
1496   GET_NUMBER_TEXT(LOCALE_SDECIMAL, cDecimalPoint);
1497   GET_NUMBER_TEXT(LOCALE_STHOUSAND, cDigitSeperator);
1498   GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint);
1499   GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeperator);
1500
1501   /* Local currency symbols are often 2 characters */
1502   lpChars->cCurrencyLocal2 = '\0';
1503   switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR)))
1504   {
1505     case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
1506     case 2: lpChars->cCurrencyLocal  = buff[0];
1507             break;
1508     default: WARN("buffer too small for LOCALE_SCURRENCY\n");
1509   }
1510   TRACE("lcid 0x%lx, cCurrencyLocal =%d,%d '%c','%c'\n", lcid, lpChars->cCurrencyLocal,
1511         lpChars->cCurrencyLocal2, lpChars->cCurrencyLocal, lpChars->cCurrencyLocal2);
1512 }
1513
1514 /* Number Parsing States */
1515 #define B_PROCESSING_EXPONENT 0x1
1516 #define B_NEGATIVE_EXPONENT   0x2
1517 #define B_EXPONENT_START      0x4
1518 #define B_INEXACT_ZEROS       0x8
1519 #define B_LEADING_ZERO        0x10
1520 #define B_PROCESSING_HEX      0x20
1521 #define B_PROCESSING_OCT      0x40
1522
1523 /**********************************************************************
1524  *              VarParseNumFromStr [OLEAUT32.46]
1525  *
1526  * Parse a string containing a number into a NUMPARSE structure.
1527  *
1528  * PARAMS
1529  *  lpszStr [I]   String to parse number from
1530  *  lcid    [I]   Locale Id for the conversion
1531  *  dwFlags [I]   0, or LOCALE_NOUSEROVERRIDE to use system default number chars
1532  *  pNumprs [I/O] Destination for parsed number
1533  *  rgbDig  [O]   Destination for digits read in
1534  *
1535  * RETURNS
1536  *  Success: S_OK. pNumprs and rgbDig contain the parsed representation of
1537  *           the number.
1538  *  Failure: E_INVALIDARG, if any parameter is invalid.
1539  *           DISP_E_TYPEMISMATCH, if the string is not a number or is formatted
1540  *           incorrectly.
1541  *           DISP_E_OVERFLOW, if rgbDig is too small to hold the number.
1542  *
1543  * NOTES
1544  *  pNumprs must have the following fields set:
1545  *   cDig: Set to the size of rgbDig.
1546  *   dwInFlags: Set to the allowable syntax of the number using NUMPRS_ flags
1547  *            from "oleauto.h".
1548  *
1549  * FIXME
1550  *  - I am unsure if this function should parse non-arabic (e.g. Thai)
1551  *   numerals, so this has not been implemented.
1552  */
1553 HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
1554                                   NUMPARSE *pNumprs, BYTE *rgbDig)
1555 {
1556   VARIANT_NUMBER_CHARS chars;
1557   BYTE rgbTmp[1024];
1558   DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;
1559   int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE);
1560   int cchUsed = 0;
1561
1562   TRACE("(%s,%ld,0x%08lx,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig);
1563
1564   if (!pNumprs || !rgbDig)
1565     return E_INVALIDARG;
1566
1567   if (pNumprs->cDig < iMaxDigits)
1568     iMaxDigits = pNumprs->cDig;
1569
1570   pNumprs->cDig = 0;
1571   pNumprs->dwOutFlags = 0;
1572   pNumprs->cchUsed = 0;
1573   pNumprs->nBaseShift = 0;
1574   pNumprs->nPwr10 = 0;
1575
1576   if (!lpszStr)
1577     return DISP_E_TYPEMISMATCH;
1578
1579   VARIANT_GetLocalisedNumberChars(&chars, lcid, dwFlags);
1580
1581   /* First consume all the leading symbols and space from the string */
1582   while (1)
1583   {
1584     if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && isspaceW(*lpszStr))
1585     {
1586       pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;
1587       do
1588       {
1589         cchUsed++;
1590         lpszStr++;
1591       } while (isspaceW(*lpszStr));
1592     }
1593     else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS &&
1594              *lpszStr == chars.cPositiveSymbol &&
1595              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS))
1596     {
1597       pNumprs->dwOutFlags |= NUMPRS_LEADING_PLUS;
1598       cchUsed++;
1599       lpszStr++;
1600     }
1601     else if (pNumprs->dwInFlags & NUMPRS_LEADING_MINUS &&
1602              *lpszStr == chars.cNegativeSymbol &&
1603              !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS))
1604     {
1605       pNumprs->dwOutFlags |= (NUMPRS_LEADING_MINUS|NUMPRS_NEG);
1606       cchUsed++;
1607       lpszStr++;
1608     }
1609     else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
1610              !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) &&
1611              *lpszStr == chars.cCurrencyLocal &&
1612              (!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2))
1613     {
1614       pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1615       cchUsed++;
1616       lpszStr++;
1617       /* Only accept currency characters */
1618       chars.cDecimalPoint = chars.cCurrencyDecimalPoint;
1619       chars.cDigitSeperator = chars.cCurrencyDigitSeperator;
1620     }
1621     else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' &&
1622              !(pNumprs->dwOutFlags & NUMPRS_PARENS))
1623     {
1624       pNumprs->dwOutFlags |= NUMPRS_PARENS;
1625       cchUsed++;
1626       lpszStr++;
1627     }
1628     else
1629       break;
1630   }
1631
1632   if (!(pNumprs->dwOutFlags & NUMPRS_CURRENCY))
1633   {
1634     /* Only accept non-currency characters */
1635     chars.cCurrencyDecimalPoint = chars.cDecimalPoint;
1636     chars.cCurrencyDigitSeperator = chars.cDigitSeperator;
1637   }
1638
1639   if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&
1640     pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1641   {
1642       dwState |= B_PROCESSING_HEX;
1643       pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
1644       cchUsed=cchUsed+2;
1645       lpszStr=lpszStr+2;
1646   }
1647   else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&
1648     pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1649   {
1650       dwState |= B_PROCESSING_OCT;
1651       pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
1652       cchUsed=cchUsed+2;
1653       lpszStr=lpszStr+2;
1654   }
1655
1656   /* Strip Leading zeros */
1657   while (*lpszStr == '0')
1658   {
1659     dwState |= B_LEADING_ZERO;
1660     cchUsed++;
1661     lpszStr++;
1662   }
1663
1664   while (*lpszStr)
1665   {
1666     if (isdigitW(*lpszStr))
1667     {
1668       if (dwState & B_PROCESSING_EXPONENT)
1669       {
1670         int exponentSize = 0;
1671         if (dwState & B_EXPONENT_START)
1672         {
1673           if (!isdigitW(*lpszStr))
1674             break; /* No exponent digits - invalid */
1675           while (*lpszStr == '0')
1676           {
1677             /* Skip leading zero's in the exponent */
1678             cchUsed++;
1679             lpszStr++;
1680           }
1681         }
1682
1683         while (isdigitW(*lpszStr))
1684         {
1685           exponentSize *= 10;
1686           exponentSize += *lpszStr - '0';
1687           cchUsed++;
1688           lpszStr++;
1689         }
1690         if (dwState & B_NEGATIVE_EXPONENT)
1691           exponentSize = -exponentSize;
1692         /* Add the exponent into the powers of 10 */
1693         pNumprs->nPwr10 += exponentSize;
1694         dwState &= ~(B_PROCESSING_EXPONENT|B_EXPONENT_START);
1695         lpszStr--; /* back up to allow processing of next char */
1696       }
1697       else
1698       {
1699         if ((pNumprs->cDig >= iMaxDigits) && !(dwState & B_PROCESSING_HEX)
1700           && !(dwState & B_PROCESSING_OCT))
1701         {
1702           pNumprs->dwOutFlags |= NUMPRS_INEXACT;
1703
1704           if (*lpszStr != '0')
1705             dwState &= ~B_INEXACT_ZEROS; /* Inexact number with non-trailing zeros */
1706
1707           /* This digit can't be represented, but count it in nPwr10 */
1708           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1709             pNumprs->nPwr10--;
1710           else
1711             pNumprs->nPwr10++;
1712         }
1713         else
1714         {
1715           if ((dwState & B_PROCESSING_OCT) && ((*lpszStr == '8') || (*lpszStr == '9'))) {
1716             return DISP_E_TYPEMISMATCH;
1717           }
1718
1719           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1720             pNumprs->nPwr10--; /* Count decimal points in nPwr10 */
1721
1722           rgbTmp[pNumprs->cDig] = *lpszStr - '0';
1723         }
1724         pNumprs->cDig++;
1725         cchUsed++;
1726       }
1727     }
1728     else if (*lpszStr == chars.cDigitSeperator && pNumprs->dwInFlags & NUMPRS_THOUSANDS)
1729     {
1730       pNumprs->dwOutFlags |= NUMPRS_THOUSANDS;
1731       cchUsed++;
1732     }
1733     else if (*lpszStr == chars.cDecimalPoint &&
1734              pNumprs->dwInFlags & NUMPRS_DECIMAL &&
1735              !(pNumprs->dwOutFlags & (NUMPRS_DECIMAL|NUMPRS_EXPONENT)))
1736     {
1737       pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
1738       cchUsed++;
1739
1740       /* If we have no digits so far, skip leading zeros */
1741       if (!pNumprs->cDig)
1742       {
1743         while (lpszStr[1] == '0')
1744         {
1745           dwState |= B_LEADING_ZERO;
1746           cchUsed++;
1747           lpszStr++;
1748           pNumprs->nPwr10--;
1749         }
1750       }
1751     }
1752     else if ((*lpszStr == 'e' || *lpszStr == 'E') &&
1753              pNumprs->dwInFlags & NUMPRS_EXPONENT &&
1754              !(pNumprs->dwOutFlags & NUMPRS_EXPONENT))
1755     {
1756       dwState |= B_PROCESSING_EXPONENT;
1757       pNumprs->dwOutFlags |= NUMPRS_EXPONENT;
1758       cchUsed++;
1759     }
1760     else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cPositiveSymbol)
1761     {
1762       cchUsed++; /* Ignore positive exponent */
1763     }
1764     else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cNegativeSymbol)
1765     {
1766       dwState |= B_NEGATIVE_EXPONENT;
1767       cchUsed++;
1768     }
1769     else if (((*lpszStr >= 'a' && *lpszStr <= 'f') ||
1770              (*lpszStr >= 'A' && *lpszStr <= 'F')) &&
1771              dwState & B_PROCESSING_HEX)
1772     {
1773       if (pNumprs->cDig >= iMaxDigits)
1774       {
1775         return DISP_E_OVERFLOW;
1776       }
1777       else
1778       {
1779         if (*lpszStr >= 'a')
1780           rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10;
1781         else
1782           rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10;
1783       }
1784       pNumprs->cDig++;
1785       cchUsed++;
1786     }
1787     else
1788       break; /* Stop at an unrecognised character */
1789
1790     lpszStr++;
1791   }
1792
1793   if (!pNumprs->cDig && dwState & B_LEADING_ZERO)
1794   {
1795     /* Ensure a 0 on its own gets stored */
1796     pNumprs->cDig = 1;
1797     rgbTmp[0] = 0;
1798   }
1799
1800   if (pNumprs->dwOutFlags & NUMPRS_EXPONENT && dwState & B_PROCESSING_EXPONENT)
1801   {
1802     pNumprs->cchUsed = cchUsed;
1803     return DISP_E_TYPEMISMATCH; /* Failed to completely parse the exponent */
1804   }
1805
1806   if (pNumprs->dwOutFlags & NUMPRS_INEXACT)
1807   {
1808     if (dwState & B_INEXACT_ZEROS)
1809       pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* All zeros doesn't set NUMPRS_INEXACT */
1810   } else if(pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1811   {
1812     /* copy all of the digits into the output digit buffer */
1813     /* this is exactly what windows does although it also returns */
1814     /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */
1815     memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1816
1817     if (dwState & B_PROCESSING_HEX) {
1818       /* hex numbers have always the same format */
1819       pNumprs->nPwr10=0;
1820       pNumprs->nBaseShift=4;
1821     } else {
1822       if (dwState & B_PROCESSING_OCT) {
1823         /* oct numbers have always the same format */
1824         pNumprs->nPwr10=0;
1825         pNumprs->nBaseShift=3;
1826       } else {
1827         while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1828         {
1829           pNumprs->nPwr10++;
1830           pNumprs->cDig--;
1831         }
1832       }
1833     }
1834   } else
1835   {
1836     /* Remove trailing zeros from the last (whole number or decimal) part */
1837     while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1838     {
1839       pNumprs->nPwr10++;
1840       pNumprs->cDig--;
1841     }
1842   }
1843
1844   if (pNumprs->cDig <= iMaxDigits)
1845     pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* Ignore stripped zeros for NUMPRS_INEXACT */
1846   else
1847     pNumprs->cDig = iMaxDigits; /* Only return iMaxDigits worth of digits */
1848
1849   /* Copy the digits we processed into rgbDig */
1850   memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1851
1852   /* Consume any trailing symbols and space */
1853   while (1)
1854   {
1855     if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && isspaceW(*lpszStr))
1856     {
1857       pNumprs->dwOutFlags |= NUMPRS_TRAILING_WHITE;
1858       do
1859       {
1860         cchUsed++;
1861         lpszStr++;
1862       } while (isspaceW(*lpszStr));
1863     }
1864     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS &&
1865              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) &&
1866              *lpszStr == chars.cPositiveSymbol)
1867     {
1868       pNumprs->dwOutFlags |= NUMPRS_TRAILING_PLUS;
1869       cchUsed++;
1870       lpszStr++;
1871     }
1872     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_MINUS &&
1873              !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS) &&
1874              *lpszStr == chars.cNegativeSymbol)
1875     {
1876       pNumprs->dwOutFlags |= (NUMPRS_TRAILING_MINUS|NUMPRS_NEG);
1877       cchUsed++;
1878       lpszStr++;
1879     }
1880     else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == ')' &&
1881              pNumprs->dwOutFlags & NUMPRS_PARENS)
1882     {
1883       cchUsed++;
1884       lpszStr++;
1885       pNumprs->dwOutFlags |= NUMPRS_NEG;
1886     }
1887     else
1888       break;
1889   }
1890
1891   if (pNumprs->dwOutFlags & NUMPRS_PARENS && !(pNumprs->dwOutFlags & NUMPRS_NEG))
1892   {
1893     pNumprs->cchUsed = cchUsed;
1894     return DISP_E_TYPEMISMATCH; /* Opening parenthesis not matched */
1895   }
1896
1897   if (pNumprs->dwInFlags & NUMPRS_USE_ALL && *lpszStr != '\0')
1898     return DISP_E_TYPEMISMATCH; /* Not all chars were consumed */
1899
1900   if (!pNumprs->cDig)
1901     return DISP_E_TYPEMISMATCH; /* No Number found */
1902
1903   pNumprs->cchUsed = cchUsed;
1904   return S_OK;
1905 }
1906
1907 /* VTBIT flags indicating an integer value */
1908 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
1909 /* VTBIT flags indicating a real number value */
1910 #define REAL_VTBITS (VTBIT_R4|VTBIT_R8|VTBIT_CY)
1911
1912 /* Helper macros to check whether bit pattern fits in VARIANT (x is a ULONG64 ) */
1913 #define FITS_AS_I1(x) ((x) >> 8 == 0)
1914 #define FITS_AS_I2(x) ((x) >> 16 == 0)
1915 #define FITS_AS_I4(x) ((x) >> 32 == 0)
1916
1917 /**********************************************************************
1918  *              VarNumFromParseNum [OLEAUT32.47]
1919  *
1920  * Convert a NUMPARSE structure into a numeric Variant type.
1921  *
1922  * PARAMS
1923  *  pNumprs  [I] Source for parsed number. cDig must be set to the size of rgbDig
1924  *  rgbDig   [I] Source for the numbers digits
1925  *  dwVtBits [I] VTBIT_ flags from "oleauto.h" indicating the acceptable dest types
1926  *  pVarDst  [O] Destination for the converted Variant value.
1927  *
1928  * RETURNS
1929  *  Success: S_OK. pVarDst contains the converted value.
1930  *  Failure: E_INVALIDARG, if any parameter is invalid.
1931  *           DISP_E_OVERFLOW, if the number is too big for the types set in dwVtBits.
1932  *
1933  * NOTES
1934  *  - The smallest favoured type present in dwVtBits that can represent the
1935  *    number in pNumprs without losing precision is used.
1936  *  - Signed types are preferrred over unsigned types of the same size.
1937  *  - Preferred types in order are: integer, float, double, currency then decimal.
1938  *  - Rounding (dropping of decimal points) occurs without error. See VarI8FromR8()
1939  *    for details of the rounding method.
1940  *  - pVarDst is not cleared before the result is stored in it.
1941  */
1942 HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
1943                                   ULONG dwVtBits, VARIANT *pVarDst)
1944 {
1945   /* Scale factors and limits for double arithmetic */
1946   static const double dblMultipliers[11] = {
1947     1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0,
1948     1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0
1949   };
1950   static const double dblMinimums[11] = {
1951     R8_MIN, R8_MIN*10.0, R8_MIN*100.0, R8_MIN*1000.0, R8_MIN*10000.0,
1952     R8_MIN*100000.0, R8_MIN*1000000.0, R8_MIN*10000000.0,
1953     R8_MIN*100000000.0, R8_MIN*1000000000.0, R8_MIN*10000000000.0
1954   };
1955   static const double dblMaximums[11] = {
1956     R8_MAX, R8_MAX/10.0, R8_MAX/100.0, R8_MAX/1000.0, R8_MAX/10000.0,
1957     R8_MAX/100000.0, R8_MAX/1000000.0, R8_MAX/10000000.0,
1958     R8_MAX/100000000.0, R8_MAX/1000000000.0, R8_MAX/10000000000.0
1959   };
1960
1961   int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0;
1962
1963   TRACE("(%p,%p,0x%lx,%p)\n", pNumprs, rgbDig, dwVtBits, pVarDst);
1964
1965   if (pNumprs->nBaseShift)
1966   {
1967     /* nBaseShift indicates a hex or octal number */
1968     ULONG64 ul64 = 0;
1969     LONG64 l64;
1970     int i;
1971
1972     /* Convert the hex or octal number string into a UI64 */
1973     for (i = 0; i < pNumprs->cDig; i++)
1974     {
1975       if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i]))
1976       {
1977         TRACE("Overflow multiplying digits\n");
1978         return DISP_E_OVERFLOW;
1979       }
1980       ul64 = (ul64<<pNumprs->nBaseShift) + rgbDig[i];
1981     }
1982
1983     /* also make a negative representation */
1984     l64=-ul64;
1985
1986     /* Try signed and unsigned types in size order */
1987     if (dwVtBits & VTBIT_I1 && FITS_AS_I1(ul64))
1988     {
1989       V_VT(pVarDst) = VT_I1;
1990       V_I1(pVarDst) = ul64;
1991       return S_OK;
1992     }
1993     else if (dwVtBits & VTBIT_UI1 && FITS_AS_I1(ul64))
1994     {
1995       V_VT(pVarDst) = VT_UI1;
1996       V_UI1(pVarDst) = ul64;
1997       return S_OK;
1998     }
1999     else if (dwVtBits & VTBIT_I2 && FITS_AS_I2(ul64))
2000     {
2001       V_VT(pVarDst) = VT_I2;
2002       V_I2(pVarDst) = ul64;
2003       return S_OK;
2004     }
2005     else if (dwVtBits & VTBIT_UI2 && FITS_AS_I2(ul64))
2006     {
2007       V_VT(pVarDst) = VT_UI2;
2008       V_UI2(pVarDst) = ul64;
2009       return S_OK;
2010     }
2011     else if (dwVtBits & VTBIT_I4 && FITS_AS_I4(ul64))
2012     {
2013       V_VT(pVarDst) = VT_I4;
2014       V_I4(pVarDst) = ul64;
2015       return S_OK;
2016     }
2017     else if (dwVtBits & VTBIT_UI4 && FITS_AS_I4(ul64))
2018     {
2019       V_VT(pVarDst) = VT_UI4;
2020       V_UI4(pVarDst) = ul64;
2021       return S_OK;
2022     }
2023     else if (dwVtBits & VTBIT_I8 && ((ul64 <= I8_MAX)||(l64>=I8_MIN)))
2024     {
2025       V_VT(pVarDst) = VT_I8;
2026       V_I8(pVarDst) = ul64;
2027       return S_OK;
2028     }
2029     else if (dwVtBits & VTBIT_UI8)
2030     {
2031       V_VT(pVarDst) = VT_UI8;
2032       V_UI8(pVarDst) = ul64;
2033       return S_OK;
2034     }
2035     else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2036     {
2037       V_VT(pVarDst) = VT_DECIMAL;
2038       DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
2039       DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2040       DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
2041       return S_OK;
2042     }
2043     else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
2044     {
2045       V_VT(pVarDst) = VT_R4;
2046       if (ul64 <= I4_MAX)
2047           V_R4(pVarDst) = ul64;
2048       else
2049           V_R4(pVarDst) = l64;
2050       return S_OK;
2051     }
2052     else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
2053     {
2054       V_VT(pVarDst) = VT_R8;
2055       if (ul64 <= I4_MAX)
2056           V_R8(pVarDst) = ul64;
2057       else
2058           V_R8(pVarDst) = l64;
2059       return S_OK;
2060     }
2061
2062     TRACE("Overflow: possible return types: 0x%lx, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64));
2063     return DISP_E_OVERFLOW;
2064   }
2065
2066   /* Count the number of relevant fractional and whole digits stored,
2067    * And compute the divisor/multiplier to scale the number by.
2068    */
2069   if (pNumprs->nPwr10 < 0)
2070   {
2071     if (-pNumprs->nPwr10 >= pNumprs->cDig)
2072     {
2073       /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */
2074       wholeNumberDigits = 0;
2075       fractionalDigits = pNumprs->cDig;
2076       divisor10 = -pNumprs->nPwr10;
2077     }
2078     else
2079     {
2080       /* An exactly represented real number e.g. 1.024 */
2081       wholeNumberDigits = pNumprs->cDig + pNumprs->nPwr10;
2082       fractionalDigits = pNumprs->cDig - wholeNumberDigits;
2083       divisor10 = pNumprs->cDig - wholeNumberDigits;
2084     }
2085   }
2086   else if (pNumprs->nPwr10 == 0)
2087   {
2088     /* An exactly represented whole number e.g. 1024 */
2089     wholeNumberDigits = pNumprs->cDig;
2090     fractionalDigits = 0;
2091   }
2092   else /* pNumprs->nPwr10 > 0 */
2093   {
2094     /* A whole number followed by nPwr10 0's e.g. 102400 */
2095     wholeNumberDigits = pNumprs->cDig;
2096     fractionalDigits = 0;
2097     multiplier10 = pNumprs->nPwr10;
2098   }
2099
2100   TRACE("cDig %d; nPwr10 %d, whole %d, frac %d ", pNumprs->cDig,
2101         pNumprs->nPwr10, wholeNumberDigits, fractionalDigits);
2102   TRACE("mult %d; div %d\n", multiplier10, divisor10);
2103
2104   if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) &&
2105       (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL))))
2106   {
2107     /* We have one or more integer output choices, and either:
2108      *  1) An integer input value, or
2109      *  2) A real number input value but no floating output choices.
2110      * Alternately, we have a DECIMAL output available and an integer input.
2111      *
2112      * So, place the integer value into pVarDst, using the smallest type
2113      * possible and preferring signed over unsigned types.
2114      */
2115     BOOL bOverflow = FALSE, bNegative;
2116     ULONG64 ul64 = 0;
2117     int i;
2118
2119     /* Convert the integer part of the number into a UI8 */
2120     for (i = 0; i < wholeNumberDigits; i++)
2121     {
2122       if (ul64 > (UI8_MAX / 10 - rgbDig[i]))
2123       {
2124         TRACE("Overflow multiplying digits\n");
2125         bOverflow = TRUE;
2126         break;
2127       }
2128       ul64 = ul64 * 10 + rgbDig[i];
2129     }
2130
2131     /* Account for the scale of the number */
2132     if (!bOverflow && multiplier10)
2133     {
2134       for (i = 0; i < multiplier10; i++)
2135       {
2136         if (ul64 > (UI8_MAX / 10))
2137         {
2138           TRACE("Overflow scaling number\n");
2139           bOverflow = TRUE;
2140           break;
2141         }
2142         ul64 = ul64 * 10;
2143       }
2144     }
2145
2146     /* If we have any fractional digits, round the value.
2147      * Note we don't have to do this if divisor10 is < 1,
2148      * because this means the fractional part must be < 0.5
2149      */
2150     if (!bOverflow && fractionalDigits && divisor10 > 0)
2151     {
2152       const BYTE* fracDig = rgbDig + wholeNumberDigits;
2153       BOOL bAdjust = FALSE;
2154
2155       TRACE("first decimal value is %d\n", *fracDig);
2156
2157       if (*fracDig > 5)
2158         bAdjust = TRUE; /* > 0.5 */
2159       else if (*fracDig == 5)
2160       {
2161         for (i = 1; i < fractionalDigits; i++)
2162         {
2163           if (fracDig[i])
2164           {
2165             bAdjust = TRUE; /* > 0.5 */
2166             break;
2167           }
2168         }
2169         /* If exactly 0.5, round only odd values */
2170         if (i == fractionalDigits && (ul64 & 1))
2171           bAdjust = TRUE;
2172       }
2173
2174       if (bAdjust)
2175       {
2176         if (ul64 == UI8_MAX)
2177         {
2178           TRACE("Overflow after rounding\n");
2179           bOverflow = TRUE;
2180         }
2181         ul64++;
2182       }
2183     }
2184
2185     /* Zero is not a negative number */
2186     bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64 ? TRUE : FALSE;
2187
2188     TRACE("Integer value is %lld, bNeg %d\n", ul64, bNegative);
2189
2190     /* For negative integers, try the signed types in size order */
2191     if (!bOverflow && bNegative)
2192     {
2193       if (dwVtBits & (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8))
2194       {
2195         if (dwVtBits & VTBIT_I1 && ul64 <= -I1_MIN)
2196         {
2197           V_VT(pVarDst) = VT_I1;
2198           V_I1(pVarDst) = -ul64;
2199           return S_OK;
2200         }
2201         else if (dwVtBits & VTBIT_I2 && ul64 <= -I2_MIN)
2202         {
2203           V_VT(pVarDst) = VT_I2;
2204           V_I2(pVarDst) = -ul64;
2205           return S_OK;
2206         }
2207         else if (dwVtBits & VTBIT_I4 && ul64 <= -((LONGLONG)I4_MIN))
2208         {
2209           V_VT(pVarDst) = VT_I4;
2210           V_I4(pVarDst) = -ul64;
2211           return S_OK;
2212         }
2213         else if (dwVtBits & VTBIT_I8 && ul64 <= (ULONGLONG)I8_MAX + 1)
2214         {
2215           V_VT(pVarDst) = VT_I8;
2216           V_I8(pVarDst) = -ul64;
2217           return S_OK;
2218         }
2219         else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2220         {
2221           /* Decimal is only output choice left - fast path */
2222           V_VT(pVarDst) = VT_DECIMAL;
2223           DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_NEG,0);
2224           DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2225           DEC_LO64(&V_DECIMAL(pVarDst)) = -ul64;
2226           return S_OK;
2227         }
2228       }
2229     }
2230     else if (!bOverflow)
2231     {
2232       /* For positive integers, try signed then unsigned types in size order */
2233       if (dwVtBits & VTBIT_I1 && ul64 <= I1_MAX)
2234       {
2235         V_VT(pVarDst) = VT_I1;
2236         V_I1(pVarDst) = ul64;
2237         return S_OK;
2238       }
2239       else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX)
2240       {
2241         V_VT(pVarDst) = VT_UI1;
2242         V_UI1(pVarDst) = ul64;
2243         return S_OK;
2244       }
2245       else if (dwVtBits & VTBIT_I2 && ul64 <= I2_MAX)
2246       {
2247         V_VT(pVarDst) = VT_I2;
2248         V_I2(pVarDst) = ul64;
2249         return S_OK;
2250       }
2251       else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX)
2252       {
2253         V_VT(pVarDst) = VT_UI2;
2254         V_UI2(pVarDst) = ul64;
2255         return S_OK;
2256       }
2257       else if (dwVtBits & VTBIT_I4 && ul64 <= I4_MAX)
2258       {
2259         V_VT(pVarDst) = VT_I4;
2260         V_I4(pVarDst) = ul64;
2261         return S_OK;
2262       }
2263       else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX)
2264       {
2265         V_VT(pVarDst) = VT_UI4;
2266         V_UI4(pVarDst) = ul64;
2267         return S_OK;
2268       }
2269       else if (dwVtBits & VTBIT_I8 && ul64 <= I8_MAX)
2270       {
2271         V_VT(pVarDst) = VT_I8;
2272         V_I8(pVarDst) = ul64;
2273         return S_OK;
2274       }
2275       else if (dwVtBits & VTBIT_UI8)
2276       {
2277         V_VT(pVarDst) = VT_UI8;
2278         V_UI8(pVarDst) = ul64;
2279         return S_OK;
2280       }
2281       else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2282       {
2283         /* Decimal is only output choice left - fast path */
2284         V_VT(pVarDst) = VT_DECIMAL;
2285         DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
2286         DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2287         DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
2288         return S_OK;
2289       }
2290     }
2291   }
2292
2293   if (dwVtBits & REAL_VTBITS)
2294   {
2295     /* Try to put the number into a float or real */
2296     BOOL bOverflow = FALSE, bNegative = pNumprs->dwOutFlags & NUMPRS_NEG;
2297     double whole = 0.0;
2298     int i;
2299
2300     /* Convert the number into a double */
2301     for (i = 0; i < pNumprs->cDig; i++)
2302       whole = whole * 10.0 + rgbDig[i];
2303
2304     TRACE("Whole double value is %16.16g\n", whole);
2305
2306     /* Account for the scale */
2307     while (multiplier10 > 10)
2308     {
2309       if (whole > dblMaximums[10])
2310       {
2311         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2312         bOverflow = TRUE;
2313         break;
2314       }
2315       whole = whole * dblMultipliers[10];
2316       multiplier10 -= 10;
2317     }
2318     if (multiplier10)
2319     {
2320       if (whole > dblMaximums[multiplier10])
2321       {
2322         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2323         bOverflow = TRUE;
2324       }
2325       else
2326         whole = whole * dblMultipliers[multiplier10];
2327     }
2328
2329     TRACE("Scaled double value is %16.16g\n", whole);
2330
2331     while (divisor10 > 10)
2332     {
2333       if (whole < dblMinimums[10] && whole != 0)
2334       {
2335         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
2336         bOverflow = TRUE;
2337         break;
2338       }
2339       whole = whole / dblMultipliers[10];
2340       divisor10 -= 10;
2341     }
2342     if (divisor10)
2343     {
2344       if (whole < dblMinimums[divisor10] && whole != 0)
2345       {
2346         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
2347         bOverflow = TRUE;
2348       }
2349       else
2350         whole = whole / dblMultipliers[divisor10];
2351     }
2352     if (!bOverflow)
2353       TRACE("Final double value is %16.16g\n", whole);
2354
2355     if (dwVtBits & VTBIT_R4 &&
2356         ((whole <= R4_MAX && whole >= R4_MIN) || whole == 0.0))
2357     {
2358       TRACE("Set R4 to final value\n");
2359       V_VT(pVarDst) = VT_R4; /* Fits into a float */
2360       V_R4(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2361       return S_OK;
2362     }
2363
2364     if (dwVtBits & VTBIT_R8)
2365     {
2366       TRACE("Set R8 to final value\n");
2367       V_VT(pVarDst) = VT_R8; /* Fits into a double */
2368       V_R8(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2369       return S_OK;
2370     }
2371
2372     if (dwVtBits & VTBIT_CY)
2373     {
2374       if (SUCCEEDED(VarCyFromR8(bNegative ? -whole : whole, &V_CY(pVarDst))))
2375       {
2376         V_VT(pVarDst) = VT_CY; /* Fits into a currency */
2377         TRACE("Set CY to final value\n");
2378         return S_OK;
2379       }
2380       TRACE("Value Overflows CY\n");
2381     }
2382   }
2383
2384   if (dwVtBits & VTBIT_DECIMAL)
2385   {
2386     int i;
2387     ULONG carry;
2388     ULONG64 tmp;
2389     DECIMAL* pDec = &V_DECIMAL(pVarDst);
2390
2391     DECIMAL_SETZERO(*pDec);
2392     DEC_LO32(pDec) = 0;
2393
2394     if (pNumprs->dwOutFlags & NUMPRS_NEG)
2395       DEC_SIGN(pDec) = DECIMAL_NEG;
2396     else
2397       DEC_SIGN(pDec) = DECIMAL_POS;
2398
2399     /* Factor the significant digits */
2400     for (i = 0; i < pNumprs->cDig; i++)
2401     {
2402       tmp = (ULONG64)DEC_LO32(pDec) * 10 + rgbDig[i];
2403       carry = (ULONG)(tmp >> 32);
2404       DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
2405       tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
2406       carry = (ULONG)(tmp >> 32);
2407       DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
2408       tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
2409       DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
2410
2411       if (tmp >> 32 & UI4_MAX)
2412       {
2413 VarNumFromParseNum_DecOverflow:
2414         TRACE("Overflow\n");
2415         DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX;
2416         return DISP_E_OVERFLOW;
2417       }
2418     }
2419
2420     /* Account for the scale of the number */
2421     while (multiplier10 > 0)
2422     {
2423       tmp = (ULONG64)DEC_LO32(pDec) * 10;
2424       carry = (ULONG)(tmp >> 32);
2425       DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
2426       tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
2427       carry = (ULONG)(tmp >> 32);
2428       DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
2429       tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
2430       DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
2431
2432       if (tmp >> 32 & UI4_MAX)
2433         goto VarNumFromParseNum_DecOverflow;
2434       multiplier10--;
2435     }
2436     DEC_SCALE(pDec) = divisor10;
2437
2438     V_VT(pVarDst) = VT_DECIMAL;
2439     return S_OK;
2440   }
2441   return DISP_E_OVERFLOW; /* No more output choices */
2442 }
2443
2444 /**********************************************************************
2445  *              VarCat [OLEAUT32.318]
2446  */
2447 HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
2448 {
2449     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2450           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), out);
2451
2452     /* Should we VariantClear out? */
2453     /* Can we handle array, vector, by ref etc. */
2454     if ((V_VT(left)&VT_TYPEMASK) == VT_NULL &&
2455         (V_VT(right)&VT_TYPEMASK) == VT_NULL)
2456     {
2457         V_VT(out) = VT_NULL;
2458         return S_OK;
2459     }
2460
2461     if (V_VT(left) == VT_BSTR && V_VT(right) == VT_BSTR)
2462     {
2463         V_VT(out) = VT_BSTR;
2464         VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
2465         return S_OK;
2466     }
2467     if (V_VT(left) == VT_BSTR) {
2468         VARIANT bstrvar;
2469         HRESULT hres;
2470
2471         V_VT(out) = VT_BSTR;
2472         VariantInit(&bstrvar);
2473         hres = VariantChangeTypeEx(&bstrvar,right,0,0,VT_BSTR);
2474         if (hres) {
2475             FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
2476             return hres;
2477         }
2478         VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar), &V_BSTR(out));
2479         return S_OK;
2480     }
2481     if (V_VT(right) == VT_BSTR) {
2482         VARIANT bstrvar;
2483         HRESULT hres;
2484
2485         V_VT(out) = VT_BSTR;
2486         VariantInit(&bstrvar);
2487         hres = VariantChangeTypeEx(&bstrvar,left,0,0,VT_BSTR);
2488         if (hres) {
2489             FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
2490             return hres;
2491         }
2492         VarBstrCat (V_BSTR(&bstrvar), V_BSTR(right), &V_BSTR(out));
2493         return S_OK;
2494     }
2495     FIXME ("types %d / %d not supported\n",V_VT(left)&VT_TYPEMASK, V_VT(right)&VT_TYPEMASK);
2496     return S_OK;
2497 }
2498
2499 /**********************************************************************
2500  *              VarCmp [OLEAUT32.176]
2501  *
2502  * flags can be:
2503  *   NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS
2504  *   NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
2505  *
2506  */
2507 HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
2508 {
2509     BOOL        lOk        = TRUE;
2510     BOOL        rOk        = TRUE;
2511     LONGLONG    lVal = -1;
2512     LONGLONG    rVal = -1;
2513     VARIANT     rv,lv;
2514     DWORD       xmask;
2515     HRESULT     rc;
2516
2517     TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%08lx)\n", left, debugstr_VT(left),
2518           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags);
2519
2520     VariantInit(&lv);VariantInit(&rv);
2521     V_VT(right) &= ~0x8000; /* hack since we sometime get this flag.  */
2522     V_VT(left) &= ~0x8000; /* hack since we sometime get this flag. */
2523
2524     /* If either are null, then return VARCMP_NULL */
2525     if ((V_VT(left)&VT_TYPEMASK) == VT_NULL ||
2526         (V_VT(right)&VT_TYPEMASK) == VT_NULL)
2527         return VARCMP_NULL;
2528
2529     /* Strings - use VarBstrCmp */
2530     if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
2531         (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
2532         return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags);
2533     }
2534
2535     xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));
2536     if (xmask & VTBIT_R8) {
2537         rc = VariantChangeType(&lv,left,0,VT_R8);
2538         if (FAILED(rc)) return rc;
2539         rc = VariantChangeType(&rv,right,0,VT_R8);
2540         if (FAILED(rc)) return rc;
2541
2542         if (V_R8(&lv) == V_R8(&rv)) return VARCMP_EQ;
2543         if (V_R8(&lv) < V_R8(&rv)) return VARCMP_LT;
2544         if (V_R8(&lv) > V_R8(&rv)) return VARCMP_GT;
2545         return E_FAIL; /* can't get here */
2546     }
2547     if (xmask & VTBIT_R4) {
2548         rc = VariantChangeType(&lv,left,0,VT_R4);
2549         if (FAILED(rc)) return rc;
2550         rc = VariantChangeType(&rv,right,0,VT_R4);
2551         if (FAILED(rc)) return rc;
2552
2553         if (V_R4(&lv) == V_R4(&rv)) return VARCMP_EQ;
2554         if (V_R4(&lv) < V_R4(&rv)) return VARCMP_LT;
2555         if (V_R4(&lv) > V_R4(&rv)) return VARCMP_GT;
2556         return E_FAIL; /* can't get here */
2557     }
2558
2559     /* Integers - Ideally like to use VarDecCmp, but no Dec support yet
2560            Use LONGLONG to maximize ranges                              */
2561     lOk = TRUE;
2562     switch (V_VT(left)&VT_TYPEMASK) {
2563     case VT_I1   : lVal = V_I1(left); break;
2564     case VT_I2   : lVal = V_I2(left); break;
2565     case VT_I4   :
2566     case VT_INT  : lVal = V_I4(left); break;
2567     case VT_UI1  : lVal = V_UI1(left); break;
2568     case VT_UI2  : lVal = V_UI2(left); break;
2569     case VT_UI4  :
2570     case VT_UINT : lVal = V_UI4(left); break;
2571     case VT_BOOL : lVal = V_BOOL(left); break;
2572     default: lOk = FALSE;
2573     }
2574
2575     rOk = TRUE;
2576     switch (V_VT(right)&VT_TYPEMASK) {
2577     case VT_I1   : rVal = V_I1(right); break;
2578     case VT_I2   : rVal = V_I2(right); break;
2579     case VT_I4   :
2580     case VT_INT  : rVal = V_I4(right); break;
2581     case VT_UI1  : rVal = V_UI1(right); break;
2582     case VT_UI2  : rVal = V_UI2(right); break;
2583     case VT_UI4  :
2584     case VT_UINT : rVal = V_UI4(right); break;
2585     case VT_BOOL : rVal = V_BOOL(right); break;
2586     default: rOk = FALSE;
2587     }
2588
2589     if (lOk && rOk) {
2590         if (lVal < rVal) {
2591             return VARCMP_LT;
2592         } else if (lVal > rVal) {
2593             return VARCMP_GT;
2594         } else {
2595             return VARCMP_EQ;
2596         }
2597     }
2598
2599     /* Strings - use VarBstrCmp */
2600     if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&
2601         (V_VT(right)&VT_TYPEMASK) == VT_DATE) {
2602
2603         if (floor(V_DATE(left)) == floor(V_DATE(right))) {
2604             /* Due to floating point rounding errors, calculate varDate in whole numbers) */
2605             double wholePart = 0.0;
2606             double leftR;
2607             double rightR;
2608
2609             /* Get the fraction * 24*60*60 to make it into whole seconds */
2610             wholePart = (double) floor( V_DATE(left) );
2611             if (wholePart == 0) wholePart = 1;
2612             leftR = floor(fmod( V_DATE(left), wholePart ) * (24*60*60));
2613
2614             wholePart = (double) floor( V_DATE(right) );
2615             if (wholePart == 0) wholePart = 1;
2616             rightR = floor(fmod( V_DATE(right), wholePart ) * (24*60*60));
2617
2618             if (leftR < rightR) {
2619                 return VARCMP_LT;
2620             } else if (leftR > rightR) {
2621                 return VARCMP_GT;
2622             } else {
2623                 return VARCMP_EQ;
2624             }
2625
2626         } else if (V_DATE(left) < V_DATE(right)) {
2627             return VARCMP_LT;
2628         } else if (V_DATE(left) > V_DATE(right)) {
2629             return VARCMP_GT;
2630         }
2631     }
2632     FIXME("VarCmp partial implementation, doesn't support vt 0x%x / 0x%x\n",V_VT(left), V_VT(right));
2633     return E_FAIL;
2634 }
2635
2636 /**********************************************************************
2637  *              VarAnd [OLEAUT32.142]
2638  *
2639  */
2640 HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2641 {
2642     HRESULT rc = E_FAIL;
2643
2644     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2645           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2646
2647     if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL &&
2648         (V_VT(right)&VT_TYPEMASK) == VT_BOOL) {
2649
2650         V_VT(result) = VT_BOOL;
2651         if (V_BOOL(left) && V_BOOL(right)) {
2652             V_BOOL(result) = VARIANT_TRUE;
2653         } else {
2654             V_BOOL(result) = VARIANT_FALSE;
2655         }
2656         rc = S_OK;
2657
2658     } else {
2659         /* Integers */
2660         BOOL         lOk        = TRUE;
2661         BOOL         rOk        = TRUE;
2662         LONGLONG     lVal = -1;
2663         LONGLONG     rVal = -1;
2664         LONGLONG     res  = -1;
2665         int          resT = 0; /* Testing has shown I2 & I2 == I2, all else
2666                                   becomes I4, even unsigned ints (incl. UI2) */
2667
2668         lOk = TRUE;
2669         switch (V_VT(left)&VT_TYPEMASK) {
2670         case VT_I1   : lVal = V_I1(left);  resT=VT_I4; break;
2671         case VT_I2   : lVal = V_I2(left);  resT=VT_I2; break;
2672         case VT_I4   :
2673         case VT_INT  : lVal = V_I4(left);  resT=VT_I4; break;
2674         case VT_UI1  : lVal = V_UI1(left);  resT=VT_I4; break;
2675         case VT_UI2  : lVal = V_UI2(left); resT=VT_I4; break;
2676         case VT_UI4  :
2677         case VT_UINT : lVal = V_UI4(left); resT=VT_I4; break;
2678         case VT_BOOL : rVal = V_BOOL(left); resT=VT_I4; break;
2679         default: lOk = FALSE;
2680         }
2681
2682         rOk = TRUE;
2683         switch (V_VT(right)&VT_TYPEMASK) {
2684         case VT_I1   : rVal = V_I1(right);  resT=VT_I4; break;
2685         case VT_I2   : rVal = V_I2(right);  resT=max(VT_I2, resT); break;
2686         case VT_I4   :
2687         case VT_INT  : rVal = V_I4(right);  resT=VT_I4; break;
2688         case VT_UI1  : rVal = V_UI1(right);  resT=VT_I4; break;
2689         case VT_UI2  : rVal = V_UI2(right); resT=VT_I4; break;
2690         case VT_UI4  :
2691         case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;
2692         case VT_BOOL : rVal = V_BOOL(right); resT=VT_I4; break;
2693         default: rOk = FALSE;
2694         }
2695
2696         if (lOk && rOk) {
2697             res = (lVal & rVal);
2698             V_VT(result) = resT;
2699             switch (resT) {
2700             case VT_I2   : V_I2(result)  = res; break;
2701             case VT_I4   : V_I4(result)  = res; break;
2702             default:
2703                 FIXME("Unexpected result variant type %x\n", resT);
2704                 V_I4(result)  = res;
2705             }
2706             rc = S_OK;
2707
2708         } else {
2709             FIXME("VarAnd stub\n");
2710         }
2711     }
2712
2713     TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
2714           debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
2715     return rc;
2716 }
2717
2718 /**********************************************************************
2719  *              VarAdd [OLEAUT32.141]
2720  * FIXME: From MSDN: If ... Then
2721  * Both expressions are of the string type Concatenated.
2722  * One expression is a string type and the other a character Addition.
2723  * One expression is numeric and the other is a string Addition.
2724  * Both expressions are numeric Addition.
2725  * Either expression is NULL NULL is returned.
2726  * Both expressions are empty  Integer subtype is returned.
2727  *
2728  */
2729 HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2730 {
2731     HRESULT rc = E_FAIL;
2732
2733     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2734           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2735
2736     if ((V_VT(left)&VT_TYPEMASK) == VT_EMPTY)
2737         return VariantCopy(result,right);
2738
2739     if ((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)
2740         return VariantCopy(result,left);
2741
2742     /* check if we add doubles */
2743     if (((V_VT(left)&VT_TYPEMASK) == VT_R8) || ((V_VT(right)&VT_TYPEMASK) == VT_R8)) {
2744         BOOL         lOk        = TRUE;
2745         BOOL         rOk        = TRUE;
2746         double       lVal = -1;
2747         double       rVal = -1;
2748         double       res  = -1;
2749
2750         lOk = TRUE;
2751         switch (V_VT(left)&VT_TYPEMASK) {
2752         case VT_I1   : lVal = V_I1(left);   break;
2753         case VT_I2   : lVal = V_I2(left);   break;
2754         case VT_I4   :
2755         case VT_INT  : lVal = V_I4(left);   break;
2756         case VT_UI1  : lVal = V_UI1(left);   break;
2757         case VT_UI2  : lVal = V_UI2(left);  break;
2758         case VT_UI4  :
2759         case VT_UINT : lVal = V_UI4(left);  break;
2760         case VT_R4   : lVal = V_R4(left);  break;
2761         case VT_R8   : lVal = V_R8(left);  break;
2762         case VT_NULL : lVal = 0.0;  break;
2763         default: lOk = FALSE;
2764         }
2765
2766         rOk = TRUE;
2767         switch (V_VT(right)&VT_TYPEMASK) {
2768         case VT_I1   : rVal = V_I1(right);  break;
2769         case VT_I2   : rVal = V_I2(right);  break;
2770         case VT_I4   :
2771         case VT_INT  : rVal = V_I4(right);  break;
2772         case VT_UI1  : rVal = V_UI1(right);  break;
2773         case VT_UI2  : rVal = V_UI2(right); break;
2774         case VT_UI4  :
2775         case VT_UINT : rVal = V_UI4(right); break;
2776         case VT_R4   : rVal = V_R4(right);break;
2777         case VT_R8   : rVal = V_R8(right);break;
2778         case VT_NULL : rVal = 0.0; break;
2779         default: rOk = FALSE;
2780         }
2781
2782         if (lOk && rOk) {
2783             res = (lVal + rVal);
2784             V_VT(result) = VT_R8;
2785             V_R8(result)  = res;
2786             rc = S_OK;
2787         } else {
2788             FIXME("Unhandled type pair %d / %d in double addition.\n",
2789                 (V_VT(left)&VT_TYPEMASK),
2790                 (V_VT(right)&VT_TYPEMASK)
2791             );
2792         }
2793         return rc;
2794     }
2795
2796     /* now check if we add floats. VT_R8 can no longer happen here! */
2797     if (((V_VT(left)&VT_TYPEMASK) == VT_R4) || ((V_VT(right)&VT_TYPEMASK) == VT_R4)) {
2798         BOOL         lOk        = TRUE;
2799         BOOL         rOk        = TRUE;
2800         float        lVal = -1;
2801         float        rVal = -1;
2802         float        res  = -1;
2803
2804         lOk = TRUE;
2805         switch (V_VT(left)&VT_TYPEMASK) {
2806         case VT_I1   : lVal = V_I1(left);   break;
2807         case VT_I2   : lVal = V_I2(left);   break;
2808         case VT_I4   :
2809         case VT_INT  : lVal = V_I4(left);   break;
2810         case VT_UI1  : lVal = V_UI1(left);   break;
2811         case VT_UI2  : lVal = V_UI2(left);  break;
2812         case VT_UI4  :
2813         case VT_UINT : lVal = V_UI4(left);  break;
2814         case VT_R4   : lVal = V_R4(left);  break;
2815         case VT_NULL : lVal = 0.0;  break;
2816         default: lOk = FALSE;
2817         }
2818
2819         rOk = TRUE;
2820         switch (V_VT(right)&VT_TYPEMASK) {
2821         case VT_I1   : rVal = V_I1(right);  break;
2822         case VT_I2   : rVal = V_I2(right);  break;
2823         case VT_I4   :
2824         case VT_INT  : rVal = V_I4(right);  break;
2825         case VT_UI1  : rVal = V_UI1(right);  break;
2826         case VT_UI2  : rVal = V_UI2(right); break;
2827         case VT_UI4  :
2828         case VT_UINT : rVal = V_UI4(right); break;
2829         case VT_R4   : rVal = V_R4(right);break;
2830         case VT_NULL : rVal = 0.0; break;
2831         default: rOk = FALSE;
2832         }
2833
2834         if (lOk && rOk) {
2835             res = (lVal + rVal);
2836             V_VT(result) = VT_R4;
2837             V_R4(result)  = res;
2838             rc = S_OK;
2839         } else {
2840             FIXME("Unhandled type pair %d / %d in float addition.\n",
2841                 (V_VT(left)&VT_TYPEMASK),
2842                 (V_VT(right)&VT_TYPEMASK)
2843             );
2844         }
2845         return rc;
2846     }
2847
2848     /* Handle strings as concat */
2849     if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
2850         (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
2851         V_VT(result) = VT_BSTR;
2852         return VarBstrCat(V_BSTR(left), V_BSTR(right), &V_BSTR(result));
2853     } else {
2854
2855         /* Integers */
2856         BOOL         lOk        = TRUE;
2857         BOOL         rOk        = TRUE;
2858         LONGLONG     lVal = -1;
2859         LONGLONG     rVal = -1;
2860         LONGLONG     res  = -1;
2861         int          resT = 0; /* Testing has shown I2 + I2 == I2, all else
2862                                   becomes I4                                */
2863
2864         lOk = TRUE;
2865         switch (V_VT(left)&VT_TYPEMASK) {
2866         case VT_I1   : lVal = V_I1(left);  resT=VT_I4; break;
2867         case VT_I2   : lVal = V_I2(left);  resT=VT_I2; break;
2868         case VT_I4   :
2869         case VT_INT  : lVal = V_I4(left);  resT=VT_I4; break;
2870         case VT_UI1  : lVal = V_UI1(left);  resT=VT_I4; break;
2871         case VT_UI2  : lVal = V_UI2(left); resT=VT_I4; break;
2872         case VT_UI4  :
2873         case VT_UINT : lVal = V_UI4(left); resT=VT_I4; break;
2874         case VT_NULL : lVal = 0; resT = VT_I4; break;
2875         default: lOk = FALSE;
2876         }
2877
2878         rOk = TRUE;
2879         switch (V_VT(right)&VT_TYPEMASK) {
2880         case VT_I1   : rVal = V_I1(right);  resT=VT_I4; break;
2881         case VT_I2   : rVal = V_I2(right);  resT=max(VT_I2, resT); break;
2882         case VT_I4   :
2883         case VT_INT  : rVal = V_I4(right);  resT=VT_I4; break;
2884         case VT_UI1  : rVal = V_UI1(right);  resT=VT_I4; break;
2885         case VT_UI2  : rVal = V_UI2(right); resT=VT_I4; break;
2886         case VT_UI4  :
2887         case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;
2888         case VT_NULL : rVal = 0; resT=VT_I4; break;
2889         default: rOk = FALSE;
2890         }
2891
2892         if (lOk && rOk) {
2893             res = (lVal + rVal);
2894             V_VT(result) = resT;
2895             switch (resT) {
2896             case VT_I2   : V_I2(result)  = res; break;
2897             case VT_I4   : V_I4(result)  = res; break;
2898             default:
2899                 FIXME("Unexpected result variant type %x\n", resT);
2900                 V_I4(result)  = res;
2901             }
2902             rc = S_OK;
2903
2904         } else {
2905             FIXME("unimplemented part (0x%x + 0x%x)\n",V_VT(left), V_VT(right));
2906         }
2907     }
2908
2909     TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
2910           debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
2911     return rc;
2912 }
2913
2914 /**********************************************************************
2915  *              VarMul [OLEAUT32.156]
2916  *
2917  */
2918 HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2919 {
2920     HRESULT rc = E_FAIL;
2921     VARTYPE lvt,rvt,resvt;
2922     VARIANT lv,rv;
2923     BOOL found;
2924
2925     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2926           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2927
2928     VariantInit(&lv);VariantInit(&rv);
2929     lvt = V_VT(left)&VT_TYPEMASK;
2930     rvt = V_VT(right)&VT_TYPEMASK;
2931     found = FALSE;resvt=VT_VOID;
2932     if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
2933         found = TRUE;
2934         resvt = VT_R8;
2935     }
2936     if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
2937         found = TRUE;
2938         resvt = VT_I4;
2939     }
2940     if (!found) {
2941         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
2942         return E_FAIL;
2943     }
2944     rc = VariantChangeType(&lv, left, 0, resvt);
2945     if (FAILED(rc)) {
2946         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
2947         return rc;
2948     }
2949     rc = VariantChangeType(&rv, right, 0, resvt);
2950     if (FAILED(rc)) {
2951         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
2952         return rc;
2953     }
2954     switch (resvt) {
2955     case VT_R8:
2956         V_VT(result) = resvt;
2957         V_R8(result) = V_R8(&lv) * V_R8(&rv);
2958         rc = S_OK;
2959         break;
2960     case VT_I4:
2961         V_VT(result) = resvt;
2962         V_I4(result) = V_I4(&lv) * V_I4(&rv);
2963         rc = S_OK;
2964         break;
2965     }
2966     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
2967           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
2968     return rc;
2969 }
2970
2971 /**********************************************************************
2972  *              VarDiv [OLEAUT32.143]
2973  *
2974  */
2975 HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2976 {
2977     HRESULT rc = E_FAIL;
2978     VARTYPE lvt,rvt,resvt;
2979     VARIANT lv,rv;
2980     BOOL found;
2981
2982     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2983           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2984
2985     VariantInit(&lv);VariantInit(&rv);
2986     lvt = V_VT(left)&VT_TYPEMASK;
2987     rvt = V_VT(right)&VT_TYPEMASK;
2988     found = FALSE;resvt = VT_VOID;
2989     if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
2990         found = TRUE;
2991         resvt = VT_R8;
2992     }
2993     if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
2994         found = TRUE;
2995         resvt = VT_I4;
2996     }
2997     if (!found) {
2998         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
2999         return E_FAIL;
3000     }
3001     rc = VariantChangeType(&lv, left, 0, resvt);
3002     if (FAILED(rc)) {
3003         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
3004         return rc;
3005     }
3006     rc = VariantChangeType(&rv, right, 0, resvt);
3007     if (FAILED(rc)) {
3008         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
3009         return rc;
3010     }
3011     switch (resvt) {
3012     case VT_R8:
3013         if (V_R8(&rv) == 0) return DISP_E_DIVBYZERO;
3014         V_VT(result) = resvt;
3015         V_R8(result) = V_R8(&lv) / V_R8(&rv);
3016         rc = S_OK;
3017         break;
3018     case VT_I4:
3019         if (V_I4(&rv) == 0) return DISP_E_DIVBYZERO;
3020         V_VT(result) = resvt;
3021         V_I4(result) = V_I4(&lv) / V_I4(&rv);
3022         rc = S_OK;
3023         break;
3024     }
3025     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
3026           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
3027     return rc;
3028 }
3029
3030 /**********************************************************************
3031  *              VarSub [OLEAUT32.159]
3032  *
3033  */
3034 HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3035 {
3036     HRESULT rc = E_FAIL;
3037     VARTYPE lvt,rvt,resvt;
3038     VARIANT lv,rv;
3039     BOOL found;
3040
3041     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3042           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
3043
3044     VariantInit(&lv);VariantInit(&rv);
3045     lvt = V_VT(left)&VT_TYPEMASK;
3046     rvt = V_VT(right)&VT_TYPEMASK;
3047     found = FALSE;resvt = VT_VOID;
3048     if (((1<<lvt) | (1<<rvt)) & ((1<<VT_DATE)|(1<<VT_R4)|(1<<VT_R8))) {
3049         found = TRUE;
3050         resvt = VT_R8;
3051     }
3052     if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
3053         found = TRUE;
3054         resvt = VT_I4;
3055     }
3056     if (!found) {
3057         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
3058         return E_FAIL;
3059     }
3060     rc = VariantChangeType(&lv, left, 0, resvt);
3061     if (FAILED(rc)) {
3062         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
3063         return rc;
3064     }
3065     rc = VariantChangeType(&rv, right, 0, resvt);
3066     if (FAILED(rc)) {
3067         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
3068         return rc;
3069     }
3070     switch (resvt) {
3071     case VT_R8:
3072         V_VT(result) = resvt;
3073         V_R8(result) = V_R8(&lv) - V_R8(&rv);
3074         rc = S_OK;
3075         break;
3076     case VT_I4:
3077         V_VT(result) = resvt;
3078         V_I4(result) = V_I4(&lv) - V_I4(&rv);
3079         rc = S_OK;
3080         break;
3081     }
3082     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
3083           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
3084     return rc;
3085 }
3086
3087 /**********************************************************************
3088  *              VarOr [OLEAUT32.157]
3089  *
3090  * Perform a logical or (OR) operation on two variants.
3091  *
3092  * PARAMS
3093  *  pVarLeft  [I] First variant
3094  *  pVarRight [I] Variant to OR with pVarLeft
3095  *  pVarOut   [O] Destination for OR result
3096  *
3097  * RETURNS
3098  *  Success: S_OK. pVarOut contains the result of the operation with its type
3099  *           taken from the table listed under VarXor().
3100  *  Failure: An HRESULT error code indicating the error.
3101  *
3102  * NOTES
3103  *  See the Notes section of VarXor() for further information.
3104  */
3105 HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3106 {
3107     VARTYPE vt = VT_I4;
3108     VARIANT varLeft, varRight, varStr;
3109     HRESULT hRet;
3110
3111     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3112           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3113           debugstr_VF(pVarRight), pVarOut);
3114
3115     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
3116         V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
3117         V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH ||
3118         V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD)
3119         return DISP_E_BADVARTYPE;
3120
3121     V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY;
3122
3123     if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
3124     {
3125         /* NULL OR Zero is NULL, NULL OR value is value */
3126         if (V_VT(pVarLeft) == VT_NULL)
3127             pVarLeft = pVarRight; /* point to the non-NULL var */
3128
3129         V_VT(pVarOut) = VT_NULL;
3130         V_I4(pVarOut) = 0;
3131
3132         switch (V_VT(pVarLeft))
3133         {
3134         case VT_DATE: case VT_R8:
3135             if (V_R8(pVarLeft))
3136                 goto VarOr_AsEmpty;
3137             return S_OK;
3138         case VT_BOOL:
3139             if (V_BOOL(pVarLeft))
3140                 *pVarOut = *pVarLeft;
3141             return S_OK;
3142          case VT_I2: case VT_UI2:
3143             if (V_I2(pVarLeft))
3144                 goto VarOr_AsEmpty;
3145             return S_OK;
3146         case VT_I1:
3147             if (V_I1(pVarLeft))
3148                 goto VarOr_AsEmpty;
3149             return S_OK;
3150         case VT_UI1:
3151             if (V_UI1(pVarLeft))
3152                 *pVarOut = *pVarLeft;
3153             return S_OK;
3154         case VT_R4:
3155             if (V_R4(pVarLeft))
3156                 goto VarOr_AsEmpty;
3157             return S_OK;
3158         case VT_I4: case VT_UI4: case VT_INT: case VT_UINT:
3159             if (V_I4(pVarLeft))
3160                 goto VarOr_AsEmpty;
3161             return S_OK;
3162         case VT_CY:
3163             if (V_CY(pVarLeft).int64)
3164                 goto VarOr_AsEmpty;
3165             return S_OK;
3166         case VT_I8: case VT_UI8:
3167             if (V_I8(pVarLeft))
3168                 goto VarOr_AsEmpty;
3169             return S_OK;
3170         case VT_DECIMAL:
3171             if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft)))
3172                 goto VarOr_AsEmpty;
3173             return S_OK;
3174         case VT_BSTR:
3175         {
3176             VARIANT_BOOL b;
3177
3178             if (!V_BSTR(pVarLeft))
3179                 return DISP_E_BADVARTYPE;
3180
3181             hRet = VarBoolFromStr(V_BSTR(pVarLeft), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
3182             if (SUCCEEDED(hRet) && b)
3183             {
3184                 V_VT(pVarOut) = VT_BOOL;
3185                 V_BOOL(pVarOut) = b;
3186             }
3187             return hRet;
3188         }
3189         case VT_NULL: case VT_EMPTY:
3190             V_VT(pVarOut) = VT_NULL;
3191             return S_OK;
3192         default:
3193             return DISP_E_BADVARTYPE;
3194         }
3195     }
3196
3197     if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY)
3198     {
3199         if (V_VT(pVarLeft) == VT_EMPTY)
3200             pVarLeft = pVarRight; /* point to the non-EMPTY var */
3201
3202 VarOr_AsEmpty:
3203         /* Since one argument is empty (0), OR'ing it with the other simply
3204          * gives the others value (as 0|x => x). So just convert the other
3205          * argument to the required result type.
3206          */
3207         switch (V_VT(pVarLeft))
3208         {
3209         case VT_BSTR:
3210             if (!V_BSTR(pVarLeft))
3211                 return DISP_E_BADVARTYPE;
3212
3213             hRet = VariantCopy(&varStr, pVarLeft);
3214             if (FAILED(hRet))
3215                 goto VarOr_Exit;
3216             pVarLeft = &varStr;
3217             hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
3218             if (FAILED(hRet))
3219                 goto VarOr_Exit;
3220             /* Fall Through ... */
3221         case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2:
3222             V_VT(pVarOut) = VT_I2;
3223             break;
3224         case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:
3225         case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:
3226         case VT_INT: case VT_UINT: case VT_UI8:
3227             V_VT(pVarOut) = VT_I4;
3228             break;
3229         case VT_I8:
3230             V_VT(pVarOut) = VT_I8;
3231             break;
3232         default:
3233             return DISP_E_BADVARTYPE;
3234         }
3235         hRet = VariantCopy(&varLeft, pVarLeft);
3236         if (FAILED(hRet))
3237             goto VarOr_Exit;
3238         pVarLeft = &varLeft;
3239         hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut));
3240         goto VarOr_Exit;
3241     }
3242
3243     if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)
3244     {
3245         V_VT(pVarOut) = VT_BOOL;
3246         V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight);
3247         return S_OK;
3248     }
3249
3250     if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)
3251     {
3252         V_VT(pVarOut) = VT_UI1;
3253         V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight);
3254         return S_OK;
3255     }
3256
3257     if (V_VT(pVarLeft) == VT_BSTR)
3258     {
3259         hRet = VariantCopy(&varStr, pVarLeft);
3260         if (FAILED(hRet))
3261             goto VarOr_Exit;
3262         pVarLeft = &varStr;
3263         hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
3264         if (FAILED(hRet))
3265             goto VarOr_Exit;
3266     }
3267
3268     if (V_VT(pVarLeft) == VT_BOOL &&
3269         (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR))
3270     {
3271         vt = VT_BOOL;
3272     }
3273     else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 ||
3274         V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) &&
3275         (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||
3276         V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR))
3277     {
3278         vt = VT_I2;
3279     }
3280     else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)
3281     {
3282         if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
3283             return DISP_E_TYPEMISMATCH;
3284         vt = VT_I8;
3285     }
3286
3287     hRet = VariantCopy(&varLeft, pVarLeft);
3288     if (FAILED(hRet))
3289         goto VarOr_Exit;
3290
3291     hRet = VariantCopy(&varRight, pVarRight);
3292     if (FAILED(hRet))
3293         goto VarOr_Exit;
3294
3295     if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4)
3296         V_VT(&varLeft) = VT_I4; /* Don't overflow */
3297     else
3298     {
3299         double d;
3300
3301         if (V_VT(&varLeft) == VT_BSTR &&
3302             FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d)))
3303             hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL);
3304         if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt)
3305             hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
3306         if (FAILED(hRet))
3307             goto VarOr_Exit;
3308     }
3309
3310     if (vt == VT_I4 && V_VT(&varRight) == VT_UI4)
3311         V_VT(&varRight) = VT_I4; /* Don't overflow */
3312     else
3313     {
3314         double d;
3315
3316         if (V_VT(&varRight) == VT_BSTR &&
3317             FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d)))
3318             hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL);
3319         if (SUCCEEDED(hRet) && V_VT(&varRight) != vt)
3320             hRet = VariantChangeType(&varRight, &varRight, 0, vt);
3321         if (FAILED(hRet))
3322             goto VarOr_Exit;
3323     }
3324
3325     V_VT(pVarOut) = vt;
3326     if (vt == VT_I8)
3327     {
3328         V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight);
3329     }
3330     else if (vt == VT_I4)
3331     {
3332         V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight);
3333     }
3334     else
3335     {
3336         V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight);
3337     }
3338
3339 VarOr_Exit:
3340     VariantClear(&varStr);
3341     VariantClear(&varLeft);
3342     VariantClear(&varRight);
3343     return hRet;
3344 }
3345
3346 /**********************************************************************
3347  * VarAbs [OLEAUT32.168]
3348  *
3349  * Convert a variant to its absolute value.
3350  *
3351  * PARAMS
3352  *  pVarIn  [I] Source variant
3353  *  pVarOut [O] Destination for converted value
3354  *
3355  * RETURNS
3356  *  Success: S_OK. pVarOut contains the absolute value of pVarIn.
3357  *  Failure: An HRESULT error code indicating the error.
3358  *
3359  * NOTES
3360  *  - This function does not process by-reference variants.
3361  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3362  *    according to the following table:
3363  *| Input Type       Output Type
3364  *| ----------       -----------
3365  *| VT_BOOL          VT_I2
3366  *| VT_BSTR          VT_R8
3367  *| (All others)     Unchanged
3368  */
3369 HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)
3370 {
3371     VARIANT varIn;
3372     HRESULT hRet = S_OK;
3373
3374     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3375           debugstr_VF(pVarIn), pVarOut);
3376
3377     if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN ||
3378         V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD ||
3379         V_VT(pVarIn) == VT_ERROR)
3380         return DISP_E_TYPEMISMATCH;
3381
3382     *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */
3383
3384 #define ABS_CASE(typ,min) \
3385     case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \
3386                   else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \
3387                   break
3388
3389     switch (V_VT(pVarIn))
3390     {
3391     ABS_CASE(I1,I1_MIN);
3392     case VT_BOOL:
3393         V_VT(pVarOut) = VT_I2;
3394         /* BOOL->I2, Fall through ... */
3395     ABS_CASE(I2,I2_MIN);
3396     case VT_INT:
3397     ABS_CASE(I4,I4_MIN);
3398     ABS_CASE(I8,I8_MIN);
3399     ABS_CASE(R4,R4_MIN);
3400     case VT_BSTR:
3401         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
3402         if (FAILED(hRet))
3403             break;
3404         V_VT(pVarOut) = VT_R8;
3405         pVarIn = &varIn;
3406         /* Fall through ... */
3407     case VT_DATE:
3408     ABS_CASE(R8,R8_MIN);
3409     case VT_CY:
3410         hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut));
3411         break;
3412     case VT_DECIMAL:
3413         DEC_SIGN(&V_DECIMAL(pVarOut)) &= ~DECIMAL_NEG;
3414         break;
3415     case VT_UI1:
3416     case VT_UI2:
3417     case VT_UINT:
3418     case VT_UI4:
3419     case VT_UI8:
3420         /* No-Op */
3421         break;
3422     case VT_EMPTY:
3423         V_VT(pVarOut) = VT_I2;
3424     case VT_NULL:
3425         V_I2(pVarOut) = 0;
3426         break;
3427     default:
3428         hRet = DISP_E_BADVARTYPE;
3429     }
3430
3431     return hRet;
3432 }
3433
3434 /**********************************************************************
3435  *              VarFix [OLEAUT32.169]
3436  *
3437  * Truncate a variants value to a whole number.
3438  *
3439  * PARAMS
3440  *  pVarIn  [I] Source variant
3441  *  pVarOut [O] Destination for converted value
3442  *
3443  * RETURNS
3444  *  Success: S_OK. pVarOut contains the converted value.
3445  *  Failure: An HRESULT error code indicating the error.
3446  *
3447  * NOTES
3448  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3449  *    according to the following table:
3450  *| Input Type       Output Type
3451  *| ----------       -----------
3452  *|  VT_BOOL          VT_I2
3453  *|  VT_EMPTY         VT_I2
3454  *|  VT_BSTR          VT_R8
3455  *|  All Others       Unchanged
3456  *  - The difference between this function and VarInt() is that VarInt() rounds
3457  *    negative numbers away from 0, while this function rounds them towards zero.
3458  */
3459 HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut)
3460 {
3461     HRESULT hRet = S_OK;
3462
3463     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3464           debugstr_VF(pVarIn), pVarOut);
3465
3466     V_VT(pVarOut) = V_VT(pVarIn);
3467
3468     switch (V_VT(pVarIn))
3469     {
3470     case VT_UI1:
3471         V_UI1(pVarOut) = V_UI1(pVarIn);
3472         break;
3473     case VT_BOOL:
3474         V_VT(pVarOut) = VT_I2;
3475         /* Fall through */
3476      case VT_I2:
3477         V_I2(pVarOut) = V_I2(pVarIn);
3478         break;
3479      case VT_I4:
3480         V_I4(pVarOut) = V_I4(pVarIn);
3481         break;
3482      case VT_I8:
3483         V_I8(pVarOut) = V_I8(pVarIn);
3484         break;
3485     case VT_R4:
3486         if (V_R4(pVarIn) < 0.0f)
3487             V_R4(pVarOut) = (float)ceil(V_R4(pVarIn));
3488         else
3489             V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
3490         break;
3491     case VT_BSTR:
3492         V_VT(pVarOut) = VT_R8;
3493         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
3494         pVarIn = pVarOut;
3495         /* Fall through */
3496     case VT_DATE:
3497     case VT_R8:
3498         if (V_R8(pVarIn) < 0.0)
3499             V_R8(pVarOut) = ceil(V_R8(pVarIn));
3500         else
3501             V_R8(pVarOut) = floor(V_R8(pVarIn));
3502         break;
3503     case VT_CY:
3504         hRet = VarCyFix(V_CY(pVarIn), &V_CY(pVarOut));
3505         break;
3506     case VT_DECIMAL:
3507         hRet = VarDecFix(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
3508         break;
3509     case VT_EMPTY:
3510         V_VT(pVarOut) = VT_I2;
3511         V_I2(pVarOut) = 0;
3512         break;
3513     case VT_NULL:
3514         /* No-Op */
3515         break;
3516     default:
3517         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
3518             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
3519             hRet = DISP_E_BADVARTYPE;
3520         else
3521             hRet = DISP_E_TYPEMISMATCH;
3522     }
3523     if (FAILED(hRet))
3524       V_VT(pVarOut) = VT_EMPTY;
3525
3526     return hRet;
3527 }
3528
3529 /**********************************************************************
3530  *              VarInt [OLEAUT32.172]
3531  *
3532  * Truncate a variants value to a whole number.
3533  *
3534  * PARAMS
3535  *  pVarIn  [I] Source variant
3536  *  pVarOut [O] Destination for converted value
3537  *
3538  * RETURNS
3539  *  Success: S_OK. pVarOut contains the converted value.
3540  *  Failure: An HRESULT error code indicating the error.
3541  *
3542  * NOTES
3543  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3544  *    according to the following table:
3545  *| Input Type       Output Type
3546  *| ----------       -----------
3547  *|  VT_BOOL          VT_I2
3548  *|  VT_EMPTY         VT_I2
3549  *|  VT_BSTR          VT_R8
3550  *|  All Others       Unchanged
3551  *  - The difference between this function and VarFix() is that VarFix() rounds
3552  *    negative numbers towards 0, while this function rounds them away from zero.
3553  */
3554 HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
3555 {
3556     HRESULT hRet = S_OK;
3557
3558     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3559           debugstr_VF(pVarIn), pVarOut);
3560
3561     V_VT(pVarOut) = V_VT(pVarIn);
3562
3563     switch (V_VT(pVarIn))
3564     {
3565     case VT_R4:
3566         V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
3567         break;
3568     case VT_BSTR:
3569         V_VT(pVarOut) = VT_R8;
3570         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
3571         pVarIn = pVarOut;
3572         /* Fall through */
3573     case VT_DATE:
3574     case VT_R8:
3575         V_R8(pVarOut) = floor(V_R8(pVarIn));
3576         break;
3577     case VT_CY:
3578         hRet = VarCyInt(V_CY(pVarIn), &V_CY(pVarOut));
3579         break;
3580     case VT_DECIMAL:
3581         hRet = VarDecInt(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
3582         break;
3583     default:
3584         return VarFix(pVarIn, pVarOut);
3585     }
3586
3587     return hRet;
3588 }
3589
3590 /**********************************************************************
3591  *              VarXor [OLEAUT32.167]
3592  *
3593  * Perform a logical exclusive-or (XOR) operation on two variants.
3594  *
3595  * PARAMS
3596  *  pVarLeft  [I] First variant
3597  *  pVarRight [I] Variant to XOR with pVarLeft
3598  *  pVarOut   [O] Destination for XOR result
3599  *
3600  * RETURNS
3601  *  Success: S_OK. pVarOut contains the result of the operation with its type
3602  *           taken from the table below).
3603  *  Failure: An HRESULT error code indicating the error.
3604  *
3605  * NOTES
3606  *  - Neither pVarLeft or pVarRight are modified by this function.
3607  *  - This function does not process by-reference variants.
3608  *  - Input types of VT_BSTR may be numeric strings or boolean text.
3609  *  - The type of result stored in pVarOut depends on the types of pVarLeft
3610  *    and pVarRight, and will be one of VT_UI1, VT_I2, VT_I4, VT_I8, VT_BOOL,
3611  *    or VT_NULL if the function succeeds.
3612  *  - Type promotion is inconsistent and as a result certain combinations of
3613  *    values will return DISP_E_OVERFLOW even when they could be represented.
3614  *    This matches the behaviour of native oleaut32.
3615  */
3616 HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3617 {
3618     VARTYPE vt;
3619     VARIANT varLeft, varRight;
3620     double d;
3621     HRESULT hRet;
3622
3623     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3624           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3625           debugstr_VF(pVarRight), pVarOut);
3626
3627     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
3628         V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT ||
3629         V_VT(pVarLeft) == VT_VARIANT || V_VT(pVarRight) == VT_VARIANT ||
3630         V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
3631         V_VT(pVarLeft) == (VARTYPE)15 || V_VT(pVarRight) == (VARTYPE)15 ||
3632         V_VT(pVarLeft) == VT_ERROR || V_VT(pVarRight) == VT_ERROR)
3633         return DISP_E_BADVARTYPE;
3634
3635     if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
3636     {
3637         /* NULL XOR anything valid is NULL */
3638         V_VT(pVarOut) = VT_NULL;
3639         return S_OK;
3640     }
3641
3642     /* Copy our inputs so we don't disturb anything */
3643     V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY;
3644
3645     hRet = VariantCopy(&varLeft, pVarLeft);
3646     if (FAILED(hRet))
3647         goto VarXor_Exit;
3648
3649     hRet = VariantCopy(&varRight, pVarRight);
3650     if (FAILED(hRet))
3651         goto VarXor_Exit;
3652
3653     /* Try any strings first as numbers, then as VT_BOOL */
3654     if (V_VT(&varLeft) == VT_BSTR)
3655     {
3656         hRet = VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d);
3657         hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL,
3658                                  FAILED(hRet) ? VT_BOOL : VT_I4);
3659         if (FAILED(hRet))
3660             goto VarXor_Exit;
3661     }
3662
3663     if (V_VT(&varRight) == VT_BSTR)
3664     {
3665         hRet = VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d);
3666         hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL,
3667                                  FAILED(hRet) ? VT_BOOL : VT_I4);
3668         if (FAILED(hRet))
3669             goto VarXor_Exit;
3670     }
3671
3672     /* Determine the result type */
3673     if (V_VT(&varLeft) == VT_I8 || V_VT(&varRight) == VT_I8)
3674     {
3675         if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
3676             return DISP_E_TYPEMISMATCH;
3677         vt = VT_I8;
3678     }
3679     else
3680     {
3681         switch ((V_VT(&varLeft) << 16) | V_VT(&varRight))
3682         {
3683         case (VT_BOOL  << 16) | VT_BOOL:
3684             vt = VT_BOOL;
3685             break;
3686         case (VT_UI1   << 16) | VT_UI1:
3687             vt = VT_UI1;
3688             break;
3689         case (VT_EMPTY << 16) | VT_EMPTY:
3690         case (VT_EMPTY << 16) | VT_UI1:
3691         case (VT_EMPTY << 16) | VT_I2:
3692         case (VT_EMPTY << 16) | VT_BOOL:
3693         case (VT_UI1   << 16) | VT_EMPTY:
3694         case (VT_UI1   << 16) | VT_I2:
3695         case (VT_UI1   << 16) | VT_BOOL:
3696         case (VT_I2    << 16) | VT_EMPTY:
3697         case (VT_I2    << 16) | VT_UI1:
3698         case (VT_I2    << 16) | VT_I2:
3699         case (VT_I2    << 16) | VT_BOOL:
3700         case (VT_BOOL  << 16) | VT_EMPTY:
3701         case (VT_BOOL  << 16) | VT_UI1:
3702         case (VT_BOOL  << 16) | VT_I2:
3703             vt = VT_I2;
3704             break;
3705         default:
3706             vt = VT_I4;
3707             break;
3708         }
3709     }
3710
3711     /* VT_UI4 does not overflow */
3712     if (vt != VT_I8)
3713     {
3714         if (V_VT(&varLeft) == VT_UI4)
3715             V_VT(&varLeft) = VT_I4;
3716         if (V_VT(&varRight) == VT_UI4)
3717             V_VT(&varRight) = VT_I4;
3718     }
3719
3720     /* Convert our input copies to the result type */
3721     if (V_VT(&varLeft) != vt)
3722         hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
3723     if (FAILED(hRet))
3724         goto VarXor_Exit;
3725
3726     if (V_VT(&varRight) != vt)
3727         hRet = VariantChangeType(&varRight, &varRight, 0, vt);
3728     if (FAILED(hRet))
3729         goto VarXor_Exit;
3730
3731     V_VT(pVarOut) = vt;
3732
3733     /* Calculate the result */
3734     switch (vt)
3735     {
3736     case VT_I8:
3737         V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight);
3738         break;
3739     case VT_I4:
3740         V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight);
3741         break;
3742     case VT_BOOL:
3743     case VT_I2:
3744         V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight);
3745         break;
3746     case VT_UI1:
3747         V_UI1(pVarOut) = V_UI1(&varLeft) ^ V_UI1(&varRight);
3748         break;
3749     }
3750
3751 VarXor_Exit:
3752     VariantClear(&varLeft);
3753     VariantClear(&varRight);
3754     return hRet;
3755 }
3756
3757 /**********************************************************************
3758  *              VarEqv [OLEAUT32.172]
3759  *
3760  * Determine if two variants contain the same value.
3761  *
3762  * PARAMS
3763  *  pVarLeft  [I] First variant to compare
3764  *  pVarRight [I] Variant to compare to pVarLeft
3765  *  pVarOut   [O] Destination for comparison result
3766  *
3767  * RETURNS
3768  *  Success: S_OK. pVarOut contains the result of the comparison (VARIANT_TRUE
3769  *           if equivalent or non-zero otherwise.
3770  *  Failure: An HRESULT error code indicating the error.
3771  *
3772  * NOTES
3773  *  - This function simply calls VarXor() on pVarLeft and pVarRight and inverts
3774  *    the result.
3775  */
3776 HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3777 {
3778     HRESULT hRet;
3779
3780     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3781           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3782           debugstr_VF(pVarRight), pVarOut);
3783
3784     hRet = VarXor(pVarLeft, pVarRight, pVarOut);
3785     if (SUCCEEDED(hRet))
3786     {
3787         if (V_VT(pVarOut) == VT_I8)
3788             V_I8(pVarOut) = ~V_I8(pVarOut);
3789         else
3790             V_UI4(pVarOut) = ~V_UI4(pVarOut);
3791     }
3792     return hRet;
3793 }
3794
3795 /**********************************************************************
3796  *              VarNeg [OLEAUT32.173]
3797  *
3798  * Negate the value of a variant.
3799  *
3800  * PARAMS
3801  *  pVarIn  [I] Source variant
3802  *  pVarOut [O] Destination for converted value
3803  *
3804  * RETURNS
3805  *  Success: S_OK. pVarOut contains the converted value.
3806  *  Failure: An HRESULT error code indicating the error.
3807  *
3808  * NOTES
3809  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3810  *    according to the following table:
3811  *| Input Type       Output Type
3812  *| ----------       -----------
3813  *|  VT_EMPTY         VT_I2
3814  *|  VT_UI1           VT_I2
3815  *|  VT_BOOL          VT_I2
3816  *|  VT_BSTR          VT_R8
3817  *|  All Others       Unchanged (unless promoted)
3818  *  - Where the negated value of a variant does not fit in its base type, the type
3819  *    is promoted according to the following table:
3820  *| Input Type       Promoted To
3821  *| ----------       -----------
3822  *|   VT_I2            VT_I4
3823  *|   VT_I4            VT_R8
3824  *|   VT_I8            VT_R8
3825  *  - The native version of this function returns DISP_E_BADVARTYPE for valid
3826  *    variant types that cannot be negated, and returns DISP_E_TYPEMISMATCH
3827  *    for types which are not valid. Since this is in contravention of the
3828  *    meaning of those error codes and unlikely to be relied on by applications,
3829  *    this implementation returns errors consistent with the other high level
3830  *    variant math functions.
3831  */
3832 HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
3833 {
3834     HRESULT hRet = S_OK;
3835
3836     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3837           debugstr_VF(pVarIn), pVarOut);
3838
3839     V_VT(pVarOut) = V_VT(pVarIn);
3840
3841     switch (V_VT(pVarIn))
3842     {
3843     case VT_UI1:
3844         V_VT(pVarOut) = VT_I2;
3845         V_I2(pVarOut) = -V_UI1(pVarIn);
3846         break;
3847     case VT_BOOL:
3848         V_VT(pVarOut) = VT_I2;
3849         /* Fall through */
3850     case VT_I2:
3851         if (V_I2(pVarIn) == I2_MIN)
3852         {
3853             V_VT(pVarOut) = VT_I4;
3854             V_I4(pVarOut) = -(int)V_I2(pVarIn);
3855         }
3856         else
3857             V_I2(pVarOut) = -V_I2(pVarIn);
3858         break;
3859     case VT_I4:
3860         if (V_I4(pVarIn) == I4_MIN)
3861         {
3862             V_VT(pVarOut) = VT_R8;
3863             V_R8(pVarOut) = -(double)V_I4(pVarIn);
3864         }
3865         else
3866             V_I4(pVarOut) = -V_I4(pVarIn);
3867         break;
3868     case VT_I8:
3869         if (V_I8(pVarIn) == I8_MIN)
3870         {
3871             V_VT(pVarOut) = VT_R8;
3872             hRet = VarR8FromI8(V_I8(pVarIn), &V_R8(pVarOut));
3873             V_R8(pVarOut) *= -1.0;
3874         }
3875         else
3876             V_I8(pVarOut) = -V_I8(pVarIn);
3877         break;
3878     case VT_R4:
3879         V_R4(pVarOut) = -V_R4(pVarIn);
3880         break;
3881     case VT_DATE:
3882     case VT_R8:
3883         V_R8(pVarOut) = -V_R8(pVarIn);
3884         break;
3885     case VT_CY:
3886         hRet = VarCyNeg(V_CY(pVarIn), &V_CY(pVarOut));
3887         break;
3888     case VT_DECIMAL:
3889         hRet = VarDecNeg(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
3890         break;
3891     case VT_BSTR:
3892         V_VT(pVarOut) = VT_R8;
3893         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
3894         V_R8(pVarOut) = -V_R8(pVarOut);
3895         break;
3896     case VT_EMPTY:
3897         V_VT(pVarOut) = VT_I2;
3898         V_I2(pVarOut) = 0;
3899         break;
3900     case VT_NULL:
3901         /* No-Op */
3902         break;
3903     default:
3904         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
3905             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
3906             hRet = DISP_E_BADVARTYPE;
3907         else
3908             hRet = DISP_E_TYPEMISMATCH;
3909     }
3910     if (FAILED(hRet))
3911       V_VT(pVarOut) = VT_EMPTY;
3912
3913     return hRet;
3914 }
3915
3916 /**********************************************************************
3917  *              VarNot [OLEAUT32.174]
3918  *
3919  * Perform a not operation on a variant.
3920  *
3921  * PARAMS
3922  *  pVarIn  [I] Source variant
3923  *  pVarOut [O] Destination for converted value
3924  *
3925  * RETURNS
3926  *  Success: S_OK. pVarOut contains the converted value.
3927  *  Failure: An HRESULT error code indicating the error.
3928  *
3929  * NOTES
3930  *  - Strictly speaking, this function performs a bitwise ones complement
3931  *    on the variants value (after possibly converting to VT_I4, see below).
3932  *    This only behaves like a boolean not operation if the value in
3933  *    pVarIn is either VARIANT_TRUE or VARIANT_FALSE and the type is signed.
3934  *  - To perform a genuine not operation, convert the variant to a VT_BOOL
3935  *    before calling this function.
3936  *  - This function does not process by-reference variants.
3937  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3938  *    according to the following table:
3939  *| Input Type       Output Type
3940  *| ----------       -----------
3941  *| VT_EMPTY         VT_I2
3942  *| VT_R4            VT_I4
3943  *| VT_R8            VT_I4
3944  *| VT_BSTR          VT_I4
3945  *| VT_DECIMAL       VT_I4
3946  *| VT_CY            VT_I4
3947  *| (All others)     Unchanged
3948  */
3949 HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
3950 {
3951     VARIANT varIn;
3952     HRESULT hRet = S_OK;
3953
3954     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3955           debugstr_VF(pVarIn), pVarOut);
3956
3957     V_VT(pVarOut) = V_VT(pVarIn);
3958
3959     switch (V_VT(pVarIn))
3960     {
3961     case VT_I1:
3962         V_I4(pVarOut) = ~V_I1(pVarIn);
3963         V_VT(pVarOut) = VT_I4;
3964         break;
3965     case VT_UI1: V_UI1(pVarOut) = ~V_UI1(pVarIn); break;
3966     case VT_BOOL:
3967     case VT_I2:  V_I2(pVarOut) = ~V_I2(pVarIn); break;
3968     case VT_UI2:
3969         V_I4(pVarOut) = ~V_UI2(pVarIn);
3970         V_VT(pVarOut) = VT_I4;
3971         break;
3972     case VT_DECIMAL:
3973         hRet = VarI4FromDec(&V_DECIMAL(pVarIn), &V_I4(&varIn));
3974         if (FAILED(hRet))
3975             break;
3976         pVarIn = &varIn;
3977         /* Fall through ... */
3978     case VT_INT:
3979         V_VT(pVarOut) = VT_I4;
3980         /* Fall through ... */
3981     case VT_I4:  V_I4(pVarOut) = ~V_I4(pVarIn); break;
3982     case VT_UINT:
3983     case VT_UI4:
3984         V_I4(pVarOut) = ~V_UI4(pVarIn);
3985         V_VT(pVarOut) = VT_I4;
3986         break;
3987     case VT_I8:  V_I8(pVarOut) = ~V_I8(pVarIn); break;
3988     case VT_UI8:
3989         V_I4(pVarOut) = ~V_UI8(pVarIn);
3990         V_VT(pVarOut) = VT_I4;
3991         break;
3992     case VT_R4:
3993         hRet = VarI4FromR4(V_R4(pVarIn), &V_I4(pVarOut));
3994         V_I4(pVarOut) = ~V_I4(pVarOut);
3995         V_VT(pVarOut) = VT_I4;
3996         break;
3997     case VT_BSTR:
3998         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
3999         if (FAILED(hRet))
4000             break;
4001         pVarIn = &varIn;
4002         /* Fall through ... */
4003     case VT_DATE:
4004     case VT_R8:
4005         hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut));
4006         V_I4(pVarOut) = ~V_I4(pVarOut);
4007         V_VT(pVarOut) = VT_I4;
4008         break;
4009     case VT_CY:
4010         hRet = VarI4FromCy(V_CY(pVarIn), &V_I4(pVarOut));
4011         V_I4(pVarOut) = ~V_I4(pVarOut);
4012         V_VT(pVarOut) = VT_I4;
4013         break;
4014     case VT_EMPTY:
4015         V_I2(pVarOut) = ~0;
4016         V_VT(pVarOut) = VT_I2;
4017         break;
4018     case VT_NULL:
4019         /* No-Op */
4020         break;
4021     default:
4022         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4023             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
4024             hRet = DISP_E_BADVARTYPE;
4025         else
4026             hRet = DISP_E_TYPEMISMATCH;
4027     }
4028     if (FAILED(hRet))
4029       V_VT(pVarOut) = VT_EMPTY;
4030
4031     return hRet;
4032 }
4033
4034 /**********************************************************************
4035  *              VarRound [OLEAUT32.175]
4036  *
4037  * Perform a round operation on a variant.
4038  *
4039  * PARAMS
4040  *  pVarIn  [I] Source variant
4041  *  deci    [I] Number of decimals to round to
4042  *  pVarOut [O] Destination for converted value
4043  *
4044  * RETURNS
4045  *  Success: S_OK. pVarOut contains the converted value.
4046  *  Failure: An HRESULT error code indicating the error.
4047  *
4048  * NOTES
4049  *  - Floating point values are rounded to the desired number of decimals.
4050  *  - Some integer types are just copied to the return variable.
4051  *  - Some other integer types are not handled and fail.
4052  */
4053 HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
4054 {
4055     VARIANT varIn;
4056     HRESULT hRet = S_OK;
4057     float factor;
4058
4059     TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci);
4060
4061     switch (V_VT(pVarIn))
4062     {
4063     /* cases that fail on windows */
4064     case VT_I1:
4065     case VT_I8:
4066     case VT_UI2:
4067     case VT_UI4:
4068         hRet = DISP_E_BADVARTYPE;
4069         break;
4070
4071     /* cases just copying in to out */
4072     case VT_UI1:
4073         V_VT(pVarOut) = V_VT(pVarIn);
4074         V_UI1(pVarOut) = V_UI1(pVarIn);
4075         break;
4076     case VT_I2:
4077         V_VT(pVarOut) = V_VT(pVarIn);
4078         V_I2(pVarOut) = V_I2(pVarIn);
4079         break;
4080     case VT_I4:
4081         V_VT(pVarOut) = V_VT(pVarIn);
4082         V_I4(pVarOut) = V_I4(pVarIn);
4083         break;
4084     case VT_NULL:
4085         V_VT(pVarOut) = V_VT(pVarIn);
4086         /* value unchanged */
4087         break;
4088
4089     /* cases that change type */
4090     case VT_EMPTY:
4091         V_VT(pVarOut) = VT_I2;
4092         V_I2(pVarOut) = 0;
4093         break;
4094     case VT_BOOL:
4095         V_VT(pVarOut) = VT_I2;
4096         V_I2(pVarOut) = V_BOOL(pVarIn);
4097         break;
4098     case VT_BSTR:
4099         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
4100         if (FAILED(hRet))
4101             break;
4102         V_VT(&varIn)=VT_R8;
4103         pVarIn = &varIn;
4104         /* Fall through ... */
4105
4106     /* cases we need to do math */
4107     case VT_R8:
4108         if (V_R8(pVarIn)>0) {
4109             V_R8(pVarOut)=floor(V_R8(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
4110         } else {
4111             V_R8(pVarOut)=ceil(V_R8(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
4112         }
4113         V_VT(pVarOut) = V_VT(pVarIn);
4114         break;
4115     case VT_R4:
4116         if (V_R4(pVarIn)>0) {
4117             V_R4(pVarOut)=floor(V_R4(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
4118         } else {
4119             V_R4(pVarOut)=ceil(V_R4(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
4120         }
4121         V_VT(pVarOut) = V_VT(pVarIn);
4122         break;
4123     case VT_DATE:
4124         if (V_DATE(pVarIn)>0) {
4125             V_DATE(pVarOut)=floor(V_DATE(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
4126         } else {
4127             V_DATE(pVarOut)=ceil(V_DATE(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
4128         }
4129         V_VT(pVarOut) = V_VT(pVarIn);
4130         break;
4131     case VT_CY:
4132         if (deci>3)
4133             factor=1;
4134         else
4135             factor=pow(10, 4-deci);
4136
4137         if (V_CY(pVarIn).int64>0) {
4138             V_CY(pVarOut).int64=floor(V_CY(pVarIn).int64/factor)*factor;
4139         } else {
4140             V_CY(pVarOut).int64=ceil(V_CY(pVarIn).int64/factor)*factor;
4141         }
4142         V_VT(pVarOut) = V_VT(pVarIn);
4143         break;
4144
4145     /* cases we don't know yet */
4146     default:
4147         FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
4148                 V_VT(pVarIn) & VT_TYPEMASK, deci);
4149         hRet = DISP_E_BADVARTYPE;
4150     }
4151
4152     if (FAILED(hRet))
4153       V_VT(pVarOut) = VT_EMPTY;
4154
4155     TRACE("returning 0x%08lx (%s%s),%f\n", hRet, debugstr_VT(pVarOut),
4156         debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) :
4157         (V_VT(pVarOut) == VT_R8) ? V_R8(pVarOut) : 0);
4158
4159     return hRet;
4160 }
4161
4162 /**********************************************************************
4163  *              VarIdiv [OLEAUT32.153]
4164  *
4165  * Converts input variants to integers and divides them. 
4166  *
4167  * PARAMS
4168  *  left     [I] Left hand variant
4169  *  right    [I] Right hand variant
4170  *  result   [O] Destination for quotient
4171  *
4172  * RETURNS
4173  *  Success: S_OK.  result contains the quotient.
4174  *  Failure: An HRESULT error code indicating the error.
4175  *
4176  * NOTES
4177  *  If either expression is null, null is returned, as per MSDN
4178  */
4179 HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
4180 {
4181     VARIANT lv, rv;
4182     HRESULT hr;
4183     
4184     VariantInit(&lv);
4185     VariantInit(&rv);
4186
4187     if ((V_VT(left) == VT_NULL) || (V_VT(right) == VT_NULL)) {
4188         hr = VariantChangeType(result, result, 0, VT_NULL);
4189         if (FAILED(hr)) {
4190             /* This should never happen */
4191             FIXME("Failed to convert return value to VT_NULL.\n");
4192             return hr;
4193         }
4194         return S_OK;
4195     }
4196
4197     hr = VariantChangeType(&lv, left, 0, VT_I4);
4198     if (FAILED(hr)) {
4199         return hr;
4200     }
4201     hr = VariantChangeType(&rv, right, 0, VT_I4);
4202     if (FAILED(hr)) {
4203         return hr;
4204     }
4205
4206     hr = VarDiv(&lv, &rv, result);
4207     return hr;
4208 }
4209
4210
4211 /**********************************************************************
4212  *              VarMod [OLEAUT32.155]
4213  *
4214  * Perform the modulus operation of the right hand variant on the left
4215  *
4216  * PARAMS
4217  *  left     [I] Left hand variant
4218  *  right    [I] Right hand variant
4219  *  result   [O] Destination for converted value
4220  *
4221  * RETURNS
4222  *  Success: S_OK. result contains the remainder.
4223  *  Failure: An HRESULT error code indicating the error.
4224  *
4225  * NOTE:
4226  *   If an error occurs the type of result will be modified but the value will not be.
4227  *   Doesn't support arrays or any special flags yet.
4228  */
4229 HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
4230 {
4231     BOOL         lOk        = TRUE;
4232     BOOL         rOk        = TRUE;
4233     HRESULT      rc         = E_FAIL;
4234     int          resT = 0;
4235     VARIANT      lv,rv;
4236
4237     VariantInit(&lv);
4238     VariantInit(&rv);
4239
4240     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
4241                   debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
4242
4243     /* check for invalid inputs */
4244     lOk = TRUE;
4245     switch (V_VT(left) & VT_TYPEMASK) {
4246     case VT_BOOL :
4247     case VT_I1   :
4248     case VT_I2   :
4249     case VT_I4   :
4250     case VT_I8   :
4251     case VT_INT  :
4252     case VT_UI1  :
4253     case VT_UI2  :
4254     case VT_UI4  :
4255     case VT_UI8  :
4256     case VT_UINT :
4257     case VT_R4   :
4258     case VT_R8   :
4259     case VT_CY   :
4260     case VT_EMPTY:
4261     case VT_DATE :
4262     case VT_BSTR :
4263       break;
4264     case VT_VARIANT:
4265     case VT_UNKNOWN:
4266       V_VT(result) = VT_EMPTY;
4267       return DISP_E_TYPEMISMATCH;
4268     case VT_DECIMAL:
4269       V_VT(result) = VT_EMPTY;
4270       return E_INVALIDARG;
4271     case VT_ERROR:
4272       return DISP_E_TYPEMISMATCH;
4273     case VT_RECORD:
4274       V_VT(result) = VT_EMPTY;
4275       return DISP_E_TYPEMISMATCH;
4276     case VT_NULL:
4277       break;
4278     default:
4279       V_VT(result) = VT_EMPTY;
4280       return DISP_E_BADVARTYPE;
4281     }
4282
4283
4284     rOk = TRUE;
4285     switch (V_VT(right) & VT_TYPEMASK) {
4286     case VT_BOOL :
4287     case VT_I1   :
4288     case VT_I2   :
4289     case VT_I4   :
4290     case VT_I8   :
4291       if((V_VT(left) == VT_INT) && (V_VT(right) == VT_I8))
4292       {
4293         V_VT(result) = VT_EMPTY;
4294         return DISP_E_TYPEMISMATCH;
4295       }
4296     case VT_INT  :
4297       if((V_VT(right) == VT_INT) && (V_VT(left) == VT_I8))
4298       {
4299         V_VT(result) = VT_EMPTY;
4300         return DISP_E_TYPEMISMATCH;
4301       }
4302     case VT_UI1  :
4303     case VT_UI2  :
4304     case VT_UI4  :
4305     case VT_UI8  :
4306     case VT_UINT :
4307     case VT_R4   :
4308     case VT_R8   :
4309     case VT_CY   :
4310       if(V_VT(left) == VT_EMPTY)
4311       {
4312         V_VT(result) = VT_I4;
4313         return S_OK;
4314       }
4315     case VT_EMPTY:
4316     case VT_DATE :
4317     case VT_BSTR:
4318       if(V_VT(left) == VT_NULL)
4319       {
4320         V_VT(result) = VT_NULL;
4321         return S_OK;
4322       }
4323       break;
4324
4325     case VT_VOID:
4326       V_VT(result) = VT_EMPTY;
4327       return DISP_E_BADVARTYPE;
4328     case VT_NULL:
4329       if(V_VT(left) == VT_VOID)
4330       {
4331         V_VT(result) = VT_EMPTY;
4332         return DISP_E_BADVARTYPE;
4333       } else if((V_VT(left) == VT_NULL) || (V_VT(left) == VT_EMPTY) || (V_VT(left) == VT_ERROR) ||
4334                 lOk)
4335       {
4336         V_VT(result) = VT_NULL;
4337         return S_OK;
4338       } else
4339       {
4340         V_VT(result) = VT_NULL;
4341         return DISP_E_BADVARTYPE;
4342       }
4343     case VT_VARIANT:
4344     case VT_UNKNOWN:
4345       V_VT(result) = VT_EMPTY;
4346       return DISP_E_TYPEMISMATCH;
4347     case VT_DECIMAL:
4348       if(V_VT(left) == VT_ERROR)
4349       {
4350         V_VT(result) = VT_EMPTY;
4351         return DISP_E_TYPEMISMATCH;
4352       } else
4353       {
4354         V_VT(result) = VT_EMPTY;
4355         return E_INVALIDARG;
4356       }
4357     case VT_ERROR:
4358       return DISP_E_TYPEMISMATCH;
4359     case VT_RECORD:
4360       if((V_VT(left) == 15) || ((V_VT(left) >= 24) && (V_VT(left) <= 35)) || !lOk)
4361       {
4362         V_VT(result) = VT_EMPTY;
4363         return DISP_E_BADVARTYPE;
4364       } else
4365       {
4366         V_VT(result) = VT_EMPTY;
4367         return DISP_E_TYPEMISMATCH;
4368       }
4369     default:
4370       V_VT(result) = VT_EMPTY;
4371       return DISP_E_BADVARTYPE;
4372     }
4373
4374     /* determine the result type */
4375     if((V_VT(left) == VT_I8)        || (V_VT(right) == VT_I8))   resT = VT_I8;
4376     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_BOOL)) resT = VT_I2;
4377     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_UI1))  resT = VT_UI1;
4378     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_I2))   resT = VT_I2;
4379     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_BOOL)) resT = VT_I2;
4380     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_UI1))  resT = VT_I2;
4381     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_I2))   resT = VT_I2;
4382     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_BOOL)) resT = VT_I2;
4383     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_UI1))  resT = VT_I2;
4384     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_I2))   resT = VT_I2;
4385     else resT = VT_I4; /* most outputs are I4 */
4386
4387     /* convert to I8 for the modulo */
4388     rc = VariantChangeType(&lv, left, 0, VT_I8);
4389     if(FAILED(rc))
4390     {
4391       FIXME("Could not convert left type %d to %d? rc == 0x%lX\n", V_VT(left), VT_I8, rc);
4392       return rc;
4393     }
4394
4395     rc = VariantChangeType(&rv, right, 0, VT_I8);
4396     if(FAILED(rc))
4397     {
4398       FIXME("Could not convert right type %d to %d? rc == 0x%lX\n", V_VT(right), VT_I8, rc);
4399       return rc;
4400     }
4401
4402     /* if right is zero set VT_EMPTY and return divide by zero */
4403     if(V_I8(&rv) == 0)
4404     {
4405       V_VT(result) = VT_EMPTY;
4406       return DISP_E_DIVBYZERO;
4407     }
4408
4409     /* perform the modulo operation */
4410     V_VT(result) = VT_I8;
4411     V_I8(result) = V_I8(&lv) % V_I8(&rv);
4412
4413     TRACE("V_I8(left) == %ld, V_I8(right) == %ld, V_I8(result) == %ld\n", (long)V_I8(&lv), (long)V_I8(&rv), (long)V_I8(result));
4414
4415     /* convert left and right to the destination type */
4416     rc = VariantChangeType(result, result, 0, resT);
4417     if(FAILED(rc))
4418     {
4419       FIXME("Could not convert 0x%x to %d?\n", V_VT(result), resT);
4420       return rc;
4421     }
4422
4423     return S_OK;
4424 }
4425
4426 /**********************************************************************
4427  *              VarPow [OLEAUT32.158]
4428  *
4429  */
4430 HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
4431 {
4432     HRESULT hr;
4433     VARIANT dl,dr;
4434
4435     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), debugstr_VF(left),
4436           right, debugstr_VT(right), debugstr_VF(right), result);
4437
4438     hr = VariantChangeType(&dl,left,0,VT_R8);
4439     if (!SUCCEEDED(hr)) {
4440         ERR("Could not change passed left argument to VT_R8, handle it differently.\n");
4441         return E_FAIL;
4442     }
4443     hr = VariantChangeType(&dr,right,0,VT_R8);
4444     if (!SUCCEEDED(hr)) {
4445         ERR("Could not change passed right argument to VT_R8, handle it differently.\n");
4446         return E_FAIL;
4447     }
4448     V_VT(result) = VT_R8;
4449     V_R8(result) = pow(V_R8(&dl),V_R8(&dr));
4450     return S_OK;
4451 }