Mark links to dir with FILE_ATTRIBUTE_REPARSE_POINT, so modern
[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(ps), &V_DECIMAL(pd));
497     case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(pd));
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  *
2721  * Add two variants.
2722  *
2723  * PARAMS
2724  *  left    [I] First variant
2725  *  right   [I] Second variant
2726  *  result  [O] Result variant
2727  *
2728  * RETURNS
2729  *  Success: S_OK.
2730  *  Failure: An HRESULT error code indicating the error.
2731  *
2732  * NOTES
2733  *  Native VarAdd up to and including WinXP dosn't like as input variants
2734  *  I1, UI2, UI4, UI8, INT and UINT.
2735  *
2736  *  Native VarAdd dosn't check for NULL in/out pointers and crashes. We do the
2737  *  same here.
2738  *
2739  * FIXME
2740  *  Overflow checking for R8 (double) overflow. Return DISP_E_OVERFLOW in that
2741  *  case.
2742  */
2743 HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2744 {
2745     HRESULT hres;
2746     VARTYPE lvt, rvt, resvt, tvt;
2747     VARIANT lv, rv, tv;
2748     double r8res;
2749
2750     /* Variant priority for coercion. Sorted from lowest to highest.
2751        VT_ERROR shows an invalid input variant type. */
2752     enum coerceprio { vt_EMPTY, vt_UI1, vt_I2, vt_I4, vt_I8, vt_BSTR,vt_R4,
2753                       vt_R8, vt_CY, vt_DATE, vt_DECIMAL, vt_DISPATCH, vt_NULL,
2754                       vt_ERROR };
2755     /* Mapping from priority to variant type. Keep in sync with coerceprio! */
2756     VARTYPE prio2vt[] = { VT_EMPTY, VT_UI1, VT_I2, VT_I4, VT_I8, VT_BSTR, VT_R4,
2757                           VT_R8, VT_CY, VT_DATE, VT_DECIMAL, VT_DISPATCH,
2758                           VT_NULL, VT_ERROR };
2759
2760     /* Mapping for coercion from input variant to priority of result variant. */
2761     static VARTYPE coerce[] = {
2762         /* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
2763         vt_EMPTY, vt_NULL, vt_I2, vt_I4, vt_R4,
2764         /* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
2765         vt_R8, vt_CY, vt_DATE, vt_BSTR, vt_DISPATCH,
2766         /* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
2767         vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
2768         /* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
2769         vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
2770     };
2771
2772     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2773           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
2774           result);
2775
2776     VariantInit(&lv);
2777     VariantInit(&rv);
2778     VariantInit(&tv);
2779     lvt = V_VT(left)&VT_TYPEMASK;
2780     rvt = V_VT(right)&VT_TYPEMASK;
2781
2782     /* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
2783        Same for any input variant type > VT_I8 */
2784     if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
2785         lvt > VT_I8 || rvt > VT_I8) {
2786         hres = DISP_E_BADVARTYPE;
2787         goto end;
2788     }
2789
2790     /* Determine the variant type to coerce to. */
2791     if (coerce[lvt] > coerce[rvt]) {
2792         resvt = prio2vt[coerce[lvt]];
2793         tvt = prio2vt[coerce[rvt]];
2794     } else {
2795         resvt = prio2vt[coerce[rvt]];
2796         tvt = prio2vt[coerce[lvt]];
2797     }
2798
2799     /* Special cases where the result variant type is defined by both
2800        input variants and not only that with the highest priority */
2801     if (resvt == VT_BSTR) {
2802         if (tvt == VT_EMPTY || tvt == VT_BSTR)
2803             resvt = VT_BSTR;
2804         else
2805             resvt = VT_R8;
2806     }
2807     if (resvt == VT_R4 && (tvt == VT_BSTR || tvt == VT_I8 || tvt == VT_I4))
2808         resvt = VT_R8;
2809
2810     /* For overflow detection use the biggest compatible type for the
2811        addition */
2812     switch (resvt) {
2813         case VT_ERROR:
2814             hres = DISP_E_BADVARTYPE;
2815             goto end;
2816         case VT_NULL:
2817             hres = S_OK;
2818             V_VT(result) = VT_NULL;
2819             goto end;
2820         case VT_DISPATCH:
2821             FIXME("can not handle variant type VT_DISPATCH\n");
2822             hres = DISP_E_TYPEMISMATCH;
2823             goto end;
2824         case VT_EMPTY:
2825             resvt = VT_I2;
2826             /* Fall through */
2827         case VT_UI1:
2828         case VT_I2:
2829         case VT_I4:
2830         case VT_I8:
2831             tvt = VT_I8;
2832             break;
2833         case VT_DATE:
2834         case VT_R4:
2835             tvt = VT_R8;
2836             break;
2837         default:
2838             tvt = resvt;
2839     }
2840
2841     /* Now coerce the variants */
2842     hres = VariantChangeType(&lv, left, 0, tvt);
2843     if (FAILED(hres))
2844         goto end;
2845     hres = VariantChangeType(&rv, right, 0, tvt);
2846     if (FAILED(hres))
2847         goto end;
2848
2849     /* Do the math */
2850     hres = S_OK;
2851     V_VT(&tv) = tvt;
2852     V_VT(result) = resvt;
2853     switch (tvt) {
2854         case VT_DECIMAL:
2855             hres = VarDecAdd(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
2856                              &V_DECIMAL(result));
2857             goto end;
2858         case VT_CY:
2859             hres = VarCyAdd(V_CY(&lv), V_CY(&rv), &V_CY(result));
2860             goto end;
2861         case VT_BSTR:
2862             /* We do not add those, we concatenate them. */
2863             hres = VarBstrCat(V_BSTR(&lv), V_BSTR(&rv), &V_BSTR(result));
2864             goto end;
2865         case VT_I8:
2866             /* Overflow detection */
2867             r8res = (double)V_I8(&lv) + (double)V_I8(&rv);
2868             if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
2869                 V_VT(result) = VT_R8;
2870                 V_R8(result) = r8res;
2871                 goto end;
2872             } else
2873                 V_I8(&tv) = V_I8(&lv) + V_I8(&rv);
2874             break;
2875         case VT_R8:
2876             /* FIXME: overflow detection */
2877             V_R8(&tv) = V_R8(&lv) + V_R8(&rv);
2878             break;
2879         default:
2880             ERR("We shouldn't get here! tvt = %d!\n", tvt);
2881             break;
2882     }
2883     if (resvt != tvt) {
2884         if ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
2885             /* Overflow! Change to the vartype with the next higher priority */
2886             resvt = prio2vt[coerce[resvt] + 1];
2887             hres = VariantChangeType(result, &tv, 0, resvt);
2888         }
2889     } else
2890         hres = VariantCopy(result, &tv);
2891
2892 end:
2893     if (hres != S_OK) {
2894         V_VT(result) = VT_EMPTY;
2895         V_I4(result) = 0;       /* No V_EMPTY */
2896     }
2897     VariantClear(&lv);
2898     VariantClear(&rv);
2899     VariantClear(&tv);
2900     TRACE("returning 0x%8lx (variant type %s)\n", hres, debugstr_VT(result));
2901     return hres;
2902 }
2903
2904 /**********************************************************************
2905  *              VarMul [OLEAUT32.156]
2906  *
2907  * Multiply two variants.
2908  *
2909  * PARAMS
2910  *  left    [I] First variant
2911  *  right   [I] Second variant
2912  *  result  [O] Result variant
2913  *
2914  * RETURNS
2915  *  Success: S_OK.
2916  *  Failure: An HRESULT error code indicating the error.
2917  *
2918  * NOTES
2919  *  Native VarMul up to and including WinXP dosn't like as input variants
2920  *  I1, UI2, UI4, UI8, INT and UINT. But it can multiply apples with oranges.
2921  *
2922  *  Native VarMul dosn't check for NULL in/out pointers and crashes. We do the
2923  *  same here.
2924  *
2925  * FIXME
2926  *  Overflow checking for R8 (double) overflow. Return DISP_E_OVERFLOW in that
2927  *  case.
2928  */
2929 HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2930 {
2931     HRESULT hres;
2932     VARTYPE lvt, rvt, resvt, tvt;
2933     VARIANT lv, rv, tv;
2934     double r8res;
2935
2936     /* Variant priority for coercion. Sorted from lowest to highest.
2937        VT_ERROR shows an invalid input variant type. */
2938     enum coerceprio { vt_UI1 = 0, vt_I2, vt_I4, vt_I8, vt_CY, vt_R4, vt_R8,
2939                       vt_DECIMAL, vt_NULL, vt_ERROR };
2940     /* Mapping from priority to variant type. Keep in sync with coerceprio! */
2941     VARTYPE prio2vt[] = { VT_UI1, VT_I2, VT_I4, VT_I8, VT_CY, VT_R4, VT_R8,
2942                           VT_DECIMAL, VT_NULL, VT_ERROR };
2943
2944     /* Mapping for coercion from input variant to priority of result variant. */
2945     static VARTYPE coerce[] = {
2946         /* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
2947         vt_UI1, vt_NULL, vt_I2, vt_I4, vt_R4,
2948         /* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
2949         vt_R8, vt_CY, vt_R8, vt_R8, vt_ERROR,
2950         /* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
2951         vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
2952         /* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
2953         vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
2954     };
2955
2956     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2957           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
2958           result);
2959
2960     VariantInit(&lv);
2961     VariantInit(&rv);
2962     VariantInit(&tv);
2963     lvt = V_VT(left)&VT_TYPEMASK;
2964     rvt = V_VT(right)&VT_TYPEMASK;
2965
2966     /* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
2967        Same for any input variant type > VT_I8 */
2968     if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
2969         lvt > VT_I8 || rvt > VT_I8) {
2970         hres = DISP_E_BADVARTYPE;
2971         goto end;
2972     }
2973
2974     /* Determine the variant type to coerce to. */
2975     if (coerce[lvt] > coerce[rvt]) {
2976         resvt = prio2vt[coerce[lvt]];
2977         tvt = prio2vt[coerce[rvt]];
2978     } else {
2979         resvt = prio2vt[coerce[rvt]];
2980         tvt = prio2vt[coerce[lvt]];
2981     }
2982
2983     /* Special cases where the result variant type is defined by both
2984        input variants and not only that with the highest priority */
2985     if (resvt == VT_R4 && (tvt == VT_CY || tvt == VT_I8 || tvt == VT_I4))
2986         resvt = VT_R8;
2987     if (lvt == VT_EMPTY && rvt == VT_EMPTY)
2988         resvt = VT_I2;
2989
2990     /* For overflow detection use the biggest compatible type for the
2991        multiplication */
2992     switch (resvt) {
2993         case VT_ERROR:
2994             hres = DISP_E_BADVARTYPE;
2995             goto end;
2996         case VT_NULL:
2997             hres = S_OK;
2998             V_VT(result) = VT_NULL;
2999             goto end;
3000         case VT_UI1:
3001         case VT_I2:
3002         case VT_I4:
3003         case VT_I8:
3004             tvt = VT_I8;
3005             break;
3006         case VT_R4:
3007             tvt = VT_R8;
3008             break;
3009         default:
3010             tvt = resvt;
3011     }
3012
3013     /* Now coerce the variants */
3014     hres = VariantChangeType(&lv, left, 0, tvt);
3015     if (FAILED(hres))
3016         goto end;
3017     hres = VariantChangeType(&rv, right, 0, tvt);
3018     if (FAILED(hres))
3019         goto end;
3020
3021     /* Do the math */
3022     hres = S_OK;
3023     V_VT(&tv) = tvt;
3024     V_VT(result) = resvt;
3025     switch (tvt) {
3026         case VT_DECIMAL:
3027             hres = VarDecMul(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
3028                              &V_DECIMAL(result));
3029             goto end;
3030         case VT_CY:
3031             hres = VarCyMul(V_CY(&lv), V_CY(&rv), &V_CY(result));
3032             goto end;
3033         case VT_I8:
3034             /* Overflow detection */
3035             r8res = (double)V_I8(&lv) * (double)V_I8(&rv);
3036             if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
3037                 V_VT(result) = VT_R8;
3038                 V_R8(result) = r8res;
3039                 goto end;
3040             } else
3041                 V_I8(&tv) = V_I8(&lv) * V_I8(&rv);
3042             break;
3043         case VT_R8:
3044             /* FIXME: overflow detection */
3045             V_R8(&tv) = V_R8(&lv) * V_R8(&rv);
3046             break;
3047         default:
3048             ERR("We shouldn't get here! tvt = %d!\n", tvt);
3049             break;
3050     }
3051     if (resvt != tvt) {
3052         while ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
3053             /* Overflow! Change to the vartype with the next higher priority */
3054             resvt = prio2vt[coerce[resvt] + 1];
3055         }
3056     } else
3057         hres = VariantCopy(result, &tv);
3058
3059 end:
3060     if (hres != S_OK) {
3061         V_VT(result) = VT_EMPTY;
3062         V_I4(result) = 0;       /* No V_EMPTY */
3063     }
3064     VariantClear(&lv);
3065     VariantClear(&rv);
3066     VariantClear(&tv);
3067     TRACE("returning 0x%8lx (variant type %s)\n", hres, debugstr_VT(result));
3068     return hres;
3069 }
3070
3071 /**********************************************************************
3072  *              VarDiv [OLEAUT32.143]
3073  *
3074  */
3075 HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3076 {
3077     HRESULT rc = E_FAIL;
3078     VARTYPE lvt,rvt,resvt;
3079     VARIANT lv,rv;
3080     BOOL found;
3081
3082     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3083           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
3084
3085     VariantInit(&lv);VariantInit(&rv);
3086     lvt = V_VT(left)&VT_TYPEMASK;
3087     rvt = V_VT(right)&VT_TYPEMASK;
3088     found = FALSE;resvt = VT_VOID;
3089     if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
3090         found = TRUE;
3091         resvt = VT_R8;
3092     }
3093     if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
3094         found = TRUE;
3095         resvt = VT_I4;
3096     }
3097     if (!found) {
3098         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
3099         return E_FAIL;
3100     }
3101     rc = VariantChangeType(&lv, left, 0, resvt);
3102     if (FAILED(rc)) {
3103         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
3104         return rc;
3105     }
3106     rc = VariantChangeType(&rv, right, 0, resvt);
3107     if (FAILED(rc)) {
3108         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
3109         return rc;
3110     }
3111     switch (resvt) {
3112     case VT_R8:
3113         if (V_R8(&rv) == 0) return DISP_E_DIVBYZERO;
3114         V_VT(result) = resvt;
3115         V_R8(result) = V_R8(&lv) / V_R8(&rv);
3116         rc = S_OK;
3117         break;
3118     case VT_I4:
3119         if (V_I4(&rv) == 0) return DISP_E_DIVBYZERO;
3120         V_VT(result) = resvt;
3121         V_I4(result) = V_I4(&lv) / V_I4(&rv);
3122         rc = S_OK;
3123         break;
3124     }
3125     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
3126           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
3127     return rc;
3128 }
3129
3130 /**********************************************************************
3131  *              VarSub [OLEAUT32.159]
3132  *
3133  */
3134 HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3135 {
3136     HRESULT rc = E_FAIL;
3137     VARTYPE lvt,rvt,resvt;
3138     VARIANT lv,rv;
3139     BOOL found;
3140
3141     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3142           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
3143
3144     VariantInit(&lv);VariantInit(&rv);
3145     lvt = V_VT(left)&VT_TYPEMASK;
3146     rvt = V_VT(right)&VT_TYPEMASK;
3147     found = FALSE;resvt = VT_VOID;
3148     if (((1<<lvt) | (1<<rvt)) & ((1<<VT_DATE)|(1<<VT_R4)|(1<<VT_R8))) {
3149         found = TRUE;
3150         resvt = VT_R8;
3151     }
3152     if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
3153         found = TRUE;
3154         resvt = VT_I4;
3155     }
3156     if (!found) {
3157         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
3158         return E_FAIL;
3159     }
3160     rc = VariantChangeType(&lv, left, 0, resvt);
3161     if (FAILED(rc)) {
3162         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
3163         return rc;
3164     }
3165     rc = VariantChangeType(&rv, right, 0, resvt);
3166     if (FAILED(rc)) {
3167         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
3168         return rc;
3169     }
3170     switch (resvt) {
3171     case VT_R8:
3172         V_VT(result) = resvt;
3173         V_R8(result) = V_R8(&lv) - V_R8(&rv);
3174         rc = S_OK;
3175         break;
3176     case VT_I4:
3177         V_VT(result) = resvt;
3178         V_I4(result) = V_I4(&lv) - V_I4(&rv);
3179         rc = S_OK;
3180         break;
3181     }
3182     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
3183           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
3184     return rc;
3185 }
3186
3187 /**********************************************************************
3188  *              VarOr [OLEAUT32.157]
3189  *
3190  * Perform a logical or (OR) operation on two variants.
3191  *
3192  * PARAMS
3193  *  pVarLeft  [I] First variant
3194  *  pVarRight [I] Variant to OR with pVarLeft
3195  *  pVarOut   [O] Destination for OR result
3196  *
3197  * RETURNS
3198  *  Success: S_OK. pVarOut contains the result of the operation with its type
3199  *           taken from the table listed under VarXor().
3200  *  Failure: An HRESULT error code indicating the error.
3201  *
3202  * NOTES
3203  *  See the Notes section of VarXor() for further information.
3204  */
3205 HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3206 {
3207     VARTYPE vt = VT_I4;
3208     VARIANT varLeft, varRight, varStr;
3209     HRESULT hRet;
3210
3211     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3212           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3213           debugstr_VF(pVarRight), pVarOut);
3214
3215     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
3216         V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
3217         V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH ||
3218         V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD)
3219         return DISP_E_BADVARTYPE;
3220
3221     V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY;
3222
3223     if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
3224     {
3225         /* NULL OR Zero is NULL, NULL OR value is value */
3226         if (V_VT(pVarLeft) == VT_NULL)
3227             pVarLeft = pVarRight; /* point to the non-NULL var */
3228
3229         V_VT(pVarOut) = VT_NULL;
3230         V_I4(pVarOut) = 0;
3231
3232         switch (V_VT(pVarLeft))
3233         {
3234         case VT_DATE: case VT_R8:
3235             if (V_R8(pVarLeft))
3236                 goto VarOr_AsEmpty;
3237             return S_OK;
3238         case VT_BOOL:
3239             if (V_BOOL(pVarLeft))
3240                 *pVarOut = *pVarLeft;
3241             return S_OK;
3242          case VT_I2: case VT_UI2:
3243             if (V_I2(pVarLeft))
3244                 goto VarOr_AsEmpty;
3245             return S_OK;
3246         case VT_I1:
3247             if (V_I1(pVarLeft))
3248                 goto VarOr_AsEmpty;
3249             return S_OK;
3250         case VT_UI1:
3251             if (V_UI1(pVarLeft))
3252                 *pVarOut = *pVarLeft;
3253             return S_OK;
3254         case VT_R4:
3255             if (V_R4(pVarLeft))
3256                 goto VarOr_AsEmpty;
3257             return S_OK;
3258         case VT_I4: case VT_UI4: case VT_INT: case VT_UINT:
3259             if (V_I4(pVarLeft))
3260                 goto VarOr_AsEmpty;
3261             return S_OK;
3262         case VT_CY:
3263             if (V_CY(pVarLeft).int64)
3264                 goto VarOr_AsEmpty;
3265             return S_OK;
3266         case VT_I8: case VT_UI8:
3267             if (V_I8(pVarLeft))
3268                 goto VarOr_AsEmpty;
3269             return S_OK;
3270         case VT_DECIMAL:
3271             if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft)))
3272                 goto VarOr_AsEmpty;
3273             return S_OK;
3274         case VT_BSTR:
3275         {
3276             VARIANT_BOOL b;
3277
3278             if (!V_BSTR(pVarLeft))
3279                 return DISP_E_BADVARTYPE;
3280
3281             hRet = VarBoolFromStr(V_BSTR(pVarLeft), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
3282             if (SUCCEEDED(hRet) && b)
3283             {
3284                 V_VT(pVarOut) = VT_BOOL;
3285                 V_BOOL(pVarOut) = b;
3286             }
3287             return hRet;
3288         }
3289         case VT_NULL: case VT_EMPTY:
3290             V_VT(pVarOut) = VT_NULL;
3291             return S_OK;
3292         default:
3293             return DISP_E_BADVARTYPE;
3294         }
3295     }
3296
3297     if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY)
3298     {
3299         if (V_VT(pVarLeft) == VT_EMPTY)
3300             pVarLeft = pVarRight; /* point to the non-EMPTY var */
3301
3302 VarOr_AsEmpty:
3303         /* Since one argument is empty (0), OR'ing it with the other simply
3304          * gives the others value (as 0|x => x). So just convert the other
3305          * argument to the required result type.
3306          */
3307         switch (V_VT(pVarLeft))
3308         {
3309         case VT_BSTR:
3310             if (!V_BSTR(pVarLeft))
3311                 return DISP_E_BADVARTYPE;
3312
3313             hRet = VariantCopy(&varStr, pVarLeft);
3314             if (FAILED(hRet))
3315                 goto VarOr_Exit;
3316             pVarLeft = &varStr;
3317             hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
3318             if (FAILED(hRet))
3319                 goto VarOr_Exit;
3320             /* Fall Through ... */
3321         case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2:
3322             V_VT(pVarOut) = VT_I2;
3323             break;
3324         case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:
3325         case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:
3326         case VT_INT: case VT_UINT: case VT_UI8:
3327             V_VT(pVarOut) = VT_I4;
3328             break;
3329         case VT_I8:
3330             V_VT(pVarOut) = VT_I8;
3331             break;
3332         default:
3333             return DISP_E_BADVARTYPE;
3334         }
3335         hRet = VariantCopy(&varLeft, pVarLeft);
3336         if (FAILED(hRet))
3337             goto VarOr_Exit;
3338         pVarLeft = &varLeft;
3339         hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut));
3340         goto VarOr_Exit;
3341     }
3342
3343     if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)
3344     {
3345         V_VT(pVarOut) = VT_BOOL;
3346         V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight);
3347         return S_OK;
3348     }
3349
3350     if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)
3351     {
3352         V_VT(pVarOut) = VT_UI1;
3353         V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight);
3354         return S_OK;
3355     }
3356
3357     if (V_VT(pVarLeft) == VT_BSTR)
3358     {
3359         hRet = VariantCopy(&varStr, pVarLeft);
3360         if (FAILED(hRet))
3361             goto VarOr_Exit;
3362         pVarLeft = &varStr;
3363         hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
3364         if (FAILED(hRet))
3365             goto VarOr_Exit;
3366     }
3367
3368     if (V_VT(pVarLeft) == VT_BOOL &&
3369         (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR))
3370     {
3371         vt = VT_BOOL;
3372     }
3373     else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 ||
3374         V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) &&
3375         (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||
3376         V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR))
3377     {
3378         vt = VT_I2;
3379     }
3380     else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)
3381     {
3382         if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
3383             return DISP_E_TYPEMISMATCH;
3384         vt = VT_I8;
3385     }
3386
3387     hRet = VariantCopy(&varLeft, pVarLeft);
3388     if (FAILED(hRet))
3389         goto VarOr_Exit;
3390
3391     hRet = VariantCopy(&varRight, pVarRight);
3392     if (FAILED(hRet))
3393         goto VarOr_Exit;
3394
3395     if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4)
3396         V_VT(&varLeft) = VT_I4; /* Don't overflow */
3397     else
3398     {
3399         double d;
3400
3401         if (V_VT(&varLeft) == VT_BSTR &&
3402             FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d)))
3403             hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL);
3404         if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt)
3405             hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
3406         if (FAILED(hRet))
3407             goto VarOr_Exit;
3408     }
3409
3410     if (vt == VT_I4 && V_VT(&varRight) == VT_UI4)
3411         V_VT(&varRight) = VT_I4; /* Don't overflow */
3412     else
3413     {
3414         double d;
3415
3416         if (V_VT(&varRight) == VT_BSTR &&
3417             FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d)))
3418             hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL);
3419         if (SUCCEEDED(hRet) && V_VT(&varRight) != vt)
3420             hRet = VariantChangeType(&varRight, &varRight, 0, vt);
3421         if (FAILED(hRet))
3422             goto VarOr_Exit;
3423     }
3424
3425     V_VT(pVarOut) = vt;
3426     if (vt == VT_I8)
3427     {
3428         V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight);
3429     }
3430     else if (vt == VT_I4)
3431     {
3432         V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight);
3433     }
3434     else
3435     {
3436         V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight);
3437     }
3438
3439 VarOr_Exit:
3440     VariantClear(&varStr);
3441     VariantClear(&varLeft);
3442     VariantClear(&varRight);
3443     return hRet;
3444 }
3445
3446 /**********************************************************************
3447  * VarAbs [OLEAUT32.168]
3448  *
3449  * Convert a variant to its absolute value.
3450  *
3451  * PARAMS
3452  *  pVarIn  [I] Source variant
3453  *  pVarOut [O] Destination for converted value
3454  *
3455  * RETURNS
3456  *  Success: S_OK. pVarOut contains the absolute value of pVarIn.
3457  *  Failure: An HRESULT error code indicating the error.
3458  *
3459  * NOTES
3460  *  - This function does not process by-reference variants.
3461  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3462  *    according to the following table:
3463  *| Input Type       Output Type
3464  *| ----------       -----------
3465  *| VT_BOOL          VT_I2
3466  *| VT_BSTR          VT_R8
3467  *| (All others)     Unchanged
3468  */
3469 HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)
3470 {
3471     VARIANT varIn;
3472     HRESULT hRet = S_OK;
3473
3474     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3475           debugstr_VF(pVarIn), pVarOut);
3476
3477     if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN ||
3478         V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD ||
3479         V_VT(pVarIn) == VT_ERROR)
3480         return DISP_E_TYPEMISMATCH;
3481
3482     *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */
3483
3484 #define ABS_CASE(typ,min) \
3485     case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \
3486                   else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \
3487                   break
3488
3489     switch (V_VT(pVarIn))
3490     {
3491     ABS_CASE(I1,I1_MIN);
3492     case VT_BOOL:
3493         V_VT(pVarOut) = VT_I2;
3494         /* BOOL->I2, Fall through ... */
3495     ABS_CASE(I2,I2_MIN);
3496     case VT_INT:
3497     ABS_CASE(I4,I4_MIN);
3498     ABS_CASE(I8,I8_MIN);
3499     ABS_CASE(R4,R4_MIN);
3500     case VT_BSTR:
3501         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
3502         if (FAILED(hRet))
3503             break;
3504         V_VT(pVarOut) = VT_R8;
3505         pVarIn = &varIn;
3506         /* Fall through ... */
3507     case VT_DATE:
3508     ABS_CASE(R8,R8_MIN);
3509     case VT_CY:
3510         hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut));
3511         break;
3512     case VT_DECIMAL:
3513         DEC_SIGN(&V_DECIMAL(pVarOut)) &= ~DECIMAL_NEG;
3514         break;
3515     case VT_UI1:
3516     case VT_UI2:
3517     case VT_UINT:
3518     case VT_UI4:
3519     case VT_UI8:
3520         /* No-Op */
3521         break;
3522     case VT_EMPTY:
3523         V_VT(pVarOut) = VT_I2;
3524     case VT_NULL:
3525         V_I2(pVarOut) = 0;
3526         break;
3527     default:
3528         hRet = DISP_E_BADVARTYPE;
3529     }
3530
3531     return hRet;
3532 }
3533
3534 /**********************************************************************
3535  *              VarFix [OLEAUT32.169]
3536  *
3537  * Truncate a variants value to a whole number.
3538  *
3539  * PARAMS
3540  *  pVarIn  [I] Source variant
3541  *  pVarOut [O] Destination for converted value
3542  *
3543  * RETURNS
3544  *  Success: S_OK. pVarOut contains the converted value.
3545  *  Failure: An HRESULT error code indicating the error.
3546  *
3547  * NOTES
3548  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3549  *    according to the following table:
3550  *| Input Type       Output Type
3551  *| ----------       -----------
3552  *|  VT_BOOL          VT_I2
3553  *|  VT_EMPTY         VT_I2
3554  *|  VT_BSTR          VT_R8
3555  *|  All Others       Unchanged
3556  *  - The difference between this function and VarInt() is that VarInt() rounds
3557  *    negative numbers away from 0, while this function rounds them towards zero.
3558  */
3559 HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut)
3560 {
3561     HRESULT hRet = S_OK;
3562
3563     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3564           debugstr_VF(pVarIn), pVarOut);
3565
3566     V_VT(pVarOut) = V_VT(pVarIn);
3567
3568     switch (V_VT(pVarIn))
3569     {
3570     case VT_UI1:
3571         V_UI1(pVarOut) = V_UI1(pVarIn);
3572         break;
3573     case VT_BOOL:
3574         V_VT(pVarOut) = VT_I2;
3575         /* Fall through */
3576      case VT_I2:
3577         V_I2(pVarOut) = V_I2(pVarIn);
3578         break;
3579      case VT_I4:
3580         V_I4(pVarOut) = V_I4(pVarIn);
3581         break;
3582      case VT_I8:
3583         V_I8(pVarOut) = V_I8(pVarIn);
3584         break;
3585     case VT_R4:
3586         if (V_R4(pVarIn) < 0.0f)
3587             V_R4(pVarOut) = (float)ceil(V_R4(pVarIn));
3588         else
3589             V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
3590         break;
3591     case VT_BSTR:
3592         V_VT(pVarOut) = VT_R8;
3593         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
3594         pVarIn = pVarOut;
3595         /* Fall through */
3596     case VT_DATE:
3597     case VT_R8:
3598         if (V_R8(pVarIn) < 0.0)
3599             V_R8(pVarOut) = ceil(V_R8(pVarIn));
3600         else
3601             V_R8(pVarOut) = floor(V_R8(pVarIn));
3602         break;
3603     case VT_CY:
3604         hRet = VarCyFix(V_CY(pVarIn), &V_CY(pVarOut));
3605         break;
3606     case VT_DECIMAL:
3607         hRet = VarDecFix(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
3608         break;
3609     case VT_EMPTY:
3610         V_VT(pVarOut) = VT_I2;
3611         V_I2(pVarOut) = 0;
3612         break;
3613     case VT_NULL:
3614         /* No-Op */
3615         break;
3616     default:
3617         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
3618             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
3619             hRet = DISP_E_BADVARTYPE;
3620         else
3621             hRet = DISP_E_TYPEMISMATCH;
3622     }
3623     if (FAILED(hRet))
3624       V_VT(pVarOut) = VT_EMPTY;
3625
3626     return hRet;
3627 }
3628
3629 /**********************************************************************
3630  *              VarInt [OLEAUT32.172]
3631  *
3632  * Truncate a variants value to a whole number.
3633  *
3634  * PARAMS
3635  *  pVarIn  [I] Source variant
3636  *  pVarOut [O] Destination for converted value
3637  *
3638  * RETURNS
3639  *  Success: S_OK. pVarOut contains the converted value.
3640  *  Failure: An HRESULT error code indicating the error.
3641  *
3642  * NOTES
3643  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3644  *    according to the following table:
3645  *| Input Type       Output Type
3646  *| ----------       -----------
3647  *|  VT_BOOL          VT_I2
3648  *|  VT_EMPTY         VT_I2
3649  *|  VT_BSTR          VT_R8
3650  *|  All Others       Unchanged
3651  *  - The difference between this function and VarFix() is that VarFix() rounds
3652  *    negative numbers towards 0, while this function rounds them away from zero.
3653  */
3654 HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
3655 {
3656     HRESULT hRet = S_OK;
3657
3658     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3659           debugstr_VF(pVarIn), pVarOut);
3660
3661     V_VT(pVarOut) = V_VT(pVarIn);
3662
3663     switch (V_VT(pVarIn))
3664     {
3665     case VT_R4:
3666         V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
3667         break;
3668     case VT_BSTR:
3669         V_VT(pVarOut) = VT_R8;
3670         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
3671         pVarIn = pVarOut;
3672         /* Fall through */
3673     case VT_DATE:
3674     case VT_R8:
3675         V_R8(pVarOut) = floor(V_R8(pVarIn));
3676         break;
3677     case VT_CY:
3678         hRet = VarCyInt(V_CY(pVarIn), &V_CY(pVarOut));
3679         break;
3680     case VT_DECIMAL:
3681         hRet = VarDecInt(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
3682         break;
3683     default:
3684         return VarFix(pVarIn, pVarOut);
3685     }
3686
3687     return hRet;
3688 }
3689
3690 /**********************************************************************
3691  *              VarXor [OLEAUT32.167]
3692  *
3693  * Perform a logical exclusive-or (XOR) operation on two variants.
3694  *
3695  * PARAMS
3696  *  pVarLeft  [I] First variant
3697  *  pVarRight [I] Variant to XOR with pVarLeft
3698  *  pVarOut   [O] Destination for XOR result
3699  *
3700  * RETURNS
3701  *  Success: S_OK. pVarOut contains the result of the operation with its type
3702  *           taken from the table below).
3703  *  Failure: An HRESULT error code indicating the error.
3704  *
3705  * NOTES
3706  *  - Neither pVarLeft or pVarRight are modified by this function.
3707  *  - This function does not process by-reference variants.
3708  *  - Input types of VT_BSTR may be numeric strings or boolean text.
3709  *  - The type of result stored in pVarOut depends on the types of pVarLeft
3710  *    and pVarRight, and will be one of VT_UI1, VT_I2, VT_I4, VT_I8, VT_BOOL,
3711  *    or VT_NULL if the function succeeds.
3712  *  - Type promotion is inconsistent and as a result certain combinations of
3713  *    values will return DISP_E_OVERFLOW even when they could be represented.
3714  *    This matches the behaviour of native oleaut32.
3715  */
3716 HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3717 {
3718     VARTYPE vt;
3719     VARIANT varLeft, varRight;
3720     double d;
3721     HRESULT hRet;
3722
3723     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3724           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3725           debugstr_VF(pVarRight), pVarOut);
3726
3727     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
3728         V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT ||
3729         V_VT(pVarLeft) == VT_VARIANT || V_VT(pVarRight) == VT_VARIANT ||
3730         V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
3731         V_VT(pVarLeft) == (VARTYPE)15 || V_VT(pVarRight) == (VARTYPE)15 ||
3732         V_VT(pVarLeft) == VT_ERROR || V_VT(pVarRight) == VT_ERROR)
3733         return DISP_E_BADVARTYPE;
3734
3735     if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
3736     {
3737         /* NULL XOR anything valid is NULL */
3738         V_VT(pVarOut) = VT_NULL;
3739         return S_OK;
3740     }
3741
3742     /* Copy our inputs so we don't disturb anything */
3743     V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY;
3744
3745     hRet = VariantCopy(&varLeft, pVarLeft);
3746     if (FAILED(hRet))
3747         goto VarXor_Exit;
3748
3749     hRet = VariantCopy(&varRight, pVarRight);
3750     if (FAILED(hRet))
3751         goto VarXor_Exit;
3752
3753     /* Try any strings first as numbers, then as VT_BOOL */
3754     if (V_VT(&varLeft) == VT_BSTR)
3755     {
3756         hRet = VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d);
3757         hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL,
3758                                  FAILED(hRet) ? VT_BOOL : VT_I4);
3759         if (FAILED(hRet))
3760             goto VarXor_Exit;
3761     }
3762
3763     if (V_VT(&varRight) == VT_BSTR)
3764     {
3765         hRet = VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d);
3766         hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL,
3767                                  FAILED(hRet) ? VT_BOOL : VT_I4);
3768         if (FAILED(hRet))
3769             goto VarXor_Exit;
3770     }
3771
3772     /* Determine the result type */
3773     if (V_VT(&varLeft) == VT_I8 || V_VT(&varRight) == VT_I8)
3774     {
3775         if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
3776             return DISP_E_TYPEMISMATCH;
3777         vt = VT_I8;
3778     }
3779     else
3780     {
3781         switch ((V_VT(&varLeft) << 16) | V_VT(&varRight))
3782         {
3783         case (VT_BOOL  << 16) | VT_BOOL:
3784             vt = VT_BOOL;
3785             break;
3786         case (VT_UI1   << 16) | VT_UI1:
3787             vt = VT_UI1;
3788             break;
3789         case (VT_EMPTY << 16) | VT_EMPTY:
3790         case (VT_EMPTY << 16) | VT_UI1:
3791         case (VT_EMPTY << 16) | VT_I2:
3792         case (VT_EMPTY << 16) | VT_BOOL:
3793         case (VT_UI1   << 16) | VT_EMPTY:
3794         case (VT_UI1   << 16) | VT_I2:
3795         case (VT_UI1   << 16) | VT_BOOL:
3796         case (VT_I2    << 16) | VT_EMPTY:
3797         case (VT_I2    << 16) | VT_UI1:
3798         case (VT_I2    << 16) | VT_I2:
3799         case (VT_I2    << 16) | VT_BOOL:
3800         case (VT_BOOL  << 16) | VT_EMPTY:
3801         case (VT_BOOL  << 16) | VT_UI1:
3802         case (VT_BOOL  << 16) | VT_I2:
3803             vt = VT_I2;
3804             break;
3805         default:
3806             vt = VT_I4;
3807             break;
3808         }
3809     }
3810
3811     /* VT_UI4 does not overflow */
3812     if (vt != VT_I8)
3813     {
3814         if (V_VT(&varLeft) == VT_UI4)
3815             V_VT(&varLeft) = VT_I4;
3816         if (V_VT(&varRight) == VT_UI4)
3817             V_VT(&varRight) = VT_I4;
3818     }
3819
3820     /* Convert our input copies to the result type */
3821     if (V_VT(&varLeft) != vt)
3822         hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
3823     if (FAILED(hRet))
3824         goto VarXor_Exit;
3825
3826     if (V_VT(&varRight) != vt)
3827         hRet = VariantChangeType(&varRight, &varRight, 0, vt);
3828     if (FAILED(hRet))
3829         goto VarXor_Exit;
3830
3831     V_VT(pVarOut) = vt;
3832
3833     /* Calculate the result */
3834     switch (vt)
3835     {
3836     case VT_I8:
3837         V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight);
3838         break;
3839     case VT_I4:
3840         V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight);
3841         break;
3842     case VT_BOOL:
3843     case VT_I2:
3844         V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight);
3845         break;
3846     case VT_UI1:
3847         V_UI1(pVarOut) = V_UI1(&varLeft) ^ V_UI1(&varRight);
3848         break;
3849     }
3850
3851 VarXor_Exit:
3852     VariantClear(&varLeft);
3853     VariantClear(&varRight);
3854     return hRet;
3855 }
3856
3857 /**********************************************************************
3858  *              VarEqv [OLEAUT32.172]
3859  *
3860  * Determine if two variants contain the same value.
3861  *
3862  * PARAMS
3863  *  pVarLeft  [I] First variant to compare
3864  *  pVarRight [I] Variant to compare to pVarLeft
3865  *  pVarOut   [O] Destination for comparison result
3866  *
3867  * RETURNS
3868  *  Success: S_OK. pVarOut contains the result of the comparison (VARIANT_TRUE
3869  *           if equivalent or non-zero otherwise.
3870  *  Failure: An HRESULT error code indicating the error.
3871  *
3872  * NOTES
3873  *  - This function simply calls VarXor() on pVarLeft and pVarRight and inverts
3874  *    the result.
3875  */
3876 HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3877 {
3878     HRESULT hRet;
3879
3880     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3881           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3882           debugstr_VF(pVarRight), pVarOut);
3883
3884     hRet = VarXor(pVarLeft, pVarRight, pVarOut);
3885     if (SUCCEEDED(hRet))
3886     {
3887         if (V_VT(pVarOut) == VT_I8)
3888             V_I8(pVarOut) = ~V_I8(pVarOut);
3889         else
3890             V_UI4(pVarOut) = ~V_UI4(pVarOut);
3891     }
3892     return hRet;
3893 }
3894
3895 /**********************************************************************
3896  *              VarNeg [OLEAUT32.173]
3897  *
3898  * Negate the value of a variant.
3899  *
3900  * PARAMS
3901  *  pVarIn  [I] Source variant
3902  *  pVarOut [O] Destination for converted value
3903  *
3904  * RETURNS
3905  *  Success: S_OK. pVarOut contains the converted value.
3906  *  Failure: An HRESULT error code indicating the error.
3907  *
3908  * NOTES
3909  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3910  *    according to the following table:
3911  *| Input Type       Output Type
3912  *| ----------       -----------
3913  *|  VT_EMPTY         VT_I2
3914  *|  VT_UI1           VT_I2
3915  *|  VT_BOOL          VT_I2
3916  *|  VT_BSTR          VT_R8
3917  *|  All Others       Unchanged (unless promoted)
3918  *  - Where the negated value of a variant does not fit in its base type, the type
3919  *    is promoted according to the following table:
3920  *| Input Type       Promoted To
3921  *| ----------       -----------
3922  *|   VT_I2            VT_I4
3923  *|   VT_I4            VT_R8
3924  *|   VT_I8            VT_R8
3925  *  - The native version of this function returns DISP_E_BADVARTYPE for valid
3926  *    variant types that cannot be negated, and returns DISP_E_TYPEMISMATCH
3927  *    for types which are not valid. Since this is in contravention of the
3928  *    meaning of those error codes and unlikely to be relied on by applications,
3929  *    this implementation returns errors consistent with the other high level
3930  *    variant math functions.
3931  */
3932 HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
3933 {
3934     HRESULT hRet = S_OK;
3935
3936     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3937           debugstr_VF(pVarIn), pVarOut);
3938
3939     V_VT(pVarOut) = V_VT(pVarIn);
3940
3941     switch (V_VT(pVarIn))
3942     {
3943     case VT_UI1:
3944         V_VT(pVarOut) = VT_I2;
3945         V_I2(pVarOut) = -V_UI1(pVarIn);
3946         break;
3947     case VT_BOOL:
3948         V_VT(pVarOut) = VT_I2;
3949         /* Fall through */
3950     case VT_I2:
3951         if (V_I2(pVarIn) == I2_MIN)
3952         {
3953             V_VT(pVarOut) = VT_I4;
3954             V_I4(pVarOut) = -(int)V_I2(pVarIn);
3955         }
3956         else
3957             V_I2(pVarOut) = -V_I2(pVarIn);
3958         break;
3959     case VT_I4:
3960         if (V_I4(pVarIn) == I4_MIN)
3961         {
3962             V_VT(pVarOut) = VT_R8;
3963             V_R8(pVarOut) = -(double)V_I4(pVarIn);
3964         }
3965         else
3966             V_I4(pVarOut) = -V_I4(pVarIn);
3967         break;
3968     case VT_I8:
3969         if (V_I8(pVarIn) == I8_MIN)
3970         {
3971             V_VT(pVarOut) = VT_R8;
3972             hRet = VarR8FromI8(V_I8(pVarIn), &V_R8(pVarOut));
3973             V_R8(pVarOut) *= -1.0;
3974         }
3975         else
3976             V_I8(pVarOut) = -V_I8(pVarIn);
3977         break;
3978     case VT_R4:
3979         V_R4(pVarOut) = -V_R4(pVarIn);
3980         break;
3981     case VT_DATE:
3982     case VT_R8:
3983         V_R8(pVarOut) = -V_R8(pVarIn);
3984         break;
3985     case VT_CY:
3986         hRet = VarCyNeg(V_CY(pVarIn), &V_CY(pVarOut));
3987         break;
3988     case VT_DECIMAL:
3989         hRet = VarDecNeg(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
3990         break;
3991     case VT_BSTR:
3992         V_VT(pVarOut) = VT_R8;
3993         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
3994         V_R8(pVarOut) = -V_R8(pVarOut);
3995         break;
3996     case VT_EMPTY:
3997         V_VT(pVarOut) = VT_I2;
3998         V_I2(pVarOut) = 0;
3999         break;
4000     case VT_NULL:
4001         /* No-Op */
4002         break;
4003     default:
4004         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4005             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
4006             hRet = DISP_E_BADVARTYPE;
4007         else
4008             hRet = DISP_E_TYPEMISMATCH;
4009     }
4010     if (FAILED(hRet))
4011       V_VT(pVarOut) = VT_EMPTY;
4012
4013     return hRet;
4014 }
4015
4016 /**********************************************************************
4017  *              VarNot [OLEAUT32.174]
4018  *
4019  * Perform a not operation on a variant.
4020  *
4021  * PARAMS
4022  *  pVarIn  [I] Source variant
4023  *  pVarOut [O] Destination for converted value
4024  *
4025  * RETURNS
4026  *  Success: S_OK. pVarOut contains the converted value.
4027  *  Failure: An HRESULT error code indicating the error.
4028  *
4029  * NOTES
4030  *  - Strictly speaking, this function performs a bitwise ones complement
4031  *    on the variants value (after possibly converting to VT_I4, see below).
4032  *    This only behaves like a boolean not operation if the value in
4033  *    pVarIn is either VARIANT_TRUE or VARIANT_FALSE and the type is signed.
4034  *  - To perform a genuine not operation, convert the variant to a VT_BOOL
4035  *    before calling this function.
4036  *  - This function does not process by-reference variants.
4037  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
4038  *    according to the following table:
4039  *| Input Type       Output Type
4040  *| ----------       -----------
4041  *| VT_EMPTY         VT_I2
4042  *| VT_R4            VT_I4
4043  *| VT_R8            VT_I4
4044  *| VT_BSTR          VT_I4
4045  *| VT_DECIMAL       VT_I4
4046  *| VT_CY            VT_I4
4047  *| (All others)     Unchanged
4048  */
4049 HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
4050 {
4051     VARIANT varIn;
4052     HRESULT hRet = S_OK;
4053
4054     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
4055           debugstr_VF(pVarIn), pVarOut);
4056
4057     V_VT(pVarOut) = V_VT(pVarIn);
4058
4059     switch (V_VT(pVarIn))
4060     {
4061     case VT_I1:
4062         V_I4(pVarOut) = ~V_I1(pVarIn);
4063         V_VT(pVarOut) = VT_I4;
4064         break;
4065     case VT_UI1: V_UI1(pVarOut) = ~V_UI1(pVarIn); break;
4066     case VT_BOOL:
4067     case VT_I2:  V_I2(pVarOut) = ~V_I2(pVarIn); break;
4068     case VT_UI2:
4069         V_I4(pVarOut) = ~V_UI2(pVarIn);
4070         V_VT(pVarOut) = VT_I4;
4071         break;
4072     case VT_DECIMAL:
4073         hRet = VarI4FromDec(&V_DECIMAL(pVarIn), &V_I4(&varIn));
4074         if (FAILED(hRet))
4075             break;
4076         pVarIn = &varIn;
4077         /* Fall through ... */
4078     case VT_INT:
4079         V_VT(pVarOut) = VT_I4;
4080         /* Fall through ... */
4081     case VT_I4:  V_I4(pVarOut) = ~V_I4(pVarIn); break;
4082     case VT_UINT:
4083     case VT_UI4:
4084         V_I4(pVarOut) = ~V_UI4(pVarIn);
4085         V_VT(pVarOut) = VT_I4;
4086         break;
4087     case VT_I8:  V_I8(pVarOut) = ~V_I8(pVarIn); break;
4088     case VT_UI8:
4089         V_I4(pVarOut) = ~V_UI8(pVarIn);
4090         V_VT(pVarOut) = VT_I4;
4091         break;
4092     case VT_R4:
4093         hRet = VarI4FromR4(V_R4(pVarIn), &V_I4(pVarOut));
4094         V_I4(pVarOut) = ~V_I4(pVarOut);
4095         V_VT(pVarOut) = VT_I4;
4096         break;
4097     case VT_BSTR:
4098         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
4099         if (FAILED(hRet))
4100             break;
4101         pVarIn = &varIn;
4102         /* Fall through ... */
4103     case VT_DATE:
4104     case VT_R8:
4105         hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut));
4106         V_I4(pVarOut) = ~V_I4(pVarOut);
4107         V_VT(pVarOut) = VT_I4;
4108         break;
4109     case VT_CY:
4110         hRet = VarI4FromCy(V_CY(pVarIn), &V_I4(pVarOut));
4111         V_I4(pVarOut) = ~V_I4(pVarOut);
4112         V_VT(pVarOut) = VT_I4;
4113         break;
4114     case VT_EMPTY:
4115         V_I2(pVarOut) = ~0;
4116         V_VT(pVarOut) = VT_I2;
4117         break;
4118     case VT_NULL:
4119         /* No-Op */
4120         break;
4121     default:
4122         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4123             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
4124             hRet = DISP_E_BADVARTYPE;
4125         else
4126             hRet = DISP_E_TYPEMISMATCH;
4127     }
4128     if (FAILED(hRet))
4129       V_VT(pVarOut) = VT_EMPTY;
4130
4131     return hRet;
4132 }
4133
4134 /**********************************************************************
4135  *              VarRound [OLEAUT32.175]
4136  *
4137  * Perform a round operation on a variant.
4138  *
4139  * PARAMS
4140  *  pVarIn  [I] Source variant
4141  *  deci    [I] Number of decimals to round to
4142  *  pVarOut [O] Destination for converted value
4143  *
4144  * RETURNS
4145  *  Success: S_OK. pVarOut contains the converted value.
4146  *  Failure: An HRESULT error code indicating the error.
4147  *
4148  * NOTES
4149  *  - Floating point values are rounded to the desired number of decimals.
4150  *  - Some integer types are just copied to the return variable.
4151  *  - Some other integer types are not handled and fail.
4152  */
4153 HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
4154 {
4155     VARIANT varIn;
4156     HRESULT hRet = S_OK;
4157     float factor;
4158
4159     TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci);
4160
4161     switch (V_VT(pVarIn))
4162     {
4163     /* cases that fail on windows */
4164     case VT_I1:
4165     case VT_I8:
4166     case VT_UI2:
4167     case VT_UI4:
4168         hRet = DISP_E_BADVARTYPE;
4169         break;
4170
4171     /* cases just copying in to out */
4172     case VT_UI1:
4173         V_VT(pVarOut) = V_VT(pVarIn);
4174         V_UI1(pVarOut) = V_UI1(pVarIn);
4175         break;
4176     case VT_I2:
4177         V_VT(pVarOut) = V_VT(pVarIn);
4178         V_I2(pVarOut) = V_I2(pVarIn);
4179         break;
4180     case VT_I4:
4181         V_VT(pVarOut) = V_VT(pVarIn);
4182         V_I4(pVarOut) = V_I4(pVarIn);
4183         break;
4184     case VT_NULL:
4185         V_VT(pVarOut) = V_VT(pVarIn);
4186         /* value unchanged */
4187         break;
4188
4189     /* cases that change type */
4190     case VT_EMPTY:
4191         V_VT(pVarOut) = VT_I2;
4192         V_I2(pVarOut) = 0;
4193         break;
4194     case VT_BOOL:
4195         V_VT(pVarOut) = VT_I2;
4196         V_I2(pVarOut) = V_BOOL(pVarIn);
4197         break;
4198     case VT_BSTR:
4199         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
4200         if (FAILED(hRet))
4201             break;
4202         V_VT(&varIn)=VT_R8;
4203         pVarIn = &varIn;
4204         /* Fall through ... */
4205
4206     /* cases we need to do math */
4207     case VT_R8:
4208         if (V_R8(pVarIn)>0) {
4209             V_R8(pVarOut)=floor(V_R8(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
4210         } else {
4211             V_R8(pVarOut)=ceil(V_R8(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
4212         }
4213         V_VT(pVarOut) = V_VT(pVarIn);
4214         break;
4215     case VT_R4:
4216         if (V_R4(pVarIn)>0) {
4217             V_R4(pVarOut)=floor(V_R4(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
4218         } else {
4219             V_R4(pVarOut)=ceil(V_R4(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
4220         }
4221         V_VT(pVarOut) = V_VT(pVarIn);
4222         break;
4223     case VT_DATE:
4224         if (V_DATE(pVarIn)>0) {
4225             V_DATE(pVarOut)=floor(V_DATE(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
4226         } else {
4227             V_DATE(pVarOut)=ceil(V_DATE(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
4228         }
4229         V_VT(pVarOut) = V_VT(pVarIn);
4230         break;
4231     case VT_CY:
4232         if (deci>3)
4233             factor=1;
4234         else
4235             factor=pow(10, 4-deci);
4236
4237         if (V_CY(pVarIn).int64>0) {
4238             V_CY(pVarOut).int64=floor(V_CY(pVarIn).int64/factor)*factor;
4239         } else {
4240             V_CY(pVarOut).int64=ceil(V_CY(pVarIn).int64/factor)*factor;
4241         }
4242         V_VT(pVarOut) = V_VT(pVarIn);
4243         break;
4244
4245     /* cases we don't know yet */
4246     default:
4247         FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
4248                 V_VT(pVarIn) & VT_TYPEMASK, deci);
4249         hRet = DISP_E_BADVARTYPE;
4250     }
4251
4252     if (FAILED(hRet))
4253       V_VT(pVarOut) = VT_EMPTY;
4254
4255     TRACE("returning 0x%08lx (%s%s),%f\n", hRet, debugstr_VT(pVarOut),
4256         debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) :
4257         (V_VT(pVarOut) == VT_R8) ? V_R8(pVarOut) : 0);
4258
4259     return hRet;
4260 }
4261
4262 /**********************************************************************
4263  *              VarIdiv [OLEAUT32.153]
4264  *
4265  * Converts input variants to integers and divides them. 
4266  *
4267  * PARAMS
4268  *  left     [I] Left hand variant
4269  *  right    [I] Right hand variant
4270  *  result   [O] Destination for quotient
4271  *
4272  * RETURNS
4273  *  Success: S_OK.  result contains the quotient.
4274  *  Failure: An HRESULT error code indicating the error.
4275  *
4276  * NOTES
4277  *  If either expression is null, null is returned, as per MSDN
4278  */
4279 HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
4280 {
4281     VARIANT lv, rv;
4282     HRESULT hr;
4283     
4284     VariantInit(&lv);
4285     VariantInit(&rv);
4286
4287     if ((V_VT(left) == VT_NULL) || (V_VT(right) == VT_NULL)) {
4288         hr = VariantChangeType(result, result, 0, VT_NULL);
4289         if (FAILED(hr)) {
4290             /* This should never happen */
4291             FIXME("Failed to convert return value to VT_NULL.\n");
4292             return hr;
4293         }
4294         return S_OK;
4295     }
4296
4297     hr = VariantChangeType(&lv, left, 0, VT_I4);
4298     if (FAILED(hr)) {
4299         return hr;
4300     }
4301     hr = VariantChangeType(&rv, right, 0, VT_I4);
4302     if (FAILED(hr)) {
4303         return hr;
4304     }
4305
4306     hr = VarDiv(&lv, &rv, result);
4307     return hr;
4308 }
4309
4310
4311 /**********************************************************************
4312  *              VarMod [OLEAUT32.155]
4313  *
4314  * Perform the modulus operation of the right hand variant on the left
4315  *
4316  * PARAMS
4317  *  left     [I] Left hand variant
4318  *  right    [I] Right hand variant
4319  *  result   [O] Destination for converted value
4320  *
4321  * RETURNS
4322  *  Success: S_OK. result contains the remainder.
4323  *  Failure: An HRESULT error code indicating the error.
4324  *
4325  * NOTE:
4326  *   If an error occurs the type of result will be modified but the value will not be.
4327  *   Doesn't support arrays or any special flags yet.
4328  */
4329 HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
4330 {
4331     BOOL         lOk        = TRUE;
4332     BOOL         rOk        = TRUE;
4333     HRESULT      rc         = E_FAIL;
4334     int          resT = 0;
4335     VARIANT      lv,rv;
4336
4337     VariantInit(&lv);
4338     VariantInit(&rv);
4339
4340     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
4341                   debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
4342
4343     /* check for invalid inputs */
4344     lOk = TRUE;
4345     switch (V_VT(left) & VT_TYPEMASK) {
4346     case VT_BOOL :
4347     case VT_I1   :
4348     case VT_I2   :
4349     case VT_I4   :
4350     case VT_I8   :
4351     case VT_INT  :
4352     case VT_UI1  :
4353     case VT_UI2  :
4354     case VT_UI4  :
4355     case VT_UI8  :
4356     case VT_UINT :
4357     case VT_R4   :
4358     case VT_R8   :
4359     case VT_CY   :
4360     case VT_EMPTY:
4361     case VT_DATE :
4362     case VT_BSTR :
4363       break;
4364     case VT_VARIANT:
4365     case VT_UNKNOWN:
4366       V_VT(result) = VT_EMPTY;
4367       return DISP_E_TYPEMISMATCH;
4368     case VT_DECIMAL:
4369       V_VT(result) = VT_EMPTY;
4370       return DISP_E_OVERFLOW;
4371     case VT_ERROR:
4372       return DISP_E_TYPEMISMATCH;
4373     case VT_RECORD:
4374       V_VT(result) = VT_EMPTY;
4375       return DISP_E_TYPEMISMATCH;
4376     case VT_NULL:
4377       break;
4378     default:
4379       V_VT(result) = VT_EMPTY;
4380       return DISP_E_BADVARTYPE;
4381     }
4382
4383
4384     rOk = TRUE;
4385     switch (V_VT(right) & VT_TYPEMASK) {
4386     case VT_BOOL :
4387     case VT_I1   :
4388     case VT_I2   :
4389     case VT_I4   :
4390     case VT_I8   :
4391       if((V_VT(left) == VT_INT) && (V_VT(right) == VT_I8))
4392       {
4393         V_VT(result) = VT_EMPTY;
4394         return DISP_E_TYPEMISMATCH;
4395       }
4396     case VT_INT  :
4397       if((V_VT(right) == VT_INT) && (V_VT(left) == VT_I8))
4398       {
4399         V_VT(result) = VT_EMPTY;
4400         return DISP_E_TYPEMISMATCH;
4401       }
4402     case VT_UI1  :
4403     case VT_UI2  :
4404     case VT_UI4  :
4405     case VT_UI8  :
4406     case VT_UINT :
4407     case VT_R4   :
4408     case VT_R8   :
4409     case VT_CY   :
4410       if(V_VT(left) == VT_EMPTY)
4411       {
4412         V_VT(result) = VT_I4;
4413         return S_OK;
4414       }
4415     case VT_EMPTY:
4416     case VT_DATE :
4417     case VT_BSTR:
4418       if(V_VT(left) == VT_NULL)
4419       {
4420         V_VT(result) = VT_NULL;
4421         return S_OK;
4422       }
4423       break;
4424
4425     case VT_VOID:
4426       V_VT(result) = VT_EMPTY;
4427       return DISP_E_BADVARTYPE;
4428     case VT_NULL:
4429       if(V_VT(left) == VT_VOID)
4430       {
4431         V_VT(result) = VT_EMPTY;
4432         return DISP_E_BADVARTYPE;
4433       } else if((V_VT(left) == VT_NULL) || (V_VT(left) == VT_EMPTY) || (V_VT(left) == VT_ERROR) ||
4434                 lOk)
4435       {
4436         V_VT(result) = VT_NULL;
4437         return S_OK;
4438       } else
4439       {
4440         V_VT(result) = VT_NULL;
4441         return DISP_E_BADVARTYPE;
4442       }
4443     case VT_VARIANT:
4444     case VT_UNKNOWN:
4445       V_VT(result) = VT_EMPTY;
4446       return DISP_E_TYPEMISMATCH;
4447     case VT_DECIMAL:
4448       if(V_VT(left) == VT_ERROR)
4449       {
4450         V_VT(result) = VT_EMPTY;
4451         return DISP_E_TYPEMISMATCH;
4452       } else
4453       {
4454         V_VT(result) = VT_EMPTY;
4455         return DISP_E_OVERFLOW;
4456       }
4457     case VT_ERROR:
4458       return DISP_E_TYPEMISMATCH;
4459     case VT_RECORD:
4460       if((V_VT(left) == 15) || ((V_VT(left) >= 24) && (V_VT(left) <= 35)) || !lOk)
4461       {
4462         V_VT(result) = VT_EMPTY;
4463         return DISP_E_BADVARTYPE;
4464       } else
4465       {
4466         V_VT(result) = VT_EMPTY;
4467         return DISP_E_TYPEMISMATCH;
4468       }
4469     default:
4470       V_VT(result) = VT_EMPTY;
4471       return DISP_E_BADVARTYPE;
4472     }
4473
4474     /* determine the result type */
4475     if((V_VT(left) == VT_I8)        || (V_VT(right) == VT_I8))   resT = VT_I8;
4476     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_BOOL)) resT = VT_I2;
4477     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_UI1))  resT = VT_UI1;
4478     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_I2))   resT = VT_I2;
4479     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_BOOL)) resT = VT_I2;
4480     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_UI1))  resT = VT_I2;
4481     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_I2))   resT = VT_I2;
4482     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_BOOL)) resT = VT_I2;
4483     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_UI1))  resT = VT_I2;
4484     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_I2))   resT = VT_I2;
4485     else resT = VT_I4; /* most outputs are I4 */
4486
4487     /* convert to I8 for the modulo */
4488     rc = VariantChangeType(&lv, left, 0, VT_I8);
4489     if(FAILED(rc))
4490     {
4491       FIXME("Could not convert left type %d to %d? rc == 0x%lX\n", V_VT(left), VT_I8, rc);
4492       return rc;
4493     }
4494
4495     rc = VariantChangeType(&rv, right, 0, VT_I8);
4496     if(FAILED(rc))
4497     {
4498       FIXME("Could not convert right type %d to %d? rc == 0x%lX\n", V_VT(right), VT_I8, rc);
4499       return rc;
4500     }
4501
4502     /* if right is zero set VT_EMPTY and return divide by zero */
4503     if(V_I8(&rv) == 0)
4504     {
4505       V_VT(result) = VT_EMPTY;
4506       return DISP_E_DIVBYZERO;
4507     }
4508
4509     /* perform the modulo operation */
4510     V_VT(result) = VT_I8;
4511     V_I8(result) = V_I8(&lv) % V_I8(&rv);
4512
4513     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));
4514
4515     /* convert left and right to the destination type */
4516     rc = VariantChangeType(result, result, 0, resT);
4517     if(FAILED(rc))
4518     {
4519       FIXME("Could not convert 0x%x to %d?\n", V_VT(result), resT);
4520       return rc;
4521     }
4522
4523     return S_OK;
4524 }
4525
4526 /**********************************************************************
4527  *              VarPow [OLEAUT32.158]
4528  *
4529  */
4530 HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
4531 {
4532     HRESULT hr;
4533     VARIANT dl,dr;
4534
4535     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), debugstr_VF(left),
4536           right, debugstr_VT(right), debugstr_VF(right), result);
4537
4538     hr = VariantChangeType(&dl,left,0,VT_R8);
4539     if (!SUCCEEDED(hr)) {
4540         ERR("Could not change passed left argument to VT_R8, handle it differently.\n");
4541         return E_FAIL;
4542     }
4543     hr = VariantChangeType(&dr,right,0,VT_R8);
4544     if (!SUCCEEDED(hr)) {
4545         ERR("Could not change passed right argument to VT_R8, handle it differently.\n");
4546         return E_FAIL;
4547     }
4548     V_VT(result) = VT_R8;
4549     V_R8(result) = pow(V_R8(&dl),V_R8(&dr));
4550     return S_OK;
4551 }