Assorted spelling fixes.
[wine] / dlls / oleaut32 / variant.c
1 /*
2  * VARIANT
3  *
4  * Copyright 1998 Jean-Claude Cote
5  * Copyright 2003 Jon Griffiths
6  * The alorithm for conversion from Julian days to day/month/year is based on
7  * that devised by Henry Fliegel, as implemented in PostgreSQL, which is
8  * Copyright 1994-7 Regents of the University of California
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24
25 #include "config.h"
26
27 #ifdef HAVE_STRING_H
28 # include <string.h>
29 #endif
30 #ifdef HAVE_STDLIB_H
31 # include <stdlib.h>
32 #endif
33 #include <math.h>
34 #include <stdarg.h>
35
36 #define NONAMELESSUNION
37 #define NONAMELESSSTRUCT
38 #include "windef.h"
39 #include "winbase.h"
40 #include "oleauto.h"
41 #include "wine/debug.h"
42 #include "wine/unicode.h"
43 #include "winerror.h"
44 #include "variant.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(ole);
47
48 const char* wine_vtypes[VT_CLSID] =
49 {
50   "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
51   "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
52   "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8",
53   "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY",
54   "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR""32","33","34","35",
55   "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
56   "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
57   "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
58   "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID"
59 };
60
61 const char* wine_vflags[16] =
62 {
63  "",
64  "|VT_VECTOR",
65  "|VT_ARRAY",
66  "|VT_VECTOR|VT_ARRAY",
67  "|VT_BYREF",
68  "|VT_VECTOR|VT_ARRAY",
69  "|VT_ARRAY|VT_BYREF",
70  "|VT_VECTOR|VT_ARRAY|VT_BYREF",
71  "|VT_HARDTYPE",
72  "|VT_VECTOR|VT_HARDTYPE",
73  "|VT_ARRAY|VT_HARDTYPE",
74  "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
75  "|VT_BYREF|VT_HARDTYPE",
76  "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
77  "|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
78  "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
79 };
80
81 /* Convert a variant from one type to another */
82 static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
83                                      VARIANTARG* ps, VARTYPE vt)
84 {
85   HRESULT res = DISP_E_TYPEMISMATCH;
86   VARTYPE vtFrom =  V_TYPE(ps);
87   DWORD dwFlags = 0;
88
89   TRACE("(%p->(%s%s),0x%08lx,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd),
90         debugstr_VF(pd), lcid, wFlags, ps, debugstr_VT(ps), debugstr_VF(ps),
91         debugstr_vt(vt), debugstr_vf(vt));
92
93   if (vt == VT_BSTR || vtFrom == VT_BSTR)
94   {
95     /* All flags passed to low level function are only used for
96      * changing to or from strings. Map these here.
97      */
98     if (wFlags & VARIANT_LOCALBOOL)
99       dwFlags |= VAR_LOCALBOOL;
100     if (wFlags & VARIANT_CALENDAR_HIJRI)
101       dwFlags |= VAR_CALENDAR_HIJRI;
102     if (wFlags & VARIANT_CALENDAR_THAI)
103       dwFlags |= VAR_CALENDAR_THAI;
104     if (wFlags & VARIANT_CALENDAR_GREGORIAN)
105       dwFlags |= VAR_CALENDAR_GREGORIAN;
106     if (wFlags & VARIANT_NOUSEROVERRIDE)
107       dwFlags |= LOCALE_NOUSEROVERRIDE;
108     if (wFlags & VARIANT_USE_NLS)
109       dwFlags |= LOCALE_USE_NLS;
110   }
111
112   /* Map int/uint to i4/ui4 */
113   if (vt == VT_INT)
114     vt = VT_I4;
115   else if (vt == VT_UINT)
116     vt = VT_UI4;
117
118   if (vtFrom == VT_INT)
119     vtFrom = VT_I4;
120   else if (vtFrom == VT_UINT)
121      vtFrom = VT_UI4;
122
123   if (vt == vtFrom)
124      return VariantCopy(pd, ps);
125
126   if (wFlags & VARIANT_NOVALUEPROP && vtFrom == VT_DISPATCH && vt != VT_UNKNOWN)
127   {
128     /* VARIANT_NOVALUEPROP prevents IDispatch objects from being coerced by
129      * accessing the default object property.
130      */
131     return DISP_E_TYPEMISMATCH;
132   }
133
134   switch (vt)
135   {
136   case VT_EMPTY:
137     if (vtFrom == VT_NULL)
138       return DISP_E_TYPEMISMATCH;
139     /* ... Fall through */
140   case VT_NULL:
141     if (vtFrom <= VT_UINT && vtFrom != (VARTYPE)15 && vtFrom != VT_ERROR)
142     {
143       res = VariantClear( pd );
144       if (vt == VT_NULL && SUCCEEDED(res))
145         V_VT(pd) = VT_NULL;
146     }
147     return res;
148
149   case VT_I1:
150     switch (vtFrom)
151     {
152     case VT_EMPTY:    V_I1(pd) = 0; return S_OK;
153     case VT_I2:       return VarI1FromI2(V_I2(ps), &V_I1(pd));
154     case VT_I4:       return VarI1FromI4(V_I4(ps), &V_I1(pd));
155     case VT_UI1:      return VarI1FromUI1(V_UI1(ps), &V_I1(pd));
156     case VT_UI2:      return VarI1FromUI2(V_UI2(ps), &V_I1(pd));
157     case VT_UI4:      return VarI1FromUI4(V_UI4(ps), &V_I1(pd));
158     case VT_I8:       return VarI1FromI8(V_I8(ps), &V_I1(pd));
159     case VT_UI8:      return VarI1FromUI8(V_UI8(ps), &V_I1(pd));
160     case VT_R4:       return VarI1FromR4(V_R4(ps), &V_I1(pd));
161     case VT_R8:       return VarI1FromR8(V_R8(ps), &V_I1(pd));
162     case VT_DATE:     return VarI1FromDate(V_DATE(ps), &V_I1(pd));
163     case VT_BOOL:     return VarI1FromBool(V_BOOL(ps), &V_I1(pd));
164     case VT_CY:       return VarI1FromCy(V_CY(ps), &V_I1(pd));
165     case VT_DECIMAL:  return VarI1FromDec(&V_DECIMAL(ps), &V_I1(pd) );
166     case VT_DISPATCH: return VarI1FromDisp(V_DISPATCH(ps), lcid, &V_I1(pd) );
167     case VT_BSTR:     return VarI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_I1(pd) );
168     }
169     break;
170
171   case VT_I2:
172     switch (vtFrom)
173     {
174     case VT_EMPTY:    V_I2(pd) = 0; return S_OK;
175     case VT_I1:       return VarI2FromI1(V_I1(ps), &V_I2(pd));
176     case VT_I4:       return VarI2FromI4(V_I4(ps), &V_I2(pd));
177     case VT_UI1:      return VarI2FromUI1(V_UI1(ps), &V_I2(pd));
178     case VT_UI2:      return VarI2FromUI2(V_UI2(ps), &V_I2(pd));
179     case VT_UI4:      return VarI2FromUI4(V_UI4(ps), &V_I2(pd));
180     case VT_I8:       return VarI2FromI8(V_I8(ps), &V_I2(pd));
181     case VT_UI8:      return VarI2FromUI8(V_UI8(ps), &V_I2(pd));
182     case VT_R4:       return VarI2FromR4(V_R4(ps), &V_I2(pd));
183     case VT_R8:       return VarI2FromR8(V_R8(ps), &V_I2(pd));
184     case VT_DATE:     return VarI2FromDate(V_DATE(ps), &V_I2(pd));
185     case VT_BOOL:     return VarI2FromBool(V_BOOL(ps), &V_I2(pd));
186     case VT_CY:       return VarI2FromCy(V_CY(ps), &V_I2(pd));
187     case VT_DECIMAL:  return VarI2FromDec(&V_DECIMAL(ps), &V_I2(pd));
188     case VT_DISPATCH: return VarI2FromDisp(V_DISPATCH(ps), lcid, &V_I2(pd));
189     case VT_BSTR:     return VarI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_I2(pd));
190     }
191     break;
192
193   case VT_I4:
194     switch (vtFrom)
195     {
196     case VT_EMPTY:    V_I4(pd) = 0; return S_OK;
197     case VT_I1:       return VarI4FromI1(V_I1(ps), &V_I4(pd));
198     case VT_I2:       return VarI4FromI2(V_I2(ps), &V_I4(pd));
199     case VT_UI1:      return VarI4FromUI1(V_UI1(ps), &V_I4(pd));
200     case VT_UI2:      return VarI4FromUI2(V_UI2(ps), &V_I4(pd));
201     case VT_UI4:      return VarI4FromUI4(V_UI4(ps), &V_I4(pd));
202     case VT_I8:       return VarI4FromI8(V_I8(ps), &V_I4(pd));
203     case VT_UI8:      return VarI4FromUI8(V_UI8(ps), &V_I4(pd));
204     case VT_R4:       return VarI4FromR4(V_R4(ps), &V_I4(pd));
205     case VT_R8:       return VarI4FromR8(V_R8(ps), &V_I4(pd));
206     case VT_DATE:     return VarI4FromDate(V_DATE(ps), &V_I4(pd));
207     case VT_BOOL:     return VarI4FromBool(V_BOOL(ps), &V_I4(pd));
208     case VT_CY:       return VarI4FromCy(V_CY(ps), &V_I4(pd));
209     case VT_DECIMAL:  return VarI4FromDec(&V_DECIMAL(ps), &V_I4(pd));
210     case VT_DISPATCH: return VarI4FromDisp(V_DISPATCH(ps), lcid, &V_I4(pd));
211     case VT_BSTR:     return VarI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_I4(pd));
212     }
213     break;
214
215   case VT_UI1:
216     switch (vtFrom)
217     {
218     case VT_EMPTY:    V_UI1(pd) = 0; return S_OK;
219     case VT_I1:       return VarUI1FromI1(V_I1(ps), &V_UI1(pd));
220     case VT_I2:       return VarUI1FromI2(V_I2(ps), &V_UI1(pd));
221     case VT_I4:       return VarUI1FromI4(V_I4(ps), &V_UI1(pd));
222     case VT_UI2:      return VarUI1FromUI2(V_UI2(ps), &V_UI1(pd));
223     case VT_UI4:      return VarUI1FromUI4(V_UI4(ps), &V_UI1(pd));
224     case VT_I8:       return VarUI1FromI8(V_I8(ps), &V_UI1(pd));
225     case VT_UI8:      return VarUI1FromUI8(V_UI8(ps), &V_UI1(pd));
226     case VT_R4:       return VarUI1FromR4(V_R4(ps), &V_UI1(pd));
227     case VT_R8:       return VarUI1FromR8(V_R8(ps), &V_UI1(pd));
228     case VT_DATE:     return VarUI1FromDate(V_DATE(ps), &V_UI1(pd));
229     case VT_BOOL:     return VarUI1FromBool(V_BOOL(ps), &V_UI1(pd));
230     case VT_CY:       return VarUI1FromCy(V_CY(ps), &V_UI1(pd));
231     case VT_DECIMAL:  return VarUI1FromDec(&V_DECIMAL(ps), &V_UI1(pd));
232     case VT_DISPATCH: return VarUI1FromDisp(V_DISPATCH(ps), lcid, &V_UI1(pd));
233     case VT_BSTR:     return VarUI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI1(pd));
234     }
235     break;
236
237   case VT_UI2:
238     switch (vtFrom)
239     {
240     case VT_EMPTY:    V_UI2(pd) = 0; return S_OK;
241     case VT_I1:       return VarUI2FromI1(V_I1(ps), &V_UI2(pd));
242     case VT_I2:       return VarUI2FromI2(V_I2(ps), &V_UI2(pd));
243     case VT_I4:       return VarUI2FromI4(V_I4(ps), &V_UI2(pd));
244     case VT_UI1:      return VarUI2FromUI1(V_UI1(ps), &V_UI2(pd));
245     case VT_UI4:      return VarUI2FromUI4(V_UI4(ps), &V_UI2(pd));
246     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
247     case VT_UI8:      return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
248     case VT_R4:       return VarUI2FromR4(V_R4(ps), &V_UI2(pd));
249     case VT_R8:       return VarUI2FromR8(V_R8(ps), &V_UI2(pd));
250     case VT_DATE:     return VarUI2FromDate(V_DATE(ps), &V_UI2(pd));
251     case VT_BOOL:     return VarUI2FromBool(V_BOOL(ps), &V_UI2(pd));
252     case VT_CY:       return VarUI2FromCy(V_CY(ps), &V_UI2(pd));
253     case VT_DECIMAL:  return VarUI2FromDec(&V_DECIMAL(ps), &V_UI2(pd));
254     case VT_DISPATCH: return VarUI2FromDisp(V_DISPATCH(ps), lcid, &V_UI2(pd));
255     case VT_BSTR:     return VarUI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI2(pd));
256     }
257     break;
258
259   case VT_UI4:
260     switch (vtFrom)
261     {
262     case VT_EMPTY:    V_UI4(pd) = 0; return S_OK;
263     case VT_I1:       return VarUI4FromI1(V_I1(ps), &V_UI4(pd));
264     case VT_I2:       return VarUI4FromI2(V_I2(ps), &V_UI4(pd));
265     case VT_I4:       return VarUI4FromI4(V_I4(ps), &V_UI4(pd));
266     case VT_UI1:      return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd));
267     case VT_UI2:      return VarUI4FromUI2(V_UI2(ps), &V_UI4(pd));
268     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
269     case VT_UI8:      return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
270     case VT_R4:       return VarUI4FromR4(V_R4(ps), &V_UI4(pd));
271     case VT_R8:       return VarUI4FromR8(V_R8(ps), &V_UI4(pd));
272     case VT_DATE:     return VarUI4FromDate(V_DATE(ps), &V_UI4(pd));
273     case VT_BOOL:     return VarUI4FromBool(V_BOOL(ps), &V_UI4(pd));
274     case VT_CY:       return VarUI4FromCy(V_CY(ps), &V_UI4(pd));
275     case VT_DECIMAL:  return VarUI4FromDec(&V_DECIMAL(ps), &V_UI4(pd));
276     case VT_DISPATCH: return VarUI4FromDisp(V_DISPATCH(ps), lcid, &V_UI4(pd));
277     case VT_BSTR:     return VarUI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI4(pd));
278     }
279     break;
280
281   case VT_UI8:
282     switch (vtFrom)
283     {
284     case VT_EMPTY:    V_UI8(pd) = 0; return S_OK;
285     case VT_I4:       if (V_I4(ps) < 0) return DISP_E_OVERFLOW; V_UI8(pd) = V_I4(ps); return S_OK;
286     case VT_I1:       return VarUI8FromI1(V_I1(ps), &V_UI8(pd));
287     case VT_I2:       return VarUI8FromI2(V_I2(ps), &V_UI8(pd));
288     case VT_UI1:      return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd));
289     case VT_UI2:      return VarUI8FromUI2(V_UI2(ps), &V_UI8(pd));
290     case VT_UI4:      return VarUI8FromUI4(V_UI4(ps), &V_UI8(pd));
291     case VT_I8:       return VarUI8FromI8(V_I8(ps), &V_UI8(pd));
292     case VT_R4:       return VarUI8FromR4(V_R4(ps), &V_UI8(pd));
293     case VT_R8:       return VarUI8FromR8(V_R8(ps), &V_UI8(pd));
294     case VT_DATE:     return VarUI8FromDate(V_DATE(ps), &V_UI8(pd));
295     case VT_BOOL:     return VarUI8FromBool(V_BOOL(ps), &V_UI8(pd));
296     case VT_CY:       return VarUI8FromCy(V_CY(ps), &V_UI8(pd));
297     case VT_DECIMAL:  return VarUI8FromDec(&V_DECIMAL(ps), &V_UI8(pd));
298     case VT_DISPATCH: return VarUI8FromDisp(V_DISPATCH(ps), lcid, &V_UI8(pd));
299     case VT_BSTR:     return VarUI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI8(pd));
300     }
301     break;
302
303   case VT_I8:
304     switch (vtFrom)
305     {
306     case VT_EMPTY:    V_I8(pd) = 0; return S_OK;
307     case VT_I4:       V_I8(pd) = V_I4(ps); return S_OK;
308     case VT_I1:       return VarI8FromI1(V_I1(ps), &V_I8(pd));
309     case VT_I2:       return VarI8FromI2(V_I2(ps), &V_I8(pd));
310     case VT_UI1:      return VarI8FromUI1(V_UI1(ps), &V_I8(pd));
311     case VT_UI2:      return VarI8FromUI2(V_UI2(ps), &V_I8(pd));
312     case VT_UI4:      return VarI8FromUI4(V_UI4(ps), &V_I8(pd));
313     case VT_UI8:      return VarI8FromUI8(V_I8(ps), &V_I8(pd));
314     case VT_R4:       return VarI8FromR4(V_R4(ps), &V_I8(pd));
315     case VT_R8:       return VarI8FromR8(V_R8(ps), &V_I8(pd));
316     case VT_DATE:     return VarI8FromDate(V_DATE(ps), &V_I8(pd));
317     case VT_BOOL:     return VarI8FromBool(V_BOOL(ps), &V_I8(pd));
318     case VT_CY:       return VarI8FromCy(V_CY(ps), &V_I8(pd));
319     case VT_DECIMAL:  return VarI8FromDec(&V_DECIMAL(ps), &V_I8(pd));
320     case VT_DISPATCH: return VarI8FromDisp(V_DISPATCH(ps), lcid, &V_I8(pd));
321     case VT_BSTR:     return VarI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_I8(pd));
322     }
323     break;
324
325   case VT_R4:
326     switch (vtFrom)
327     {
328     case VT_EMPTY:    V_R4(pd) = 0.0f; return S_OK;
329     case VT_I1:       return VarR4FromI1(V_I1(ps), &V_R4(pd));
330     case VT_I2:       return VarR4FromI2(V_I2(ps), &V_R4(pd));
331     case VT_I4:       return VarR4FromI4(V_I4(ps), &V_R4(pd));
332     case VT_UI1:      return VarR4FromUI1(V_UI1(ps), &V_R4(pd));
333     case VT_UI2:      return VarR4FromUI2(V_UI2(ps), &V_R4(pd));
334     case VT_UI4:      return VarR4FromUI4(V_UI4(ps), &V_R4(pd));
335     case VT_I8:       return VarR4FromI8(V_I8(ps), &V_R4(pd));
336     case VT_UI8:      return VarR4FromUI8(V_UI8(ps), &V_R4(pd));
337     case VT_R8:       return VarR4FromR8(V_R8(ps), &V_R4(pd));
338     case VT_DATE:     return VarR4FromDate(V_DATE(ps), &V_R4(pd));
339     case VT_BOOL:     return VarR4FromBool(V_BOOL(ps), &V_R4(pd));
340     case VT_CY:       return VarR4FromCy(V_CY(ps), &V_R4(pd));
341     case VT_DECIMAL:  return VarR4FromDec(&V_DECIMAL(ps), &V_R4(pd));
342     case VT_DISPATCH: return VarR4FromDisp(V_DISPATCH(ps), lcid, &V_R4(pd));
343     case VT_BSTR:     return VarR4FromStr(V_BSTR(ps), lcid, dwFlags, &V_R4(pd));
344     }
345     break;
346
347   case VT_R8:
348     switch (vtFrom)
349     {
350     case VT_EMPTY:    V_R8(pd) = 0.0; return S_OK;
351     case VT_I1:       return VarR8FromI1(V_I1(ps), &V_R8(pd));
352     case VT_I2:       return VarR8FromI2(V_I2(ps), &V_R8(pd));
353     case VT_I4:       return VarR8FromI4(V_I4(ps), &V_R8(pd));
354     case VT_UI1:      return VarR8FromUI1(V_UI1(ps), &V_R8(pd));
355     case VT_UI2:      return VarR8FromUI2(V_UI2(ps), &V_R8(pd));
356     case VT_UI4:      return VarR8FromUI4(V_UI4(ps), &V_R8(pd));
357     case VT_I8:       return VarR8FromI8(V_I8(ps), &V_R8(pd));
358     case VT_UI8:      return VarR8FromUI8(V_UI8(ps), &V_R8(pd));
359     case VT_R4:       return VarR8FromR4(V_R4(ps), &V_R8(pd));
360     case VT_DATE:     return VarR8FromDate(V_DATE(ps), &V_R8(pd));
361     case VT_BOOL:     return VarR8FromBool(V_BOOL(ps), &V_R8(pd));
362     case VT_CY:       return VarR8FromCy(V_CY(ps), &V_R8(pd));
363     case VT_DECIMAL:  return VarR8FromDec(&V_DECIMAL(ps), &V_R8(pd));
364     case VT_DISPATCH: return VarR8FromDisp(V_DISPATCH(ps), lcid, &V_R8(pd));
365     case VT_BSTR:     return VarR8FromStr(V_BSTR(ps), lcid, dwFlags, &V_R8(pd));
366     }
367     break;
368
369   case VT_DATE:
370     switch (vtFrom)
371     {
372     case VT_EMPTY:    V_DATE(pd) = 0.0; return S_OK;
373     case VT_I1:       return VarDateFromI1(V_I1(ps), &V_DATE(pd));
374     case VT_I2:       return VarDateFromI2(V_I2(ps), &V_DATE(pd));
375     case VT_I4:       return VarDateFromI4(V_I4(ps), &V_DATE(pd));
376     case VT_UI1:      return VarDateFromUI1(V_UI1(ps), &V_DATE(pd));
377     case VT_UI2:      return VarDateFromUI2(V_UI2(ps), &V_DATE(pd));
378     case VT_UI4:      return VarDateFromUI4(V_UI4(ps), &V_DATE(pd));
379     case VT_I8:       return VarDateFromI8(V_I8(ps), &V_DATE(pd));
380     case VT_UI8:      return VarDateFromUI8(V_UI8(ps), &V_DATE(pd));
381     case VT_R4:       return VarDateFromR4(V_R4(ps), &V_DATE(pd));
382     case VT_R8:       return VarDateFromR8(V_R8(ps), &V_DATE(pd));
383     case VT_BOOL:     return VarDateFromBool(V_BOOL(ps), &V_DATE(pd));
384     case VT_CY:       return VarDateFromCy(V_CY(ps), &V_DATE(pd));
385     case VT_DECIMAL:  return VarDateFromDec(&V_DECIMAL(ps), &V_DATE(pd));
386     case VT_DISPATCH: return VarDateFromDisp(V_DISPATCH(ps), lcid, &V_DATE(pd));
387     case VT_BSTR:     return VarDateFromStr(V_BSTR(ps), lcid, dwFlags, &V_DATE(pd));
388     }
389     break;
390
391   case VT_BOOL:
392     switch (vtFrom)
393     {
394     case VT_EMPTY:    V_BOOL(pd) = 0; return S_OK;
395     case VT_I1:       return VarBoolFromI1(V_I1(ps), &V_BOOL(pd));
396     case VT_I2:       return VarBoolFromI2(V_I2(ps), &V_BOOL(pd));
397     case VT_I4:       return VarBoolFromI4(V_I4(ps), &V_BOOL(pd));
398     case VT_UI1:      return VarBoolFromUI1(V_UI1(ps), &V_BOOL(pd));
399     case VT_UI2:      return VarBoolFromUI2(V_UI2(ps), &V_BOOL(pd));
400     case VT_UI4:      return VarBoolFromUI4(V_UI4(ps), &V_BOOL(pd));
401     case VT_I8:       return VarBoolFromI8(V_I8(ps), &V_BOOL(pd));
402     case VT_UI8:      return VarBoolFromUI8(V_UI8(ps), &V_BOOL(pd));
403     case VT_R4:       return VarBoolFromR4(V_R4(ps), &V_BOOL(pd));
404     case VT_R8:       return VarBoolFromR8(V_R8(ps), &V_BOOL(pd));
405     case VT_DATE:     return VarBoolFromDate(V_DATE(ps), &V_BOOL(pd));
406     case VT_CY:       return VarBoolFromCy(V_CY(ps), &V_BOOL(pd));
407     case VT_DECIMAL:  return VarBoolFromDec(&V_DECIMAL(ps), &V_BOOL(pd));
408     case VT_DISPATCH: return VarBoolFromDisp(V_DISPATCH(ps), lcid, &V_BOOL(pd));
409     case VT_BSTR:     return VarBoolFromStr(V_BSTR(ps), lcid, dwFlags, &V_BOOL(pd));
410     }
411     break;
412
413   case VT_BSTR:
414     switch (vtFrom)
415     {
416     case VT_EMPTY:
417       V_BSTR(pd) = SysAllocStringLen(NULL, 0);
418       return V_BSTR(pd) ? S_OK : E_OUTOFMEMORY;
419     case VT_BOOL:
420       if (wFlags & (VARIANT_ALPHABOOL|VARIANT_LOCALBOOL))
421          return VarBstrFromBool(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
422       return VarBstrFromI2(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
423     case VT_I1:       return VarBstrFromI1(V_I1(ps), lcid, dwFlags, &V_BSTR(pd));
424     case VT_I2:       return VarBstrFromI2(V_I2(ps), lcid, dwFlags, &V_BSTR(pd));
425     case VT_I4:       return VarBstrFromI4(V_I4(ps), lcid, dwFlags, &V_BSTR(pd));
426     case VT_UI1:      return VarBstrFromUI1(V_UI1(ps), lcid, dwFlags, &V_BSTR(pd));
427     case VT_UI2:      return VarBstrFromUI2(V_UI2(ps), lcid, dwFlags, &V_BSTR(pd));
428     case VT_UI4:      return VarBstrFromUI4(V_UI4(ps), lcid, dwFlags, &V_BSTR(pd));
429     case VT_I8:       return VarBstrFromI8(V_I8(ps), lcid, dwFlags, &V_BSTR(pd));
430     case VT_UI8:      return VarBstrFromUI8(V_UI8(ps), lcid, dwFlags, &V_BSTR(pd));
431     case VT_R4:       return VarBstrFromR4(V_R4(ps), lcid, dwFlags, &V_BSTR(pd));
432     case VT_R8:       return VarBstrFromR8(V_R8(ps), lcid, dwFlags, &V_BSTR(pd));
433     case VT_DATE:     return VarBstrFromDate(V_DATE(ps), lcid, dwFlags, &V_BSTR(pd));
434     case VT_CY:       return VarBstrFromCy(V_CY(ps), lcid, dwFlags, &V_BSTR(pd));
435     case VT_DECIMAL:  return VarBstrFromDec(&V_DECIMAL(ps), lcid, dwFlags, &V_BSTR(pd));
436 /*  case VT_DISPATCH: return VarBstrFromDisp(V_DISPATCH(ps), lcid, dwFlags, &V_BSTR(pd)); */
437     }
438     break;
439
440   case VT_CY:
441     switch (vtFrom)
442     {
443     case VT_EMPTY:    V_CY(pd).int64 = 0; return S_OK;
444     case VT_I1:       return VarCyFromI1(V_I1(ps), &V_CY(pd));
445     case VT_I2:       return VarCyFromI2(V_I2(ps), &V_CY(pd));
446     case VT_I4:       return VarCyFromI4(V_I4(ps), &V_CY(pd));
447     case VT_UI1:      return VarCyFromUI1(V_UI1(ps), &V_CY(pd));
448     case VT_UI2:      return VarCyFromUI2(V_UI2(ps), &V_CY(pd));
449     case VT_UI4:      return VarCyFromUI4(V_UI4(ps), &V_CY(pd));
450     case VT_I8:       return VarCyFromI8(V_I8(ps), &V_CY(pd));
451     case VT_UI8:      return VarCyFromUI8(V_UI8(ps), &V_CY(pd));
452     case VT_R4:       return VarCyFromR4(V_R4(ps), &V_CY(pd));
453     case VT_R8:       return VarCyFromR8(V_R8(ps), &V_CY(pd));
454     case VT_DATE:     return VarCyFromDate(V_DATE(ps), &V_CY(pd));
455     case VT_BOOL:     return VarCyFromBool(V_BOOL(ps), &V_CY(pd));
456     case VT_DECIMAL:  return VarCyFromDec(&V_DECIMAL(ps), &V_CY(pd));
457     case VT_DISPATCH: return VarCyFromDisp(V_DISPATCH(ps), lcid, &V_CY(pd));
458     case VT_BSTR:     return VarCyFromStr(V_BSTR(ps), lcid, dwFlags, &V_CY(pd));
459     }
460     break;
461
462   case VT_DECIMAL:
463     switch (vtFrom)
464     {
465     case VT_EMPTY:
466     case VT_BOOL:
467        DEC_SIGNSCALE(&V_DECIMAL(pd)) = SIGNSCALE(DECIMAL_POS,0);
468        DEC_HI32(&V_DECIMAL(pd)) = 0;
469        DEC_MID32(&V_DECIMAL(pd)) = 0;
470         /* VarDecFromBool() coerces to -1/0, ChangeTypeEx() coerces to 1/0.
471          * VT_NULL and VT_EMPTY always give a 0 value.
472          */
473        DEC_LO32(&V_DECIMAL(pd)) = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0;
474        return S_OK;
475     case VT_I1:       return VarDecFromI1(V_I1(ps), &V_DECIMAL(pd));
476     case VT_I2:       return VarDecFromI2(V_I2(ps), &V_DECIMAL(pd));
477     case VT_I4:       return VarDecFromI4(V_I4(ps), &V_DECIMAL(pd));
478     case VT_UI1:      return VarDecFromUI1(V_UI1(ps), &V_DECIMAL(pd));
479     case VT_UI2:      return VarDecFromUI2(V_UI2(ps), &V_DECIMAL(pd));
480     case VT_UI4:      return VarDecFromUI4(V_UI4(ps), &V_DECIMAL(pd));
481     case VT_I8:       return VarDecFromI8(V_I8(ps), &V_DECIMAL(pd));
482     case VT_UI8:      return VarDecFromUI8(V_UI8(ps), &V_DECIMAL(pd));
483     case VT_R4:       return VarDecFromR4(V_R4(ps), &V_DECIMAL(pd));
484     case VT_R8:       return VarDecFromR8(V_R8(ps), &V_DECIMAL(pd));
485     case VT_DATE:     return VarDecFromDate(V_DATE(ps), &V_DECIMAL(pd));
486     case VT_CY:       return VarDecFromCy(V_CY(pd), &V_DECIMAL(ps));
487     case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(ps));
488     case VT_BSTR:     return VarDecFromStr(V_BSTR(ps), lcid, dwFlags, &V_DECIMAL(pd));
489     }
490     break;
491
492   case VT_UNKNOWN:
493     switch (vtFrom)
494     {
495     case VT_DISPATCH:
496       if (V_DISPATCH(ps) == NULL)
497         V_UNKNOWN(pd) = NULL;
498       else
499         res = IDispatch_QueryInterface(V_DISPATCH(ps), &IID_IUnknown, (LPVOID*)&V_UNKNOWN(pd));
500       break;
501     }
502     break;
503
504   case VT_DISPATCH:
505     switch (vtFrom)
506     {
507     case VT_UNKNOWN:
508       if (V_UNKNOWN(ps) == NULL)
509         V_DISPATCH(pd) = NULL;
510       else
511         res = IUnknown_QueryInterface(V_UNKNOWN(ps), &IID_IDispatch, (LPVOID*)&V_DISPATCH(pd));
512       break;
513     }
514     break;
515
516   case VT_RECORD:
517     break;
518   }
519   return res;
520 }
521
522 /* Coerce to/from an array */
523 static inline HRESULT VARIANT_CoerceArray(VARIANTARG* pd, VARIANTARG* ps, VARTYPE vt)
524 {
525   if (vt == VT_BSTR && V_VT(ps) == (VT_ARRAY|VT_UI1))
526     return BstrFromVector(V_ARRAY(ps), &V_BSTR(pd));
527
528   if (V_VT(ps) == VT_BSTR && vt == (VT_ARRAY|VT_UI1))
529     return VectorFromBstr(V_BSTR(ps), &V_ARRAY(ps));
530
531   if (V_VT(ps) == vt)
532     return SafeArrayCopy(V_ARRAY(ps), &V_ARRAY(pd));
533
534   return DISP_E_TYPEMISMATCH;
535 }
536
537 /******************************************************************************
538  * Check if a variants type is valid.
539  */
540 static inline HRESULT VARIANT_ValidateType(VARTYPE vt)
541 {
542   VARTYPE vtExtra = vt & VT_EXTRA_TYPE;
543
544   vt &= VT_TYPEMASK;
545
546   if (!(vtExtra & (VT_VECTOR|VT_RESERVED)))
547   {
548     if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID)
549     {
550       if ((vtExtra & (VT_BYREF|VT_ARRAY)) && vt <= VT_NULL)
551         return DISP_E_BADVARTYPE;
552       if (vt != (VARTYPE)15)
553         return S_OK;
554     }
555   }
556   return DISP_E_BADVARTYPE;
557 }
558
559 /******************************************************************************
560  *              VariantInit     [OLEAUT32.8]
561  *
562  * Initialise a variant.
563  *
564  * PARAMS
565  *  pVarg [O] Variant to initialise
566  *
567  * RETURNS
568  *  Nothing.
569  *
570  * NOTES
571  *  This function simply sets the type of the variant to VT_EMPTY. It does not
572  *  free any existing value, use VariantClear() for that.
573  */
574 void WINAPI VariantInit(VARIANTARG* pVarg)
575 {
576   TRACE("(%p)\n", pVarg);
577
578   V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
579 }
580
581 /******************************************************************************
582  *              VariantClear    [OLEAUT32.9]
583  *
584  * Clear a variant.
585  *
586  * PARAMS
587  *  pVarg [I/O] Variant to clear
588  *
589  * RETURNS
590  *  Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
591  *  Failure: DISP_E_BADVARTYPE, if the variant is a not a valid variant type.
592  */
593 HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
594 {
595   HRESULT hres = S_OK;
596
597   TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
598
599   hres = VARIANT_ValidateType(V_VT(pVarg));
600
601   if (SUCCEEDED(hres))
602   {
603     if (!V_ISBYREF(pVarg))
604     {
605       if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY)
606       {
607         if (V_ARRAY(pVarg))
608           hres = SafeArrayDestroy(V_ARRAY(pVarg));
609       }
610       else if (V_VT(pVarg) == VT_BSTR)
611       {
612         if (V_BSTR(pVarg))
613           SysFreeString(V_BSTR(pVarg));
614       }
615       else if (V_VT(pVarg) == VT_RECORD)
616       {
617         struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
618         if (pBr->pRecInfo)
619         {
620           IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
621           IRecordInfo_Release(pBr->pRecInfo);
622         }
623       }
624       else if (V_VT(pVarg) == VT_DISPATCH ||
625                V_VT(pVarg) == VT_UNKNOWN)
626       {
627         if (V_UNKNOWN(pVarg))
628           IUnknown_Release(V_UNKNOWN(pVarg));
629       }
630       else if (V_VT(pVarg) == VT_VARIANT)
631       {
632         if (V_VARIANTREF(pVarg))
633           VariantClear(V_VARIANTREF(pVarg));
634       }
635     }
636     V_VT(pVarg) = VT_EMPTY;
637   }
638   return hres;
639 }
640
641 /******************************************************************************
642  * Copy an IRecordInfo object contained in a variant.
643  */
644 static HRESULT VARIANT_CopyIRecordInfo(struct __tagBRECORD* pBr)
645 {
646   HRESULT hres = S_OK;
647
648   if (pBr->pRecInfo)
649   {
650     ULONG ulSize;
651
652     hres = IRecordInfo_GetSize(pBr->pRecInfo, &ulSize);
653     if (SUCCEEDED(hres))
654     {
655       PVOID pvRecord = HeapAlloc(GetProcessHeap(), 0, ulSize);
656       if (!pvRecord)
657         hres = E_OUTOFMEMORY;
658       else
659       {
660         memcpy(pvRecord, pBr->pvRecord, ulSize);
661         pBr->pvRecord = pvRecord;
662
663         hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord);
664         if (SUCCEEDED(hres))
665           IRecordInfo_AddRef(pBr->pRecInfo);
666       }
667     }
668   }
669   else if (pBr->pvRecord)
670     hres = E_INVALIDARG;
671   return hres;
672 }
673
674 /******************************************************************************
675  *    VariantCopy  [OLEAUT32.10]
676  *
677  * Copy a variant.
678  *
679  * PARAMS
680  *  pvargDest [O] Destination for copy
681  *  pvargSrc  [I] Source variant to copy
682  *
683  * RETURNS
684  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
685  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid type.
686  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
687  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
688  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
689  *
690  * NOTES
691  *  - If pvargSrc == pvargDest, this function does nothing, and succeeds if
692  *    pvargSrc is valid. Otherwise, pvargDest is always cleared using
693  *    VariantClear() before pvargSrc is copied to it. If clearing pvargDest
694  *    fails, so does this function.
695  *  - VT_CLSID is a valid type type for pvargSrc, but not for pvargDest.
696  *  - For by-value non-intrinsic types, a deep copy is made, i.e. The whole value
697  *    is copied rather than just any pointers to it.
698  *  - For by-value object types the object pointer is copied and the objects
699  *    reference count increased using IUnknown_AddRef().
700  *  - For all by-reference types, only the referencing pointer is copied.
701  */
702 HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
703 {
704   HRESULT hres = S_OK;
705
706   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
707         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
708         debugstr_VF(pvargSrc));
709
710   if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */
711       FAILED(VARIANT_ValidateType(V_VT(pvargSrc))))
712     return DISP_E_BADVARTYPE;
713
714   if (pvargSrc != pvargDest &&
715       SUCCEEDED(hres = VariantClear(pvargDest)))
716   {
717     *pvargDest = *pvargSrc; /* Shallow copy the value */
718
719     if (!V_ISBYREF(pvargSrc))
720     {
721       if (V_ISARRAY(pvargSrc))
722       {
723         if (V_ARRAY(pvargSrc))
724           hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest));
725       }
726       else if (V_VT(pvargSrc) == VT_BSTR)
727       {
728         if (V_BSTR(pvargSrc))
729         {
730           V_BSTR(pvargDest) = SysAllocStringLen(V_BSTR(pvargSrc), SysStringLen(V_BSTR(pvargSrc)));
731           if (!V_BSTR(pvargDest))
732             hres = E_OUTOFMEMORY;
733         }
734       }
735       else if (V_VT(pvargSrc) == VT_RECORD)
736       {
737         hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
738       }
739       else if (V_VT(pvargSrc) == VT_DISPATCH ||
740                V_VT(pvargSrc) == VT_UNKNOWN)
741       {
742         if (V_UNKNOWN(pvargSrc))
743           IUnknown_AddRef(V_UNKNOWN(pvargSrc));
744       }
745     }
746   }
747   return hres;
748 }
749
750 /* Return the byte size of a variants data */
751 static inline size_t VARIANT_DataSize(const VARIANT* pv)
752 {
753   switch (V_TYPE(pv))
754   {
755   case VT_I1:
756   case VT_UI1:   return sizeof(BYTE); break;
757   case VT_I2:
758   case VT_UI2:   return sizeof(SHORT); break;
759   case VT_INT:
760   case VT_UINT:
761   case VT_I4:
762   case VT_UI4:   return sizeof(LONG); break;
763   case VT_I8:
764   case VT_UI8:   return sizeof(LONGLONG); break;
765   case VT_R4:    return sizeof(float); break;
766   case VT_R8:    return sizeof(double); break;
767   case VT_DATE:  return sizeof(DATE); break;
768   case VT_BOOL:  return sizeof(VARIANT_BOOL); break;
769   case VT_DISPATCH:
770   case VT_UNKNOWN:
771   case VT_BSTR:  return sizeof(void*); break;
772   case VT_CY:    return sizeof(CY); break;
773   case VT_ERROR: return sizeof(SCODE); break;
774   }
775   TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv));
776   return 0;
777 }
778
779 /******************************************************************************
780  *    VariantCopyInd  [OLEAUT32.11]
781  *
782  * Copy a variant, dereferencing it it is by-reference.
783  *
784  * PARAMS
785  *  pvargDest [O] Destination for copy
786  *  pvargSrc  [I] Source variant to copy
787  *
788  * RETURNS
789  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
790  *  Failure: An HRESULT error code indicating the error.
791  *
792  * NOTES
793  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid by-value type.
794  *           E_INVALIDARG, if pvargSrc  is an invalid by-reference type.
795  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
796  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
797  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
798  *
799  * NOTES
800  *  - If pvargSrc is by-value, this function behaves exactly as VariantCopy().
801  *  - If pvargSrc is by-reference, the value copied to pvargDest is the pointed-to
802  *    value.
803  *  - if pvargSrc == pvargDest, this function dereferences in place. Otherwise,
804  *    pvargDest is always cleared using VariantClear() before pvargSrc is copied
805  *    to it. If clearing pvargDest fails, so does this function.
806  */
807 HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
808 {
809   VARIANTARG vTmp, *pSrc = pvargSrc;
810   VARTYPE vt;
811   HRESULT hres = S_OK;
812
813   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
814         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
815         debugstr_VF(pvargSrc));
816
817   if (!V_ISBYREF(pvargSrc))
818     return VariantCopy(pvargDest, pvargSrc);
819
820   /* Argument checking is more lax than VariantCopy()... */
821   vt = V_TYPE(pvargSrc);
822   if (V_ISARRAY(pvargSrc) ||
823      (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
824      !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED))))
825   {
826     /* OK */
827   }
828   else
829     return E_INVALIDARG; /* ...And the return value for invalid types differs too */
830
831   if (pvargSrc == pvargDest)
832   {
833     /* In place copy. Use a shallow copy of pvargSrc & init pvargDest.
834      * This avoids an expensive VariantCopy() call - e.g. SafeArrayCopy().
835      */
836     vTmp = *pvargSrc;
837     pSrc = &vTmp;
838     V_VT(pvargDest) = VT_EMPTY;
839   }
840   else
841   {
842     /* Copy into another variant. Free the variant in pvargDest */
843     if (FAILED(hres = VariantClear(pvargDest)))
844       return hres;
845   }
846
847   if (V_ISARRAY(pSrc))
848   {
849     /* Native doesn't check that *V_ARRAYREF(pSrc) is valid */
850     hres = SafeArrayCopy(*V_ARRAYREF(pSrc), &V_ARRAY(pvargDest));
851   }
852   else if (V_VT(pSrc) == (VT_BSTR|VT_BYREF))
853   {
854     /* Native doesn't check that *V_BSTRREF(pSrc) is valid */
855     V_BSTR(pvargDest) = SysAllocStringLen(*V_BSTRREF(pSrc), SysStringLen(*V_BSTRREF(pSrc)));
856   }
857   else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF))
858   {
859     V_UNION(pvargDest,brecVal) = V_UNION(pvargSrc,brecVal);
860     hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
861   }
862   else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) ||
863            V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF))
864   {
865     /* Native doesn't check that *V_UNKNOWNREF(pSrc) is valid */
866     V_UNKNOWN(pvargDest) = *V_UNKNOWNREF(pSrc);
867     if (*V_UNKNOWNREF(pSrc))
868       IUnknown_AddRef(*V_UNKNOWNREF(pSrc));
869   }
870   else if (V_VT(pSrc) == (VT_VARIANT|VT_BYREF))
871   {
872     /* Native doesn't check that *V_VARIANTREF(pSrc) is valid */
873     if (V_VT(V_VARIANTREF(pSrc)) == (VT_VARIANT|VT_BYREF))
874       hres = E_INVALIDARG; /* Don't dereference more than one level */
875     else
876       hres = VariantCopyInd(pvargDest, V_VARIANTREF(pSrc));
877
878     /* Use the dereferenced variants type value, not VT_VARIANT */
879     goto VariantCopyInd_Return;
880   }
881   else if (V_VT(pSrc) == (VT_DECIMAL|VT_BYREF))
882   {
883     memcpy(&DEC_SCALE(&V_DECIMAL(pvargDest)), &DEC_SCALE(V_DECIMALREF(pSrc)),
884            sizeof(DECIMAL) - sizeof(USHORT));
885   }
886   else
887   {
888     /* Copy the pointed to data into this variant */
889     memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(pSrc));
890   }
891
892   V_VT(pvargDest) = V_VT(pSrc) & ~VT_BYREF;
893
894 VariantCopyInd_Return:
895
896   if (pSrc != pvargSrc)
897     VariantClear(pSrc);
898
899   TRACE("returning 0x%08lx, %p->(%s%s)\n", hres, pvargDest,
900         debugstr_VT(pvargDest), debugstr_VF(pvargDest));
901   return hres;
902 }
903
904 /******************************************************************************
905  *    VariantChangeType  [OLEAUT32.12]
906  *
907  * Change the type of a variant.
908  *
909  * PARAMS
910  *  pvargDest [O] Destination for the converted variant
911  *  pvargSrc  [O] Source variant to change the type of
912  *  wFlags    [I] VARIANT_ flags from "oleauto.h"
913  *  vt        [I] Variant type to change pvargSrc into
914  *
915  * RETURNS
916  *  Success: S_OK. pvargDest contains the converted value.
917  *  Failure: An HRESULT error code describing the failure.
918  *
919  * NOTES
920  *  The LCID used for the conversion is LOCALE_USER_DEFAULT.
921  *  See VariantChangeTypeEx.
922  */
923 HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
924                                  USHORT wFlags, VARTYPE vt)
925 {
926   return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
927 }
928
929 /******************************************************************************
930  *    VariantChangeTypeEx  [OLEAUT32.147]
931  *
932  * Change the type of a variant.
933  *
934  * PARAMS
935  *  pvargDest [O] Destination for the converted variant
936  *  pvargSrc  [O] Source variant to change the type of
937  *  lcid      [I] LCID for the conversion
938  *  wFlags    [I] VARIANT_ flags from "oleauto.h"
939  *  vt        [I] Variant type to change pvargSrc into
940  *
941  * RETURNS
942  *  Success: S_OK. pvargDest contains the converted value.
943  *  Failure: An HRESULT error code describing the failure.
944  *
945  * NOTES
946  *  pvargDest and pvargSrc can point to the same variant to perform an in-place
947  *  conversion. If the conversion is successful, pvargSrc will be freed.
948  */
949 HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
950                                    LCID lcid, USHORT wFlags, VARTYPE vt)
951 {
952   HRESULT res = S_OK;
953
954   TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%04x,%s%s)\n", pvargDest,
955         debugstr_VT(pvargDest), debugstr_VF(pvargDest), pvargSrc,
956         debugstr_VT(pvargSrc), debugstr_VF(pvargSrc), lcid, wFlags,
957         debugstr_vt(vt), debugstr_vf(vt));
958
959   if (vt == VT_CLSID)
960     res = DISP_E_BADVARTYPE;
961   else
962   {
963     res = VARIANT_ValidateType(V_VT(pvargSrc));
964
965     if (SUCCEEDED(res))
966     {
967       res = VARIANT_ValidateType(vt);
968
969       if (SUCCEEDED(res))
970       {
971         VARIANTARG vTmp;
972
973         V_VT(&vTmp) = VT_EMPTY;
974         res = VariantCopyInd(&vTmp, pvargSrc);
975
976         if (SUCCEEDED(res))
977         {
978           res = VariantClear(pvargDest);
979
980           if (SUCCEEDED(res))
981           {
982             if (V_ISARRAY(&vTmp) || (vt & VT_ARRAY))
983               res = VARIANT_CoerceArray(pvargDest, &vTmp, vt);
984             else
985               res = VARIANT_Coerce(pvargDest, lcid, wFlags, &vTmp, vt);
986
987             if (SUCCEEDED(res))
988               V_VT(pvargDest) = vt;
989           }
990           VariantClear(&vTmp);
991         }
992       }
993     }
994   }
995
996   TRACE("returning 0x%08lx, %p->(%s%s)\n", res, pvargDest,
997         debugstr_VT(pvargDest), debugstr_VF(pvargDest));
998   return res;
999 }
1000
1001 /* Date Conversions */
1002
1003 #define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
1004
1005 /* Convert a VT_DATE value to a Julian Date */
1006 static inline int VARIANT_JulianFromDate(int dateIn)
1007 {
1008   int julianDays = dateIn;
1009
1010   julianDays -= DATE_MIN; /* Convert to + days from 1 Jan 100 AD */
1011   julianDays += 1757585;  /* Convert to + days from 23 Nov 4713 BC (Julian) */
1012   return julianDays;
1013 }
1014
1015 /* Convert a Julian Date to a VT_DATE value */
1016 static inline int VARIANT_DateFromJulian(int dateIn)
1017 {
1018   int julianDays = dateIn;
1019
1020   julianDays -= 1757585;  /* Convert to + days from 1 Jan 100 AD */
1021   julianDays += DATE_MIN; /* Convert to +/- days from 1 Jan 1899 AD */
1022   return julianDays;
1023 }
1024
1025 /* Convert a Julian date to Day/Month/Year - from PostgreSQL */
1026 static inline void VARIANT_DMYFromJulian(int jd, USHORT *year, USHORT *month, USHORT *day)
1027 {
1028   int j, i, l, n;
1029
1030   l = jd + 68569;
1031   n = l * 4 / 146097;
1032   l -= (n * 146097 + 3) / 4;
1033   i = (4000 * (l + 1)) / 1461001;
1034   l += 31 - (i * 1461) / 4;
1035   j = (l * 80) / 2447;
1036   *day = l - (j * 2447) / 80;
1037   l = j / 11;
1038   *month = (j + 2) - (12 * l);
1039   *year = 100 * (n - 49) + i + l;
1040 }
1041
1042 /* Convert Day/Month/Year to a Julian date - from PostgreSQL */
1043 static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day)
1044 {
1045   int m12 = (month - 14) / 12;
1046
1047   return ((1461 * (year + 4800 + m12)) / 4 + (367 * (month - 2 - 12 * m12)) / 12 -
1048            (3 * ((year + 4900 + m12) / 100)) / 4 + day - 32075);
1049 }
1050
1051 /* Macros for accessing DOS format date/time fields */
1052 #define DOS_YEAR(x)   (1980 + (x >> 9))
1053 #define DOS_MONTH(x)  ((x >> 5) & 0xf)
1054 #define DOS_DAY(x)    (x & 0x1f)
1055 #define DOS_HOUR(x)   (x >> 11)
1056 #define DOS_MINUTE(x) ((x >> 5) & 0x3f)
1057 #define DOS_SECOND(x) ((x & 0x1f) << 1)
1058 /* Create a DOS format date/time */
1059 #define DOS_DATE(d,m,y) (d | (m << 5) | ((y-1980) << 9))
1060 #define DOS_TIME(h,m,s) ((s >> 1) | (m << 5) | (h << 11))
1061
1062 /* Roll a date forwards or backwards to correct it */
1063 static HRESULT VARIANT_RollUdate(UDATE *lpUd)
1064 {
1065   static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1066
1067   TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
1068         lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
1069
1070   /* Years < 100 are treated as 1900 + year */
1071   if (lpUd->st.wYear < 100)
1072     lpUd->st.wYear += 1900;
1073
1074   if (!lpUd->st.wMonth)
1075   {
1076     /* Roll back to December of the previous year */
1077     lpUd->st.wMonth = 12;
1078     lpUd->st.wYear--;
1079   }
1080   else while (lpUd->st.wMonth > 12)
1081   {
1082     /* Roll forward the correct number of months */
1083     lpUd->st.wYear++;
1084     lpUd->st.wMonth -= 12;
1085   }
1086
1087   if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 ||
1088       lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59)
1089     return E_INVALIDARG; /* Invalid values */
1090
1091   if (!lpUd->st.wDay)
1092   {
1093     /* Roll back the date one day */
1094     if (lpUd->st.wMonth == 1)
1095     {
1096       /* Roll back to December 31 of the previous year */
1097       lpUd->st.wDay   = 31;
1098       lpUd->st.wMonth = 12;
1099       lpUd->st.wYear--;
1100     }
1101     else
1102     {
1103       lpUd->st.wMonth--; /* Previous month */
1104       if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
1105         lpUd->st.wDay = 29; /* Februaury has 29 days on leap years */
1106       else
1107         lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */
1108     }
1109   }
1110   else if (lpUd->st.wDay > 28)
1111   {
1112     int rollForward = 0;
1113
1114     /* Possibly need to roll the date forward */
1115     if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
1116       rollForward = lpUd->st.wDay - 29; /* Februaury has 29 days on leap years */
1117     else
1118       rollForward = lpUd->st.wDay - days[lpUd->st.wMonth];
1119
1120     if (rollForward > 0)
1121     {
1122       lpUd->st.wDay = rollForward;
1123       lpUd->st.wMonth++;
1124       if (lpUd->st.wMonth > 12)
1125       {
1126         lpUd->st.wMonth = 1; /* Roll forward into January of the next year */
1127         lpUd->st.wYear++;
1128       }
1129     }
1130   }
1131   TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
1132         lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
1133   return S_OK;
1134 }
1135
1136 /**********************************************************************
1137  *              DosDateTimeToVariantTime [OLEAUT32.14]
1138  *
1139  * Convert a Dos format date and time into variant VT_DATE format.
1140  *
1141  * PARAMS
1142  *  wDosDate [I] Dos format date
1143  *  wDosTime [I] Dos format time
1144  *  pDateOut [O] Destination for VT_DATE format
1145  *
1146  * RETURNS
1147  *  Success: TRUE. pDateOut contains the converted time.
1148  *  Failure: FALSE, if wDosDate or wDosTime are invalid (see notes).
1149  *
1150  * NOTES
1151  * - Dos format dates can only hold dates from 1-Jan-1980 to 31-Dec-2099.
1152  * - Dos format times are accurate to only 2 second precision.
1153  * - The format of a Dos Date is:
1154  *| Bits   Values  Meaning
1155  *| ----   ------  -------
1156  *| 0-4    1-31    Day of the week. 0 rolls back one day. A value greater than
1157  *|                the days in the month rolls forward the extra days.
1158  *| 5-8    1-12    Month of the year. 0 rolls back to December of the previous
1159  *|                year. 13-15 are invalid.
1160  *| 9-15   0-119   Year based from 1980 (Max 2099). 120-127 are invalid.
1161  * - The format of a Dos Time is:
1162  *| Bits   Values  Meaning
1163  *| ----   ------  -------
1164  *| 0-4    0-29    Seconds/2. 30 and 31 are invalid.
1165  *| 5-10   0-59    Minutes. 60-63 are invalid.
1166  *| 11-15  0-23    Hours (24 hour clock). 24-32 are invalid.
1167  */
1168 INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
1169                                     double *pDateOut)
1170 {
1171   UDATE ud;
1172
1173   TRACE("(0x%x(%d/%d/%d),0x%x(%d:%d:%d),%p)\n",
1174         wDosDate, DOS_YEAR(wDosDate), DOS_MONTH(wDosDate), DOS_DAY(wDosDate),
1175         wDosTime, DOS_HOUR(wDosTime), DOS_MINUTE(wDosTime), DOS_SECOND(wDosTime),
1176         pDateOut);
1177
1178   ud.st.wYear = DOS_YEAR(wDosDate);
1179   ud.st.wMonth = DOS_MONTH(wDosDate);
1180   if (ud.st.wYear > 2099 || ud.st.wMonth > 12)
1181     return FALSE;
1182   ud.st.wDay = DOS_DAY(wDosDate);
1183   ud.st.wHour = DOS_HOUR(wDosTime);
1184   ud.st.wMinute = DOS_MINUTE(wDosTime);
1185   ud.st.wSecond = DOS_SECOND(wDosTime);
1186   ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
1187
1188   return !VarDateFromUdate(&ud, 0, pDateOut);
1189 }
1190
1191 /**********************************************************************
1192  *              VariantTimeToDosDateTime [OLEAUT32.13]
1193  *
1194  * Convert a variant format date into a Dos format date and time.
1195  *
1196  *  dateIn    [I] VT_DATE time format
1197  *  pwDosDate [O] Destination for Dos format date
1198  *  pwDosTime [O] Destination for Dos format time
1199  *
1200  * RETURNS
1201  *  Success: TRUE. pwDosDate and pwDosTime contains the converted values.
1202  *  Failure: FALSE, if dateIn cannot be represented in Dos format.
1203  *
1204  * NOTES
1205  *   See DosDateTimeToVariantTime() for Dos format details and bugs.
1206  */
1207 INT WINAPI VariantTimeToDosDateTime(double dateIn, USHORT *pwDosDate, USHORT *pwDosTime)
1208 {
1209   UDATE ud;
1210
1211   TRACE("(%g,%p,%p)\n", dateIn, pwDosDate, pwDosTime);
1212
1213   if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1214     return FALSE;
1215
1216   if (ud.st.wYear < 1980 || ud.st.wYear > 2099)
1217     return FALSE;
1218
1219   *pwDosDate = DOS_DATE(ud.st.wDay, ud.st.wMonth, ud.st.wYear);
1220   *pwDosTime = DOS_TIME(ud.st.wHour, ud.st.wMinute, ud.st.wSecond);
1221
1222   TRACE("Returning 0x%x(%d/%d/%d), 0x%x(%d:%d:%d)\n",
1223         *pwDosDate, DOS_YEAR(*pwDosDate), DOS_MONTH(*pwDosDate), DOS_DAY(*pwDosDate),
1224         *pwDosTime, DOS_HOUR(*pwDosTime), DOS_MINUTE(*pwDosTime), DOS_SECOND(*pwDosTime));
1225   return TRUE;
1226 }
1227
1228 /***********************************************************************
1229  *              SystemTimeToVariantTime [OLEAUT32.184]
1230  *
1231  * Convert a System format date and time into variant VT_DATE format.
1232  *
1233  * PARAMS
1234  *  lpSt     [I] System format date and time
1235  *  pDateOut [O] Destination for VT_DATE format date
1236  *
1237  * RETURNS
1238  *  Success: TRUE. *pDateOut contains the converted value.
1239  *  Failure: FALSE, if lpSt cannot be represented in VT_DATE format.
1240  */
1241 INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut)
1242 {
1243   UDATE ud;
1244
1245   TRACE("(%p->%d/%d/%d %d:%d:%d,%p)\n", lpSt, lpSt->wDay, lpSt->wMonth,
1246         lpSt->wYear, lpSt->wHour, lpSt->wMinute, lpSt->wSecond, pDateOut);
1247
1248   if (lpSt->wMonth > 12)
1249     return FALSE;
1250
1251   memcpy(&ud.st, lpSt, sizeof(ud.st));
1252   return !VarDateFromUdate(&ud, 0, pDateOut);
1253 }
1254
1255 /***********************************************************************
1256  *              VariantTimeToSystemTime [OLEAUT32.185]
1257  *
1258  * Convert a variant VT_DATE into a System format date and time.
1259  *
1260  * PARAMS
1261  *  datein [I] Variant VT_DATE format date
1262  *  lpSt   [O] Destination for System format date and time
1263  *
1264  * RETURNS
1265  *  Success: TRUE. *lpSt contains the converted value.
1266  *  Failure: FALSE, if dateIn is too large or small.
1267  */
1268 INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt)
1269 {
1270   UDATE ud;
1271
1272   TRACE("(%g,%p)\n", dateIn, lpSt);
1273
1274   if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1275     return FALSE;
1276
1277   memcpy(lpSt, &ud.st, sizeof(ud.st));
1278   return TRUE;
1279 }
1280
1281 /***********************************************************************
1282  *              VarDateFromUdate [OLEAUT32.330]
1283  *
1284  * Convert an unpacked format date and time to a variant VT_DATE.
1285  *
1286  * PARAMS
1287  *  pUdateIn [I] Unpacked format date and time to convert
1288  *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1289  *  pDateOut [O] Destination for variant VT_DATE.
1290  *
1291  * RETURNS
1292  *  Success: S_OK. *pDateOut contains the converted value.
1293  *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
1294  */
1295 HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
1296 {
1297   UDATE ud;
1298   double dateVal;
1299
1300   TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08lx,%p)\n", pUdateIn,
1301         pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
1302         pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond,
1303         pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek,
1304         pUdateIn->wDayOfYear, dwFlags, pDateOut);
1305
1306   memcpy(&ud, pUdateIn, sizeof(ud));
1307
1308   if (dwFlags & VAR_VALIDDATE)
1309     WARN("Ignoring VAR_VALIDDATE\n");
1310
1311   if (FAILED(VARIANT_RollUdate(&ud)))
1312     return E_INVALIDARG;
1313
1314   /* Date */
1315   dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay));
1316
1317   /* Time */
1318   dateVal += ud.st.wHour / 24.0;
1319   dateVal += ud.st.wMinute / 1440.0;
1320   dateVal += ud.st.wSecond / 86400.0;
1321   dateVal += ud.st.wMilliseconds / 86400000.0;
1322
1323   TRACE("Returning %g\n", dateVal);
1324   *pDateOut = dateVal;
1325   return S_OK;
1326 }
1327
1328 /***********************************************************************
1329  *              VarUdateFromDate [OLEAUT32.331]
1330  *
1331  * Convert a variant VT_DATE into an unpacked format date and time.
1332  *
1333  * PARAMS
1334  *  datein    [I] Variant VT_DATE format date
1335  *  dwFlags   [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1336  *  lpUdate   [O] Destination for unpacked format date and time
1337  *
1338  * RETURNS
1339  *  Success: S_OK. *lpUdate contains the converted value.
1340  *  Failure: E_INVALIDARG, if dateIn is too large or small.
1341  */
1342 HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
1343 {
1344   /* Cumulative totals of days per month */
1345   static const USHORT cumulativeDays[] =
1346   {
1347     0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
1348   };
1349   double datePart, timePart;
1350   int julianDays;
1351
1352   TRACE("(%g,0x%08lx,%p)\n", dateIn, dwFlags, lpUdate);
1353
1354   if (dateIn <= (DATE_MIN - 1.0) || dateIn >= (DATE_MAX + 1.0))
1355     return E_INVALIDARG;
1356
1357   datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn);
1358   /* Compensate for int truncation (always downwards) */
1359   timePart = dateIn - datePart + 0.00000000001;
1360   if (timePart >= 1.0)
1361     timePart -= 0.00000000001;
1362
1363   /* Date */
1364   julianDays = VARIANT_JulianFromDate(dateIn);
1365   VARIANT_DMYFromJulian(julianDays, &lpUdate->st.wYear, &lpUdate->st.wMonth,
1366                         &lpUdate->st.wDay);
1367
1368   datePart = (datePart + 1.5) / 7.0;
1369   lpUdate->st.wDayOfWeek = (datePart - floor(datePart)) * 7;
1370   if (lpUdate->st.wDayOfWeek == 0)
1371     lpUdate->st.wDayOfWeek = 5;
1372   else if (lpUdate->st.wDayOfWeek == 1)
1373     lpUdate->st.wDayOfWeek = 6;
1374   else
1375     lpUdate->st.wDayOfWeek -= 2;
1376
1377   if (lpUdate->st.wMonth > 2 && IsLeapYear(lpUdate->st.wYear))
1378     lpUdate->wDayOfYear = 1; /* After February, in a leap year */
1379   else
1380     lpUdate->wDayOfYear = 0;
1381
1382   lpUdate->wDayOfYear += cumulativeDays[lpUdate->st.wMonth];
1383   lpUdate->wDayOfYear += lpUdate->st.wDay;
1384
1385   /* Time */
1386   timePart *= 24.0;
1387   lpUdate->st.wHour = timePart;
1388   timePart -= lpUdate->st.wHour;
1389   timePart *= 60.0;
1390   lpUdate->st.wMinute = timePart;
1391   timePart -= lpUdate->st.wMinute;
1392   timePart *= 60.0;
1393   lpUdate->st.wSecond = timePart;
1394   timePart -= lpUdate->st.wSecond;
1395   lpUdate->st.wMilliseconds = 0;
1396   if (timePart > 0.5)
1397   {
1398     /* Round the milliseconds, adjusting the time/date forward if needed */
1399     if (lpUdate->st.wSecond < 59)
1400       lpUdate->st.wSecond++;
1401     else
1402     {
1403       lpUdate->st.wSecond = 0;
1404       if (lpUdate->st.wMinute < 59)
1405         lpUdate->st.wMinute++;
1406       else
1407       {
1408         lpUdate->st.wMinute = 0;
1409         if (lpUdate->st.wHour < 23)
1410           lpUdate->st.wHour++;
1411         else
1412         {
1413           lpUdate->st.wHour = 0;
1414           /* Roll over a whole day */
1415           if (++lpUdate->st.wDay > 28)
1416             VARIANT_RollUdate(lpUdate);
1417         }
1418       }
1419     }
1420   }
1421   return S_OK;
1422 }
1423
1424 #define GET_NUMBER_TEXT(fld,name) \
1425   buff[0] = 0; \
1426   if (!GetLocaleInfoW(lcid, lctype|fld, buff, sizeof(WCHAR) * 2)) \
1427     WARN("buffer too small for " #fld "\n"); \
1428   else \
1429     if (buff[0]) lpChars->name = buff[0]; \
1430   TRACE("lcid 0x%lx, " #name "=%d '%c'\n", lcid, lpChars->name, lpChars->name)
1431
1432 /* Get the valid number characters for an lcid */
1433 void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
1434 {
1435   static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',',','$',0,'.',',' };
1436   LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE;
1437   WCHAR buff[4];
1438
1439   memcpy(lpChars, &defaultChars, sizeof(defaultChars));
1440   GET_NUMBER_TEXT(LOCALE_SNEGATIVESIGN, cNegativeSymbol);
1441   GET_NUMBER_TEXT(LOCALE_SPOSITIVESIGN, cPositiveSymbol);
1442   GET_NUMBER_TEXT(LOCALE_SDECIMAL, cDecimalPoint);
1443   GET_NUMBER_TEXT(LOCALE_STHOUSAND, cDigitSeperator);
1444   GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint);
1445   GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeperator);
1446
1447   /* Local currency symbols are often 2 characters */
1448   lpChars->cCurrencyLocal2 = '\0';
1449   switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(WCHAR) * 4))
1450   {
1451     case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
1452     case 2: lpChars->cCurrencyLocal  = buff[0];
1453             break;
1454     default: WARN("buffer too small for LOCALE_SCURRENCY\n");
1455   }
1456   TRACE("lcid 0x%lx, cCurrencyLocal =%d,%d '%c','%c'\n", lcid, lpChars->cCurrencyLocal,
1457         lpChars->cCurrencyLocal2, lpChars->cCurrencyLocal, lpChars->cCurrencyLocal2);
1458 }
1459
1460 /* Number Parsing States */
1461 #define B_PROCESSING_EXPONENT 0x1
1462 #define B_NEGATIVE_EXPONENT   0x2
1463 #define B_EXPONENT_START      0x4
1464 #define B_INEXACT_ZEROS       0x8
1465 #define B_LEADING_ZERO        0x10
1466
1467 /**********************************************************************
1468  *              VarParseNumFromStr [OLEAUT32.46]
1469  *
1470  * Parse a string containing a number into a NUMPARSE structure.
1471  *
1472  * PARAMS
1473  *  lpszStr [I]   String to parse number from
1474  *  lcid    [I]   Locale Id for the conversion
1475  *  dwFlags [I]   0, or LOCALE_NOUSEROVERRIDE to use system default number chars
1476  *  pNumprs [I/O] Destination for parsed number
1477  *  rgbDig  [O]   Destination for digits read in
1478  *
1479  * RETURNS
1480  *  Success: S_OK. pNumprs and rgbDig contain the parsed representation of
1481  *           the number.
1482  *  Failure: E_INVALIDARG, if any parameter is invalid.
1483  *           DISP_E_TYPEMISMATCH, if the string is not a number or is formatted
1484  *           incorrectly.
1485  *           DISP_E_OVERFLOW, if rgbDig is too small to hold the number.
1486  *
1487  * NOTES
1488  *  pNumprs must have the following fields set:
1489  *   cDig: Set to the size of rgbDig.
1490  *   dwInFlags: Set to the allowable syntax of the number using NUMPRS_ flags
1491  *            from "oleauto.h".
1492  *
1493  * FIXME
1494  *  - I am unsure if this function should parse non-arabic (e.g. Thai)
1495  *   numerals, so this has not been implemented.
1496  */
1497 HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
1498                                   NUMPARSE *pNumprs, BYTE *rgbDig)
1499 {
1500   VARIANT_NUMBER_CHARS chars;
1501   BYTE rgbTmp[1024];
1502   DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;
1503   int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE);
1504   int cchUsed = 0;
1505
1506   TRACE("(%s,%ld,0x%08lx,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig);
1507
1508   if (pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1509     FIXME("dwInFlags & NUMPRS_HEX_OCT not yet implemented!\n");
1510
1511   if (!pNumprs || !rgbDig)
1512     return E_INVALIDARG;
1513
1514   if (pNumprs->cDig < iMaxDigits)
1515     iMaxDigits = pNumprs->cDig;
1516
1517   pNumprs->cDig = 0;
1518   pNumprs->dwOutFlags = 0;
1519   pNumprs->cchUsed = 0;
1520   pNumprs->nBaseShift = 0;
1521   pNumprs->nPwr10 = 0;
1522
1523   if (!lpszStr)
1524     return DISP_E_TYPEMISMATCH;
1525
1526   VARIANT_GetLocalisedNumberChars(&chars, lcid, dwFlags);
1527
1528   /* First consume all the leading symbols and space from the string */
1529   while (1)
1530   {
1531     if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && isspaceW(*lpszStr))
1532     {
1533       pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;
1534       do
1535       {
1536         cchUsed++;
1537         lpszStr++;
1538       } while (isspaceW(*lpszStr));
1539     }
1540     else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS &&
1541              *lpszStr == chars.cPositiveSymbol &&
1542              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS))
1543     {
1544       pNumprs->dwOutFlags |= NUMPRS_LEADING_PLUS;
1545       cchUsed++;
1546       lpszStr++;
1547     }
1548     else if (pNumprs->dwInFlags & NUMPRS_LEADING_MINUS &&
1549              *lpszStr == chars.cNegativeSymbol &&
1550              !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS))
1551     {
1552       pNumprs->dwOutFlags |= (NUMPRS_LEADING_MINUS|NUMPRS_NEG);
1553       cchUsed++;
1554       lpszStr++;
1555     }
1556     else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
1557              !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) &&
1558              *lpszStr == chars.cCurrencyLocal &&
1559              (!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2))
1560     {
1561       pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1562       cchUsed++;
1563       lpszStr++;
1564       /* Only accept currency characters */
1565       chars.cDecimalPoint = chars.cCurrencyDecimalPoint;
1566       chars.cDigitSeperator = chars.cCurrencyDigitSeperator;
1567     }
1568     else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' &&
1569              !(pNumprs->dwOutFlags & NUMPRS_PARENS))
1570     {
1571       pNumprs->dwOutFlags |= NUMPRS_PARENS;
1572       cchUsed++;
1573       lpszStr++;
1574     }
1575     else
1576       break;
1577   }
1578
1579   if (!(pNumprs->dwOutFlags & NUMPRS_CURRENCY))
1580   {
1581     /* Only accept non-currency characters */
1582     chars.cCurrencyDecimalPoint = chars.cDecimalPoint;
1583     chars.cCurrencyDigitSeperator = chars.cDigitSeperator;
1584   }
1585
1586   /* Strip Leading zeros */
1587   while (*lpszStr == '0')
1588   {
1589     dwState |= B_LEADING_ZERO;
1590     cchUsed++;
1591     lpszStr++;
1592   }
1593
1594   while (*lpszStr)
1595   {
1596     if (isdigitW(*lpszStr))
1597     {
1598       if (dwState & B_PROCESSING_EXPONENT)
1599       {
1600         int exponentSize = 0;
1601         if (dwState & B_EXPONENT_START)
1602         {
1603           while (*lpszStr == '0')
1604           {
1605             /* Skip leading zero's in the exponent */
1606             cchUsed++;
1607             lpszStr++;
1608           }
1609           if (!isdigitW(*lpszStr))
1610             break; /* No exponent digits - invalid */
1611         }
1612
1613         while (isdigitW(*lpszStr))
1614         {
1615           exponentSize *= 10;
1616           exponentSize += *lpszStr - '0';
1617           cchUsed++;
1618           lpszStr++;
1619         }
1620         if (dwState & B_NEGATIVE_EXPONENT)
1621           exponentSize = -exponentSize;
1622         /* Add the exponent into the powers of 10 */
1623         pNumprs->nPwr10 += exponentSize;
1624         dwState &= ~(B_PROCESSING_EXPONENT|B_EXPONENT_START);
1625         lpszStr--; /* back up to allow processing of next char */
1626       }
1627       else
1628       {
1629         if (pNumprs->cDig >= iMaxDigits)
1630         {
1631           pNumprs->dwOutFlags |= NUMPRS_INEXACT;
1632
1633           if (*lpszStr != '0')
1634             dwState &= ~B_INEXACT_ZEROS; /* Inexact number with non-trailing zeros */
1635
1636           /* This digit can't be represented, but count it in nPwr10 */
1637           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1638             pNumprs->nPwr10--;
1639           else
1640             pNumprs->nPwr10++;
1641         }
1642         else
1643         {
1644           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1645             pNumprs->nPwr10--; /* Count decimal points in nPwr10 */
1646           rgbTmp[pNumprs->cDig] = *lpszStr - '0';
1647         }
1648         pNumprs->cDig++;
1649         cchUsed++;
1650       }
1651     }
1652     else if (*lpszStr == chars.cDigitSeperator && pNumprs->dwInFlags & NUMPRS_THOUSANDS)
1653     {
1654       pNumprs->dwOutFlags |= NUMPRS_THOUSANDS;
1655       cchUsed++;
1656     }
1657     else if (*lpszStr == chars.cDecimalPoint &&
1658              pNumprs->dwInFlags & NUMPRS_DECIMAL &&
1659              !(pNumprs->dwOutFlags & (NUMPRS_DECIMAL|NUMPRS_EXPONENT)))
1660     {
1661       pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
1662       cchUsed++;
1663
1664       /* Remove trailing zeros from the whole number part */
1665       while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1666       {
1667         pNumprs->nPwr10++;
1668         pNumprs->cDig--;
1669       }
1670
1671       /* If we have no digits so far, skip leading zeros */
1672       if (!pNumprs->cDig)
1673       {
1674         while (lpszStr[1] == '0')
1675         {
1676           dwState |= B_LEADING_ZERO;
1677           cchUsed++;
1678           lpszStr++;
1679         }
1680       }
1681     }
1682     else if ((*lpszStr == 'e' || *lpszStr == 'E') &&
1683              pNumprs->dwInFlags & NUMPRS_EXPONENT &&
1684              !(pNumprs->dwOutFlags & NUMPRS_EXPONENT))
1685     {
1686       dwState |= B_PROCESSING_EXPONENT;
1687       pNumprs->dwOutFlags |= NUMPRS_EXPONENT;
1688       cchUsed++;
1689     }
1690     else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cPositiveSymbol)
1691     {
1692       cchUsed++; /* Ignore positive exponent */
1693     }
1694     else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cNegativeSymbol)
1695     {
1696       dwState |= B_NEGATIVE_EXPONENT;
1697       cchUsed++;
1698     }
1699     else
1700       break; /* Stop at an unrecognised character */
1701
1702     lpszStr++;
1703   }
1704
1705   if (!pNumprs->cDig && dwState & B_LEADING_ZERO)
1706   {
1707     /* Ensure a 0 on its own gets stored */
1708     pNumprs->cDig = 1;
1709     rgbTmp[0] = 0;
1710   }
1711
1712   if (pNumprs->dwOutFlags & NUMPRS_EXPONENT && dwState & B_PROCESSING_EXPONENT)
1713   {
1714     pNumprs->cchUsed = cchUsed;
1715     return DISP_E_TYPEMISMATCH; /* Failed to completely parse the exponent */
1716   }
1717
1718   if (pNumprs->dwOutFlags & NUMPRS_INEXACT)
1719   {
1720     if (dwState & B_INEXACT_ZEROS)
1721       pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* All zeros doesn't set NUMPRS_INEXACT */
1722   }
1723   else
1724   {
1725     /* Remove trailing zeros from the last (whole number or decimal) part */
1726     while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1727     {
1728       if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1729         pNumprs->nPwr10--;
1730       else
1731         pNumprs->nPwr10++;
1732       pNumprs->cDig--;
1733     }
1734   }
1735
1736   if (pNumprs->cDig <= iMaxDigits)
1737     pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* Ignore stripped zeros for NUMPRS_INEXACT */
1738   else
1739     pNumprs->cDig = iMaxDigits; /* Only return iMaxDigits worth of digits */
1740
1741   /* Copy the digits we processed into rgbDig */
1742   memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1743
1744   /* Consume any trailing symbols and space */
1745   while (1)
1746   {
1747     if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && isspaceW(*lpszStr))
1748     {
1749       pNumprs->dwOutFlags |= NUMPRS_TRAILING_WHITE;
1750       do
1751       {
1752         cchUsed++;
1753         lpszStr++;
1754       } while (isspaceW(*lpszStr));
1755     }
1756     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS &&
1757              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) &&
1758              *lpszStr == chars.cPositiveSymbol)
1759     {
1760       pNumprs->dwOutFlags |= NUMPRS_TRAILING_PLUS;
1761       cchUsed++;
1762       lpszStr++;
1763     }
1764     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_MINUS &&
1765              !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS) &&
1766              *lpszStr == chars.cNegativeSymbol)
1767     {
1768       pNumprs->dwOutFlags |= (NUMPRS_TRAILING_MINUS|NUMPRS_NEG);
1769       cchUsed++;
1770       lpszStr++;
1771     }
1772     else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == ')' &&
1773              pNumprs->dwOutFlags & NUMPRS_PARENS)
1774     {
1775       cchUsed++;
1776       lpszStr++;
1777       pNumprs->dwOutFlags |= NUMPRS_NEG;
1778     }
1779     else
1780       break;
1781   }
1782
1783   if (pNumprs->dwOutFlags & NUMPRS_PARENS && !(pNumprs->dwOutFlags & NUMPRS_NEG))
1784   {
1785     pNumprs->cchUsed = cchUsed;
1786     return DISP_E_TYPEMISMATCH; /* Opening parenthesis not matched */
1787   }
1788
1789   if (pNumprs->dwInFlags & NUMPRS_USE_ALL && *lpszStr != '\0')
1790     return DISP_E_TYPEMISMATCH; /* Not all chars were consumed */
1791
1792   if (!pNumprs->cDig)
1793     return DISP_E_TYPEMISMATCH; /* No Number found */
1794
1795   pNumprs->cchUsed = cchUsed;
1796   return S_OK;
1797 }
1798
1799 /* VTBIT flags indicating an integer value */
1800 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
1801 /* VTBIT flags indicating a real number value */
1802 #define REAL_VTBITS (VTBIT_R4|VTBIT_R8|VTBIT_CY)
1803
1804 /**********************************************************************
1805  *              VarNumFromParseNum [OLEAUT32.47]
1806  *
1807  * Convert a NUMPARSE structure into a numeric Variant type.
1808  *
1809  * PARAMS
1810  *  pNumprs  [I] Source for parsed number. cDig must be set to the size of rgbDig
1811  *  rgbDig   [I] Source for the numbers digits
1812  *  dwVtBits [I] VTBIT_ flags from "oleauto.h" indicating the acceptable dest types
1813  *  pVarDst  [O] Destination for the converted Variant value.
1814  *
1815  * RETURNS
1816  *  Success: S_OK. pVarDst contains the converted value.
1817  *  Failure: E_INVALIDARG, if any parameter is invalid.
1818  *           DISP_E_OVERFLOW, if the number is too big for the types set in dwVtBits.
1819  *
1820  * NOTES
1821  *  - The smallest favoured type present in dwVtBits that can represent the
1822  *    number in pNumprs without losing precision is used.
1823  *  - Signed types are preferrred over unsigned types of the same size.
1824  *  - Preferred types in order are: integer, float, double, currency then decimal.
1825  *  - Rounding (dropping of decimal points) occurs without error. See VarI8FromR8()
1826  *    for details of the rounding method.
1827  *  - pVarDst is not cleared before the result is stored in it.
1828  */
1829 HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
1830                                   ULONG dwVtBits, VARIANT *pVarDst)
1831 {
1832   /* Scale factors and limits for double arithmetic */
1833   static const double dblMultipliers[11] = {
1834     1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0,
1835     1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0
1836   };
1837   static const double dblMinimums[11] = {
1838     R8_MIN, R8_MIN*10.0, R8_MIN*100.0, R8_MIN*1000.0, R8_MIN*10000.0,
1839     R8_MIN*100000.0, R8_MIN*1000000.0, R8_MIN*10000000.0,
1840     R8_MIN*100000000.0, R8_MIN*1000000000.0, R8_MIN*10000000000.0
1841   };
1842   static const double dblMaximums[11] = {
1843     R8_MAX, R8_MAX/10.0, R8_MAX/100.0, R8_MAX/1000.0, R8_MAX/10000.0,
1844     R8_MAX/100000.0, R8_MAX/1000000.0, R8_MAX/10000000.0,
1845     R8_MAX/100000000.0, R8_MAX/1000000000.0, R8_MAX/10000000000.0
1846   };
1847
1848   int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0;
1849
1850   TRACE("(%p,%p,0x%lx,%p)\n", pNumprs, rgbDig, dwVtBits, pVarDst);
1851
1852   if (pNumprs->nBaseShift)
1853   {
1854     /* nBaseShift indicates a hex or octal number */
1855     FIXME("nBaseShift=%d not yet implemented, returning overflow\n", pNumprs->nBaseShift);
1856     return DISP_E_OVERFLOW;
1857   }
1858
1859   /* Count the number of relevant fractional and whole digits stored,
1860    * And compute the divisor/multiplier to scale the number by.
1861    */
1862   if (pNumprs->nPwr10 < 0)
1863   {
1864     if (-pNumprs->nPwr10 >= pNumprs->cDig)
1865     {
1866       /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */
1867       wholeNumberDigits = 0;
1868       fractionalDigits = pNumprs->cDig;
1869       divisor10 = -pNumprs->nPwr10;
1870     }
1871     else
1872     {
1873       /* An exactly represented real number e.g. 1.024 */
1874       wholeNumberDigits = pNumprs->cDig + pNumprs->nPwr10;
1875       fractionalDigits = pNumprs->cDig - wholeNumberDigits;
1876       divisor10 = pNumprs->cDig - wholeNumberDigits;
1877     }
1878   }
1879   else if (pNumprs->nPwr10 == 0)
1880   {
1881     /* An exactly represented whole number e.g. 1024 */
1882     wholeNumberDigits = pNumprs->cDig;
1883     fractionalDigits = 0;
1884   }
1885   else /* pNumprs->nPwr10 > 0 */
1886   {
1887     /* A whole number followed by nPwr10 0's e.g. 102400 */
1888     wholeNumberDigits = pNumprs->cDig;
1889     fractionalDigits = 0;
1890     multiplier10 = pNumprs->nPwr10;
1891   }
1892
1893   TRACE("cDig %d; nPwr10 %d, whole %d, frac %d ", pNumprs->cDig,
1894         pNumprs->nPwr10, wholeNumberDigits, fractionalDigits);
1895   TRACE("mult %d; div %d\n", multiplier10, divisor10);
1896
1897   if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) &&
1898       (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL))))
1899   {
1900     /* We have one or more integer output choices, and either:
1901      *  1) An integer input value, or
1902      *  2) A real number input value but no floating output choices.
1903      * Alternately, we have a DECIMAL output available and an integer input.
1904      *
1905      * So, place the integer value into pVarDst, using the smallest type
1906      * possible and preferring signed over unsigned types.
1907      */
1908     BOOL bOverflow = FALSE, bNegative;
1909     ULONG64 ul64 = 0;
1910     int i;
1911
1912     /* Convert the integer part of the number into a UI8 */
1913     for (i = 0; i < wholeNumberDigits; i++)
1914     {
1915       if (ul64 > (UI8_MAX / 10 - rgbDig[i]))
1916       {
1917         TRACE("Overflow multiplying digits\n");
1918         bOverflow = TRUE;
1919         break;
1920       }
1921       ul64 = ul64 * 10 + rgbDig[i];
1922     }
1923
1924     /* Account for the scale of the number */
1925     if (!bOverflow && multiplier10)
1926     {
1927       for (i = 0; i < multiplier10; i++)
1928       {
1929         if (ul64 > (UI8_MAX / 10))
1930         {
1931           TRACE("Overflow scaling number\n");
1932           bOverflow = TRUE;
1933           break;
1934         }
1935         ul64 = ul64 * 10;
1936       }
1937     }
1938
1939     /* If we have any fractional digits, round the value.
1940      * Note we don't have to do this if divisor10 is < 1,
1941      * because this means the fractional part must be < 0.5
1942      */
1943     if (!bOverflow && fractionalDigits && divisor10 > 0)
1944     {
1945       const BYTE* fracDig = rgbDig + wholeNumberDigits;
1946       BOOL bAdjust = FALSE;
1947
1948       TRACE("first decimal value is %d\n", *fracDig);
1949
1950       if (*fracDig > 5)
1951         bAdjust = TRUE; /* > 0.5 */
1952       else if (*fracDig == 5)
1953       {
1954         for (i = 1; i < fractionalDigits; i++)
1955         {
1956           if (fracDig[i])
1957           {
1958             bAdjust = TRUE; /* > 0.5 */
1959             break;
1960           }
1961         }
1962         /* If exactly 0.5, round only odd values */
1963         if (i == fractionalDigits && (ul64 & 1))
1964           bAdjust = TRUE;
1965       }
1966
1967       if (bAdjust)
1968       {
1969         if (ul64 == UI8_MAX)
1970         {
1971           TRACE("Overflow after rounding\n");
1972           bOverflow = TRUE;
1973         }
1974         ul64++;
1975       }
1976     }
1977
1978     /* Zero is not a negative number */
1979     bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64 ? TRUE : FALSE;
1980
1981     TRACE("Integer value is %lld, bNeg %d\n", ul64, bNegative);
1982
1983     /* For negative integers, try the signed types in size order */
1984     if (!bOverflow && bNegative)
1985     {
1986       if (dwVtBits & (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8))
1987       {
1988         if (dwVtBits & VTBIT_I1 && ul64 <= -I1_MIN)
1989         {
1990           V_VT(pVarDst) = VT_I1;
1991           V_I1(pVarDst) = -ul64;
1992           return S_OK;
1993         }
1994         else if (dwVtBits & VTBIT_I2 && ul64 <= -I2_MIN)
1995         {
1996           V_VT(pVarDst) = VT_I2;
1997           V_I2(pVarDst) = -ul64;
1998           return S_OK;
1999         }
2000         else if (dwVtBits & VTBIT_I4 && ul64 <= -((LONGLONG)I4_MIN))
2001         {
2002           V_VT(pVarDst) = VT_I4;
2003           V_I4(pVarDst) = -ul64;
2004           return S_OK;
2005         }
2006         else if (dwVtBits & VTBIT_I8 && ul64 <= (ULONGLONG)I8_MAX + 1)
2007         {
2008           V_VT(pVarDst) = VT_I8;
2009           V_I8(pVarDst) = -ul64;
2010           return S_OK;
2011         }
2012         else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2013         {
2014           /* Decimal is only output choice left - fast path */
2015           V_VT(pVarDst) = VT_DECIMAL;
2016           DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_NEG,0);
2017           DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2018           DEC_LO64(&V_DECIMAL(pVarDst)) = -ul64;
2019           return S_OK;
2020         }
2021       }
2022     }
2023     else if (!bOverflow)
2024     {
2025       /* For positive integers, try signed then unsigned types in size order */
2026       if (dwVtBits & VTBIT_I1 && ul64 <= I1_MAX)
2027       {
2028         V_VT(pVarDst) = VT_I1;
2029         V_I1(pVarDst) = ul64;
2030         return S_OK;
2031       }
2032       else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX)
2033       {
2034         V_VT(pVarDst) = VT_UI1;
2035         V_UI1(pVarDst) = ul64;
2036         return S_OK;
2037       }
2038       else if (dwVtBits & VTBIT_I2 && ul64 <= I2_MAX)
2039       {
2040         V_VT(pVarDst) = VT_I2;
2041         V_I2(pVarDst) = ul64;
2042         return S_OK;
2043       }
2044       else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX)
2045       {
2046         V_VT(pVarDst) = VT_UI2;
2047         V_UI2(pVarDst) = ul64;
2048         return S_OK;
2049       }
2050       else if (dwVtBits & VTBIT_I4 && ul64 <= I4_MAX)
2051       {
2052         V_VT(pVarDst) = VT_I4;
2053         V_I4(pVarDst) = ul64;
2054         return S_OK;
2055       }
2056       else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX)
2057       {
2058         V_VT(pVarDst) = VT_UI4;
2059         V_UI4(pVarDst) = ul64;
2060         return S_OK;
2061       }
2062       else if (dwVtBits & VTBIT_I8 && ul64 <= I8_MAX)
2063       {
2064         V_VT(pVarDst) = VT_I8;
2065         V_I8(pVarDst) = ul64;
2066         return S_OK;
2067       }
2068       else if (dwVtBits & VTBIT_UI8)
2069       {
2070         V_VT(pVarDst) = VT_UI8;
2071         V_UI8(pVarDst) = ul64;
2072         return S_OK;
2073       }
2074       else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2075       {
2076         /* Decimal is only output choice left - fast path */
2077         V_VT(pVarDst) = VT_DECIMAL;
2078         DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
2079         DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2080         DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
2081         return S_OK;
2082       }
2083     }
2084   }
2085
2086   if (dwVtBits & REAL_VTBITS)
2087   {
2088     /* Try to put the number into a float or real */
2089     BOOL bOverflow = FALSE, bNegative = pNumprs->dwOutFlags & NUMPRS_NEG;
2090     double whole = 0.0;
2091     int i;
2092
2093     /* Convert the number into a double */
2094     for (i = 0; i < pNumprs->cDig; i++)
2095       whole = whole * 10.0 + rgbDig[i];
2096
2097     TRACE("Whole double value is %16.16g\n", whole);
2098
2099     /* Account for the scale */
2100     while (multiplier10 > 10)
2101     {
2102       if (whole > dblMaximums[10])
2103       {
2104         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2105         bOverflow = TRUE;
2106         break;
2107       }
2108       whole = whole * dblMultipliers[10];
2109       multiplier10 -= 10;
2110     }
2111     if (multiplier10)
2112     {
2113       if (whole > dblMaximums[multiplier10])
2114       {
2115         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2116         bOverflow = TRUE;
2117       }
2118       else
2119         whole = whole * dblMultipliers[multiplier10];
2120     }
2121
2122     TRACE("Scaled double value is %16.16g\n", whole);
2123
2124     while (divisor10 > 10)
2125     {
2126       if (whole < dblMinimums[10])
2127       {
2128         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
2129         bOverflow = TRUE;
2130         break;
2131       }
2132       whole = whole / dblMultipliers[10];
2133       divisor10 -= 10;
2134     }
2135     if (divisor10)
2136     {
2137       if (whole < dblMinimums[divisor10])
2138       {
2139         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
2140         bOverflow = TRUE;
2141       }
2142       else
2143         whole = whole / dblMultipliers[divisor10];
2144     }
2145     if (!bOverflow)
2146       TRACE("Final double value is %16.16g\n", whole);
2147
2148     if (dwVtBits & VTBIT_R4 &&
2149         ((whole <= R4_MAX && whole >= R4_MIN) || whole == 0.0))
2150     {
2151       TRACE("Set R4 to final value\n");
2152       V_VT(pVarDst) = VT_R4; /* Fits into a float */
2153       V_R4(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2154       return S_OK;
2155     }
2156
2157     if (dwVtBits & VTBIT_R8)
2158     {
2159       TRACE("Set R8 to final value\n");
2160       V_VT(pVarDst) = VT_R8; /* Fits into a double */
2161       V_R8(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2162       return S_OK;
2163     }
2164
2165     if (dwVtBits & VTBIT_CY)
2166     {
2167       if (SUCCEEDED(VarCyFromR8(bNegative ? -whole : whole, &V_CY(pVarDst))))
2168       {
2169         V_VT(pVarDst) = VT_CY; /* Fits into a currency */
2170         TRACE("Set CY to final value\n");
2171         return S_OK;
2172       }
2173       TRACE("Value Overflows CY\n");
2174     }
2175   }
2176
2177   if (dwVtBits & VTBIT_DECIMAL)
2178   {
2179     int i;
2180     ULONG carry;
2181     ULONG64 tmp;
2182     DECIMAL* pDec = &V_DECIMAL(pVarDst);
2183
2184     DECIMAL_SETZERO(pDec);
2185     DEC_LO32(pDec) = 0;
2186
2187     if (pNumprs->dwOutFlags & NUMPRS_NEG)
2188       DEC_SIGN(pDec) = DECIMAL_NEG;
2189     else
2190       DEC_SIGN(pDec) = DECIMAL_POS;
2191
2192     /* Factor the significant digits */
2193     for (i = 0; i < pNumprs->cDig; i++)
2194     {
2195       tmp = (ULONG64)DEC_LO32(pDec) * 10 + rgbDig[i];
2196       carry = (ULONG)(tmp >> 32);
2197       DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
2198       tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
2199       carry = (ULONG)(tmp >> 32);
2200       DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
2201       tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
2202       DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
2203
2204       if (tmp >> 32 & UI4_MAX)
2205       {
2206 VarNumFromParseNum_DecOverflow:
2207         TRACE("Overflow\n");
2208         DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX;
2209         return DISP_E_OVERFLOW;
2210       }
2211     }
2212
2213     /* Account for the scale of the number */
2214     while (multiplier10 > 0)
2215     {
2216       tmp = (ULONG64)DEC_LO32(pDec) * 10;
2217       carry = (ULONG)(tmp >> 32);
2218       DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
2219       tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
2220       carry = (ULONG)(tmp >> 32);
2221       DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
2222       tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
2223       DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
2224
2225       if (tmp >> 32 & UI4_MAX)
2226         goto VarNumFromParseNum_DecOverflow;
2227       multiplier10--;
2228     }
2229     DEC_SCALE(pDec) = divisor10;
2230
2231     V_VT(pVarDst) = VT_DECIMAL;
2232     return S_OK;
2233   }
2234   return DISP_E_OVERFLOW; /* No more output choices */
2235 }
2236
2237 /**********************************************************************
2238  *              VarCat [OLEAUT32.318]
2239  */
2240 HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
2241 {
2242     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2243           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), out);
2244
2245     /* Should we VariantClear out? */
2246     /* Can we handle array, vector, by ref etc. */
2247     if ((V_VT(left)&VT_TYPEMASK) == VT_NULL &&
2248         (V_VT(right)&VT_TYPEMASK) == VT_NULL)
2249     {
2250         V_VT(out) = VT_NULL;
2251         return S_OK;
2252     }
2253
2254     if (V_VT(left) == VT_BSTR && V_VT(right) == VT_BSTR)
2255     {
2256         V_VT(out) = VT_BSTR;
2257         VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
2258         return S_OK;
2259     }
2260     if (V_VT(left) == VT_BSTR) {
2261         VARIANT bstrvar;
2262         HRESULT hres;
2263
2264         V_VT(out) = VT_BSTR;
2265         hres = VariantChangeTypeEx(&bstrvar,right,0,0,VT_BSTR);
2266         if (hres) {
2267             FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
2268             return hres;
2269         }
2270         VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar), &V_BSTR(out));
2271         return S_OK;
2272     }
2273     if (V_VT(right) == VT_BSTR) {
2274         VARIANT bstrvar;
2275         HRESULT hres;
2276
2277         V_VT(out) = VT_BSTR;
2278         hres = VariantChangeTypeEx(&bstrvar,left,0,0,VT_BSTR);
2279         if (hres) {
2280             FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
2281             return hres;
2282         }
2283         VarBstrCat (V_BSTR(&bstrvar), V_BSTR(right), &V_BSTR(out));
2284         return S_OK;
2285     }
2286     FIXME ("types %d / %d not supported\n",V_VT(left)&VT_TYPEMASK, V_VT(right)&VT_TYPEMASK);
2287     return S_OK;
2288 }
2289
2290 /**********************************************************************
2291  *              VarCmp [OLEAUT32.176]
2292  *
2293  * flags can be:
2294  *   NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS
2295  *   NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
2296  *
2297  */
2298 HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
2299 {
2300     BOOL        lOk        = TRUE;
2301     BOOL        rOk        = TRUE;
2302     LONGLONG    lVal = -1;
2303     LONGLONG    rVal = -1;
2304     VARIANT     rv,lv;
2305     DWORD       xmask;
2306     HRESULT     rc;
2307
2308     TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%08lx)\n", left, debugstr_VT(left),
2309           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags);
2310
2311     VariantInit(&lv);VariantInit(&rv);
2312     V_VT(right) &= ~0x8000; /* hack since we sometime get this flag.  */
2313     V_VT(left) &= ~0x8000; /* hack since we sometime get this flag. */
2314
2315     /* If either are null, then return VARCMP_NULL */
2316     if ((V_VT(left)&VT_TYPEMASK) == VT_NULL ||
2317         (V_VT(right)&VT_TYPEMASK) == VT_NULL)
2318         return VARCMP_NULL;
2319
2320     /* Strings - use VarBstrCmp */
2321     if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
2322         (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
2323         return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags);
2324     }
2325
2326     xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));
2327     if (xmask & (1<<VT_R8)) {
2328         rc = VariantChangeType(&lv,left,0,VT_R8);
2329         if (FAILED(rc)) return rc;
2330         rc = VariantChangeType(&rv,right,0,VT_R8);
2331         if (FAILED(rc)) return rc;
2332
2333         if (V_R8(&lv) == V_R8(&rv)) return VARCMP_EQ;
2334         if (V_R8(&lv) < V_R8(&rv)) return VARCMP_LT;
2335         if (V_R8(&lv) > V_R8(&rv)) return VARCMP_GT;
2336         return E_FAIL; /* can't get here */
2337     }
2338     if (xmask & (1<<VT_R4)) {
2339         rc = VariantChangeType(&lv,left,0,VT_R4);
2340         if (FAILED(rc)) return rc;
2341         rc = VariantChangeType(&rv,right,0,VT_R4);
2342         if (FAILED(rc)) return rc;
2343
2344         if (V_R4(&lv) == V_R4(&rv)) return VARCMP_EQ;
2345         if (V_R4(&lv) < V_R4(&rv)) return VARCMP_LT;
2346         if (V_R4(&lv) > V_R4(&rv)) return VARCMP_GT;
2347         return E_FAIL; /* can't get here */
2348     }
2349
2350     /* Integers - Ideally like to use VarDecCmp, but no Dec support yet
2351            Use LONGLONG to maximize ranges                              */
2352     lOk = TRUE;
2353     switch (V_VT(left)&VT_TYPEMASK) {
2354     case VT_I1   : lVal = V_UNION(left,cVal); break;
2355     case VT_I2   : lVal = V_UNION(left,iVal); break;
2356     case VT_I4   : lVal = V_UNION(left,lVal); break;
2357     case VT_INT  : lVal = V_UNION(left,lVal); break;
2358     case VT_UI1  : lVal = V_UNION(left,bVal); break;
2359     case VT_UI2  : lVal = V_UNION(left,uiVal); break;
2360     case VT_UI4  : lVal = V_UNION(left,ulVal); break;
2361     case VT_UINT : lVal = V_UNION(left,ulVal); break;
2362     case VT_BOOL : lVal = V_UNION(left,boolVal); break;
2363     default: lOk = FALSE;
2364     }
2365
2366     rOk = TRUE;
2367     switch (V_VT(right)&VT_TYPEMASK) {
2368     case VT_I1   : rVal = V_UNION(right,cVal); break;
2369     case VT_I2   : rVal = V_UNION(right,iVal); break;
2370     case VT_I4   : rVal = V_UNION(right,lVal); break;
2371     case VT_INT  : rVal = V_UNION(right,lVal); break;
2372     case VT_UI1  : rVal = V_UNION(right,bVal); break;
2373     case VT_UI2  : rVal = V_UNION(right,uiVal); break;
2374     case VT_UI4  : rVal = V_UNION(right,ulVal); break;
2375     case VT_UINT : rVal = V_UNION(right,ulVal); break;
2376     case VT_BOOL : rVal = V_UNION(right,boolVal); break;
2377     default: rOk = FALSE;
2378     }
2379
2380     if (lOk && rOk) {
2381         if (lVal < rVal) {
2382             return VARCMP_LT;
2383         } else if (lVal > rVal) {
2384             return VARCMP_GT;
2385         } else {
2386             return VARCMP_EQ;
2387         }
2388     }
2389
2390     /* Strings - use VarBstrCmp */
2391     if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&
2392         (V_VT(right)&VT_TYPEMASK) == VT_DATE) {
2393
2394         if (floor(V_UNION(left,date)) == floor(V_UNION(right,date))) {
2395             /* Due to floating point rounding errors, calculate varDate in whole numbers) */
2396             double wholePart = 0.0;
2397             double leftR;
2398             double rightR;
2399
2400             /* Get the fraction * 24*60*60 to make it into whole seconds */
2401             wholePart = (double) floor( V_UNION(left,date) );
2402             if (wholePart == 0) wholePart = 1;
2403             leftR = floor(fmod( V_UNION(left,date), wholePart ) * (24*60*60));
2404
2405             wholePart = (double) floor( V_UNION(right,date) );
2406             if (wholePart == 0) wholePart = 1;
2407             rightR = floor(fmod( V_UNION(right,date), wholePart ) * (24*60*60));
2408
2409             if (leftR < rightR) {
2410                 return VARCMP_LT;
2411             } else if (leftR > rightR) {
2412                 return VARCMP_GT;
2413             } else {
2414                 return VARCMP_EQ;
2415             }
2416
2417         } else if (V_UNION(left,date) < V_UNION(right,date)) {
2418             return VARCMP_LT;
2419         } else if (V_UNION(left,date) > V_UNION(right,date)) {
2420             return VARCMP_GT;
2421         }
2422     }
2423     FIXME("VarCmp partial implementation, doesn't support vt 0x%x / 0x%x\n",V_VT(left), V_VT(right));
2424     return E_FAIL;
2425 }
2426
2427 /**********************************************************************
2428  *              VarAnd [OLEAUT32.142]
2429  *
2430  */
2431 HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2432 {
2433     HRESULT rc = E_FAIL;
2434
2435     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2436           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2437
2438     if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL &&
2439         (V_VT(right)&VT_TYPEMASK) == VT_BOOL) {
2440
2441         V_VT(result) = VT_BOOL;
2442         if (V_BOOL(left) && V_BOOL(right)) {
2443             V_BOOL(result) = VARIANT_TRUE;
2444         } else {
2445             V_BOOL(result) = VARIANT_FALSE;
2446         }
2447         rc = S_OK;
2448
2449     } else {
2450         /* Integers */
2451         BOOL         lOk        = TRUE;
2452         BOOL         rOk        = TRUE;
2453         LONGLONG     lVal = -1;
2454         LONGLONG     rVal = -1;
2455         LONGLONG     res  = -1;
2456         int          resT = 0; /* Testing has shown I2 & I2 == I2, all else
2457                                   becomes I4, even unsigned ints (incl. UI2) */
2458
2459         lOk = TRUE;
2460         switch (V_VT(left)&VT_TYPEMASK) {
2461         case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;
2462         case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;
2463         case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
2464         case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
2465         case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;
2466         case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
2467         case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
2468         case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
2469         default: lOk = FALSE;
2470         }
2471
2472         rOk = TRUE;
2473         switch (V_VT(right)&VT_TYPEMASK) {
2474         case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;
2475         case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;
2476         case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
2477         case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
2478         case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;
2479         case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
2480         case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
2481         case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
2482         default: rOk = FALSE;
2483         }
2484
2485         if (lOk && rOk) {
2486             res = (lVal & rVal);
2487             V_VT(result) = resT;
2488             switch (resT) {
2489             case VT_I2   : V_UNION(result,iVal)  = res; break;
2490             case VT_I4   : V_UNION(result,lVal)  = res; break;
2491             default:
2492                 FIXME("Unexpected result variant type %x\n", resT);
2493                 V_UNION(result,lVal)  = res;
2494             }
2495             rc = S_OK;
2496
2497         } else {
2498             FIXME("VarAnd stub\n");
2499         }
2500     }
2501
2502     TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
2503           debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
2504     return rc;
2505 }
2506
2507 /**********************************************************************
2508  *              VarAdd [OLEAUT32.141]
2509  * FIXME: From MSDN: If ... Then
2510  * Both expressions are of the string type Concatenated.
2511  * One expression is a string type and the other a character Addition.
2512  * One expression is numeric and the other is a string Addition.
2513  * Both expressions are numeric Addition.
2514  * Either expression is NULL NULL is returned.
2515  * Both expressions are empty  Integer subtype is returned.
2516  *
2517  */
2518 HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2519 {
2520     HRESULT rc = E_FAIL;
2521
2522     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2523           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2524
2525     if ((V_VT(left)&VT_TYPEMASK) == VT_EMPTY)
2526         return VariantCopy(result,right);
2527
2528     if ((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)
2529         return VariantCopy(result,left);
2530
2531     /* check if we add doubles */
2532     if (((V_VT(left)&VT_TYPEMASK) == VT_R8) || ((V_VT(right)&VT_TYPEMASK) == VT_R8)) {
2533         BOOL         lOk        = TRUE;
2534         BOOL         rOk        = TRUE;
2535         double       lVal = -1;
2536         double       rVal = -1;
2537         double       res  = -1;
2538
2539         lOk = TRUE;
2540         switch (V_VT(left)&VT_TYPEMASK) {
2541         case VT_I1   : lVal = V_UNION(left,cVal);   break;
2542         case VT_I2   : lVal = V_UNION(left,iVal);   break;
2543         case VT_I4   : lVal = V_UNION(left,lVal);   break;
2544         case VT_INT  : lVal = V_UNION(left,lVal);   break;
2545         case VT_UI1  : lVal = V_UNION(left,bVal);   break;
2546         case VT_UI2  : lVal = V_UNION(left,uiVal);  break;
2547         case VT_UI4  : lVal = V_UNION(left,ulVal);  break;
2548         case VT_UINT : lVal = V_UNION(left,ulVal);  break;
2549         case VT_R4   : lVal = V_UNION(left,fltVal);  break;
2550         case VT_R8   : lVal = V_UNION(left,dblVal);  break;
2551         case VT_NULL : lVal = 0.0;  break;
2552         default: lOk = FALSE;
2553         }
2554
2555         rOk = TRUE;
2556         switch (V_VT(right)&VT_TYPEMASK) {
2557         case VT_I1   : rVal = V_UNION(right,cVal);  break;
2558         case VT_I2   : rVal = V_UNION(right,iVal);  break;
2559         case VT_I4   : rVal = V_UNION(right,lVal);  break;
2560         case VT_INT  : rVal = V_UNION(right,lVal);  break;
2561         case VT_UI1  : rVal = V_UNION(right,bVal);  break;
2562         case VT_UI2  : rVal = V_UNION(right,uiVal); break;
2563         case VT_UI4  : rVal = V_UNION(right,ulVal); break;
2564         case VT_UINT : rVal = V_UNION(right,ulVal); break;
2565         case VT_R4   : rVal = V_UNION(right,fltVal);break;
2566         case VT_R8   : rVal = V_UNION(right,dblVal);break;
2567         case VT_NULL : rVal = 0.0; break;
2568         default: rOk = FALSE;
2569         }
2570
2571         if (lOk && rOk) {
2572             res = (lVal + rVal);
2573             V_VT(result) = VT_R8;
2574             V_UNION(result,dblVal)  = res;
2575             rc = S_OK;
2576         } else {
2577             FIXME("Unhandled type pair %d / %d in double addition.\n",
2578                 (V_VT(left)&VT_TYPEMASK),
2579                 (V_VT(right)&VT_TYPEMASK)
2580             );
2581         }
2582         return rc;
2583     }
2584
2585     /* now check if we add floats. VT_R8 can no longer happen here! */
2586     if (((V_VT(left)&VT_TYPEMASK) == VT_R4) || ((V_VT(right)&VT_TYPEMASK) == VT_R4)) {
2587         BOOL         lOk        = TRUE;
2588         BOOL         rOk        = TRUE;
2589         float        lVal = -1;
2590         float        rVal = -1;
2591         float        res  = -1;
2592
2593         lOk = TRUE;
2594         switch (V_VT(left)&VT_TYPEMASK) {
2595         case VT_I1   : lVal = V_UNION(left,cVal);   break;
2596         case VT_I2   : lVal = V_UNION(left,iVal);   break;
2597         case VT_I4   : lVal = V_UNION(left,lVal);   break;
2598         case VT_INT  : lVal = V_UNION(left,lVal);   break;
2599         case VT_UI1  : lVal = V_UNION(left,bVal);   break;
2600         case VT_UI2  : lVal = V_UNION(left,uiVal);  break;
2601         case VT_UI4  : lVal = V_UNION(left,ulVal);  break;
2602         case VT_UINT : lVal = V_UNION(left,ulVal);  break;
2603         case VT_R4   : lVal = V_UNION(left,fltVal);  break;
2604         case VT_NULL : lVal = 0.0;  break;
2605         default: lOk = FALSE;
2606         }
2607
2608         rOk = TRUE;
2609         switch (V_VT(right)&VT_TYPEMASK) {
2610         case VT_I1   : rVal = V_UNION(right,cVal);  break;
2611         case VT_I2   : rVal = V_UNION(right,iVal);  break;
2612         case VT_I4   : rVal = V_UNION(right,lVal);  break;
2613         case VT_INT  : rVal = V_UNION(right,lVal);  break;
2614         case VT_UI1  : rVal = V_UNION(right,bVal);  break;
2615         case VT_UI2  : rVal = V_UNION(right,uiVal); break;
2616         case VT_UI4  : rVal = V_UNION(right,ulVal); break;
2617         case VT_UINT : rVal = V_UNION(right,ulVal); break;
2618         case VT_R4   : rVal = V_UNION(right,fltVal);break;
2619         case VT_NULL : rVal = 0.0; break;
2620         default: rOk = FALSE;
2621         }
2622
2623         if (lOk && rOk) {
2624             res = (lVal + rVal);
2625             V_VT(result) = VT_R4;
2626             V_UNION(result,fltVal)  = res;
2627             rc = S_OK;
2628         } else {
2629             FIXME("Unhandled type pair %d / %d in float addition.\n", 
2630                 (V_VT(left)&VT_TYPEMASK),
2631                 (V_VT(right)&VT_TYPEMASK)
2632             );
2633         }
2634         return rc;
2635     }
2636
2637     /* Handle strings as concat */
2638     if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
2639         (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
2640         V_VT(result) = VT_BSTR;
2641         return VarBstrCat(V_BSTR(left), V_BSTR(right), &V_BSTR(result));
2642     } else {
2643
2644         /* Integers */
2645         BOOL         lOk        = TRUE;
2646         BOOL         rOk        = TRUE;
2647         LONGLONG     lVal = -1;
2648         LONGLONG     rVal = -1;
2649         LONGLONG     res  = -1;
2650         int          resT = 0; /* Testing has shown I2 + I2 == I2, all else
2651                                   becomes I4                                */
2652
2653         lOk = TRUE;
2654         switch (V_VT(left)&VT_TYPEMASK) {
2655         case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;
2656         case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;
2657         case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
2658         case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
2659         case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;
2660         case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
2661         case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
2662         case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
2663         case VT_NULL : lVal = 0; resT = VT_I4; break;
2664         default: lOk = FALSE;
2665         }
2666
2667         rOk = TRUE;
2668         switch (V_VT(right)&VT_TYPEMASK) {
2669         case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;
2670         case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;
2671         case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
2672         case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
2673         case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;
2674         case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
2675         case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
2676         case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
2677         case VT_NULL : rVal = 0; resT=VT_I4; break;
2678         default: rOk = FALSE;
2679         }
2680
2681         if (lOk && rOk) {
2682             res = (lVal + rVal);
2683             V_VT(result) = resT;
2684             switch (resT) {
2685             case VT_I2   : V_UNION(result,iVal)  = res; break;
2686             case VT_I4   : V_UNION(result,lVal)  = res; break;
2687             default:
2688                 FIXME("Unexpected result variant type %x\n", resT);
2689                 V_UNION(result,lVal)  = res;
2690             }
2691             rc = S_OK;
2692
2693         } else {
2694             FIXME("unimplemented part (0x%x + 0x%x)\n",V_VT(left), V_VT(right));
2695         }
2696     }
2697
2698     TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
2699           debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
2700     return rc;
2701 }
2702
2703 /**********************************************************************
2704  *              VarMul [OLEAUT32.156]
2705  *
2706  */
2707 HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2708 {
2709     HRESULT rc = E_FAIL;
2710     VARTYPE lvt,rvt,resvt;
2711     VARIANT lv,rv;
2712     BOOL found;
2713
2714     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2715           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2716
2717     VariantInit(&lv);VariantInit(&rv);
2718     lvt = V_VT(left)&VT_TYPEMASK;
2719     rvt = V_VT(right)&VT_TYPEMASK;
2720     found = FALSE;resvt=VT_VOID;
2721     if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {
2722         found = TRUE;
2723         resvt = VT_R8;
2724     }
2725     if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {
2726         found = TRUE;
2727         resvt = VT_I4;
2728     }
2729     if (!found) {
2730         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
2731         return E_FAIL;
2732     }
2733     rc = VariantChangeType(&lv, left, 0, resvt);
2734     if (FAILED(rc)) {
2735         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
2736         return rc;
2737     }
2738     rc = VariantChangeType(&rv, right, 0, resvt);
2739     if (FAILED(rc)) {
2740         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
2741         return rc;
2742     }
2743     switch (resvt) {
2744     case VT_R8:
2745         V_VT(result) = resvt;
2746         V_R8(result) = V_R8(&lv) * V_R8(&rv);
2747         rc = S_OK;
2748         break;
2749     case VT_I4:
2750         V_VT(result) = resvt;
2751         V_I4(result) = V_I4(&lv) * V_I4(&rv);
2752         rc = S_OK;
2753         break;
2754     }
2755     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
2756           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
2757     return rc;
2758 }
2759
2760 /**********************************************************************
2761  *              VarDiv [OLEAUT32.143]
2762  *
2763  */
2764 HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2765 {
2766     HRESULT rc = E_FAIL;
2767     VARTYPE lvt,rvt,resvt;
2768     VARIANT lv,rv;
2769     BOOL found;
2770
2771     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2772           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2773
2774     VariantInit(&lv);VariantInit(&rv);
2775     lvt = V_VT(left)&VT_TYPEMASK;
2776     rvt = V_VT(right)&VT_TYPEMASK;
2777     found = FALSE;resvt = VT_VOID;
2778     if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {
2779         found = TRUE;
2780         resvt = VT_R8;
2781     }
2782     if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {
2783         found = TRUE;
2784         resvt = VT_I4;
2785     }
2786     if (!found) {
2787         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
2788         return E_FAIL;
2789     }
2790     rc = VariantChangeType(&lv, left, 0, resvt);
2791     if (FAILED(rc)) {
2792         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
2793         return rc;
2794     }
2795     rc = VariantChangeType(&rv, right, 0, resvt);
2796     if (FAILED(rc)) {
2797         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
2798         return rc;
2799     }
2800     switch (resvt) {
2801     case VT_R8:
2802         V_VT(result) = resvt;
2803         V_R8(result) = V_R8(&lv) / V_R8(&rv);
2804         rc = S_OK;
2805         break;
2806     case VT_I4:
2807         V_VT(result) = resvt;
2808         V_I4(result) = V_I4(&lv) / V_I4(&rv);
2809         rc = S_OK;
2810         break;
2811     }
2812     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
2813           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
2814     return rc;
2815 }
2816
2817 /**********************************************************************
2818  *              VarSub [OLEAUT32.159]
2819  *
2820  */
2821 HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2822 {
2823     HRESULT rc = E_FAIL;
2824     VARTYPE lvt,rvt,resvt;
2825     VARIANT lv,rv;
2826     BOOL found;
2827
2828     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2829           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2830
2831     VariantInit(&lv);VariantInit(&rv);
2832     lvt = V_VT(left)&VT_TYPEMASK;
2833     rvt = V_VT(right)&VT_TYPEMASK;
2834     found = FALSE;resvt = VT_VOID;
2835     if (((1<<lvt) | (1<<rvt)) & ((1<<VT_DATE)|(1<<VT_R4)|(1<<VT_R8))) {
2836         found = TRUE;
2837         resvt = VT_R8;
2838     }
2839     if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {
2840         found = TRUE;
2841         resvt = VT_I4;
2842     }
2843     if (!found) {
2844         FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
2845         return E_FAIL;
2846     }
2847     rc = VariantChangeType(&lv, left, 0, resvt);
2848     if (FAILED(rc)) {
2849         FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
2850         return rc;
2851     }
2852     rc = VariantChangeType(&rv, right, 0, resvt);
2853     if (FAILED(rc)) {
2854         FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
2855         return rc;
2856     }
2857     switch (resvt) {
2858     case VT_R8:
2859         V_VT(result) = resvt;
2860         V_R8(result) = V_R8(&lv) - V_R8(&rv);
2861         rc = S_OK;
2862         break;
2863     case VT_I4:
2864         V_VT(result) = resvt;
2865         V_I4(result) = V_I4(&lv) - V_I4(&rv);
2866         rc = S_OK;
2867         break;
2868     }
2869     TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
2870           debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
2871     return rc;
2872 }
2873
2874 /**********************************************************************
2875  *              VarOr [OLEAUT32.157]
2876  *
2877  */
2878 HRESULT WINAPI VarOr(LPVARIANT left, LPVARIANT right, LPVARIANT result)
2879 {
2880     HRESULT rc = E_FAIL;
2881
2882     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2883           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
2884
2885     if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL &&
2886         (V_VT(right)&VT_TYPEMASK) == VT_BOOL) {
2887
2888         V_VT(result) = VT_BOOL;
2889         if (V_BOOL(left) || V_BOOL(right)) {
2890             V_BOOL(result) = VARIANT_TRUE;
2891         } else {
2892             V_BOOL(result) = VARIANT_FALSE;
2893         }
2894         rc = S_OK;
2895
2896     } else {
2897         /* Integers */
2898         BOOL         lOk        = TRUE;
2899         BOOL         rOk        = TRUE;
2900         LONGLONG     lVal = -1;
2901         LONGLONG     rVal = -1;
2902         LONGLONG     res  = -1;
2903         int          resT = 0; /* Testing has shown I2 & I2 == I2, all else
2904                                   becomes I4, even unsigned ints (incl. UI2) */
2905
2906         lOk = TRUE;
2907         switch (V_VT(left)&VT_TYPEMASK) {
2908         case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;
2909         case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;
2910         case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
2911         case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
2912         case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;
2913         case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
2914         case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
2915         case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
2916         default: lOk = FALSE;
2917         }
2918
2919         rOk = TRUE;
2920         switch (V_VT(right)&VT_TYPEMASK) {
2921         case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;
2922         case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;
2923         case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
2924         case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
2925         case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;
2926         case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
2927         case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
2928         case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
2929         default: rOk = FALSE;
2930         }
2931
2932         if (lOk && rOk) {
2933             res = (lVal | rVal);
2934             V_VT(result) = resT;
2935             switch (resT) {
2936             case VT_I2   : V_UNION(result,iVal)  = res; break;
2937             case VT_I4   : V_UNION(result,lVal)  = res; break;
2938             default:
2939                 FIXME("Unexpected result variant type %x\n", resT);
2940                 V_UNION(result,lVal)  = res;
2941             }
2942             rc = S_OK;
2943
2944         } else {
2945             FIXME("unimplemented part\n");
2946         }
2947     }
2948
2949     TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
2950           debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
2951     return rc;
2952 }
2953
2954 /**********************************************************************
2955  * VarAbs [OLEAUT32.168]
2956  *
2957  * Convert a variant to its absolute value.
2958  *
2959  * PARAMS
2960  *  pVarIn  [I] Source variant
2961  *  pVarOut [O] Destination for converted value
2962  *
2963  * RETURNS
2964  *  Success: S_OK. pVarOut contains the absolute value of pVarIn.
2965  *  Failure: An HRESULT error code indicating the error.
2966  *
2967  * NOTES
2968  *  - This function does not process by-reference variants.
2969  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
2970  *    according to the following table:
2971  *| Input Type       Output Type
2972  *| ----------       -----------
2973  *| VT_BOOL          VT_I2
2974  *| VT_BSTR          VT_R8
2975  *| (All others)     Unchanged
2976  */
2977 HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)
2978 {
2979     VARIANT varIn;
2980     HRESULT hRet = S_OK;
2981
2982     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
2983           debugstr_VF(pVarIn), pVarOut);
2984
2985     if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN ||
2986         V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD ||
2987         V_VT(pVarIn) == VT_ERROR)
2988         return DISP_E_TYPEMISMATCH;
2989
2990     *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */
2991
2992 #define ABS_CASE(typ,min) \
2993     case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \
2994                   else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \
2995                   break
2996
2997     switch (V_VT(pVarIn))
2998     {
2999     ABS_CASE(I1,I1_MIN);
3000     case VT_BOOL:
3001         V_VT(pVarOut) = VT_I2;
3002         /* BOOL->I2, Fall through ... */
3003     ABS_CASE(I2,I2_MIN);
3004     case VT_INT:
3005     ABS_CASE(I4,I4_MIN);
3006     ABS_CASE(I8,I8_MIN);
3007     ABS_CASE(R4,R4_MIN);
3008     case VT_BSTR:
3009         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
3010         if (FAILED(hRet))
3011             break;
3012         V_VT(pVarOut) = VT_R8;
3013         pVarIn = &varIn;
3014         /* Fall through ... */
3015     case VT_DATE:
3016     ABS_CASE(R8,R8_MIN);
3017     case VT_CY:
3018         hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut));
3019         break;
3020     case VT_DECIMAL:
3021         DEC_SIGN(&V_DECIMAL(pVarOut)) &= ~DECIMAL_NEG;
3022         break;
3023     case VT_UI1:
3024     case VT_UI2:
3025     case VT_UINT:
3026     case VT_UI4:
3027     case VT_UI8:
3028     case VT_EMPTY:
3029     case VT_NULL:
3030         /* No-Op */
3031         break;
3032     default:
3033         hRet = DISP_E_BADVARTYPE;
3034     }
3035
3036     return hRet;
3037 }
3038
3039 /**********************************************************************
3040  *              VarNot [OLEAUT32.174]
3041  *
3042  * Perform a not operation on a variant.
3043  *
3044  * PARAMS
3045  *  pVarIn  [I] Source variant
3046  *  pVarOut [O] Destination for converted value
3047  *
3048  * RETURNS
3049  *  Success: S_OK. pVarOut contains the converted value.
3050  *  Failure: An HRESULT error code indicating the error.
3051  *
3052  * NOTES
3053  *  - Strictly speaking, this function performs a bitwise ones compliment
3054  *    on the variants value (after possibly converting to VT_I4, see below).
3055  *    This only behaves like a boolean not operation if the value in
3056  *    pVarIn is either VARIANT_TRUE or VARIANT_FALSE and the type is signed.
3057  *  - To perform a genuine not operation, convert the variant to a VT_BOOL
3058  *    before calling this function.
3059  *  - This function does not process by-reference variants.
3060  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
3061  *    according to the following table:
3062  *| Input Type       Output Type
3063  *| ----------       -----------
3064  *| VT_R4            VT_I4
3065  *| VT_R8            VT_I4
3066  *| VT_BSTR          VT_I4
3067  *| VT_DECIMAL       VT_I4
3068  *| VT_CY            VT_I4
3069  *| (All others)     Unchanged
3070  */
3071 HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
3072 {
3073     VARIANT varIn;
3074     HRESULT hRet = S_OK;
3075
3076     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
3077           debugstr_VF(pVarIn), pVarOut);
3078
3079     V_VT(pVarOut) = V_VT(pVarIn);
3080
3081     switch (V_VT(pVarIn))
3082     {
3083     case VT_I1:  V_I1(pVarOut) = ~V_I1(pVarIn); break;
3084     case VT_UI1: V_UI1(pVarOut) = ~V_UI1(pVarIn); break;
3085     case VT_BOOL:
3086     case VT_I2:  V_I2(pVarOut) = ~V_I2(pVarIn); break;
3087     case VT_UI2: V_UI2(pVarOut) = ~V_UI2(pVarIn); break;
3088     case VT_DECIMAL:
3089         hRet = VarI4FromDec(&V_DECIMAL(pVarIn), &V_I4(&varIn));
3090         if (FAILED(hRet))
3091             break;
3092         pVarIn = &varIn;
3093         V_VT(pVarOut) = VT_I4;
3094         /* Fall through ... */
3095     case VT_INT:
3096     case VT_I4:  V_I4(pVarOut) = ~V_I4(pVarIn); break;
3097     case VT_UINT:
3098     case VT_UI4: V_UI4(pVarOut) = ~V_UI4(pVarIn); break;
3099     case VT_I8:  V_I8(pVarOut) = ~V_I8(pVarIn); break;
3100     case VT_UI8: V_UI8(pVarOut) = ~V_UI8(pVarIn); break;
3101     case VT_R4:
3102         hRet = VarI4FromR4(V_R4(pVarIn), &V_I4(pVarOut));
3103         V_I4(pVarOut) = ~V_I4(pVarOut);
3104         V_VT(pVarOut) = VT_I4;
3105         break;
3106     case VT_BSTR:
3107         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
3108         if (FAILED(hRet))
3109             break;
3110         pVarIn = &varIn;
3111         /* Fall through ... */
3112     case VT_DATE:
3113     case VT_R8:
3114         hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut));
3115         V_I4(pVarOut) = ~V_I4(pVarOut);
3116         V_VT(pVarOut) = VT_I4;
3117         break;
3118     case VT_CY:
3119         /* FIXME: */
3120         break;
3121     case VT_EMPTY:
3122     case VT_NULL:
3123         /* No-Op */
3124         break;
3125     default:
3126         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
3127             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
3128             hRet = DISP_E_BADVARTYPE;
3129         else
3130             hRet = DISP_E_TYPEMISMATCH;
3131     }
3132     if (FAILED(hRet))
3133       V_VT(pVarOut) = VT_EMPTY;
3134
3135     return hRet;
3136 }
3137
3138 /**********************************************************************
3139  *              VarMod [OLEAUT32.154]
3140  *
3141  */
3142 HRESULT WINAPI VarMod(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
3143 {
3144     FIXME("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
3145           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
3146           debugstr_VF(pVarRight), pVarOut);
3147     return E_FAIL;
3148 }
3149
3150 /**********************************************************************
3151  *              VarPow [OLEAUT32.158]
3152  *
3153  */
3154 HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3155 {
3156     HRESULT hr;
3157     VARIANT dl,dr;
3158
3159     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), debugstr_VF(left),
3160           right, debugstr_VT(right), debugstr_VF(right), result);
3161
3162     hr = VariantChangeType(&dl,left,0,VT_R8);
3163     if (!SUCCEEDED(hr)) {
3164         ERR("Could not change passed left argument to VT_R8, handle it differently.\n");
3165         return E_FAIL;
3166     }
3167     hr = VariantChangeType(&dr,right,0,VT_R8);
3168     if (!SUCCEEDED(hr)) {
3169         ERR("Could not change passed right argument to VT_R8, handle it differently.\n");
3170         return E_FAIL;
3171     }
3172     V_VT(result) = VT_R8;
3173     V_R8(result) = pow(V_R8(&dl),V_R8(&dr));
3174     return S_OK;
3175 }
3176
3177 /**********************************************************************
3178  *              VarInt [OLEAUT32.172]
3179  *
3180  */
3181 HRESULT WINAPI VarInt(LPVARIANT var, LPVARIANT result)
3182 {
3183     TRACE("(%p->(%s%s),%p)\n", var, debugstr_VT(var), debugstr_VF(var), result);
3184
3185     switch(V_VT(var)) {
3186     case VT_R4:
3187         V_VT(result) = VT_I4;
3188         V_I4(result) = floor(V_R4(var));
3189         break;
3190     case VT_R8:
3191         V_VT(result) = VT_I4;
3192         V_I4(result) = floor(V_R8(var));
3193         break;
3194     default:
3195         FIXME("Unhandled variant type 0x%x\n", V_VT(var));
3196         return DISP_E_TYPEMISMATCH;
3197     }
3198     return S_OK;
3199 }