msdaps: Implement the marshalling object.
[wine] / dlls / oleaut32 / variant.c
1 /*
2  * VARIANT
3  *
4  * Copyright 1998 Jean-Claude Cote
5  * Copyright 2003 Jon Griffiths
6  * Copyright 2005 Daniel Remenak
7  * Copyright 2006 Google (Benjamin Arai)
8  *
9  * The algorithm for conversion from Julian days to day/month/year is based on
10  * that devised by Henry Fliegel, as implemented in PostgreSQL, which is
11  * Copyright 1994-7 Regents of the University of California
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27
28 #include "config.h"
29
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33
34 #define COBJMACROS
35 #define NONAMELESSUNION
36 #define NONAMELESSSTRUCT
37
38 #include "windef.h"
39 #include "winbase.h"
40 #include "wine/unicode.h"
41 #include "winerror.h"
42 #include "variant.h"
43 #include "resource.h"
44 #include "wine/debug.h"
45
46 WINE_DEFAULT_DEBUG_CHANNEL(variant);
47
48 const char * const wine_vtypes[VT_CLSID+1] =
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 * const 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%08x,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:      V_I1(pd) = V_UI1(ps); return S_OK;
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:      V_I2(pd) = V_UI2(ps); return S_OK;
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:      V_I4(pd) = V_UI4(ps); return S_OK;
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:       V_UI1(pd) = V_I1(ps); return S_OK;
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:       V_UI2(pd) = V_I2(ps); return S_OK;
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:       V_UI4(pd) = V_I4(ps); return S_OK;
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:       V_UI8(pd) = V_I8(ps); return S_OK;
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:      V_I8(pd) = V_UI8(ps); return S_OK;
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(ps), &V_DECIMAL(pd));
487     case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(pd));
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 HRESULT VARIANT_ClearInd(VARIANTARG *pVarg)
582 {
583     HRESULT hres;
584
585     TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
586
587     hres = VARIANT_ValidateType(V_VT(pVarg));
588     if (FAILED(hres))
589         return hres;
590
591     switch (V_VT(pVarg))
592     {
593     case VT_DISPATCH:
594     case VT_UNKNOWN:
595         if (V_UNKNOWN(pVarg))
596             IUnknown_Release(V_UNKNOWN(pVarg));
597         break;
598     case VT_UNKNOWN | VT_BYREF:
599     case VT_DISPATCH | VT_BYREF:
600         if(*V_UNKNOWNREF(pVarg))
601             IUnknown_Release(*V_UNKNOWNREF(pVarg));
602         break;
603     case VT_BSTR:
604         SysFreeString(V_BSTR(pVarg));
605         break;
606     case VT_BSTR | VT_BYREF:
607         SysFreeString(*V_BSTRREF(pVarg));
608         break;
609     case VT_VARIANT | VT_BYREF:
610         VariantClear(V_VARIANTREF(pVarg));
611         break;
612     case VT_RECORD:
613     case VT_RECORD | VT_BYREF:
614     {
615         struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
616         if (pBr->pRecInfo)
617         {
618             IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
619             IRecordInfo_Release(pBr->pRecInfo);
620         }
621         break;
622     }
623     default:
624         if (V_ISARRAY(pVarg) || (V_VT(pVarg) & ~VT_BYREF) == VT_SAFEARRAY)
625         {
626             if (V_ISBYREF(pVarg))
627             {
628                 if (*V_ARRAYREF(pVarg))
629                     hres = SafeArrayDestroy(*V_ARRAYREF(pVarg));
630             }
631             else if (V_ARRAY(pVarg))
632                 hres = SafeArrayDestroy(V_ARRAY(pVarg));
633         }
634         break;
635     }
636
637     V_VT(pVarg) = VT_EMPTY;
638     return hres;
639 }
640
641 /******************************************************************************
642  *              VariantClear    [OLEAUT32.9]
643  *
644  * Clear a variant.
645  *
646  * PARAMS
647  *  pVarg [I/O] Variant to clear
648  *
649  * RETURNS
650  *  Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
651  *  Failure: DISP_E_BADVARTYPE, if the variant is not a valid variant type.
652  */
653 HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
654 {
655   HRESULT hres = S_OK;
656
657   TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
658
659   hres = VARIANT_ValidateType(V_VT(pVarg));
660
661   if (SUCCEEDED(hres))
662   {
663     if (!V_ISBYREF(pVarg))
664     {
665       if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY)
666       {
667         if (V_ARRAY(pVarg))
668           hres = SafeArrayDestroy(V_ARRAY(pVarg));
669       }
670       else if (V_VT(pVarg) == VT_BSTR)
671       {
672         SysFreeString(V_BSTR(pVarg));
673       }
674       else if (V_VT(pVarg) == VT_RECORD)
675       {
676         struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
677         if (pBr->pRecInfo)
678         {
679           IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
680           IRecordInfo_Release(pBr->pRecInfo);
681         }
682       }
683       else if (V_VT(pVarg) == VT_DISPATCH ||
684                V_VT(pVarg) == VT_UNKNOWN)
685       {
686         if (V_UNKNOWN(pVarg))
687           IUnknown_Release(V_UNKNOWN(pVarg));
688       }
689     }
690     V_VT(pVarg) = VT_EMPTY;
691   }
692   return hres;
693 }
694
695 /******************************************************************************
696  * Copy an IRecordInfo object contained in a variant.
697  */
698 static HRESULT VARIANT_CopyIRecordInfo(struct __tagBRECORD* pBr)
699 {
700   HRESULT hres = S_OK;
701
702   if (pBr->pRecInfo)
703   {
704     ULONG ulSize;
705
706     hres = IRecordInfo_GetSize(pBr->pRecInfo, &ulSize);
707     if (SUCCEEDED(hres))
708     {
709       PVOID pvRecord = HeapAlloc(GetProcessHeap(), 0, ulSize);
710       if (!pvRecord)
711         hres = E_OUTOFMEMORY;
712       else
713       {
714         memcpy(pvRecord, pBr->pvRecord, ulSize);
715         pBr->pvRecord = pvRecord;
716
717         hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord);
718         if (SUCCEEDED(hres))
719           IRecordInfo_AddRef(pBr->pRecInfo);
720       }
721     }
722   }
723   else if (pBr->pvRecord)
724     hres = E_INVALIDARG;
725   return hres;
726 }
727
728 /******************************************************************************
729  *    VariantCopy  [OLEAUT32.10]
730  *
731  * Copy a variant.
732  *
733  * PARAMS
734  *  pvargDest [O] Destination for copy
735  *  pvargSrc  [I] Source variant to copy
736  *
737  * RETURNS
738  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
739  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid type.
740  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
741  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
742  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
743  *
744  * NOTES
745  *  - If pvargSrc == pvargDest, this function does nothing, and succeeds if
746  *    pvargSrc is valid. Otherwise, pvargDest is always cleared using
747  *    VariantClear() before pvargSrc is copied to it. If clearing pvargDest
748  *    fails, so does this function.
749  *  - VT_CLSID is a valid type type for pvargSrc, but not for pvargDest.
750  *  - For by-value non-intrinsic types, a deep copy is made, i.e. The whole value
751  *    is copied rather than just any pointers to it.
752  *  - For by-value object types the object pointer is copied and the objects
753  *    reference count increased using IUnknown_AddRef().
754  *  - For all by-reference types, only the referencing pointer is copied.
755  */
756 HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
757 {
758   HRESULT hres = S_OK;
759
760   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
761         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
762         debugstr_VF(pvargSrc));
763
764   if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */
765       FAILED(VARIANT_ValidateType(V_VT(pvargSrc))))
766     return DISP_E_BADVARTYPE;
767
768   if (pvargSrc != pvargDest &&
769       SUCCEEDED(hres = VariantClear(pvargDest)))
770   {
771     *pvargDest = *pvargSrc; /* Shallow copy the value */
772
773     if (!V_ISBYREF(pvargSrc))
774     {
775       if (V_ISARRAY(pvargSrc))
776       {
777         if (V_ARRAY(pvargSrc))
778           hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest));
779       }
780       else if (V_VT(pvargSrc) == VT_BSTR)
781       {
782         V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc)));
783         if (!V_BSTR(pvargDest))
784         {
785           TRACE("!V_BSTR(pvargDest), SysAllocStringByteLen() failed to allocate %d bytes\n", SysStringByteLen(V_BSTR(pvargSrc)));
786           hres = E_OUTOFMEMORY;
787         }
788       }
789       else if (V_VT(pvargSrc) == VT_RECORD)
790       {
791         hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
792       }
793       else if (V_VT(pvargSrc) == VT_DISPATCH ||
794                V_VT(pvargSrc) == VT_UNKNOWN)
795       {
796         if (V_UNKNOWN(pvargSrc))
797           IUnknown_AddRef(V_UNKNOWN(pvargSrc));
798       }
799     }
800   }
801   return hres;
802 }
803
804 /* Return the byte size of a variants data */
805 static inline size_t VARIANT_DataSize(const VARIANT* pv)
806 {
807   switch (V_TYPE(pv))
808   {
809   case VT_I1:
810   case VT_UI1:   return sizeof(BYTE);
811   case VT_I2:
812   case VT_UI2:   return sizeof(SHORT);
813   case VT_INT:
814   case VT_UINT:
815   case VT_I4:
816   case VT_UI4:   return sizeof(LONG);
817   case VT_I8:
818   case VT_UI8:   return sizeof(LONGLONG);
819   case VT_R4:    return sizeof(float);
820   case VT_R8:    return sizeof(double);
821   case VT_DATE:  return sizeof(DATE);
822   case VT_BOOL:  return sizeof(VARIANT_BOOL);
823   case VT_DISPATCH:
824   case VT_UNKNOWN:
825   case VT_BSTR:  return sizeof(void*);
826   case VT_CY:    return sizeof(CY);
827   case VT_ERROR: return sizeof(SCODE);
828   }
829   TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv));
830   return 0;
831 }
832
833 /******************************************************************************
834  *    VariantCopyInd  [OLEAUT32.11]
835  *
836  * Copy a variant, dereferencing it if it is by-reference.
837  *
838  * PARAMS
839  *  pvargDest [O] Destination for copy
840  *  pvargSrc  [I] Source variant to copy
841  *
842  * RETURNS
843  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
844  *  Failure: An HRESULT error code indicating the error.
845  *
846  * NOTES
847  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid by-value type.
848  *           E_INVALIDARG, if pvargSrc  is an invalid by-reference type.
849  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
850  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
851  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
852  *
853  * NOTES
854  *  - If pvargSrc is by-value, this function behaves exactly as VariantCopy().
855  *  - If pvargSrc is by-reference, the value copied to pvargDest is the pointed-to
856  *    value.
857  *  - if pvargSrc == pvargDest, this function dereferences in place. Otherwise,
858  *    pvargDest is always cleared using VariantClear() before pvargSrc is copied
859  *    to it. If clearing pvargDest fails, so does this function.
860  */
861 HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
862 {
863   VARIANTARG vTmp, *pSrc = pvargSrc;
864   VARTYPE vt;
865   HRESULT hres = S_OK;
866
867   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
868         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
869         debugstr_VF(pvargSrc));
870
871   if (!V_ISBYREF(pvargSrc))
872     return VariantCopy(pvargDest, pvargSrc);
873
874   /* Argument checking is more lax than VariantCopy()... */
875   vt = V_TYPE(pvargSrc);
876   if (V_ISARRAY(pvargSrc) ||
877      (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
878      !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED))))
879   {
880     /* OK */
881   }
882   else
883     return E_INVALIDARG; /* ...And the return value for invalid types differs too */
884
885   if (pvargSrc == pvargDest)
886   {
887     /* In place copy. Use a shallow copy of pvargSrc & init pvargDest.
888      * This avoids an expensive VariantCopy() call - e.g. SafeArrayCopy().
889      */
890     vTmp = *pvargSrc;
891     pSrc = &vTmp;
892     V_VT(pvargDest) = VT_EMPTY;
893   }
894   else
895   {
896     /* Copy into another variant. Free the variant in pvargDest */
897     if (FAILED(hres = VariantClear(pvargDest)))
898     {
899       TRACE("VariantClear() of destination failed\n");
900       return hres;
901     }
902   }
903
904   if (V_ISARRAY(pSrc))
905   {
906     /* Native doesn't check that *V_ARRAYREF(pSrc) is valid */
907     hres = SafeArrayCopy(*V_ARRAYREF(pSrc), &V_ARRAY(pvargDest));
908   }
909   else if (V_VT(pSrc) == (VT_BSTR|VT_BYREF))
910   {
911     /* Native doesn't check that *V_BSTRREF(pSrc) is valid */
912     V_BSTR(pvargDest) = SysAllocStringByteLen((char*)*V_BSTRREF(pSrc), SysStringByteLen(*V_BSTRREF(pSrc)));
913   }
914   else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF))
915   {
916     V_UNION(pvargDest,brecVal) = V_UNION(pvargSrc,brecVal);
917     hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
918   }
919   else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) ||
920            V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF))
921   {
922     /* Native doesn't check that *V_UNKNOWNREF(pSrc) is valid */
923     V_UNKNOWN(pvargDest) = *V_UNKNOWNREF(pSrc);
924     if (*V_UNKNOWNREF(pSrc))
925       IUnknown_AddRef(*V_UNKNOWNREF(pSrc));
926   }
927   else if (V_VT(pSrc) == (VT_VARIANT|VT_BYREF))
928   {
929     /* Native doesn't check that *V_VARIANTREF(pSrc) is valid */
930     if (V_VT(V_VARIANTREF(pSrc)) == (VT_VARIANT|VT_BYREF))
931       hres = E_INVALIDARG; /* Don't dereference more than one level */
932     else
933       hres = VariantCopyInd(pvargDest, V_VARIANTREF(pSrc));
934
935     /* Use the dereferenced variants type value, not VT_VARIANT */
936     goto VariantCopyInd_Return;
937   }
938   else if (V_VT(pSrc) == (VT_DECIMAL|VT_BYREF))
939   {
940     memcpy(&DEC_SCALE(&V_DECIMAL(pvargDest)), &DEC_SCALE(V_DECIMALREF(pSrc)),
941            sizeof(DECIMAL) - sizeof(USHORT));
942   }
943   else
944   {
945     /* Copy the pointed to data into this variant */
946     memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(pSrc));
947   }
948
949   V_VT(pvargDest) = V_VT(pSrc) & ~VT_BYREF;
950
951 VariantCopyInd_Return:
952
953   if (pSrc != pvargSrc)
954     VariantClear(pSrc);
955
956   TRACE("returning 0x%08x, %p->(%s%s)\n", hres, pvargDest,
957         debugstr_VT(pvargDest), debugstr_VF(pvargDest));
958   return hres;
959 }
960
961 /******************************************************************************
962  *    VariantChangeType  [OLEAUT32.12]
963  *
964  * Change the type of a variant.
965  *
966  * PARAMS
967  *  pvargDest [O] Destination for the converted variant
968  *  pvargSrc  [O] Source variant to change the type of
969  *  wFlags    [I] VARIANT_ flags from "oleauto.h"
970  *  vt        [I] Variant type to change pvargSrc into
971  *
972  * RETURNS
973  *  Success: S_OK. pvargDest contains the converted value.
974  *  Failure: An HRESULT error code describing the failure.
975  *
976  * NOTES
977  *  The LCID used for the conversion is LOCALE_USER_DEFAULT.
978  *  See VariantChangeTypeEx.
979  */
980 HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
981                                  USHORT wFlags, VARTYPE vt)
982 {
983   return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt );
984 }
985
986 /******************************************************************************
987  *    VariantChangeTypeEx  [OLEAUT32.147]
988  *
989  * Change the type of a variant.
990  *
991  * PARAMS
992  *  pvargDest [O] Destination for the converted variant
993  *  pvargSrc  [O] Source variant to change the type of
994  *  lcid      [I] LCID for the conversion
995  *  wFlags    [I] VARIANT_ flags from "oleauto.h"
996  *  vt        [I] Variant type to change pvargSrc into
997  *
998  * RETURNS
999  *  Success: S_OK. pvargDest contains the converted value.
1000  *  Failure: An HRESULT error code describing the failure.
1001  *
1002  * NOTES
1003  *  pvargDest and pvargSrc can point to the same variant to perform an in-place
1004  *  conversion. If the conversion is successful, pvargSrc will be freed.
1005  */
1006 HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
1007                                    LCID lcid, USHORT wFlags, VARTYPE vt)
1008 {
1009   HRESULT res = S_OK;
1010
1011   TRACE("(%p->(%s%s),%p->(%s%s),0x%08x,0x%04x,%s%s)\n", pvargDest,
1012         debugstr_VT(pvargDest), debugstr_VF(pvargDest), pvargSrc,
1013         debugstr_VT(pvargSrc), debugstr_VF(pvargSrc), lcid, wFlags,
1014         debugstr_vt(vt), debugstr_vf(vt));
1015
1016   if (vt == VT_CLSID)
1017     res = DISP_E_BADVARTYPE;
1018   else
1019   {
1020     res = VARIANT_ValidateType(V_VT(pvargSrc));
1021
1022     if (SUCCEEDED(res))
1023     {
1024       res = VARIANT_ValidateType(vt);
1025
1026       if (SUCCEEDED(res))
1027       {
1028         VARIANTARG vTmp, vSrcDeref;
1029
1030         if(V_ISBYREF(pvargSrc) && !V_BYREF(pvargSrc))
1031           res = DISP_E_TYPEMISMATCH;
1032         else
1033         {
1034           V_VT(&vTmp) = VT_EMPTY;
1035           V_VT(&vSrcDeref) = VT_EMPTY;
1036           VariantClear(&vTmp);
1037           VariantClear(&vSrcDeref);
1038         }
1039
1040         if (SUCCEEDED(res))
1041         {
1042           res = VariantCopyInd(&vSrcDeref, pvargSrc);
1043           if (SUCCEEDED(res))
1044           {
1045             if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY))
1046               res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt);
1047             else
1048               res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt);
1049
1050             if (SUCCEEDED(res)) {
1051                 V_VT(&vTmp) = vt;
1052                 VariantCopy(pvargDest, &vTmp);
1053             }
1054             VariantClear(&vTmp);
1055             VariantClear(&vSrcDeref);
1056           }
1057         }
1058       }
1059     }
1060   }
1061
1062   TRACE("returning 0x%08x, %p->(%s%s)\n", res, pvargDest,
1063         debugstr_VT(pvargDest), debugstr_VF(pvargDest));
1064   return res;
1065 }
1066
1067 /* Date Conversions */
1068
1069 #define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
1070
1071 /* Convert a VT_DATE value to a Julian Date */
1072 static inline int VARIANT_JulianFromDate(int dateIn)
1073 {
1074   int julianDays = dateIn;
1075
1076   julianDays -= DATE_MIN; /* Convert to + days from 1 Jan 100 AD */
1077   julianDays += 1757585;  /* Convert to + days from 23 Nov 4713 BC (Julian) */
1078   return julianDays;
1079 }
1080
1081 /* Convert a Julian Date to a VT_DATE value */
1082 static inline int VARIANT_DateFromJulian(int dateIn)
1083 {
1084   int julianDays = dateIn;
1085
1086   julianDays -= 1757585;  /* Convert to + days from 1 Jan 100 AD */
1087   julianDays += DATE_MIN; /* Convert to +/- days from 1 Jan 1899 AD */
1088   return julianDays;
1089 }
1090
1091 /* Convert a Julian date to Day/Month/Year - from PostgreSQL */
1092 static inline void VARIANT_DMYFromJulian(int jd, USHORT *year, USHORT *month, USHORT *day)
1093 {
1094   int j, i, l, n;
1095
1096   l = jd + 68569;
1097   n = l * 4 / 146097;
1098   l -= (n * 146097 + 3) / 4;
1099   i = (4000 * (l + 1)) / 1461001;
1100   l += 31 - (i * 1461) / 4;
1101   j = (l * 80) / 2447;
1102   *day = l - (j * 2447) / 80;
1103   l = j / 11;
1104   *month = (j + 2) - (12 * l);
1105   *year = 100 * (n - 49) + i + l;
1106 }
1107
1108 /* Convert Day/Month/Year to a Julian date - from PostgreSQL */
1109 static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day)
1110 {
1111   int m12 = (month - 14) / 12;
1112
1113   return ((1461 * (year + 4800 + m12)) / 4 + (367 * (month - 2 - 12 * m12)) / 12 -
1114            (3 * ((year + 4900 + m12) / 100)) / 4 + day - 32075);
1115 }
1116
1117 /* Macros for accessing DOS format date/time fields */
1118 #define DOS_YEAR(x)   (1980 + (x >> 9))
1119 #define DOS_MONTH(x)  ((x >> 5) & 0xf)
1120 #define DOS_DAY(x)    (x & 0x1f)
1121 #define DOS_HOUR(x)   (x >> 11)
1122 #define DOS_MINUTE(x) ((x >> 5) & 0x3f)
1123 #define DOS_SECOND(x) ((x & 0x1f) << 1)
1124 /* Create a DOS format date/time */
1125 #define DOS_DATE(d,m,y) (d | (m << 5) | ((y-1980) << 9))
1126 #define DOS_TIME(h,m,s) ((s >> 1) | (m << 5) | (h << 11))
1127
1128 /* Roll a date forwards or backwards to correct it */
1129 static HRESULT VARIANT_RollUdate(UDATE *lpUd)
1130 {
1131   static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1132   short iYear, iMonth, iDay, iHour, iMinute, iSecond;
1133
1134   /* interpret values signed */
1135   iYear   = lpUd->st.wYear;
1136   iMonth  = lpUd->st.wMonth;
1137   iDay    = lpUd->st.wDay;
1138   iHour   = lpUd->st.wHour;
1139   iMinute = lpUd->st.wMinute;
1140   iSecond = lpUd->st.wSecond;
1141
1142   TRACE("Raw date: %d/%d/%d %d:%d:%d\n", iDay, iMonth,
1143         iYear, iHour, iMinute, iSecond);
1144
1145   if (iYear > 9999 || iYear < -9999)
1146     return E_INVALIDARG; /* Invalid value */
1147   /* Years < 100 are treated as 1900 + year */
1148   if (iYear >= 0 && iYear < 100)
1149     iYear += 1900;
1150
1151   iMinute += (iSecond - (iSecond % 60)) / 60;
1152   iSecond = iSecond % 60;
1153   iHour   += (iMinute - (iMinute % 60)) / 60;
1154   iMinute = iMinute % 60;
1155   iDay    += (iHour - (iHour % 24)) / 24;
1156   iHour   = iHour % 24;
1157   /* FIXME: Roll Days */
1158   iYear    += (iMonth - (iMonth % 12)) / 12;
1159   iMonth   = iMonth % 12;
1160
1161   if (iSecond<0){iSecond+=60; iMinute--;}
1162   if (iMinute<0){iMinute+=60; iHour--;}
1163   if (iHour<0)  {iHour+=24; iDay--;}
1164   if (iDay<0)
1165   {
1166       iDay+=days[iMonth];
1167       iMonth--;
1168       if (iMonth == 2 && IsLeapYear(iYear))
1169         iDay++;
1170   }
1171   if (iMonth<=0) {iMonth+=12; iYear--;}
1172   if (iYear<0)  iYear+=2000;
1173
1174   if (!lpUd->st.wDay)
1175   {
1176     /* Roll back the date one day */
1177     if (lpUd->st.wMonth == 1)
1178     {
1179       /* Roll back to December 31 of the previous year */
1180       lpUd->st.wDay   = 31;
1181       lpUd->st.wMonth = 12;
1182       lpUd->st.wYear--;
1183     }
1184     else
1185     {
1186       lpUd->st.wMonth--; /* Previous month */
1187       if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
1188         lpUd->st.wDay = 29; /* February has 29 days on leap years */
1189       else
1190         lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */
1191     }
1192   }
1193   else if (lpUd->st.wDay > 28)
1194   {
1195     int rollForward = 0;
1196
1197     /* Possibly need to roll the date forward */
1198     if (iMonth == 2 && IsLeapYear(iYear))
1199       rollForward = iDay - 29; /* February has 29 days on leap years */
1200     else
1201       rollForward = iDay - days[iMonth];
1202
1203     if (rollForward > 0)
1204     {
1205       iDay = rollForward;
1206       iMonth++;
1207       if (iMonth > 12)
1208       {
1209         iMonth = 1; /* Roll forward into January of the next year */
1210         iYear++;
1211       }
1212     }
1213   }
1214
1215   lpUd->st.wYear   = iYear;
1216   lpUd->st.wMonth  = iMonth;
1217   lpUd->st.wDay    = iDay;
1218   lpUd->st.wHour   = iHour;
1219   lpUd->st.wMinute = iMinute;
1220   lpUd->st.wSecond = iSecond;
1221
1222   TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
1223         lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
1224   return S_OK;
1225 }
1226
1227 /**********************************************************************
1228  *              DosDateTimeToVariantTime [OLEAUT32.14]
1229  *
1230  * Convert a Dos format date and time into variant VT_DATE format.
1231  *
1232  * PARAMS
1233  *  wDosDate [I] Dos format date
1234  *  wDosTime [I] Dos format time
1235  *  pDateOut [O] Destination for VT_DATE format
1236  *
1237  * RETURNS
1238  *  Success: TRUE. pDateOut contains the converted time.
1239  *  Failure: FALSE, if wDosDate or wDosTime are invalid (see notes).
1240  *
1241  * NOTES
1242  * - Dos format dates can only hold dates from 1-Jan-1980 to 31-Dec-2099.
1243  * - Dos format times are accurate to only 2 second precision.
1244  * - The format of a Dos Date is:
1245  *| Bits   Values  Meaning
1246  *| ----   ------  -------
1247  *| 0-4    1-31    Day of the week. 0 rolls back one day. A value greater than
1248  *|                the days in the month rolls forward the extra days.
1249  *| 5-8    1-12    Month of the year. 0 rolls back to December of the previous
1250  *|                year. 13-15 are invalid.
1251  *| 9-15   0-119   Year based from 1980 (Max 2099). 120-127 are invalid.
1252  * - The format of a Dos Time is:
1253  *| Bits   Values  Meaning
1254  *| ----   ------  -------
1255  *| 0-4    0-29    Seconds/2. 30 and 31 are invalid.
1256  *| 5-10   0-59    Minutes. 60-63 are invalid.
1257  *| 11-15  0-23    Hours (24 hour clock). 24-32 are invalid.
1258  */
1259 INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
1260                                     double *pDateOut)
1261 {
1262   UDATE ud;
1263
1264   TRACE("(0x%x(%d/%d/%d),0x%x(%d:%d:%d),%p)\n",
1265         wDosDate, DOS_YEAR(wDosDate), DOS_MONTH(wDosDate), DOS_DAY(wDosDate),
1266         wDosTime, DOS_HOUR(wDosTime), DOS_MINUTE(wDosTime), DOS_SECOND(wDosTime),
1267         pDateOut);
1268
1269   ud.st.wYear = DOS_YEAR(wDosDate);
1270   ud.st.wMonth = DOS_MONTH(wDosDate);
1271   if (ud.st.wYear > 2099 || ud.st.wMonth > 12)
1272     return FALSE;
1273   ud.st.wDay = DOS_DAY(wDosDate);
1274   ud.st.wHour = DOS_HOUR(wDosTime);
1275   ud.st.wMinute = DOS_MINUTE(wDosTime);
1276   ud.st.wSecond = DOS_SECOND(wDosTime);
1277   ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
1278   if (ud.st.wHour > 23 || ud.st.wMinute > 59 || ud.st.wSecond > 59)
1279     return FALSE; /* Invalid values in Dos*/
1280
1281   return VarDateFromUdate(&ud, 0, pDateOut) == S_OK;
1282 }
1283
1284 /**********************************************************************
1285  *              VariantTimeToDosDateTime [OLEAUT32.13]
1286  *
1287  * Convert a variant format date into a Dos format date and time.
1288  *
1289  *  dateIn    [I] VT_DATE time format
1290  *  pwDosDate [O] Destination for Dos format date
1291  *  pwDosTime [O] Destination for Dos format time
1292  *
1293  * RETURNS
1294  *  Success: TRUE. pwDosDate and pwDosTime contains the converted values.
1295  *  Failure: FALSE, if dateIn cannot be represented in Dos format.
1296  *
1297  * NOTES
1298  *   See DosDateTimeToVariantTime() for Dos format details and bugs.
1299  */
1300 INT WINAPI VariantTimeToDosDateTime(double dateIn, USHORT *pwDosDate, USHORT *pwDosTime)
1301 {
1302   UDATE ud;
1303
1304   TRACE("(%g,%p,%p)\n", dateIn, pwDosDate, pwDosTime);
1305
1306   if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1307     return FALSE;
1308
1309   if (ud.st.wYear < 1980 || ud.st.wYear > 2099)
1310     return FALSE;
1311
1312   *pwDosDate = DOS_DATE(ud.st.wDay, ud.st.wMonth, ud.st.wYear);
1313   *pwDosTime = DOS_TIME(ud.st.wHour, ud.st.wMinute, ud.st.wSecond);
1314
1315   TRACE("Returning 0x%x(%d/%d/%d), 0x%x(%d:%d:%d)\n",
1316         *pwDosDate, DOS_YEAR(*pwDosDate), DOS_MONTH(*pwDosDate), DOS_DAY(*pwDosDate),
1317         *pwDosTime, DOS_HOUR(*pwDosTime), DOS_MINUTE(*pwDosTime), DOS_SECOND(*pwDosTime));
1318   return TRUE;
1319 }
1320
1321 /***********************************************************************
1322  *              SystemTimeToVariantTime [OLEAUT32.184]
1323  *
1324  * Convert a System format date and time into variant VT_DATE format.
1325  *
1326  * PARAMS
1327  *  lpSt     [I] System format date and time
1328  *  pDateOut [O] Destination for VT_DATE format date
1329  *
1330  * RETURNS
1331  *  Success: TRUE. *pDateOut contains the converted value.
1332  *  Failure: FALSE, if lpSt cannot be represented in VT_DATE format.
1333  */
1334 INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut)
1335 {
1336   UDATE ud;
1337
1338   TRACE("(%p->%d/%d/%d %d:%d:%d,%p)\n", lpSt, lpSt->wDay, lpSt->wMonth,
1339         lpSt->wYear, lpSt->wHour, lpSt->wMinute, lpSt->wSecond, pDateOut);
1340
1341   if (lpSt->wMonth > 12)
1342     return FALSE;
1343
1344   ud.st = *lpSt;
1345   return VarDateFromUdate(&ud, 0, pDateOut) == S_OK;
1346 }
1347
1348 /***********************************************************************
1349  *              VariantTimeToSystemTime [OLEAUT32.185]
1350  *
1351  * Convert a variant VT_DATE into a System format date and time.
1352  *
1353  * PARAMS
1354  *  datein [I] Variant VT_DATE format date
1355  *  lpSt   [O] Destination for System format date and time
1356  *
1357  * RETURNS
1358  *  Success: TRUE. *lpSt contains the converted value.
1359  *  Failure: FALSE, if dateIn is too large or small.
1360  */
1361 INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt)
1362 {
1363   UDATE ud;
1364
1365   TRACE("(%g,%p)\n", dateIn, lpSt);
1366
1367   if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
1368     return FALSE;
1369
1370   *lpSt = ud.st;
1371   return TRUE;
1372 }
1373
1374 /***********************************************************************
1375  *              VarDateFromUdateEx [OLEAUT32.319]
1376  *
1377  * Convert an unpacked format date and time to a variant VT_DATE.
1378  *
1379  * PARAMS
1380  *  pUdateIn [I] Unpacked format date and time to convert
1381  *  lcid     [I] Locale identifier for the conversion
1382  *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1383  *  pDateOut [O] Destination for variant VT_DATE.
1384  *
1385  * RETURNS
1386  *  Success: S_OK. *pDateOut contains the converted value.
1387  *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
1388  */
1389 HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut)
1390 {
1391   UDATE ud;
1392   double dateVal;
1393
1394   TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08x,0x%08x,%p)\n", pUdateIn,
1395         pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
1396         pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond,
1397         pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek,
1398         pUdateIn->wDayOfYear, lcid, dwFlags, pDateOut);
1399
1400   if (lcid != MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT))
1401     FIXME("lcid possibly not handled, treating as en-us\n");
1402
1403   ud = *pUdateIn;
1404
1405   if (dwFlags & VAR_VALIDDATE)
1406     WARN("Ignoring VAR_VALIDDATE\n");
1407
1408   if (FAILED(VARIANT_RollUdate(&ud)))
1409     return E_INVALIDARG;
1410
1411   /* Date */
1412   dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay));
1413
1414   /* Time */
1415   dateVal += ud.st.wHour / 24.0;
1416   dateVal += ud.st.wMinute / 1440.0;
1417   dateVal += ud.st.wSecond / 86400.0;
1418
1419   TRACE("Returning %g\n", dateVal);
1420   *pDateOut = dateVal;
1421   return S_OK;
1422 }
1423
1424 /***********************************************************************
1425  *              VarDateFromUdate [OLEAUT32.330]
1426  *
1427  * Convert an unpacked format date and time to a variant VT_DATE.
1428  *
1429  * PARAMS
1430  *  pUdateIn [I] Unpacked format date and time to convert
1431  *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1432  *  pDateOut [O] Destination for variant VT_DATE.
1433  *
1434  * RETURNS
1435  *  Success: S_OK. *pDateOut contains the converted value.
1436  *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
1437  *
1438  * NOTES
1439  *  This function uses the United States English locale for the conversion. Use
1440  *  VarDateFromUdateEx() for alternate locales.
1441  */
1442 HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
1443 {
1444   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
1445   
1446   return VarDateFromUdateEx(pUdateIn, lcid, dwFlags, pDateOut);
1447 }
1448
1449 /***********************************************************************
1450  *              VarUdateFromDate [OLEAUT32.331]
1451  *
1452  * Convert a variant VT_DATE into an unpacked format date and time.
1453  *
1454  * PARAMS
1455  *  datein    [I] Variant VT_DATE format date
1456  *  dwFlags   [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1457  *  lpUdate   [O] Destination for unpacked format date and time
1458  *
1459  * RETURNS
1460  *  Success: S_OK. *lpUdate contains the converted value.
1461  *  Failure: E_INVALIDARG, if dateIn is too large or small.
1462  */
1463 HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
1464 {
1465   /* Cumulative totals of days per month */
1466   static const USHORT cumulativeDays[] =
1467   {
1468     0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
1469   };
1470   double datePart, timePart;
1471   int julianDays;
1472
1473   TRACE("(%g,0x%08x,%p)\n", dateIn, dwFlags, lpUdate);
1474
1475   if (dateIn <= (DATE_MIN - 1.0) || dateIn >= (DATE_MAX + 1.0))
1476     return E_INVALIDARG;
1477
1478   datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn);
1479   /* Compensate for int truncation (always downwards) */
1480   timePart = dateIn - datePart + 0.00000000001;
1481   if (timePart >= 1.0)
1482     timePart -= 0.00000000001;
1483
1484   /* Date */
1485   julianDays = VARIANT_JulianFromDate(dateIn);
1486   VARIANT_DMYFromJulian(julianDays, &lpUdate->st.wYear, &lpUdate->st.wMonth,
1487                         &lpUdate->st.wDay);
1488
1489   datePart = (datePart + 1.5) / 7.0;
1490   lpUdate->st.wDayOfWeek = (datePart - floor(datePart)) * 7;
1491   if (lpUdate->st.wDayOfWeek == 0)
1492     lpUdate->st.wDayOfWeek = 5;
1493   else if (lpUdate->st.wDayOfWeek == 1)
1494     lpUdate->st.wDayOfWeek = 6;
1495   else
1496     lpUdate->st.wDayOfWeek -= 2;
1497
1498   if (lpUdate->st.wMonth > 2 && IsLeapYear(lpUdate->st.wYear))
1499     lpUdate->wDayOfYear = 1; /* After February, in a leap year */
1500   else
1501     lpUdate->wDayOfYear = 0;
1502
1503   lpUdate->wDayOfYear += cumulativeDays[lpUdate->st.wMonth];
1504   lpUdate->wDayOfYear += lpUdate->st.wDay;
1505
1506   /* Time */
1507   timePart *= 24.0;
1508   lpUdate->st.wHour = timePart;
1509   timePart -= lpUdate->st.wHour;
1510   timePart *= 60.0;
1511   lpUdate->st.wMinute = timePart;
1512   timePart -= lpUdate->st.wMinute;
1513   timePart *= 60.0;
1514   lpUdate->st.wSecond = timePart;
1515   timePart -= lpUdate->st.wSecond;
1516   lpUdate->st.wMilliseconds = 0;
1517   if (timePart > 0.5)
1518   {
1519     /* Round the milliseconds, adjusting the time/date forward if needed */
1520     if (lpUdate->st.wSecond < 59)
1521       lpUdate->st.wSecond++;
1522     else
1523     {
1524       lpUdate->st.wSecond = 0;
1525       if (lpUdate->st.wMinute < 59)
1526         lpUdate->st.wMinute++;
1527       else
1528       {
1529         lpUdate->st.wMinute = 0;
1530         if (lpUdate->st.wHour < 23)
1531           lpUdate->st.wHour++;
1532         else
1533         {
1534           lpUdate->st.wHour = 0;
1535           /* Roll over a whole day */
1536           if (++lpUdate->st.wDay > 28)
1537             VARIANT_RollUdate(lpUdate);
1538         }
1539       }
1540     }
1541   }
1542   return S_OK;
1543 }
1544
1545 #define GET_NUMBER_TEXT(fld,name) \
1546   buff[0] = 0; \
1547   if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \
1548     WARN("buffer too small for " #fld "\n"); \
1549   else \
1550     if (buff[0]) lpChars->name = buff[0]; \
1551   TRACE("lcid 0x%x, " #name "=%d '%c'\n", lcid, lpChars->name, lpChars->name)
1552
1553 /* Get the valid number characters for an lcid */
1554 static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags)
1555 {
1556   static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',',','$',0,'.',',' };
1557   static CRITICAL_SECTION csLastChars = { NULL, -1, 0, 0, 0, 0 };
1558   static VARIANT_NUMBER_CHARS lastChars;
1559   static LCID lastLcid = -1;
1560   static DWORD lastFlags = 0;
1561   LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE;
1562   WCHAR buff[4];
1563
1564   /* To make caching thread-safe, a critical section is needed */
1565   EnterCriticalSection(&csLastChars);
1566
1567   /* Asking for default locale entries is very expensive: It is a registry
1568      server call. So cache one locally, as Microsoft does it too */
1569   if(lcid == lastLcid && dwFlags == lastFlags)
1570   {
1571     memcpy(lpChars, &lastChars, sizeof(defaultChars));
1572     LeaveCriticalSection(&csLastChars);
1573     return;
1574   }
1575
1576   memcpy(lpChars, &defaultChars, sizeof(defaultChars));
1577   GET_NUMBER_TEXT(LOCALE_SNEGATIVESIGN, cNegativeSymbol);
1578   GET_NUMBER_TEXT(LOCALE_SPOSITIVESIGN, cPositiveSymbol);
1579   GET_NUMBER_TEXT(LOCALE_SDECIMAL, cDecimalPoint);
1580   GET_NUMBER_TEXT(LOCALE_STHOUSAND, cDigitSeparator);
1581   GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint);
1582   GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeparator);
1583
1584   /* Local currency symbols are often 2 characters */
1585   lpChars->cCurrencyLocal2 = '\0';
1586   switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR)))
1587   {
1588     case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
1589     case 2: lpChars->cCurrencyLocal  = buff[0];
1590             break;
1591     default: WARN("buffer too small for LOCALE_SCURRENCY\n");
1592   }
1593   TRACE("lcid 0x%x, cCurrencyLocal =%d,%d '%c','%c'\n", lcid, lpChars->cCurrencyLocal,
1594         lpChars->cCurrencyLocal2, lpChars->cCurrencyLocal, lpChars->cCurrencyLocal2);
1595
1596   memcpy(&lastChars, lpChars, sizeof(defaultChars));
1597   lastLcid = lcid;
1598   lastFlags = dwFlags;
1599   LeaveCriticalSection(&csLastChars);
1600 }
1601
1602 /* Number Parsing States */
1603 #define B_PROCESSING_EXPONENT 0x1
1604 #define B_NEGATIVE_EXPONENT   0x2
1605 #define B_EXPONENT_START      0x4
1606 #define B_INEXACT_ZEROS       0x8
1607 #define B_LEADING_ZERO        0x10
1608 #define B_PROCESSING_HEX      0x20
1609 #define B_PROCESSING_OCT      0x40
1610
1611 /**********************************************************************
1612  *              VarParseNumFromStr [OLEAUT32.46]
1613  *
1614  * Parse a string containing a number into a NUMPARSE structure.
1615  *
1616  * PARAMS
1617  *  lpszStr [I]   String to parse number from
1618  *  lcid    [I]   Locale Id for the conversion
1619  *  dwFlags [I]   0, or LOCALE_NOUSEROVERRIDE to use system default number chars
1620  *  pNumprs [I/O] Destination for parsed number
1621  *  rgbDig  [O]   Destination for digits read in
1622  *
1623  * RETURNS
1624  *  Success: S_OK. pNumprs and rgbDig contain the parsed representation of
1625  *           the number.
1626  *  Failure: E_INVALIDARG, if any parameter is invalid.
1627  *           DISP_E_TYPEMISMATCH, if the string is not a number or is formatted
1628  *           incorrectly.
1629  *           DISP_E_OVERFLOW, if rgbDig is too small to hold the number.
1630  *
1631  * NOTES
1632  *  pNumprs must have the following fields set:
1633  *   cDig: Set to the size of rgbDig.
1634  *   dwInFlags: Set to the allowable syntax of the number using NUMPRS_ flags
1635  *            from "oleauto.h".
1636  *
1637  * FIXME
1638  *  - I am unsure if this function should parse non-arabic (e.g. Thai)
1639  *   numerals, so this has not been implemented.
1640  */
1641 HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags,
1642                                   NUMPARSE *pNumprs, BYTE *rgbDig)
1643 {
1644   VARIANT_NUMBER_CHARS chars;
1645   BYTE rgbTmp[1024];
1646   DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS;
1647   int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE);
1648   int cchUsed = 0;
1649
1650   TRACE("(%s,%d,0x%08x,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig);
1651
1652   if (!pNumprs || !rgbDig)
1653     return E_INVALIDARG;
1654
1655   if (pNumprs->cDig < iMaxDigits)
1656     iMaxDigits = pNumprs->cDig;
1657
1658   pNumprs->cDig = 0;
1659   pNumprs->dwOutFlags = 0;
1660   pNumprs->cchUsed = 0;
1661   pNumprs->nBaseShift = 0;
1662   pNumprs->nPwr10 = 0;
1663
1664   if (!lpszStr)
1665     return DISP_E_TYPEMISMATCH;
1666
1667   VARIANT_GetLocalisedNumberChars(&chars, lcid, dwFlags);
1668
1669   /* First consume all the leading symbols and space from the string */
1670   while (1)
1671   {
1672     if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && isspaceW(*lpszStr))
1673     {
1674       pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE;
1675       do
1676       {
1677         cchUsed++;
1678         lpszStr++;
1679       } while (isspaceW(*lpszStr));
1680     }
1681     else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS &&
1682              *lpszStr == chars.cPositiveSymbol &&
1683              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS))
1684     {
1685       pNumprs->dwOutFlags |= NUMPRS_LEADING_PLUS;
1686       cchUsed++;
1687       lpszStr++;
1688     }
1689     else if (pNumprs->dwInFlags & NUMPRS_LEADING_MINUS &&
1690              *lpszStr == chars.cNegativeSymbol &&
1691              !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS))
1692     {
1693       pNumprs->dwOutFlags |= (NUMPRS_LEADING_MINUS|NUMPRS_NEG);
1694       cchUsed++;
1695       lpszStr++;
1696     }
1697     else if (pNumprs->dwInFlags & NUMPRS_CURRENCY &&
1698              !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) &&
1699              *lpszStr == chars.cCurrencyLocal &&
1700              (!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2))
1701     {
1702       pNumprs->dwOutFlags |= NUMPRS_CURRENCY;
1703       cchUsed++;
1704       lpszStr++;
1705       /* Only accept currency characters */
1706       chars.cDecimalPoint = chars.cCurrencyDecimalPoint;
1707       chars.cDigitSeparator = chars.cCurrencyDigitSeparator;
1708     }
1709     else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' &&
1710              !(pNumprs->dwOutFlags & NUMPRS_PARENS))
1711     {
1712       pNumprs->dwOutFlags |= NUMPRS_PARENS;
1713       cchUsed++;
1714       lpszStr++;
1715     }
1716     else
1717       break;
1718   }
1719
1720   if (!(pNumprs->dwOutFlags & NUMPRS_CURRENCY))
1721   {
1722     /* Only accept non-currency characters */
1723     chars.cCurrencyDecimalPoint = chars.cDecimalPoint;
1724     chars.cCurrencyDigitSeparator = chars.cDigitSeparator;
1725   }
1726
1727   if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&
1728     pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1729   {
1730       dwState |= B_PROCESSING_HEX;
1731       pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
1732       cchUsed=cchUsed+2;
1733       lpszStr=lpszStr+2;
1734   }
1735   else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&
1736     pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1737   {
1738       dwState |= B_PROCESSING_OCT;
1739       pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
1740       cchUsed=cchUsed+2;
1741       lpszStr=lpszStr+2;
1742   }
1743
1744   /* Strip Leading zeros */
1745   while (*lpszStr == '0')
1746   {
1747     dwState |= B_LEADING_ZERO;
1748     cchUsed++;
1749     lpszStr++;
1750   }
1751
1752   while (*lpszStr)
1753   {
1754     if (isdigitW(*lpszStr))
1755     {
1756       if (dwState & B_PROCESSING_EXPONENT)
1757       {
1758         int exponentSize = 0;
1759         if (dwState & B_EXPONENT_START)
1760         {
1761           if (!isdigitW(*lpszStr))
1762             break; /* No exponent digits - invalid */
1763           while (*lpszStr == '0')
1764           {
1765             /* Skip leading zero's in the exponent */
1766             cchUsed++;
1767             lpszStr++;
1768           }
1769         }
1770
1771         while (isdigitW(*lpszStr))
1772         {
1773           exponentSize *= 10;
1774           exponentSize += *lpszStr - '0';
1775           cchUsed++;
1776           lpszStr++;
1777         }
1778         if (dwState & B_NEGATIVE_EXPONENT)
1779           exponentSize = -exponentSize;
1780         /* Add the exponent into the powers of 10 */
1781         pNumprs->nPwr10 += exponentSize;
1782         dwState &= ~(B_PROCESSING_EXPONENT|B_EXPONENT_START);
1783         lpszStr--; /* back up to allow processing of next char */
1784       }
1785       else
1786       {
1787         if ((pNumprs->cDig >= iMaxDigits) && !(dwState & B_PROCESSING_HEX)
1788           && !(dwState & B_PROCESSING_OCT))
1789         {
1790           pNumprs->dwOutFlags |= NUMPRS_INEXACT;
1791
1792           if (*lpszStr != '0')
1793             dwState &= ~B_INEXACT_ZEROS; /* Inexact number with non-trailing zeros */
1794
1795           /* This digit can't be represented, but count it in nPwr10 */
1796           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1797             pNumprs->nPwr10--;
1798           else
1799             pNumprs->nPwr10++;
1800         }
1801         else
1802         {
1803           if ((dwState & B_PROCESSING_OCT) && ((*lpszStr == '8') || (*lpszStr == '9'))) {
1804             return DISP_E_TYPEMISMATCH;
1805           }
1806
1807           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
1808             pNumprs->nPwr10--; /* Count decimal points in nPwr10 */
1809
1810           rgbTmp[pNumprs->cDig] = *lpszStr - '0';
1811         }
1812         pNumprs->cDig++;
1813         cchUsed++;
1814       }
1815     }
1816     else if (*lpszStr == chars.cDigitSeparator && pNumprs->dwInFlags & NUMPRS_THOUSANDS)
1817     {
1818       pNumprs->dwOutFlags |= NUMPRS_THOUSANDS;
1819       cchUsed++;
1820     }
1821     else if (*lpszStr == chars.cDecimalPoint &&
1822              pNumprs->dwInFlags & NUMPRS_DECIMAL &&
1823              !(pNumprs->dwOutFlags & (NUMPRS_DECIMAL|NUMPRS_EXPONENT)))
1824     {
1825       pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
1826       cchUsed++;
1827
1828       /* If we have no digits so far, skip leading zeros */
1829       if (!pNumprs->cDig)
1830       {
1831         while (lpszStr[1] == '0')
1832         {
1833           dwState |= B_LEADING_ZERO;
1834           cchUsed++;
1835           lpszStr++;
1836           pNumprs->nPwr10--;
1837         }
1838       }
1839     }
1840     else if (((*lpszStr >= 'a' && *lpszStr <= 'f') ||
1841              (*lpszStr >= 'A' && *lpszStr <= 'F')) &&
1842              dwState & B_PROCESSING_HEX)
1843     {
1844       if (pNumprs->cDig >= iMaxDigits)
1845       {
1846         return DISP_E_OVERFLOW;
1847       }
1848       else
1849       {
1850         if (*lpszStr >= 'a')
1851           rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10;
1852         else
1853           rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10;
1854       }
1855       pNumprs->cDig++;
1856       cchUsed++;
1857     }
1858     else if ((*lpszStr == 'e' || *lpszStr == 'E') &&
1859              pNumprs->dwInFlags & NUMPRS_EXPONENT &&
1860              !(pNumprs->dwOutFlags & NUMPRS_EXPONENT))
1861     {
1862       dwState |= B_PROCESSING_EXPONENT;
1863       pNumprs->dwOutFlags |= NUMPRS_EXPONENT;
1864       cchUsed++;
1865     }
1866     else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cPositiveSymbol)
1867     {
1868       cchUsed++; /* Ignore positive exponent */
1869     }
1870     else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cNegativeSymbol)
1871     {
1872       dwState |= B_NEGATIVE_EXPONENT;
1873       cchUsed++;
1874     }
1875     else
1876       break; /* Stop at an unrecognised character */
1877
1878     lpszStr++;
1879   }
1880
1881   if (!pNumprs->cDig && dwState & B_LEADING_ZERO)
1882   {
1883     /* Ensure a 0 on its own gets stored */
1884     pNumprs->cDig = 1;
1885     rgbTmp[0] = 0;
1886   }
1887
1888   if (pNumprs->dwOutFlags & NUMPRS_EXPONENT && dwState & B_PROCESSING_EXPONENT)
1889   {
1890     pNumprs->cchUsed = cchUsed;
1891     WARN("didn't completely parse exponent\n");
1892     return DISP_E_TYPEMISMATCH; /* Failed to completely parse the exponent */
1893   }
1894
1895   if (pNumprs->dwOutFlags & NUMPRS_INEXACT)
1896   {
1897     if (dwState & B_INEXACT_ZEROS)
1898       pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* All zeros doesn't set NUMPRS_INEXACT */
1899   } else if(pNumprs->dwInFlags & NUMPRS_HEX_OCT)
1900   {
1901     /* copy all of the digits into the output digit buffer */
1902     /* this is exactly what windows does although it also returns */
1903     /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */
1904     memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1905
1906     if (dwState & B_PROCESSING_HEX) {
1907       /* hex numbers have always the same format */
1908       pNumprs->nPwr10=0;
1909       pNumprs->nBaseShift=4;
1910     } else {
1911       if (dwState & B_PROCESSING_OCT) {
1912         /* oct numbers have always the same format */
1913         pNumprs->nPwr10=0;
1914         pNumprs->nBaseShift=3;
1915       } else {
1916         while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1917         {
1918           pNumprs->nPwr10++;
1919           pNumprs->cDig--;
1920         }
1921       }
1922     }
1923   } else
1924   {
1925     /* Remove trailing zeros from the last (whole number or decimal) part */
1926     while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
1927     {
1928       pNumprs->nPwr10++;
1929       pNumprs->cDig--;
1930     }
1931   }
1932
1933   if (pNumprs->cDig <= iMaxDigits)
1934     pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* Ignore stripped zeros for NUMPRS_INEXACT */
1935   else
1936     pNumprs->cDig = iMaxDigits; /* Only return iMaxDigits worth of digits */
1937
1938   /* Copy the digits we processed into rgbDig */
1939   memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
1940
1941   /* Consume any trailing symbols and space */
1942   while (1)
1943   {
1944     if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && isspaceW(*lpszStr))
1945     {
1946       pNumprs->dwOutFlags |= NUMPRS_TRAILING_WHITE;
1947       do
1948       {
1949         cchUsed++;
1950         lpszStr++;
1951       } while (isspaceW(*lpszStr));
1952     }
1953     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS &&
1954              !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) &&
1955              *lpszStr == chars.cPositiveSymbol)
1956     {
1957       pNumprs->dwOutFlags |= NUMPRS_TRAILING_PLUS;
1958       cchUsed++;
1959       lpszStr++;
1960     }
1961     else if (pNumprs->dwInFlags & NUMPRS_TRAILING_MINUS &&
1962              !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS) &&
1963              *lpszStr == chars.cNegativeSymbol)
1964     {
1965       pNumprs->dwOutFlags |= (NUMPRS_TRAILING_MINUS|NUMPRS_NEG);
1966       cchUsed++;
1967       lpszStr++;
1968     }
1969     else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == ')' &&
1970              pNumprs->dwOutFlags & NUMPRS_PARENS)
1971     {
1972       cchUsed++;
1973       lpszStr++;
1974       pNumprs->dwOutFlags |= NUMPRS_NEG;
1975     }
1976     else
1977       break;
1978   }
1979
1980   if (pNumprs->dwOutFlags & NUMPRS_PARENS && !(pNumprs->dwOutFlags & NUMPRS_NEG))
1981   {
1982     pNumprs->cchUsed = cchUsed;
1983     return DISP_E_TYPEMISMATCH; /* Opening parenthesis not matched */
1984   }
1985
1986   if (pNumprs->dwInFlags & NUMPRS_USE_ALL && *lpszStr != '\0')
1987     return DISP_E_TYPEMISMATCH; /* Not all chars were consumed */
1988
1989   if (!pNumprs->cDig)
1990     return DISP_E_TYPEMISMATCH; /* No Number found */
1991
1992   pNumprs->cchUsed = cchUsed;
1993   return S_OK;
1994 }
1995
1996 /* VTBIT flags indicating an integer value */
1997 #define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8)
1998 /* VTBIT flags indicating a real number value */
1999 #define REAL_VTBITS (VTBIT_R4|VTBIT_R8|VTBIT_CY)
2000
2001 /* Helper macros to check whether bit pattern fits in VARIANT (x is a ULONG64 ) */
2002 #define FITS_AS_I1(x) ((x) >> 8 == 0)
2003 #define FITS_AS_I2(x) ((x) >> 16 == 0)
2004 #define FITS_AS_I4(x) ((x) >> 32 == 0)
2005
2006 /**********************************************************************
2007  *              VarNumFromParseNum [OLEAUT32.47]
2008  *
2009  * Convert a NUMPARSE structure into a numeric Variant type.
2010  *
2011  * PARAMS
2012  *  pNumprs  [I] Source for parsed number. cDig must be set to the size of rgbDig
2013  *  rgbDig   [I] Source for the numbers digits
2014  *  dwVtBits [I] VTBIT_ flags from "oleauto.h" indicating the acceptable dest types
2015  *  pVarDst  [O] Destination for the converted Variant value.
2016  *
2017  * RETURNS
2018  *  Success: S_OK. pVarDst contains the converted value.
2019  *  Failure: E_INVALIDARG, if any parameter is invalid.
2020  *           DISP_E_OVERFLOW, if the number is too big for the types set in dwVtBits.
2021  *
2022  * NOTES
2023  *  - The smallest favoured type present in dwVtBits that can represent the
2024  *    number in pNumprs without losing precision is used.
2025  *  - Signed types are preferred over unsigned types of the same size.
2026  *  - Preferred types in order are: integer, float, double, currency then decimal.
2027  *  - Rounding (dropping of decimal points) occurs without error. See VarI8FromR8()
2028  *    for details of the rounding method.
2029  *  - pVarDst is not cleared before the result is stored in it.
2030  *  - WinXP and Win2003 support VTBIT_I8, VTBIT_UI8 but that's buggy (by
2031  *    design?): If some other VTBIT's for integers are specified together
2032  *    with VTBIT_I8 and the number will fit only in a VT_I8 Windows will "cast"
2033  *    the number to the smallest requested integer truncating this way the
2034  *    number.  Wine doesn't implement this "feature" (yet?).
2035  */
2036 HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig,
2037                                   ULONG dwVtBits, VARIANT *pVarDst)
2038 {
2039   /* Scale factors and limits for double arithmetic */
2040   static const double dblMultipliers[11] = {
2041     1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0,
2042     1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0
2043   };
2044   static const double dblMinimums[11] = {
2045     R8_MIN, R8_MIN*10.0, R8_MIN*100.0, R8_MIN*1000.0, R8_MIN*10000.0,
2046     R8_MIN*100000.0, R8_MIN*1000000.0, R8_MIN*10000000.0,
2047     R8_MIN*100000000.0, R8_MIN*1000000000.0, R8_MIN*10000000000.0
2048   };
2049   static const double dblMaximums[11] = {
2050     R8_MAX, R8_MAX/10.0, R8_MAX/100.0, R8_MAX/1000.0, R8_MAX/10000.0,
2051     R8_MAX/100000.0, R8_MAX/1000000.0, R8_MAX/10000000.0,
2052     R8_MAX/100000000.0, R8_MAX/1000000000.0, R8_MAX/10000000000.0
2053   };
2054
2055   int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0;
2056
2057   TRACE("(%p,%p,0x%x,%p)\n", pNumprs, rgbDig, dwVtBits, pVarDst);
2058
2059   if (pNumprs->nBaseShift)
2060   {
2061     /* nBaseShift indicates a hex or octal number */
2062     ULONG64 ul64 = 0;
2063     LONG64 l64;
2064     int i;
2065
2066     /* Convert the hex or octal number string into a UI64 */
2067     for (i = 0; i < pNumprs->cDig; i++)
2068     {
2069       if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i]))
2070       {
2071         TRACE("Overflow multiplying digits\n");
2072         return DISP_E_OVERFLOW;
2073       }
2074       ul64 = (ul64<<pNumprs->nBaseShift) + rgbDig[i];
2075     }
2076
2077     /* also make a negative representation */
2078     l64=-ul64;
2079
2080     /* Try signed and unsigned types in size order */
2081     if (dwVtBits & VTBIT_I1 && FITS_AS_I1(ul64))
2082     {
2083       V_VT(pVarDst) = VT_I1;
2084       V_I1(pVarDst) = ul64;
2085       return S_OK;
2086     }
2087     else if (dwVtBits & VTBIT_UI1 && FITS_AS_I1(ul64))
2088     {
2089       V_VT(pVarDst) = VT_UI1;
2090       V_UI1(pVarDst) = ul64;
2091       return S_OK;
2092     }
2093     else if (dwVtBits & VTBIT_I2 && FITS_AS_I2(ul64))
2094     {
2095       V_VT(pVarDst) = VT_I2;
2096       V_I2(pVarDst) = ul64;
2097       return S_OK;
2098     }
2099     else if (dwVtBits & VTBIT_UI2 && FITS_AS_I2(ul64))
2100     {
2101       V_VT(pVarDst) = VT_UI2;
2102       V_UI2(pVarDst) = ul64;
2103       return S_OK;
2104     }
2105     else if (dwVtBits & VTBIT_I4 && FITS_AS_I4(ul64))
2106     {
2107       V_VT(pVarDst) = VT_I4;
2108       V_I4(pVarDst) = ul64;
2109       return S_OK;
2110     }
2111     else if (dwVtBits & VTBIT_UI4 && FITS_AS_I4(ul64))
2112     {
2113       V_VT(pVarDst) = VT_UI4;
2114       V_UI4(pVarDst) = ul64;
2115       return S_OK;
2116     }
2117     else if (dwVtBits & VTBIT_I8 && ((ul64 <= I8_MAX)||(l64>=I8_MIN)))
2118     {
2119       V_VT(pVarDst) = VT_I8;
2120       V_I8(pVarDst) = ul64;
2121       return S_OK;
2122     }
2123     else if (dwVtBits & VTBIT_UI8)
2124     {
2125       V_VT(pVarDst) = VT_UI8;
2126       V_UI8(pVarDst) = ul64;
2127       return S_OK;
2128     }
2129     else if ((dwVtBits & VTBIT_DECIMAL) == VTBIT_DECIMAL)
2130     {
2131       V_VT(pVarDst) = VT_DECIMAL;
2132       DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
2133       DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2134       DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
2135       return S_OK;
2136     }
2137     else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
2138     {
2139       V_VT(pVarDst) = VT_R4;
2140       if (ul64 <= I4_MAX)
2141           V_R4(pVarDst) = ul64;
2142       else
2143           V_R4(pVarDst) = l64;
2144       return S_OK;
2145     }
2146     else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
2147     {
2148       V_VT(pVarDst) = VT_R8;
2149       if (ul64 <= I4_MAX)
2150           V_R8(pVarDst) = ul64;
2151       else
2152           V_R8(pVarDst) = l64;
2153       return S_OK;
2154     }
2155
2156     TRACE("Overflow: possible return types: 0x%x, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64));
2157     return DISP_E_OVERFLOW;
2158   }
2159
2160   /* Count the number of relevant fractional and whole digits stored,
2161    * And compute the divisor/multiplier to scale the number by.
2162    */
2163   if (pNumprs->nPwr10 < 0)
2164   {
2165     if (-pNumprs->nPwr10 >= pNumprs->cDig)
2166     {
2167       /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */
2168       wholeNumberDigits = 0;
2169       fractionalDigits = pNumprs->cDig;
2170       divisor10 = -pNumprs->nPwr10;
2171     }
2172     else
2173     {
2174       /* An exactly represented real number e.g. 1.024 */
2175       wholeNumberDigits = pNumprs->cDig + pNumprs->nPwr10;
2176       fractionalDigits = pNumprs->cDig - wholeNumberDigits;
2177       divisor10 = pNumprs->cDig - wholeNumberDigits;
2178     }
2179   }
2180   else if (pNumprs->nPwr10 == 0)
2181   {
2182     /* An exactly represented whole number e.g. 1024 */
2183     wholeNumberDigits = pNumprs->cDig;
2184     fractionalDigits = 0;
2185   }
2186   else /* pNumprs->nPwr10 > 0 */
2187   {
2188     /* A whole number followed by nPwr10 0's e.g. 102400 */
2189     wholeNumberDigits = pNumprs->cDig;
2190     fractionalDigits = 0;
2191     multiplier10 = pNumprs->nPwr10;
2192   }
2193
2194   TRACE("cDig %d; nPwr10 %d, whole %d, frac %d mult %d; div %d\n",
2195         pNumprs->cDig, pNumprs->nPwr10, wholeNumberDigits, fractionalDigits,
2196         multiplier10, divisor10);
2197
2198   if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) &&
2199       (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL))))
2200   {
2201     /* We have one or more integer output choices, and either:
2202      *  1) An integer input value, or
2203      *  2) A real number input value but no floating output choices.
2204      * Alternately, we have a DECIMAL output available and an integer input.
2205      *
2206      * So, place the integer value into pVarDst, using the smallest type
2207      * possible and preferring signed over unsigned types.
2208      */
2209     BOOL bOverflow = FALSE, bNegative;
2210     ULONG64 ul64 = 0;
2211     int i;
2212
2213     /* Convert the integer part of the number into a UI8 */
2214     for (i = 0; i < wholeNumberDigits; i++)
2215     {
2216       if (ul64 > (UI8_MAX / 10 - rgbDig[i]))
2217       {
2218         TRACE("Overflow multiplying digits\n");
2219         bOverflow = TRUE;
2220         break;
2221       }
2222       ul64 = ul64 * 10 + rgbDig[i];
2223     }
2224
2225     /* Account for the scale of the number */
2226     if (!bOverflow && multiplier10)
2227     {
2228       for (i = 0; i < multiplier10; i++)
2229       {
2230         if (ul64 > (UI8_MAX / 10))
2231         {
2232           TRACE("Overflow scaling number\n");
2233           bOverflow = TRUE;
2234           break;
2235         }
2236         ul64 = ul64 * 10;
2237       }
2238     }
2239
2240     /* If we have any fractional digits, round the value.
2241      * Note we don't have to do this if divisor10 is < 1,
2242      * because this means the fractional part must be < 0.5
2243      */
2244     if (!bOverflow && fractionalDigits && divisor10 > 0)
2245     {
2246       const BYTE* fracDig = rgbDig + wholeNumberDigits;
2247       BOOL bAdjust = FALSE;
2248
2249       TRACE("first decimal value is %d\n", *fracDig);
2250
2251       if (*fracDig > 5)
2252         bAdjust = TRUE; /* > 0.5 */
2253       else if (*fracDig == 5)
2254       {
2255         for (i = 1; i < fractionalDigits; i++)
2256         {
2257           if (fracDig[i])
2258           {
2259             bAdjust = TRUE; /* > 0.5 */
2260             break;
2261           }
2262         }
2263         /* If exactly 0.5, round only odd values */
2264         if (i == fractionalDigits && (ul64 & 1))
2265           bAdjust = TRUE;
2266       }
2267
2268       if (bAdjust)
2269       {
2270         if (ul64 == UI8_MAX)
2271         {
2272           TRACE("Overflow after rounding\n");
2273           bOverflow = TRUE;
2274         }
2275         ul64++;
2276       }
2277     }
2278
2279     /* Zero is not a negative number */
2280     bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64 ? TRUE : FALSE;
2281
2282     TRACE("Integer value is 0x%s, bNeg %d\n", wine_dbgstr_longlong(ul64), bNegative);
2283
2284     /* For negative integers, try the signed types in size order */
2285     if (!bOverflow && bNegative)
2286     {
2287       if (dwVtBits & (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8))
2288       {
2289         if (dwVtBits & VTBIT_I1 && ul64 <= -I1_MIN)
2290         {
2291           V_VT(pVarDst) = VT_I1;
2292           V_I1(pVarDst) = -ul64;
2293           return S_OK;
2294         }
2295         else if (dwVtBits & VTBIT_I2 && ul64 <= -I2_MIN)
2296         {
2297           V_VT(pVarDst) = VT_I2;
2298           V_I2(pVarDst) = -ul64;
2299           return S_OK;
2300         }
2301         else if (dwVtBits & VTBIT_I4 && ul64 <= -((LONGLONG)I4_MIN))
2302         {
2303           V_VT(pVarDst) = VT_I4;
2304           V_I4(pVarDst) = -ul64;
2305           return S_OK;
2306         }
2307         else if (dwVtBits & VTBIT_I8 && ul64 <= (ULONGLONG)I8_MAX + 1)
2308         {
2309           V_VT(pVarDst) = VT_I8;
2310           V_I8(pVarDst) = -ul64;
2311           return S_OK;
2312         }
2313         else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2314         {
2315           /* Decimal is only output choice left - fast path */
2316           V_VT(pVarDst) = VT_DECIMAL;
2317           DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_NEG,0);
2318           DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2319           DEC_LO64(&V_DECIMAL(pVarDst)) = -ul64;
2320           return S_OK;
2321         }
2322       }
2323     }
2324     else if (!bOverflow)
2325     {
2326       /* For positive integers, try signed then unsigned types in size order */
2327       if (dwVtBits & VTBIT_I1 && ul64 <= I1_MAX)
2328       {
2329         V_VT(pVarDst) = VT_I1;
2330         V_I1(pVarDst) = ul64;
2331         return S_OK;
2332       }
2333       else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX)
2334       {
2335         V_VT(pVarDst) = VT_UI1;
2336         V_UI1(pVarDst) = ul64;
2337         return S_OK;
2338       }
2339       else if (dwVtBits & VTBIT_I2 && ul64 <= I2_MAX)
2340       {
2341         V_VT(pVarDst) = VT_I2;
2342         V_I2(pVarDst) = ul64;
2343         return S_OK;
2344       }
2345       else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX)
2346       {
2347         V_VT(pVarDst) = VT_UI2;
2348         V_UI2(pVarDst) = ul64;
2349         return S_OK;
2350       }
2351       else if (dwVtBits & VTBIT_I4 && ul64 <= I4_MAX)
2352       {
2353         V_VT(pVarDst) = VT_I4;
2354         V_I4(pVarDst) = ul64;
2355         return S_OK;
2356       }
2357       else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX)
2358       {
2359         V_VT(pVarDst) = VT_UI4;
2360         V_UI4(pVarDst) = ul64;
2361         return S_OK;
2362       }
2363       else if (dwVtBits & VTBIT_I8 && ul64 <= I8_MAX)
2364       {
2365         V_VT(pVarDst) = VT_I8;
2366         V_I8(pVarDst) = ul64;
2367         return S_OK;
2368       }
2369       else if (dwVtBits & VTBIT_UI8)
2370       {
2371         V_VT(pVarDst) = VT_UI8;
2372         V_UI8(pVarDst) = ul64;
2373         return S_OK;
2374       }
2375       else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
2376       {
2377         /* Decimal is only output choice left - fast path */
2378         V_VT(pVarDst) = VT_DECIMAL;
2379         DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
2380         DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
2381         DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
2382         return S_OK;
2383       }
2384     }
2385   }
2386
2387   if (dwVtBits & REAL_VTBITS)
2388   {
2389     /* Try to put the number into a float or real */
2390     BOOL bOverflow = FALSE, bNegative = pNumprs->dwOutFlags & NUMPRS_NEG;
2391     double whole = 0.0;
2392     int i;
2393
2394     /* Convert the number into a double */
2395     for (i = 0; i < pNumprs->cDig; i++)
2396       whole = whole * 10.0 + rgbDig[i];
2397
2398     TRACE("Whole double value is %16.16g\n", whole);
2399
2400     /* Account for the scale */
2401     while (multiplier10 > 10)
2402     {
2403       if (whole > dblMaximums[10])
2404       {
2405         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2406         bOverflow = TRUE;
2407         break;
2408       }
2409       whole = whole * dblMultipliers[10];
2410       multiplier10 -= 10;
2411     }
2412     if (multiplier10 && !bOverflow)
2413     {
2414       if (whole > dblMaximums[multiplier10])
2415       {
2416         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY);
2417         bOverflow = TRUE;
2418       }
2419       else
2420         whole = whole * dblMultipliers[multiplier10];
2421     }
2422
2423     if (!bOverflow)
2424         TRACE("Scaled double value is %16.16g\n", whole);
2425
2426     while (divisor10 > 10 && !bOverflow)
2427     {
2428       if (whole < dblMinimums[10] && whole != 0)
2429       {
2430         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
2431         bOverflow = TRUE;
2432         break;
2433       }
2434       whole = whole / dblMultipliers[10];
2435       divisor10 -= 10;
2436     }
2437     if (divisor10 && !bOverflow)
2438     {
2439       if (whole < dblMinimums[divisor10] && whole != 0)
2440       {
2441         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
2442         bOverflow = TRUE;
2443       }
2444       else
2445         whole = whole / dblMultipliers[divisor10];
2446     }
2447     if (!bOverflow)
2448       TRACE("Final double value is %16.16g\n", whole);
2449
2450     if (dwVtBits & VTBIT_R4 &&
2451         ((whole <= R4_MAX && whole >= R4_MIN) || whole == 0.0))
2452     {
2453       TRACE("Set R4 to final value\n");
2454       V_VT(pVarDst) = VT_R4; /* Fits into a float */
2455       V_R4(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2456       return S_OK;
2457     }
2458
2459     if (dwVtBits & VTBIT_R8)
2460     {
2461       TRACE("Set R8 to final value\n");
2462       V_VT(pVarDst) = VT_R8; /* Fits into a double */
2463       V_R8(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole;
2464       return S_OK;
2465     }
2466
2467     if (dwVtBits & VTBIT_CY)
2468     {
2469       if (SUCCEEDED(VarCyFromR8(bNegative ? -whole : whole, &V_CY(pVarDst))))
2470       {
2471         V_VT(pVarDst) = VT_CY; /* Fits into a currency */
2472         TRACE("Set CY to final value\n");
2473         return S_OK;
2474       }
2475       TRACE("Value Overflows CY\n");
2476     }
2477   }
2478
2479   if (dwVtBits & VTBIT_DECIMAL)
2480   {
2481     int i;
2482     ULONG carry;
2483     ULONG64 tmp;
2484     DECIMAL* pDec = &V_DECIMAL(pVarDst);
2485
2486     DECIMAL_SETZERO(*pDec);
2487     DEC_LO32(pDec) = 0;
2488
2489     if (pNumprs->dwOutFlags & NUMPRS_NEG)
2490       DEC_SIGN(pDec) = DECIMAL_NEG;
2491     else
2492       DEC_SIGN(pDec) = DECIMAL_POS;
2493
2494     /* Factor the significant digits */
2495     for (i = 0; i < pNumprs->cDig; i++)
2496     {
2497       tmp = (ULONG64)DEC_LO32(pDec) * 10 + rgbDig[i];
2498       carry = (ULONG)(tmp >> 32);
2499       DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
2500       tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
2501       carry = (ULONG)(tmp >> 32);
2502       DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
2503       tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
2504       DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
2505
2506       if (tmp >> 32 & UI4_MAX)
2507       {
2508 VarNumFromParseNum_DecOverflow:
2509         TRACE("Overflow\n");
2510         DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX;
2511         return DISP_E_OVERFLOW;
2512       }
2513     }
2514
2515     /* Account for the scale of the number */
2516     while (multiplier10 > 0)
2517     {
2518       tmp = (ULONG64)DEC_LO32(pDec) * 10;
2519       carry = (ULONG)(tmp >> 32);
2520       DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX);
2521       tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry;
2522       carry = (ULONG)(tmp >> 32);
2523       DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX);
2524       tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry;
2525       DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX);
2526
2527       if (tmp >> 32 & UI4_MAX)
2528         goto VarNumFromParseNum_DecOverflow;
2529       multiplier10--;
2530     }
2531     DEC_SCALE(pDec) = divisor10;
2532
2533     V_VT(pVarDst) = VT_DECIMAL;
2534     return S_OK;
2535   }
2536   return DISP_E_OVERFLOW; /* No more output choices */
2537 }
2538
2539 /**********************************************************************
2540  *              VarCat [OLEAUT32.318]
2541  *
2542  * Concatenates one variant onto another.
2543  *
2544  * PARAMS
2545  *  left    [I] First variant
2546  *  right   [I] Second variant
2547  *  result  [O] Result variant
2548  *
2549  * RETURNS
2550  *  Success: S_OK.
2551  *  Failure: An HRESULT error code indicating the error.
2552  */
2553 HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
2554 {
2555     VARTYPE leftvt,rightvt,resultvt;
2556     HRESULT hres;
2557     static WCHAR str_true[32];
2558     static WCHAR str_false[32];
2559     static const WCHAR sz_empty[] = {'\0'};
2560     leftvt = V_VT(left);
2561     rightvt = V_VT(right);
2562
2563     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
2564           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), out);
2565
2566     if (!str_true[0]) {
2567         VARIANT_GetLocalisedText(LOCALE_USER_DEFAULT, IDS_FALSE, str_false);
2568         VARIANT_GetLocalisedText(LOCALE_USER_DEFAULT, IDS_TRUE, str_true);
2569     }
2570
2571     /* when both left and right are NULL the result is NULL */
2572     if (leftvt == VT_NULL && rightvt == VT_NULL)
2573     {
2574         V_VT(out) = VT_NULL;
2575         return S_OK;
2576     }
2577
2578     hres = S_OK;
2579     resultvt = VT_EMPTY;
2580
2581     /* There are many special case for errors and return types */
2582     if (leftvt == VT_VARIANT && (rightvt == VT_ERROR ||
2583         rightvt == VT_DATE || rightvt == VT_DECIMAL))
2584         hres = DISP_E_TYPEMISMATCH;
2585     else if ((leftvt == VT_I2 || leftvt == VT_I4 ||
2586         leftvt == VT_R4 || leftvt == VT_R8 ||
2587         leftvt == VT_CY || leftvt == VT_BOOL ||
2588         leftvt == VT_BSTR || leftvt == VT_I1 ||
2589         leftvt == VT_UI1 || leftvt == VT_UI2 ||
2590         leftvt == VT_UI4 || leftvt == VT_I8 ||
2591         leftvt == VT_UI8 || leftvt == VT_INT ||
2592         leftvt == VT_UINT || leftvt == VT_EMPTY ||
2593         leftvt == VT_NULL || leftvt == VT_DATE ||
2594         leftvt == VT_DECIMAL || leftvt == VT_DISPATCH)
2595         &&
2596         (rightvt == VT_I2 || rightvt == VT_I4 ||
2597         rightvt == VT_R4 || rightvt == VT_R8 ||
2598         rightvt == VT_CY || rightvt == VT_BOOL ||
2599         rightvt == VT_BSTR || rightvt == VT_I1 ||
2600         rightvt == VT_UI1 || rightvt == VT_UI2 ||
2601         rightvt == VT_UI4 || rightvt == VT_I8 ||
2602         rightvt == VT_UI8 || rightvt == VT_INT ||
2603         rightvt == VT_UINT || rightvt == VT_EMPTY ||
2604         rightvt == VT_NULL || rightvt == VT_DATE ||
2605         rightvt == VT_DECIMAL || rightvt == VT_DISPATCH))
2606         resultvt = VT_BSTR;
2607     else if (rightvt == VT_ERROR && leftvt < VT_VOID)
2608         hres = DISP_E_TYPEMISMATCH;
2609     else if (leftvt == VT_ERROR && (rightvt == VT_DATE ||
2610         rightvt == VT_ERROR || rightvt == VT_DECIMAL))
2611         hres = DISP_E_TYPEMISMATCH;
2612     else if (rightvt == VT_DATE || rightvt == VT_ERROR ||
2613         rightvt == VT_DECIMAL)
2614         hres = DISP_E_BADVARTYPE;
2615     else if (leftvt == VT_ERROR || rightvt == VT_ERROR)
2616         hres = DISP_E_TYPEMISMATCH;
2617     else if (leftvt == VT_VARIANT)
2618         hres = DISP_E_TYPEMISMATCH;
2619     else if (rightvt == VT_VARIANT && (leftvt == VT_EMPTY ||
2620         leftvt == VT_NULL || leftvt ==  VT_I2 ||
2621         leftvt == VT_I4 || leftvt == VT_R4 ||
2622         leftvt == VT_R8 || leftvt == VT_CY ||
2623         leftvt == VT_DATE || leftvt == VT_BSTR ||
2624         leftvt == VT_BOOL ||  leftvt == VT_DECIMAL ||
2625         leftvt == VT_I1 || leftvt == VT_UI1 ||
2626         leftvt == VT_UI2 || leftvt == VT_UI4 ||
2627         leftvt == VT_I8 || leftvt == VT_UI8 ||
2628         leftvt == VT_INT || leftvt == VT_UINT))
2629         hres = DISP_E_TYPEMISMATCH;
2630     else
2631         hres = DISP_E_BADVARTYPE;
2632
2633     /* if result type is not S_OK, then no need to go further */
2634     if (hres != S_OK)
2635     {
2636         V_VT(out) = resultvt;
2637         return hres;
2638     }
2639     /* Else proceed with formatting inputs to strings */
2640     else
2641     {
2642         VARIANT bstrvar_left, bstrvar_right;
2643         V_VT(out) = VT_BSTR;
2644
2645         VariantInit(&bstrvar_left);
2646         VariantInit(&bstrvar_right);
2647
2648         /* Convert left side variant to string */
2649         if (leftvt != VT_BSTR)
2650         {
2651             if (leftvt == VT_BOOL)
2652             {
2653                 /* Bools are handled as localized True/False strings instead of 0/-1 as in MSDN */
2654                 V_VT(&bstrvar_left) = VT_BSTR;
2655                 if (V_BOOL(left) == TRUE)
2656                     V_BSTR(&bstrvar_left) = SysAllocString(str_true);
2657                 else
2658                     V_BSTR(&bstrvar_left) = SysAllocString(str_false);
2659             }
2660             /* Fill with empty string for later concat with right side */
2661             else if (leftvt == VT_NULL)
2662             {
2663                 V_VT(&bstrvar_left) = VT_BSTR;
2664                 V_BSTR(&bstrvar_left) = SysAllocString(sz_empty);
2665             }
2666             else
2667             {
2668                 hres = VariantChangeTypeEx(&bstrvar_left,left,0,0,VT_BSTR);
2669                 if (hres != S_OK) {
2670                     VariantClear(&bstrvar_left);
2671                     VariantClear(&bstrvar_right);
2672                     if (leftvt == VT_NULL && (rightvt == VT_EMPTY ||
2673                         rightvt == VT_NULL || rightvt ==  VT_I2 ||
2674                         rightvt == VT_I4 || rightvt == VT_R4 ||
2675                         rightvt == VT_R8 || rightvt == VT_CY ||
2676                         rightvt == VT_DATE || rightvt == VT_BSTR ||
2677                         rightvt == VT_BOOL ||  rightvt == VT_DECIMAL ||
2678                         rightvt == VT_I1 || rightvt == VT_UI1 ||
2679                         rightvt == VT_UI2 || rightvt == VT_UI4 ||
2680                         rightvt == VT_I8 || rightvt == VT_UI8 ||
2681                         rightvt == VT_INT || rightvt == VT_UINT))
2682                         return DISP_E_BADVARTYPE;
2683                     return hres;
2684                 }
2685             }
2686         }
2687
2688         /* convert right side variant to string */
2689         if (rightvt != VT_BSTR)
2690         {
2691             if (rightvt == VT_BOOL)
2692             {
2693                 /* Bools are handled as localized True/False strings instead of 0/-1 as in MSDN */
2694                 V_VT(&bstrvar_right) = VT_BSTR;
2695                 if (V_BOOL(right) == TRUE)
2696                     V_BSTR(&bstrvar_right) = SysAllocString(str_true);
2697                 else
2698                     V_BSTR(&bstrvar_right) = SysAllocString(str_false);
2699             }
2700             /* Fill with empty string for later concat with right side */
2701             else if (rightvt == VT_NULL)
2702             {
2703                 V_VT(&bstrvar_right) = VT_BSTR;
2704                 V_BSTR(&bstrvar_right) = SysAllocString(sz_empty);
2705             }
2706             else
2707             {
2708                 hres = VariantChangeTypeEx(&bstrvar_right,right,0,0,VT_BSTR);
2709                 if (hres != S_OK) {
2710                     VariantClear(&bstrvar_left);
2711                     VariantClear(&bstrvar_right);
2712                     if (rightvt == VT_NULL && (leftvt == VT_EMPTY ||
2713                         leftvt == VT_NULL || leftvt ==  VT_I2 ||
2714                         leftvt == VT_I4 || leftvt == VT_R4 ||
2715                         leftvt == VT_R8 || leftvt == VT_CY ||
2716                         leftvt == VT_DATE || leftvt == VT_BSTR ||
2717                         leftvt == VT_BOOL ||  leftvt == VT_DECIMAL ||
2718                         leftvt == VT_I1 || leftvt == VT_UI1 ||
2719                         leftvt == VT_UI2 || leftvt == VT_UI4 ||
2720                         leftvt == VT_I8 || leftvt == VT_UI8 ||
2721                         leftvt == VT_INT || leftvt == VT_UINT))
2722                         return DISP_E_BADVARTYPE;
2723                     return hres;
2724                 }
2725             }
2726         }
2727
2728         /* Concat the resulting strings together */
2729         if (leftvt == VT_BSTR && rightvt == VT_BSTR)
2730             VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
2731         else if (leftvt != VT_BSTR && rightvt != VT_BSTR)
2732             VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(&bstrvar_right), &V_BSTR(out));
2733         else if (leftvt != VT_BSTR && rightvt == VT_BSTR)
2734             VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(right), &V_BSTR(out));
2735         else if (leftvt == VT_BSTR && rightvt != VT_BSTR)
2736             VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar_right), &V_BSTR(out));
2737
2738         VariantClear(&bstrvar_left);
2739         VariantClear(&bstrvar_right);
2740         return S_OK;
2741     }
2742 }
2743
2744
2745 /* Wrapper around VariantChangeTypeEx() which permits changing a
2746    variant with VT_RESERVED flag set. Needed by VarCmp. */
2747 static HRESULT _VarChangeTypeExWrap (VARIANTARG* pvargDest,
2748                     VARIANTARG* pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
2749 {
2750     HRESULT res;
2751     VARTYPE flags;
2752
2753     flags = V_VT(pvargSrc) & ~VT_TYPEMASK;
2754     V_VT(pvargSrc) &= ~VT_RESERVED;
2755     res = VariantChangeTypeEx(pvargDest,pvargSrc,lcid,wFlags,vt);
2756     V_VT(pvargSrc) |= flags;
2757
2758     return res;
2759 }
2760
2761 /**********************************************************************
2762  *              VarCmp [OLEAUT32.176]
2763  *
2764  * Compare two variants.
2765  *
2766  * PARAMS
2767  *  left    [I] First variant
2768  *  right   [I] Second variant
2769  *  lcid    [I] LCID (locale identifier) for the comparison
2770  *  flags   [I] Flags to be used in the comparison:
2771  *              NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS,
2772  *              NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
2773  *
2774  * RETURNS
2775  *  VARCMP_LT:   left variant is less than right variant.
2776  *  VARCMP_EQ:   input variants are equal.
2777  *  VARCMP_GT:   left variant is greater than right variant.
2778  *  VARCMP_NULL: either one of the input variants is NULL.
2779  *  Failure:     An HRESULT error code indicating the error.
2780  *
2781  * NOTES
2782  *  Native VarCmp up to and including WinXP doesn't like I1, UI2, VT_UI4,
2783  *  UI8 and UINT as input variants. INT is accepted only as left variant.
2784  *
2785  *  If both input variants are ERROR then VARCMP_EQ will be returned, else
2786  *  an ERROR variant will trigger an error.
2787  *
2788  *  Both input variants can have VT_RESERVED flag set which is ignored
2789  *  unless one and only one of the variants is a BSTR and the other one
2790  *  is not an EMPTY variant. All four VT_RESERVED combinations have a
2791  *  different meaning:
2792  *   - BSTR and other: BSTR is always greater than the other variant.
2793  *   - BSTR|VT_RESERVED and other: a string comparison is performed.
2794  *   - BSTR and other|VT_RESERVED: If the BSTR is a number a numeric
2795  *     comparison will take place else the BSTR is always greater.
2796  *   - BSTR|VT_RESERVED and other|VT_RESERVED: It seems that the other
2797  *     variant is ignored and the return value depends only on the sign
2798  *     of the BSTR if it is a number else the BSTR is always greater. A
2799  *     positive BSTR is greater, a negative one is smaller than the other
2800  *     variant.
2801  *
2802  * SEE
2803  *  VarBstrCmp for the lcid and flags usage.
2804  */
2805 HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
2806 {
2807     VARTYPE     lvt, rvt, vt;
2808     VARIANT     rv,lv;
2809     DWORD       xmask;
2810     HRESULT     rc;
2811
2812     TRACE("(%p->(%s%s),%p->(%s%s),0x%08x,0x%08x)\n", left, debugstr_VT(left),
2813           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags);
2814
2815     lvt = V_VT(left) & VT_TYPEMASK;
2816     rvt = V_VT(right) & VT_TYPEMASK;
2817     xmask = (1 << lvt) | (1 << rvt);
2818
2819     /* If we have any flag set except VT_RESERVED bail out.
2820        Same for the left input variant type > VT_INT and for the
2821        right input variant type > VT_I8. Yes, VT_INT is only supported
2822        as left variant. Go figure */
2823     if (((V_VT(left) | V_VT(right)) & ~VT_TYPEMASK & ~VT_RESERVED) ||
2824             lvt > VT_INT || rvt > VT_I8) {
2825         return DISP_E_BADVARTYPE;
2826     }
2827
2828     /* Don't ask me why but native VarCmp cannot handle: VT_I1, VT_UI2, VT_UI4,
2829        VT_UINT and VT_UI8. Tested with DCOM98, Win2k, WinXP */
2830     if (rvt == VT_INT || xmask & (VTBIT_I1 | VTBIT_UI2 | VTBIT_UI4 | VTBIT_UI8 |
2831                 VTBIT_DISPATCH | VTBIT_VARIANT | VTBIT_UNKNOWN | VTBIT_15))
2832         return DISP_E_TYPEMISMATCH;
2833
2834     /* If both variants are VT_ERROR return VARCMP_EQ */
2835     if (xmask == VTBIT_ERROR)
2836         return VARCMP_EQ;
2837     else if (xmask & VTBIT_ERROR)
2838         return DISP_E_TYPEMISMATCH;
2839
2840     if (xmask & VTBIT_NULL)
2841         return VARCMP_NULL;
2842
2843     VariantInit(&lv);
2844     VariantInit(&rv);
2845
2846     /* Two BSTRs, ignore VT_RESERVED */
2847     if (xmask == VTBIT_BSTR)
2848         return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags);
2849
2850     /* A BSTR and an other variant; we have to take care of VT_RESERVED */
2851     if (xmask & VTBIT_BSTR) {
2852         VARIANT *bstrv, *nonbv;
2853         VARTYPE nonbvt;
2854         int swap = 0;
2855
2856         /* Swap the variants so the BSTR is always on the left */
2857         if (lvt == VT_BSTR) {
2858             bstrv = left;
2859             nonbv = right;
2860             nonbvt = rvt;
2861         } else {
2862             swap = 1;
2863             bstrv = right;
2864             nonbv = left;
2865             nonbvt = lvt;
2866         }
2867
2868         /* BSTR and EMPTY: ignore VT_RESERVED */
2869         if (nonbvt == VT_EMPTY)
2870             rc = (!V_BSTR(bstrv) || !*V_BSTR(bstrv)) ? VARCMP_EQ : VARCMP_GT;
2871         else {
2872             VARTYPE breserv = V_VT(bstrv) & ~VT_TYPEMASK;
2873             VARTYPE nreserv = V_VT(nonbv) & ~VT_TYPEMASK;
2874
2875             if (!breserv && !nreserv) 
2876                 /* No VT_RESERVED set ==> BSTR always greater */
2877                 rc = VARCMP_GT;
2878             else if (breserv && !nreserv) {
2879                 /* BSTR has VT_RESERVED set. Do a string comparison */
2880                 rc = VariantChangeTypeEx(&rv,nonbv,lcid,0,VT_BSTR);
2881                 if (FAILED(rc))
2882                     return rc;
2883                 rc = VarBstrCmp(V_BSTR(bstrv), V_BSTR(&rv), lcid, flags);
2884                 VariantClear(&rv);
2885             } else if (V_BSTR(bstrv) && *V_BSTR(bstrv)) {
2886             /* Non NULL nor empty BSTR */
2887                 /* If the BSTR is not a number the BSTR is greater */
2888                 rc = _VarChangeTypeExWrap(&lv,bstrv,lcid,0,VT_R8);
2889                 if (FAILED(rc))
2890                     rc = VARCMP_GT;
2891                 else if (breserv && nreserv)
2892                     /* FIXME: This is strange: with both VT_RESERVED set it
2893                        looks like the result depends only on the sign of
2894                        the BSTR number */
2895                     rc = (V_R8(&lv) >= 0) ? VARCMP_GT : VARCMP_LT;
2896                 else
2897                     /* Numeric comparison, will be handled below.
2898                        VARCMP_NULL used only to break out. */
2899                     rc = VARCMP_NULL;
2900                 VariantClear(&lv);
2901                 VariantClear(&rv);
2902             } else
2903                 /* Empty or NULL BSTR */
2904                 rc = VARCMP_GT;
2905         }
2906         /* Fixup the return code if we swapped left and right */
2907         if (swap) {
2908             if (rc == VARCMP_GT)
2909                 rc = VARCMP_LT;
2910             else if (rc == VARCMP_LT)
2911                 rc = VARCMP_GT;
2912         }
2913         if (rc != VARCMP_NULL)
2914             return rc;
2915     }
2916
2917     if (xmask & VTBIT_DECIMAL)
2918         vt = VT_DECIMAL;
2919     else if (xmask & VTBIT_BSTR)
2920         vt = VT_R8;
2921     else if (xmask & VTBIT_R4)
2922         vt = VT_R4;
2923     else if (xmask & (VTBIT_R8 | VTBIT_DATE))
2924         vt = VT_R8;
2925     else if (xmask & VTBIT_CY)
2926         vt = VT_CY;
2927     else
2928         /* default to I8 */
2929         vt = VT_I8;
2930
2931     /* Coerce the variants */
2932     rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
2933     if (rc == DISP_E_OVERFLOW && vt != VT_R8) {
2934         /* Overflow, change to R8 */
2935         vt = VT_R8;
2936         rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
2937     }
2938     if (FAILED(rc))
2939         return rc;
2940     rc = _VarChangeTypeExWrap(&rv,right,lcid,0,vt);
2941     if (rc == DISP_E_OVERFLOW && vt != VT_R8) {
2942         /* Overflow, change to R8 */
2943         vt = VT_R8;
2944         rc = _VarChangeTypeExWrap(&lv,left,lcid,0,vt);
2945         if (FAILED(rc))
2946             return rc;
2947         rc = _VarChangeTypeExWrap(&rv,right,lcid,0,vt);
2948     }
2949     if (FAILED(rc))
2950         return rc;
2951
2952 #define _VARCMP(a,b) \
2953     (((a) == (b)) ? VARCMP_EQ : (((a) < (b)) ? VARCMP_LT : VARCMP_GT))
2954
2955     switch (vt) {
2956         case VT_CY:
2957             return VarCyCmp(V_CY(&lv), V_CY(&rv));
2958         case VT_DECIMAL:
2959             return VarDecCmp(&V_DECIMAL(&lv), &V_DECIMAL(&rv));
2960         case VT_I8:
2961             return _VARCMP(V_I8(&lv), V_I8(&rv));
2962         case VT_R4:
2963             return _VARCMP(V_R4(&lv), V_R4(&rv));
2964         case VT_R8:
2965             return _VARCMP(V_R8(&lv), V_R8(&rv));
2966         default:
2967             /* We should never get here */
2968             return E_FAIL;
2969     }
2970 #undef _VARCMP
2971 }
2972
2973 static HRESULT VARIANT_FetchDispatchValue(LPVARIANT pvDispatch, LPVARIANT pValue)
2974 {
2975     HRESULT hres;
2976     static DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
2977
2978     if ((V_VT(pvDispatch) & VT_TYPEMASK) == VT_DISPATCH) {
2979         if (NULL == V_DISPATCH(pvDispatch)) return DISP_E_TYPEMISMATCH;
2980         hres = IDispatch_Invoke(V_DISPATCH(pvDispatch), DISPID_VALUE, &IID_NULL,
2981             LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &emptyParams, pValue,
2982             NULL, NULL);
2983     } else {
2984         hres = DISP_E_TYPEMISMATCH;
2985     }
2986     return hres;
2987 }
2988
2989 /**********************************************************************
2990  *              VarAnd [OLEAUT32.142]
2991  *
2992  * Computes the logical AND of two variants.
2993  *
2994  * PARAMS
2995  *  left    [I] First variant
2996  *  right   [I] Second variant
2997  *  result  [O] Result variant
2998  *
2999  * RETURNS
3000  *  Success: S_OK.
3001  *  Failure: An HRESULT error code indicating the error.
3002  */
3003 HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3004 {
3005     HRESULT hres = S_OK;
3006     VARTYPE resvt = VT_EMPTY;
3007     VARTYPE leftvt,rightvt;
3008     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
3009     VARIANT varLeft, varRight;
3010     VARIANT tempLeft, tempRight;
3011
3012     VariantInit(&varLeft);
3013     VariantInit(&varRight);
3014     VariantInit(&tempLeft);
3015     VariantInit(&tempRight);
3016
3017     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3018           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
3019
3020     /* Handle VT_DISPATCH by storing and taking address of returned value */
3021     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3022     {
3023         hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3024         if (FAILED(hres)) goto VarAnd_Exit;
3025         left = &tempLeft;
3026     }
3027     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3028     {
3029         hres = VARIANT_FetchDispatchValue(right, &tempRight);
3030         if (FAILED(hres)) goto VarAnd_Exit;
3031         right = &tempRight;
3032     }
3033
3034     leftvt = V_VT(left)&VT_TYPEMASK;
3035     rightvt = V_VT(right)&VT_TYPEMASK;
3036     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
3037     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
3038
3039     if (leftExtraFlags != rightExtraFlags)
3040     {
3041         hres = DISP_E_BADVARTYPE;
3042         goto VarAnd_Exit;
3043     }
3044     ExtraFlags = leftExtraFlags;
3045
3046     /* Native VarAnd always returns an error when using extra
3047      * flags or if the variant combination is I8 and INT.
3048      */
3049     if ((leftvt == VT_I8 && rightvt == VT_INT) ||
3050         (leftvt == VT_INT && rightvt == VT_I8) ||
3051         ExtraFlags != 0)
3052     {
3053         hres = DISP_E_BADVARTYPE;
3054         goto VarAnd_Exit;
3055     }
3056
3057     /* Determine return type */
3058     else if (leftvt == VT_I8 || rightvt == VT_I8)
3059         resvt = VT_I8;
3060     else if (leftvt == VT_I4 || rightvt == VT_I4 ||
3061         leftvt == VT_UINT || rightvt == VT_UINT ||
3062         leftvt == VT_INT || rightvt == VT_INT ||
3063         leftvt == VT_UINT || rightvt == VT_UINT ||
3064         leftvt == VT_R4 || rightvt == VT_R4 ||
3065         leftvt == VT_R8 || rightvt == VT_R8 ||
3066         leftvt == VT_CY || rightvt == VT_CY ||
3067         leftvt == VT_DATE || rightvt == VT_DATE ||
3068         leftvt == VT_I1 || rightvt == VT_I1 ||
3069         leftvt == VT_UI2 || rightvt == VT_UI2 ||
3070         leftvt == VT_UI4 || rightvt == VT_UI4 ||
3071         leftvt == VT_UI8 || rightvt == VT_UI8 ||
3072         leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3073         resvt = VT_I4;
3074     else if (leftvt == VT_UI1 || rightvt == VT_UI1 ||
3075         leftvt == VT_I2 || rightvt == VT_I2 ||
3076         leftvt == VT_EMPTY || rightvt == VT_EMPTY)
3077         if ((leftvt == VT_NULL && rightvt == VT_UI1) ||
3078             (leftvt == VT_UI1 && rightvt == VT_NULL) ||
3079             (leftvt == VT_UI1 && rightvt == VT_UI1))
3080             resvt = VT_UI1;
3081         else
3082             resvt = VT_I2;
3083     else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
3084         (leftvt == VT_BSTR && rightvt == VT_BSTR))
3085         resvt = VT_BOOL;
3086     else if (leftvt == VT_NULL || rightvt == VT_NULL ||
3087         leftvt == VT_BSTR || rightvt == VT_BSTR)
3088         resvt = VT_NULL;
3089     else
3090     {
3091         hres = DISP_E_BADVARTYPE;
3092         goto VarAnd_Exit;
3093     }
3094
3095     if (leftvt == VT_NULL || rightvt == VT_NULL)
3096     {
3097         /*
3098          * Special cases for when left variant is VT_NULL
3099          * (VT_NULL & 0 = VT_NULL, VT_NULL & value = value)
3100          */
3101         if (leftvt == VT_NULL)
3102         {
3103             VARIANT_BOOL b;
3104             switch(rightvt)
3105             {
3106             case VT_I1:   if (V_I1(right)) resvt = VT_NULL; break;
3107             case VT_UI1:  if (V_UI1(right)) resvt = VT_NULL; break;
3108             case VT_I2:   if (V_I2(right)) resvt = VT_NULL; break;
3109             case VT_UI2:  if (V_UI2(right)) resvt = VT_NULL; break;
3110             case VT_I4:   if (V_I4(right)) resvt = VT_NULL; break;
3111             case VT_UI4:  if (V_UI4(right)) resvt = VT_NULL; break;
3112             case VT_I8:   if (V_I8(right)) resvt = VT_NULL; break;
3113             case VT_UI8:  if (V_UI8(right)) resvt = VT_NULL; break;
3114             case VT_INT:  if (V_INT(right)) resvt = VT_NULL; break;
3115             case VT_UINT: if (V_UINT(right)) resvt = VT_NULL; break;
3116             case VT_BOOL: if (V_BOOL(right)) resvt = VT_NULL; break;
3117             case VT_R4:   if (V_R4(right)) resvt = VT_NULL; break;
3118             case VT_R8:   if (V_R8(right)) resvt = VT_NULL; break;
3119             case VT_CY:
3120                 if(V_CY(right).int64)
3121                     resvt = VT_NULL;
3122                 break;
3123             case VT_DECIMAL:
3124                 if (DEC_HI32(&V_DECIMAL(right)) ||
3125                     DEC_LO64(&V_DECIMAL(right)))
3126                     resvt = VT_NULL;
3127                 break;
3128             case VT_BSTR:
3129                 hres = VarBoolFromStr(V_BSTR(right),
3130                 LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
3131                 if (FAILED(hres))
3132                     return hres;
3133                 else if (b)
3134                     V_VT(result) = VT_NULL;
3135                 else
3136                 {
3137                     V_VT(result) = VT_BOOL;
3138                     V_BOOL(result) = b;
3139                 }
3140                 goto VarAnd_Exit;
3141             }
3142         }
3143         V_VT(result) = resvt;
3144         goto VarAnd_Exit;
3145     }
3146
3147     hres = VariantCopy(&varLeft, left);
3148     if (FAILED(hres)) goto VarAnd_Exit;
3149
3150     hres = VariantCopy(&varRight, right);
3151     if (FAILED(hres)) goto VarAnd_Exit;
3152
3153     if (resvt == VT_I4 && V_VT(&varLeft) == VT_UI4)
3154         V_VT(&varLeft) = VT_I4; /* Don't overflow */
3155     else
3156     {
3157         double d;
3158
3159         if (V_VT(&varLeft) == VT_BSTR &&
3160             FAILED(VarR8FromStr(V_BSTR(&varLeft),
3161             LOCALE_USER_DEFAULT, 0, &d)))
3162             hres = VariantChangeType(&varLeft,&varLeft,
3163             VARIANT_LOCALBOOL, VT_BOOL);
3164             if (SUCCEEDED(hres) && V_VT(&varLeft) != resvt)
3165                 hres = VariantChangeType(&varLeft,&varLeft,0,resvt);
3166             if (FAILED(hres)) goto VarAnd_Exit;
3167     }
3168
3169     if (resvt == VT_I4 && V_VT(&varRight) == VT_UI4)
3170         V_VT(&varRight) = VT_I4; /* Don't overflow */
3171     else
3172     {
3173         double d;
3174
3175         if (V_VT(&varRight) == VT_BSTR &&
3176             FAILED(VarR8FromStr(V_BSTR(&varRight),
3177             LOCALE_USER_DEFAULT, 0, &d)))
3178             hres = VariantChangeType(&varRight, &varRight,
3179                 VARIANT_LOCALBOOL, VT_BOOL);
3180         if (SUCCEEDED(hres) && V_VT(&varRight) != resvt)
3181             hres = VariantChangeType(&varRight, &varRight, 0, resvt);
3182         if (FAILED(hres)) goto VarAnd_Exit;
3183     }
3184
3185     V_VT(result) = resvt;
3186     switch(resvt)
3187     {
3188     case VT_I8:
3189         V_I8(result) = V_I8(&varLeft) & V_I8(&varRight);
3190         break;
3191     case VT_I4:
3192         V_I4(result) = V_I4(&varLeft) & V_I4(&varRight);
3193         break;
3194     case VT_I2:
3195         V_I2(result) = V_I2(&varLeft) & V_I2(&varRight);
3196         break;
3197     case VT_UI1:
3198         V_UI1(result) = V_UI1(&varLeft) & V_UI1(&varRight);
3199         break;
3200     case VT_BOOL:
3201         V_BOOL(result) = V_BOOL(&varLeft) & V_BOOL(&varRight);
3202         break;
3203     default:
3204         FIXME("Couldn't bitwise AND variant types %d,%d\n",
3205             leftvt,rightvt);
3206     }
3207
3208 VarAnd_Exit:
3209     VariantClear(&varLeft);
3210     VariantClear(&varRight);
3211     VariantClear(&tempLeft);
3212     VariantClear(&tempRight);
3213
3214     return hres;
3215 }
3216
3217 /**********************************************************************
3218  *              VarAdd [OLEAUT32.141]
3219  *
3220  * Add two variants.
3221  *
3222  * PARAMS
3223  *  left    [I] First variant
3224  *  right   [I] Second variant
3225  *  result  [O] Result variant
3226  *
3227  * RETURNS
3228  *  Success: S_OK.
3229  *  Failure: An HRESULT error code indicating the error.
3230  *
3231  * NOTES
3232  *  Native VarAdd up to and including WinXP doesn't like I1, UI2, UI4,
3233  *  UI8, INT and UINT as input variants.
3234  *
3235  *  Native VarAdd doesn't check for NULL in/out pointers and crashes. We do the
3236  *  same here.
3237  *
3238  * FIXME
3239  *  Overflow checking for R8 (double) overflow. Return DISP_E_OVERFLOW in that
3240  *  case.
3241  */
3242 HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3243 {
3244     HRESULT hres;
3245     VARTYPE lvt, rvt, resvt, tvt;
3246     VARIANT lv, rv, tv;
3247     VARIANT tempLeft, tempRight;
3248     double r8res;
3249
3250     /* Variant priority for coercion. Sorted from lowest to highest.
3251        VT_ERROR shows an invalid input variant type. */
3252     enum coerceprio { vt_EMPTY, vt_UI1, vt_I2, vt_I4, vt_I8, vt_BSTR,vt_R4,
3253                       vt_R8, vt_CY, vt_DATE, vt_DECIMAL, vt_DISPATCH, vt_NULL,
3254                       vt_ERROR };
3255     /* Mapping from priority to variant type. Keep in sync with coerceprio! */
3256     static const VARTYPE prio2vt[] = { VT_EMPTY, VT_UI1, VT_I2, VT_I4, VT_I8, VT_BSTR, VT_R4,
3257                           VT_R8, VT_CY, VT_DATE, VT_DECIMAL, VT_DISPATCH,
3258                           VT_NULL, VT_ERROR };
3259
3260     /* Mapping for coercion from input variant to priority of result variant. */
3261     static const VARTYPE coerce[] = {
3262         /* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
3263         vt_EMPTY, vt_NULL, vt_I2, vt_I4, vt_R4,
3264         /* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
3265         vt_R8, vt_CY, vt_DATE, vt_BSTR, vt_DISPATCH,
3266         /* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
3267         vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
3268         /* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
3269         vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
3270     };
3271
3272     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3273           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
3274           result);
3275
3276     VariantInit(&lv);
3277     VariantInit(&rv);
3278     VariantInit(&tv);
3279     VariantInit(&tempLeft);
3280     VariantInit(&tempRight);
3281
3282     /* Handle VT_DISPATCH by storing and taking address of returned value */
3283     if ((V_VT(left) & VT_TYPEMASK) != VT_NULL && (V_VT(right) & VT_TYPEMASK) != VT_NULL)
3284     {
3285         if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3286         {
3287             hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3288             if (FAILED(hres)) goto end;
3289             left = &tempLeft;
3290         }
3291         if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3292         {
3293             hres = VARIANT_FetchDispatchValue(right, &tempRight);
3294             if (FAILED(hres)) goto end;
3295             right = &tempRight;
3296         }
3297     }
3298
3299     lvt = V_VT(left)&VT_TYPEMASK;
3300     rvt = V_VT(right)&VT_TYPEMASK;
3301
3302     /* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
3303        Same for any input variant type > VT_I8 */
3304     if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
3305         lvt > VT_I8 || rvt > VT_I8) {
3306         hres = DISP_E_BADVARTYPE;
3307         goto end;
3308     }
3309
3310     /* Determine the variant type to coerce to. */
3311     if (coerce[lvt] > coerce[rvt]) {
3312         resvt = prio2vt[coerce[lvt]];
3313         tvt = prio2vt[coerce[rvt]];
3314     } else {
3315         resvt = prio2vt[coerce[rvt]];
3316         tvt = prio2vt[coerce[lvt]];
3317     }
3318
3319     /* Special cases where the result variant type is defined by both
3320        input variants and not only that with the highest priority */
3321     if (resvt == VT_BSTR) {
3322         if (tvt == VT_EMPTY || tvt == VT_BSTR)
3323             resvt = VT_BSTR;
3324         else
3325             resvt = VT_R8;
3326     }
3327     if (resvt == VT_R4 && (tvt == VT_BSTR || tvt == VT_I8 || tvt == VT_I4))
3328         resvt = VT_R8;
3329
3330     /* For overflow detection use the biggest compatible type for the
3331        addition */
3332     switch (resvt) {
3333         case VT_ERROR:
3334             hres = DISP_E_BADVARTYPE;
3335             goto end;
3336         case VT_NULL:
3337             hres = S_OK;
3338             V_VT(result) = VT_NULL;
3339             goto end;
3340         case VT_DISPATCH:
3341             FIXME("cannot handle variant type VT_DISPATCH\n");
3342             hres = DISP_E_TYPEMISMATCH;
3343             goto end;
3344         case VT_EMPTY:
3345             resvt = VT_I2;
3346             /* Fall through */
3347         case VT_UI1:
3348         case VT_I2:
3349         case VT_I4:
3350         case VT_I8:
3351             tvt = VT_I8;
3352             break;
3353         case VT_DATE:
3354         case VT_R4:
3355             tvt = VT_R8;
3356             break;
3357         default:
3358             tvt = resvt;
3359     }
3360
3361     /* Now coerce the variants */
3362     hres = VariantChangeType(&lv, left, 0, tvt);
3363     if (FAILED(hres))
3364         goto end;
3365     hres = VariantChangeType(&rv, right, 0, tvt);
3366     if (FAILED(hres))
3367         goto end;
3368
3369     /* Do the math */
3370     hres = S_OK;
3371     V_VT(result) = resvt;
3372     switch (tvt) {
3373         case VT_DECIMAL:
3374             hres = VarDecAdd(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
3375                              &V_DECIMAL(result));
3376             goto end;
3377         case VT_CY:
3378             hres = VarCyAdd(V_CY(&lv), V_CY(&rv), &V_CY(result));
3379             goto end;
3380         case VT_BSTR:
3381             /* We do not add those, we concatenate them. */
3382             hres = VarBstrCat(V_BSTR(&lv), V_BSTR(&rv), &V_BSTR(result));
3383             goto end;
3384         case VT_I8:
3385             /* Overflow detection */
3386             r8res = (double)V_I8(&lv) + (double)V_I8(&rv);
3387             if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
3388                 V_VT(result) = VT_R8;
3389                 V_R8(result) = r8res;
3390                 goto end;
3391             } else {
3392                 V_VT(&tv) = tvt;
3393                 V_I8(&tv) = V_I8(&lv) + V_I8(&rv);
3394             }
3395             break;
3396         case VT_R8:
3397             V_VT(&tv) = tvt;
3398             /* FIXME: overflow detection */
3399             V_R8(&tv) = V_R8(&lv) + V_R8(&rv);
3400             break;
3401         default:
3402             ERR("We shouldn't get here! tvt = %d!\n", tvt);
3403             break;
3404     }
3405     if (resvt != tvt) {
3406         if ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
3407             /* Overflow! Change to the vartype with the next higher priority.
3408                With one exception: I4 ==> R8 even if it would fit in I8 */
3409             if (resvt == VT_I4)
3410                 resvt = VT_R8;
3411             else
3412                 resvt = prio2vt[coerce[resvt] + 1];
3413             hres = VariantChangeType(result, &tv, 0, resvt);
3414         }
3415     } else
3416         hres = VariantCopy(result, &tv);
3417
3418 end:
3419     if (hres != S_OK) {
3420         V_VT(result) = VT_EMPTY;
3421         V_I4(result) = 0;       /* No V_EMPTY */
3422     }
3423     VariantClear(&lv);
3424     VariantClear(&rv);
3425     VariantClear(&tv);
3426     VariantClear(&tempLeft);
3427     VariantClear(&tempRight);
3428     TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
3429     return hres;
3430 }
3431
3432 /**********************************************************************
3433  *              VarMul [OLEAUT32.156]
3434  *
3435  * Multiply two variants.
3436  *
3437  * PARAMS
3438  *  left    [I] First variant
3439  *  right   [I] Second variant
3440  *  result  [O] Result variant
3441  *
3442  * RETURNS
3443  *  Success: S_OK.
3444  *  Failure: An HRESULT error code indicating the error.
3445  *
3446  * NOTES
3447  *  Native VarMul up to and including WinXP doesn't like I1, UI2, UI4,
3448  *  UI8, INT and UINT as input variants. But it can multiply apples with oranges.
3449  *
3450  *  Native VarMul doesn't check for NULL in/out pointers and crashes. We do the
3451  *  same here.
3452  *
3453  * FIXME
3454  *  Overflow checking for R8 (double) overflow. Return DISP_E_OVERFLOW in that
3455  *  case.
3456  */
3457 HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3458 {
3459     HRESULT hres;
3460     VARTYPE lvt, rvt, resvt, tvt;
3461     VARIANT lv, rv, tv;
3462     VARIANT tempLeft, tempRight;
3463     double r8res;
3464
3465     /* Variant priority for coercion. Sorted from lowest to highest.
3466        VT_ERROR shows an invalid input variant type. */
3467     enum coerceprio { vt_UI1 = 0, vt_I2, vt_I4, vt_I8, vt_CY, vt_R4, vt_R8,
3468                       vt_DECIMAL, vt_NULL, vt_ERROR };
3469     /* Mapping from priority to variant type. Keep in sync with coerceprio! */
3470     static const VARTYPE prio2vt[] = { VT_UI1, VT_I2, VT_I4, VT_I8, VT_CY, VT_R4, VT_R8,
3471                           VT_DECIMAL, VT_NULL, VT_ERROR };
3472
3473     /* Mapping for coercion from input variant to priority of result variant. */
3474     static const VARTYPE coerce[] = {
3475         /* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
3476         vt_UI1, vt_NULL, vt_I2, vt_I4, vt_R4,
3477         /* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
3478         vt_R8, vt_CY, vt_R8, vt_R8, vt_ERROR,
3479         /* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
3480         vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
3481         /* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
3482         vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
3483     };
3484
3485     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3486           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
3487           result);
3488
3489     VariantInit(&lv);
3490     VariantInit(&rv);
3491     VariantInit(&tv);
3492     VariantInit(&tempLeft);
3493     VariantInit(&tempRight);
3494
3495     /* Handle VT_DISPATCH by storing and taking address of returned value */
3496     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3497     {
3498         hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3499         if (FAILED(hres)) goto end;
3500         left = &tempLeft;
3501     }
3502     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3503     {
3504         hres = VARIANT_FetchDispatchValue(right, &tempRight);
3505         if (FAILED(hres)) goto end;
3506         right = &tempRight;
3507     }
3508
3509     lvt = V_VT(left)&VT_TYPEMASK;
3510     rvt = V_VT(right)&VT_TYPEMASK;
3511
3512     /* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
3513        Same for any input variant type > VT_I8 */
3514     if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
3515         lvt > VT_I8 || rvt > VT_I8) {
3516         hres = DISP_E_BADVARTYPE;
3517         goto end;
3518     }
3519
3520     /* Determine the variant type to coerce to. */
3521     if (coerce[lvt] > coerce[rvt]) {
3522         resvt = prio2vt[coerce[lvt]];
3523         tvt = prio2vt[coerce[rvt]];
3524     } else {
3525         resvt = prio2vt[coerce[rvt]];
3526         tvt = prio2vt[coerce[lvt]];
3527     }
3528
3529     /* Special cases where the result variant type is defined by both
3530        input variants and not only that with the highest priority */
3531     if (resvt == VT_R4 && (tvt == VT_CY || tvt == VT_I8 || tvt == VT_I4))
3532         resvt = VT_R8;
3533     if (lvt == VT_EMPTY && rvt == VT_EMPTY)
3534         resvt = VT_I2;
3535
3536     /* For overflow detection use the biggest compatible type for the
3537        multiplication */
3538     switch (resvt) {
3539         case VT_ERROR:
3540             hres = DISP_E_BADVARTYPE;
3541             goto end;
3542         case VT_NULL:
3543             hres = S_OK;
3544             V_VT(result) = VT_NULL;
3545             goto end;
3546         case VT_UI1:
3547         case VT_I2:
3548         case VT_I4:
3549         case VT_I8:
3550             tvt = VT_I8;
3551             break;
3552         case VT_R4:
3553             tvt = VT_R8;
3554             break;
3555         default:
3556             tvt = resvt;
3557     }
3558
3559     /* Now coerce the variants */
3560     hres = VariantChangeType(&lv, left, 0, tvt);
3561     if (FAILED(hres))
3562         goto end;
3563     hres = VariantChangeType(&rv, right, 0, tvt);
3564     if (FAILED(hres))
3565         goto end;
3566
3567     /* Do the math */
3568     hres = S_OK;
3569     V_VT(&tv) = tvt;
3570     V_VT(result) = resvt;
3571     switch (tvt) {
3572         case VT_DECIMAL:
3573             hres = VarDecMul(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
3574                              &V_DECIMAL(result));
3575             goto end;
3576         case VT_CY:
3577             hres = VarCyMul(V_CY(&lv), V_CY(&rv), &V_CY(result));
3578             goto end;
3579         case VT_I8:
3580             /* Overflow detection */
3581             r8res = (double)V_I8(&lv) * (double)V_I8(&rv);
3582             if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
3583                 V_VT(result) = VT_R8;
3584                 V_R8(result) = r8res;
3585                 goto end;
3586             } else
3587                 V_I8(&tv) = V_I8(&lv) * V_I8(&rv);
3588             break;
3589         case VT_R8:
3590             /* FIXME: overflow detection */
3591             V_R8(&tv) = V_R8(&lv) * V_R8(&rv);
3592             break;
3593         default:
3594             ERR("We shouldn't get here! tvt = %d!\n", tvt);
3595             break;
3596     }
3597     if (resvt != tvt) {
3598         while ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
3599             /* Overflow! Change to the vartype with the next higher priority.
3600                With one exception: I4 ==> R8 even if it would fit in I8 */
3601             if (resvt == VT_I4)
3602                 resvt = VT_R8;
3603             else
3604                 resvt = prio2vt[coerce[resvt] + 1];
3605         }
3606     } else
3607         hres = VariantCopy(result, &tv);
3608
3609 end:
3610     if (hres != S_OK) {
3611         V_VT(result) = VT_EMPTY;
3612         V_I4(result) = 0;       /* No V_EMPTY */
3613     }
3614     VariantClear(&lv);
3615     VariantClear(&rv);
3616     VariantClear(&tv);
3617     VariantClear(&tempLeft);
3618     VariantClear(&tempRight);
3619     TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
3620     return hres;
3621 }
3622
3623 /**********************************************************************
3624  *              VarDiv [OLEAUT32.143]
3625  *
3626  * Divides one variant with another.
3627  *
3628  * PARAMS
3629  *  left    [I] First variant
3630  *  right   [I] Second variant
3631  *  result  [O] Result variant
3632  *
3633  * RETURNS
3634  *  Success: S_OK.
3635  *  Failure: An HRESULT error code indicating the error.
3636  */
3637 HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3638 {
3639     HRESULT hres = S_OK;
3640     VARTYPE resvt = VT_EMPTY;
3641     VARTYPE leftvt,rightvt;
3642     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
3643     VARIANT lv,rv;
3644     VARIANT tempLeft, tempRight;
3645
3646     VariantInit(&tempLeft);
3647     VariantInit(&tempRight);
3648     VariantInit(&lv);
3649     VariantInit(&rv);
3650
3651     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3652           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
3653
3654     /* Handle VT_DISPATCH by storing and taking address of returned value */
3655     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
3656     {
3657         hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3658         if (FAILED(hres)) goto end;
3659         left = &tempLeft;
3660     }
3661     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
3662     {
3663         hres = VARIANT_FetchDispatchValue(right, &tempRight);
3664         if (FAILED(hres)) goto end;
3665         right = &tempRight;
3666     }
3667
3668     leftvt = V_VT(left)&VT_TYPEMASK;
3669     rightvt = V_VT(right)&VT_TYPEMASK;
3670     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
3671     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
3672
3673     if (leftExtraFlags != rightExtraFlags)
3674     {
3675         hres = DISP_E_BADVARTYPE;
3676         goto end;
3677     }
3678     ExtraFlags = leftExtraFlags;
3679
3680     /* Native VarDiv always returns an error when using extra flags */
3681     if (ExtraFlags != 0)
3682     {
3683         hres = DISP_E_BADVARTYPE;
3684         goto end;
3685     }
3686
3687     /* Determine return type */
3688     if (!(rightvt == VT_EMPTY))
3689     {
3690         if (leftvt == VT_NULL || rightvt == VT_NULL)
3691         {
3692             V_VT(result) = VT_NULL;
3693             hres = S_OK;
3694             goto end;
3695         }
3696         else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3697             resvt = VT_DECIMAL;
3698         else if (leftvt == VT_I8 || rightvt == VT_I8 ||
3699             leftvt == VT_CY || rightvt == VT_CY ||
3700             leftvt == VT_DATE || rightvt == VT_DATE ||
3701             leftvt == VT_I4 || rightvt == VT_I4 ||
3702             leftvt == VT_BSTR || rightvt == VT_BSTR ||
3703             leftvt == VT_I2 || rightvt == VT_I2 ||
3704             leftvt == VT_BOOL || rightvt == VT_BOOL ||
3705             leftvt == VT_R8 || rightvt == VT_R8 ||
3706             leftvt == VT_UI1 || rightvt == VT_UI1)
3707         {
3708             if ((leftvt == VT_UI1 && rightvt == VT_R4) ||
3709                 (leftvt == VT_R4 && rightvt == VT_UI1))
3710                 resvt = VT_R4;
3711             else if ((leftvt == VT_R4 && (rightvt == VT_BOOL ||
3712                 rightvt == VT_I2)) || (rightvt == VT_R4 &&
3713                 (leftvt == VT_BOOL || leftvt == VT_I2)))
3714                 resvt = VT_R4;
3715             else
3716                 resvt = VT_R8;
3717         }
3718         else if (leftvt == VT_R4 || rightvt == VT_R4)
3719             resvt = VT_R4;
3720     }
3721     else if (leftvt == VT_NULL && rightvt == VT_EMPTY)
3722     {
3723         V_VT(result) = VT_NULL;
3724         hres = S_OK;
3725         goto end;
3726     }
3727     else
3728     {
3729         hres = DISP_E_BADVARTYPE;
3730         goto end;
3731     }
3732
3733     /* coerce to the result type */
3734     hres = VariantChangeType(&lv, left, 0, resvt);
3735     if (hres != S_OK) goto end;
3736
3737     hres = VariantChangeType(&rv, right, 0, resvt);
3738     if (hres != S_OK) goto end;
3739
3740     /* do the math */
3741     V_VT(result) = resvt;
3742     switch (resvt)
3743     {
3744     case VT_R4:
3745     if (V_R4(&lv) == 0.0 && V_R4(&rv) == 0.0)
3746     {
3747         hres = DISP_E_OVERFLOW;
3748         V_VT(result) = VT_EMPTY;
3749     }
3750     else if (V_R4(&rv) == 0.0)
3751     {
3752         hres = DISP_E_DIVBYZERO;
3753         V_VT(result) = VT_EMPTY;
3754     }
3755     else
3756         V_R4(result) = V_R4(&lv) / V_R4(&rv);
3757     break;
3758     case VT_R8:
3759     if (V_R8(&lv) == 0.0 && V_R8(&rv) == 0.0)
3760     {
3761         hres = DISP_E_OVERFLOW;
3762         V_VT(result) = VT_EMPTY;
3763     }
3764     else if (V_R8(&rv) == 0.0)
3765     {
3766         hres = DISP_E_DIVBYZERO;
3767         V_VT(result) = VT_EMPTY;
3768     }
3769     else
3770         V_R8(result) = V_R8(&lv) / V_R8(&rv);
3771     break;
3772     case VT_DECIMAL:
3773     hres = VarDecDiv(&(V_DECIMAL(&lv)), &(V_DECIMAL(&rv)), &(V_DECIMAL(result)));
3774     break;
3775     }
3776
3777 end:
3778     VariantClear(&lv);
3779     VariantClear(&rv);
3780     VariantClear(&tempLeft);
3781     VariantClear(&tempRight);
3782     TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
3783     return hres;
3784 }
3785
3786 /**********************************************************************
3787  *              VarSub [OLEAUT32.159]
3788  *
3789  * Subtract two variants.
3790  *
3791  * PARAMS
3792  *  left    [I] First variant
3793  *  right   [I] Second variant
3794  *  result  [O] Result variant
3795  *
3796  * RETURNS
3797  *  Success: S_OK.
3798  *  Failure: An HRESULT error code indicating the error.
3799  */
3800 HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
3801 {
3802     HRESULT hres = S_OK;
3803     VARTYPE resvt = VT_EMPTY;
3804     VARTYPE leftvt,rightvt;
3805     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
3806     VARIANT lv,rv;
3807     VARIANT tempLeft, tempRight;
3808
3809     VariantInit(&lv);
3810     VariantInit(&rv);
3811     VariantInit(&tempLeft);
3812     VariantInit(&tempRight);
3813
3814     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
3815           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
3816
3817     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH &&
3818         (V_VT(left)&(~VT_TYPEMASK)) == 0 &&
3819         (V_VT(right) & VT_TYPEMASK) != VT_NULL)
3820     {
3821         if (NULL == V_DISPATCH(left)) {
3822             if ((V_VT(right) & VT_TYPEMASK) >= VT_INT_PTR)
3823                 hres = DISP_E_BADVARTYPE;
3824             else if ((V_VT(right) & VT_TYPEMASK) >= VT_UI8 &&
3825                 (V_VT(right) & VT_TYPEMASK) < VT_RECORD)
3826                 hres = DISP_E_BADVARTYPE;
3827             else switch (V_VT(right) & VT_TYPEMASK)
3828             {
3829             case VT_VARIANT:
3830             case VT_UNKNOWN:
3831             case 15:
3832             case VT_I1:
3833             case VT_UI2:
3834             case VT_UI4:
3835                 hres = DISP_E_BADVARTYPE;
3836             }
3837             if (FAILED(hres)) goto end;
3838         }
3839         hres = VARIANT_FetchDispatchValue(left, &tempLeft);
3840         if (FAILED(hres)) goto end;
3841         left = &tempLeft;
3842     }
3843     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH &&
3844         (V_VT(right)&(~VT_TYPEMASK)) == 0 &&
3845         (V_VT(left) & VT_TYPEMASK) != VT_NULL)
3846     {
3847         if (NULL == V_DISPATCH(right))
3848         {
3849             if ((V_VT(left) & VT_TYPEMASK) >= VT_INT_PTR)
3850                 hres = DISP_E_BADVARTYPE;
3851             else if ((V_VT(left) & VT_TYPEMASK) >= VT_UI8 &&
3852                 (V_VT(left) & VT_TYPEMASK) < VT_RECORD)
3853                 hres = DISP_E_BADVARTYPE;
3854             else switch (V_VT(left) & VT_TYPEMASK)
3855             {
3856             case VT_VARIANT:
3857             case VT_UNKNOWN:
3858             case 15:
3859             case VT_I1:
3860             case VT_UI2:
3861             case VT_UI4:
3862                 hres = DISP_E_BADVARTYPE;
3863             }
3864             if (FAILED(hres)) goto end;
3865         }
3866         hres = VARIANT_FetchDispatchValue(right, &tempRight);
3867         if (FAILED(hres)) goto end;
3868         right = &tempRight;
3869     }
3870
3871     leftvt = V_VT(left)&VT_TYPEMASK;
3872     rightvt = V_VT(right)&VT_TYPEMASK;
3873     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
3874     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
3875
3876     if (leftExtraFlags != rightExtraFlags)
3877     {
3878         hres = DISP_E_BADVARTYPE;
3879         goto end;
3880     }
3881     ExtraFlags = leftExtraFlags;
3882
3883     /* determine return type and return code */
3884     /* All extra flags produce errors */
3885     if (ExtraFlags == (VT_VECTOR|VT_BYREF|VT_RESERVED) ||
3886         ExtraFlags == (VT_VECTOR|VT_RESERVED) ||
3887         ExtraFlags == (VT_VECTOR|VT_BYREF) ||
3888         ExtraFlags == (VT_BYREF|VT_RESERVED) ||
3889         ExtraFlags == VT_VECTOR ||
3890         ExtraFlags == VT_BYREF ||
3891         ExtraFlags == VT_RESERVED)
3892     {
3893         hres = DISP_E_BADVARTYPE;
3894         goto end;
3895     }
3896     else if (ExtraFlags >= VT_ARRAY)
3897     {
3898         hres = DISP_E_TYPEMISMATCH;
3899         goto end;
3900     }
3901     /* Native VarSub cannot handle: VT_I1, VT_UI2, VT_UI4,
3902        VT_INT, VT_UINT and VT_UI8. Tested with WinXP */
3903     else if (leftvt == VT_CLSID || rightvt == VT_CLSID ||
3904         leftvt == VT_VARIANT || rightvt == VT_VARIANT ||
3905         leftvt == VT_I1 || rightvt == VT_I1 ||
3906         leftvt == VT_UI2 || rightvt == VT_UI2 ||
3907         leftvt == VT_UI4 || rightvt == VT_UI4 ||
3908         leftvt == VT_UI8 || rightvt == VT_UI8 ||
3909         leftvt == VT_INT || rightvt == VT_INT ||
3910         leftvt == VT_UINT || rightvt == VT_UINT ||
3911         leftvt == VT_UNKNOWN || rightvt == VT_UNKNOWN ||
3912         leftvt == VT_RECORD || rightvt == VT_RECORD)
3913     {
3914         if (leftvt == VT_RECORD && rightvt == VT_I8)
3915             hres = DISP_E_TYPEMISMATCH;
3916         else if (leftvt < VT_UI1 && rightvt == VT_RECORD)
3917             hres = DISP_E_TYPEMISMATCH;
3918         else if (leftvt >= VT_UI1 && rightvt == VT_RECORD)
3919             hres = DISP_E_TYPEMISMATCH;
3920         else if (leftvt == VT_RECORD && rightvt <= VT_UI1)
3921             hres = DISP_E_TYPEMISMATCH;
3922         else if (leftvt == VT_RECORD && rightvt > VT_UI1)
3923             hres = DISP_E_BADVARTYPE;
3924         else
3925             hres = DISP_E_BADVARTYPE;
3926         goto end;
3927     }
3928     /*  The following flags/types are invalid for left variant */
3929     else if (!((leftvt <= VT_LPWSTR || leftvt == VT_RECORD ||
3930         leftvt == VT_CLSID) && leftvt != (VARTYPE)15 /* undefined vt */ &&
3931         (leftvt < VT_VOID || leftvt > VT_LPWSTR)))
3932     {
3933         hres = DISP_E_BADVARTYPE;
3934         goto end;
3935     }
3936     /*  The following flags/types are invalid for right variant */
3937     else if (!((rightvt <= VT_LPWSTR || rightvt == VT_RECORD ||
3938         rightvt == VT_CLSID) && rightvt != (VARTYPE)15 /* undefined vt */ &&
3939         (rightvt < VT_VOID || rightvt > VT_LPWSTR)))
3940     {
3941         hres = DISP_E_BADVARTYPE;
3942         goto end;
3943     }
3944     else if ((leftvt == VT_NULL && rightvt == VT_DISPATCH) ||
3945         (leftvt == VT_DISPATCH && rightvt == VT_NULL))
3946         resvt = VT_NULL;
3947     else if (leftvt == VT_DISPATCH || rightvt == VT_DISPATCH ||
3948         leftvt == VT_ERROR || rightvt == VT_ERROR)
3949     {
3950         hres = DISP_E_TYPEMISMATCH;
3951         goto end;
3952     }
3953     else if (leftvt == VT_NULL || rightvt == VT_NULL)
3954         resvt = VT_NULL;
3955     else if ((leftvt == VT_EMPTY && rightvt == VT_BSTR) ||
3956         (leftvt == VT_DATE && rightvt == VT_DATE) ||
3957         (leftvt == VT_BSTR && rightvt == VT_EMPTY) ||
3958         (leftvt == VT_BSTR && rightvt == VT_BSTR))
3959         resvt = VT_R8;
3960     else if (leftvt == VT_DECIMAL || rightvt == VT_DECIMAL)
3961         resvt = VT_DECIMAL;
3962     else if (leftvt == VT_DATE || rightvt == VT_DATE)
3963         resvt = VT_DATE;
3964     else if (leftvt == VT_CY || rightvt == VT_CY)
3965         resvt = VT_CY;
3966     else if (leftvt == VT_R8 || rightvt == VT_R8)
3967         resvt = VT_R8;
3968     else if (leftvt == VT_BSTR || rightvt == VT_BSTR)
3969         resvt = VT_R8;
3970     else if (leftvt == VT_R4 || rightvt == VT_R4)
3971     {
3972         if (leftvt == VT_I4 || rightvt == VT_I4 ||
3973             leftvt == VT_I8 || rightvt == VT_I8)
3974             resvt = VT_R8;
3975         else
3976             resvt = VT_R4;
3977     }
3978     else if (leftvt == VT_I8 || rightvt == VT_I8)
3979         resvt = VT_I8;
3980     else if (leftvt == VT_I4 || rightvt == VT_I4)
3981         resvt = VT_I4;
3982     else if (leftvt == VT_I2 || rightvt == VT_I2 ||
3983         leftvt == VT_BOOL || rightvt == VT_BOOL ||
3984         (leftvt == VT_EMPTY && rightvt == VT_EMPTY))
3985         resvt = VT_I2;
3986     else if (leftvt == VT_UI1 || rightvt == VT_UI1)
3987         resvt = VT_UI1;
3988     else
3989     {
3990         hres = DISP_E_TYPEMISMATCH;
3991         goto end;
3992     }
3993
3994     /* coerce to the result type */
3995     if (leftvt == VT_BSTR && rightvt == VT_DATE)
3996         hres = VariantChangeType(&lv, left, 0, VT_R8);
3997     else
3998         hres = VariantChangeType(&lv, left, 0, resvt);
3999     if (hres != S_OK) goto end;
4000     if (leftvt == VT_DATE && rightvt == VT_BSTR)
4001         hres = VariantChangeType(&rv, right, 0, VT_R8);
4002     else
4003         hres = VariantChangeType(&rv, right, 0, resvt);
4004     if (hres != S_OK) goto end;
4005
4006     /* do the math */
4007     V_VT(result) = resvt;
4008     switch (resvt)
4009     {
4010     case VT_NULL:
4011     break;
4012     case VT_DATE:
4013     V_DATE(result) = V_DATE(&lv) - V_DATE(&rv);
4014     break;
4015     case VT_CY:
4016     hres = VarCySub(V_CY(&lv), V_CY(&rv), &(V_CY(result)));
4017     break;
4018     case VT_R4:
4019     V_R4(result) = V_R4(&lv) - V_R4(&rv);
4020     break;
4021     case VT_I8:
4022     V_I8(result) = V_I8(&lv) - V_I8(&rv);
4023     break;
4024     case VT_I4:
4025     V_I4(result) = V_I4(&lv) - V_I4(&rv);
4026     break;
4027     case VT_I2:
4028     V_I2(result) = V_I2(&lv) - V_I2(&rv);
4029     break;
4030     case VT_I1:
4031     V_I1(result) = V_I1(&lv) - V_I1(&rv);
4032     break;
4033     case VT_UI1:
4034     V_UI1(result) = V_UI2(&lv) - V_UI1(&rv);
4035     break;
4036     case VT_R8:
4037     V_R8(result) = V_R8(&lv) - V_R8(&rv);
4038     break;
4039     case VT_DECIMAL:
4040     hres = VarDecSub(&(V_DECIMAL(&lv)), &(V_DECIMAL(&rv)), &(V_DECIMAL(result)));
4041     break;
4042     }
4043
4044 end:
4045     VariantClear(&lv);
4046     VariantClear(&rv);
4047     VariantClear(&tempLeft);
4048     VariantClear(&tempRight);
4049     TRACE("returning 0x%8x (variant type %s)\n", hres, debugstr_VT(result));
4050     return hres;
4051 }
4052
4053
4054 /**********************************************************************
4055  *              VarOr [OLEAUT32.157]
4056  *
4057  * Perform a logical or (OR) operation on two variants.
4058  *
4059  * PARAMS
4060  *  pVarLeft  [I] First variant
4061  *  pVarRight [I] Variant to OR with pVarLeft
4062  *  pVarOut   [O] Destination for OR result
4063  *
4064  * RETURNS
4065  *  Success: S_OK. pVarOut contains the result of the operation with its type
4066  *           taken from the table listed under VarXor().
4067  *  Failure: An HRESULT error code indicating the error.
4068  *
4069  * NOTES
4070  *  See the Notes section of VarXor() for further information.
4071  */
4072 HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
4073 {
4074     VARTYPE vt = VT_I4;
4075     VARIANT varLeft, varRight, varStr;
4076     HRESULT hRet;
4077     VARIANT tempLeft, tempRight;
4078
4079     VariantInit(&tempLeft);
4080     VariantInit(&tempRight);
4081     VariantInit(&varLeft);
4082     VariantInit(&varRight);
4083     VariantInit(&varStr);
4084
4085     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
4086           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
4087           debugstr_VF(pVarRight), pVarOut);
4088
4089     /* Handle VT_DISPATCH by storing and taking address of returned value */
4090     if ((V_VT(pVarLeft) & VT_TYPEMASK) == VT_DISPATCH)
4091     {
4092         hRet = VARIANT_FetchDispatchValue(pVarLeft, &tempLeft);
4093         if (FAILED(hRet)) goto VarOr_Exit;
4094         pVarLeft = &tempLeft;
4095     }
4096     if ((V_VT(pVarRight) & VT_TYPEMASK) == VT_DISPATCH)
4097     {
4098         hRet = VARIANT_FetchDispatchValue(pVarRight, &tempRight);
4099         if (FAILED(hRet)) goto VarOr_Exit;
4100         pVarRight = &tempRight;
4101     }
4102
4103     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
4104         V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
4105         V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH ||
4106         V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD)
4107     {
4108         hRet = DISP_E_BADVARTYPE;
4109         goto VarOr_Exit;
4110     }
4111
4112     V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY;
4113
4114     if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
4115     {
4116         /* NULL OR Zero is NULL, NULL OR value is value */
4117         if (V_VT(pVarLeft) == VT_NULL)
4118             pVarLeft = pVarRight; /* point to the non-NULL var */
4119
4120         V_VT(pVarOut) = VT_NULL;
4121         V_I4(pVarOut) = 0;
4122
4123         switch (V_VT(pVarLeft))
4124         {
4125         case VT_DATE: case VT_R8:
4126             if (V_R8(pVarLeft))
4127                 goto VarOr_AsEmpty;
4128             hRet = S_OK;
4129             goto VarOr_Exit;
4130         case VT_BOOL:
4131             if (V_BOOL(pVarLeft))
4132                 *pVarOut = *pVarLeft;
4133             hRet = S_OK;
4134             goto VarOr_Exit;
4135          case VT_I2: case VT_UI2:
4136             if (V_I2(pVarLeft))
4137                 goto VarOr_AsEmpty;
4138             hRet = S_OK;
4139             goto VarOr_Exit;
4140         case VT_I1:
4141             if (V_I1(pVarLeft))
4142                 goto VarOr_AsEmpty;
4143             hRet = S_OK;
4144             goto VarOr_Exit;
4145         case VT_UI1:
4146             if (V_UI1(pVarLeft))
4147                 *pVarOut = *pVarLeft;
4148             hRet = S_OK;
4149             goto VarOr_Exit;
4150         case VT_R4:
4151             if (V_R4(pVarLeft))
4152                 goto VarOr_AsEmpty;
4153             hRet = S_OK;
4154             goto VarOr_Exit;
4155         case VT_I4: case VT_UI4: case VT_INT: case VT_UINT:
4156             if (V_I4(pVarLeft))
4157                 goto VarOr_AsEmpty;
4158             hRet = S_OK;
4159             goto VarOr_Exit;
4160         case VT_CY:
4161             if (V_CY(pVarLeft).int64)
4162                 goto VarOr_AsEmpty;
4163             hRet = S_OK;
4164             goto VarOr_Exit;
4165         case VT_I8: case VT_UI8:
4166             if (V_I8(pVarLeft))
4167                 goto VarOr_AsEmpty;
4168             hRet = S_OK;
4169             goto VarOr_Exit;
4170         case VT_DECIMAL:
4171             if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft)))
4172                 goto VarOr_AsEmpty;
4173             hRet = S_OK;
4174             goto VarOr_Exit;
4175         case VT_BSTR:
4176         {
4177             VARIANT_BOOL b;
4178
4179             if (!V_BSTR(pVarLeft))
4180             {
4181                 hRet = DISP_E_BADVARTYPE;
4182                 goto VarOr_Exit;
4183             }
4184
4185             hRet = VarBoolFromStr(V_BSTR(pVarLeft), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
4186             if (SUCCEEDED(hRet) && b)
4187             {
4188                 V_VT(pVarOut) = VT_BOOL;
4189                 V_BOOL(pVarOut) = b;
4190             }
4191             goto VarOr_Exit;
4192         }
4193         case VT_NULL: case VT_EMPTY:
4194             V_VT(pVarOut) = VT_NULL;
4195             hRet = S_OK;
4196             goto VarOr_Exit;
4197         default:
4198             hRet = DISP_E_BADVARTYPE;
4199             goto VarOr_Exit;
4200         }
4201     }
4202
4203     if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY)
4204     {
4205         if (V_VT(pVarLeft) == VT_EMPTY)
4206             pVarLeft = pVarRight; /* point to the non-EMPTY var */
4207
4208 VarOr_AsEmpty:
4209         /* Since one argument is empty (0), OR'ing it with the other simply
4210          * gives the others value (as 0|x => x). So just convert the other
4211          * argument to the required result type.
4212          */
4213         switch (V_VT(pVarLeft))
4214         {
4215         case VT_BSTR:
4216             if (!V_BSTR(pVarLeft))
4217             {
4218                 hRet = DISP_E_BADVARTYPE;
4219                 goto VarOr_Exit;
4220             }
4221
4222             hRet = VariantCopy(&varStr, pVarLeft);
4223             if (FAILED(hRet))
4224                 goto VarOr_Exit;
4225             pVarLeft = &varStr;
4226             hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
4227             if (FAILED(hRet))
4228                 goto VarOr_Exit;
4229             /* Fall Through ... */
4230         case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2:
4231             V_VT(pVarOut) = VT_I2;
4232             break;
4233         case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:
4234         case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:
4235         case VT_INT: case VT_UINT: case VT_UI8:
4236             V_VT(pVarOut) = VT_I4;
4237             break;
4238         case VT_I8:
4239             V_VT(pVarOut) = VT_I8;
4240             break;
4241         default:
4242             hRet = DISP_E_BADVARTYPE;
4243             goto VarOr_Exit;
4244         }
4245         hRet = VariantCopy(&varLeft, pVarLeft);
4246         if (FAILED(hRet))
4247             goto VarOr_Exit;
4248         pVarLeft = &varLeft;
4249         hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut));
4250         goto VarOr_Exit;
4251     }
4252
4253     if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)
4254     {
4255         V_VT(pVarOut) = VT_BOOL;
4256         V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight);
4257         hRet = S_OK;
4258         goto VarOr_Exit;
4259     }
4260
4261     if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)
4262     {
4263         V_VT(pVarOut) = VT_UI1;
4264         V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight);
4265         hRet = S_OK;
4266         goto VarOr_Exit;
4267     }
4268
4269     if (V_VT(pVarLeft) == VT_BSTR)
4270     {
4271         hRet = VariantCopy(&varStr, pVarLeft);
4272         if (FAILED(hRet))
4273             goto VarOr_Exit;
4274         pVarLeft = &varStr;
4275         hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
4276         if (FAILED(hRet))
4277             goto VarOr_Exit;
4278     }
4279
4280     if (V_VT(pVarLeft) == VT_BOOL &&
4281         (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR))
4282     {
4283         vt = VT_BOOL;
4284     }
4285     else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 ||
4286         V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) &&
4287         (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||
4288         V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR))
4289     {
4290         vt = VT_I2;
4291     }
4292     else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)
4293     {
4294         if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
4295         {
4296             hRet = DISP_E_TYPEMISMATCH;
4297             goto VarOr_Exit;
4298         }
4299         vt = VT_I8;
4300     }
4301
4302     hRet = VariantCopy(&varLeft, pVarLeft);
4303     if (FAILED(hRet))
4304         goto VarOr_Exit;
4305
4306     hRet = VariantCopy(&varRight, pVarRight);
4307     if (FAILED(hRet))
4308         goto VarOr_Exit;
4309
4310     if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4)
4311         V_VT(&varLeft) = VT_I4; /* Don't overflow */
4312     else
4313     {
4314         double d;
4315
4316         if (V_VT(&varLeft) == VT_BSTR &&
4317             FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d)))
4318             hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL);
4319         if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt)
4320             hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
4321         if (FAILED(hRet))
4322             goto VarOr_Exit;
4323     }
4324
4325     if (vt == VT_I4 && V_VT(&varRight) == VT_UI4)
4326         V_VT(&varRight) = VT_I4; /* Don't overflow */
4327     else
4328     {
4329         double d;
4330
4331         if (V_VT(&varRight) == VT_BSTR &&
4332             FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d)))
4333             hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL);
4334         if (SUCCEEDED(hRet) && V_VT(&varRight) != vt)
4335             hRet = VariantChangeType(&varRight, &varRight, 0, vt);
4336         if (FAILED(hRet))
4337             goto VarOr_Exit;
4338     }
4339
4340     V_VT(pVarOut) = vt;
4341     if (vt == VT_I8)
4342     {
4343         V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight);
4344     }
4345     else if (vt == VT_I4)
4346     {
4347         V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight);
4348     }
4349     else
4350     {
4351         V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight);
4352     }
4353
4354 VarOr_Exit:
4355     VariantClear(&varStr);
4356     VariantClear(&varLeft);
4357     VariantClear(&varRight);
4358     VariantClear(&tempLeft);
4359     VariantClear(&tempRight);
4360     return hRet;
4361 }
4362
4363 /**********************************************************************
4364  * VarAbs [OLEAUT32.168]
4365  *
4366  * Convert a variant to its absolute value.
4367  *
4368  * PARAMS
4369  *  pVarIn  [I] Source variant
4370  *  pVarOut [O] Destination for converted value
4371  *
4372  * RETURNS
4373  *  Success: S_OK. pVarOut contains the absolute value of pVarIn.
4374  *  Failure: An HRESULT error code indicating the error.
4375  *
4376  * NOTES
4377  *  - This function does not process by-reference variants.
4378  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
4379  *    according to the following table:
4380  *| Input Type       Output Type
4381  *| ----------       -----------
4382  *| VT_BOOL          VT_I2
4383  *| VT_BSTR          VT_R8
4384  *| (All others)     Unchanged
4385  */
4386 HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut)
4387 {
4388     VARIANT varIn;
4389     HRESULT hRet = S_OK;
4390     VARIANT temp;
4391
4392     VariantInit(&temp);
4393
4394     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
4395           debugstr_VF(pVarIn), pVarOut);
4396
4397     /* Handle VT_DISPATCH by storing and taking address of returned value */
4398     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4399     {
4400         hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4401         if (FAILED(hRet)) goto VarAbs_Exit;
4402         pVarIn = &temp;
4403     }
4404
4405     if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN ||
4406         V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD ||
4407         V_VT(pVarIn) == VT_ERROR)
4408     {
4409         hRet = DISP_E_TYPEMISMATCH;
4410         goto VarAbs_Exit;
4411     }
4412     *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */
4413
4414 #define ABS_CASE(typ,min) \
4415     case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \
4416                   else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \
4417                   break
4418
4419     switch (V_VT(pVarIn))
4420     {
4421     ABS_CASE(I1,I1_MIN);
4422     case VT_BOOL:
4423         V_VT(pVarOut) = VT_I2;
4424         /* BOOL->I2, Fall through ... */
4425     ABS_CASE(I2,I2_MIN);
4426     case VT_INT:
4427     ABS_CASE(I4,I4_MIN);
4428     ABS_CASE(I8,I8_MIN);
4429     ABS_CASE(R4,R4_MIN);
4430     case VT_BSTR:
4431         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
4432         if (FAILED(hRet))
4433             break;
4434         V_VT(pVarOut) = VT_R8;
4435         pVarIn = &varIn;
4436         /* Fall through ... */
4437     case VT_DATE:
4438     ABS_CASE(R8,R8_MIN);
4439     case VT_CY:
4440         hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut));
4441         break;
4442     case VT_DECIMAL:
4443         DEC_SIGN(&V_DECIMAL(pVarOut)) &= ~DECIMAL_NEG;
4444         break;
4445     case VT_UI1:
4446     case VT_UI2:
4447     case VT_UINT:
4448     case VT_UI4:
4449     case VT_UI8:
4450         /* No-Op */
4451         break;
4452     case VT_EMPTY:
4453         V_VT(pVarOut) = VT_I2;
4454     case VT_NULL:
4455         V_I2(pVarOut) = 0;
4456         break;
4457     default:
4458         hRet = DISP_E_BADVARTYPE;
4459     }
4460
4461 VarAbs_Exit:
4462     VariantClear(&temp);
4463     return hRet;
4464 }
4465
4466 /**********************************************************************
4467  *              VarFix [OLEAUT32.169]
4468  *
4469  * Truncate a variants value to a whole number.
4470  *
4471  * PARAMS
4472  *  pVarIn  [I] Source variant
4473  *  pVarOut [O] Destination for converted value
4474  *
4475  * RETURNS
4476  *  Success: S_OK. pVarOut contains the converted value.
4477  *  Failure: An HRESULT error code indicating the error.
4478  *
4479  * NOTES
4480  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
4481  *    according to the following table:
4482  *| Input Type       Output Type
4483  *| ----------       -----------
4484  *|  VT_BOOL          VT_I2
4485  *|  VT_EMPTY         VT_I2
4486  *|  VT_BSTR          VT_R8
4487  *|  All Others       Unchanged
4488  *  - The difference between this function and VarInt() is that VarInt() rounds
4489  *    negative numbers away from 0, while this function rounds them towards zero.
4490  */
4491 HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut)
4492 {
4493     HRESULT hRet = S_OK;
4494     VARIANT temp;
4495
4496     VariantInit(&temp);
4497
4498     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
4499           debugstr_VF(pVarIn), pVarOut);
4500
4501     /* Handle VT_DISPATCH by storing and taking address of returned value */
4502     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4503     {
4504         hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4505         if (FAILED(hRet)) goto VarFix_Exit;
4506         pVarIn = &temp;
4507     }
4508     V_VT(pVarOut) = V_VT(pVarIn);
4509
4510     switch (V_VT(pVarIn))
4511     {
4512     case VT_UI1:
4513         V_UI1(pVarOut) = V_UI1(pVarIn);
4514         break;
4515     case VT_BOOL:
4516         V_VT(pVarOut) = VT_I2;
4517         /* Fall through */
4518      case VT_I2:
4519         V_I2(pVarOut) = V_I2(pVarIn);
4520         break;
4521      case VT_I4:
4522         V_I4(pVarOut) = V_I4(pVarIn);
4523         break;
4524      case VT_I8:
4525         V_I8(pVarOut) = V_I8(pVarIn);
4526         break;
4527     case VT_R4:
4528         if (V_R4(pVarIn) < 0.0f)
4529             V_R4(pVarOut) = (float)ceil(V_R4(pVarIn));
4530         else
4531             V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
4532         break;
4533     case VT_BSTR:
4534         V_VT(pVarOut) = VT_R8;
4535         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4536         pVarIn = pVarOut;
4537         /* Fall through */
4538     case VT_DATE:
4539     case VT_R8:
4540         if (V_R8(pVarIn) < 0.0)
4541             V_R8(pVarOut) = ceil(V_R8(pVarIn));
4542         else
4543             V_R8(pVarOut) = floor(V_R8(pVarIn));
4544         break;
4545     case VT_CY:
4546         hRet = VarCyFix(V_CY(pVarIn), &V_CY(pVarOut));
4547         break;
4548     case VT_DECIMAL:
4549         hRet = VarDecFix(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
4550         break;
4551     case VT_EMPTY:
4552         V_VT(pVarOut) = VT_I2;
4553         V_I2(pVarOut) = 0;
4554         break;
4555     case VT_NULL:
4556         /* No-Op */
4557         break;
4558     default:
4559         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4560             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
4561             hRet = DISP_E_BADVARTYPE;
4562         else
4563             hRet = DISP_E_TYPEMISMATCH;
4564     }
4565 VarFix_Exit:
4566     if (FAILED(hRet))
4567       V_VT(pVarOut) = VT_EMPTY;
4568     VariantClear(&temp);
4569
4570     return hRet;
4571 }
4572
4573 /**********************************************************************
4574  *              VarInt [OLEAUT32.172]
4575  *
4576  * Truncate a variants value to a whole number.
4577  *
4578  * PARAMS
4579  *  pVarIn  [I] Source variant
4580  *  pVarOut [O] Destination for converted value
4581  *
4582  * RETURNS
4583  *  Success: S_OK. pVarOut contains the converted value.
4584  *  Failure: An HRESULT error code indicating the error.
4585  *
4586  * NOTES
4587  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
4588  *    according to the following table:
4589  *| Input Type       Output Type
4590  *| ----------       -----------
4591  *|  VT_BOOL          VT_I2
4592  *|  VT_EMPTY         VT_I2
4593  *|  VT_BSTR          VT_R8
4594  *|  All Others       Unchanged
4595  *  - The difference between this function and VarFix() is that VarFix() rounds
4596  *    negative numbers towards 0, while this function rounds them away from zero.
4597  */
4598 HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
4599 {
4600     HRESULT hRet = S_OK;
4601     VARIANT temp;
4602
4603     VariantInit(&temp);
4604
4605     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
4606           debugstr_VF(pVarIn), pVarOut);
4607
4608     /* Handle VT_DISPATCH by storing and taking address of returned value */
4609     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4610     {
4611         hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4612         if (FAILED(hRet)) goto VarInt_Exit;
4613         pVarIn = &temp;
4614     }
4615     V_VT(pVarOut) = V_VT(pVarIn);
4616
4617     switch (V_VT(pVarIn))
4618     {
4619     case VT_R4:
4620         V_R4(pVarOut) = (float)floor(V_R4(pVarIn));
4621         break;
4622     case VT_BSTR:
4623         V_VT(pVarOut) = VT_R8;
4624         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4625         pVarIn = pVarOut;
4626         /* Fall through */
4627     case VT_DATE:
4628     case VT_R8:
4629         V_R8(pVarOut) = floor(V_R8(pVarIn));
4630         break;
4631     case VT_CY:
4632         hRet = VarCyInt(V_CY(pVarIn), &V_CY(pVarOut));
4633         break;
4634     case VT_DECIMAL:
4635         hRet = VarDecInt(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
4636         break;
4637     default:
4638         hRet = VarFix(pVarIn, pVarOut);
4639     }
4640 VarInt_Exit:
4641     VariantClear(&temp);
4642
4643     return hRet;
4644 }
4645
4646 /**********************************************************************
4647  *              VarXor [OLEAUT32.167]
4648  *
4649  * Perform a logical exclusive-or (XOR) operation on two variants.
4650  *
4651  * PARAMS
4652  *  pVarLeft  [I] First variant
4653  *  pVarRight [I] Variant to XOR with pVarLeft
4654  *  pVarOut   [O] Destination for XOR result
4655  *
4656  * RETURNS
4657  *  Success: S_OK. pVarOut contains the result of the operation with its type
4658  *           taken from the table below).
4659  *  Failure: An HRESULT error code indicating the error.
4660  *
4661  * NOTES
4662  *  - Neither pVarLeft or pVarRight are modified by this function.
4663  *  - This function does not process by-reference variants.
4664  *  - Input types of VT_BSTR may be numeric strings or boolean text.
4665  *  - The type of result stored in pVarOut depends on the types of pVarLeft
4666  *    and pVarRight, and will be one of VT_UI1, VT_I2, VT_I4, VT_I8, VT_BOOL,
4667  *    or VT_NULL if the function succeeds.
4668  *  - Type promotion is inconsistent and as a result certain combinations of
4669  *    values will return DISP_E_OVERFLOW even when they could be represented.
4670  *    This matches the behaviour of native oleaut32.
4671  */
4672 HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
4673 {
4674     VARTYPE vt;
4675     VARIANT varLeft, varRight;
4676     VARIANT tempLeft, tempRight;
4677     double d;
4678     HRESULT hRet;
4679
4680     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
4681           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
4682           debugstr_VF(pVarRight), pVarOut);
4683
4684     if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
4685         V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT ||
4686         V_VT(pVarLeft) == VT_VARIANT || V_VT(pVarRight) == VT_VARIANT ||
4687         V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
4688         V_VT(pVarLeft) == (VARTYPE)15 || V_VT(pVarRight) == (VARTYPE)15 ||
4689         V_VT(pVarLeft) == VT_ERROR || V_VT(pVarRight) == VT_ERROR)
4690         return DISP_E_BADVARTYPE;
4691
4692     if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
4693     {
4694         /* NULL XOR anything valid is NULL */
4695         V_VT(pVarOut) = VT_NULL;
4696         return S_OK;
4697     }
4698
4699     VariantInit(&tempLeft);
4700     VariantInit(&tempRight);
4701
4702     /* Handle VT_DISPATCH by storing and taking address of returned value */
4703     if ((V_VT(pVarLeft) & VT_TYPEMASK) == VT_DISPATCH)
4704     {
4705         hRet = VARIANT_FetchDispatchValue(pVarLeft, &tempLeft);
4706         if (FAILED(hRet)) goto VarXor_Exit;
4707         pVarLeft = &tempLeft;
4708     }
4709     if ((V_VT(pVarRight) & VT_TYPEMASK) == VT_DISPATCH)
4710     {
4711         hRet = VARIANT_FetchDispatchValue(pVarRight, &tempRight);
4712         if (FAILED(hRet)) goto VarXor_Exit;
4713         pVarRight = &tempRight;
4714     }
4715
4716     /* Copy our inputs so we don't disturb anything */
4717     V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY;
4718
4719     hRet = VariantCopy(&varLeft, pVarLeft);
4720     if (FAILED(hRet))
4721         goto VarXor_Exit;
4722
4723     hRet = VariantCopy(&varRight, pVarRight);
4724     if (FAILED(hRet))
4725         goto VarXor_Exit;
4726
4727     /* Try any strings first as numbers, then as VT_BOOL */
4728     if (V_VT(&varLeft) == VT_BSTR)
4729     {
4730         hRet = VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d);
4731         hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL,
4732                                  FAILED(hRet) ? VT_BOOL : VT_I4);
4733         if (FAILED(hRet))
4734             goto VarXor_Exit;
4735     }
4736
4737     if (V_VT(&varRight) == VT_BSTR)
4738     {
4739         hRet = VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d);
4740         hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL,
4741                                  FAILED(hRet) ? VT_BOOL : VT_I4);
4742         if (FAILED(hRet))
4743             goto VarXor_Exit;
4744     }
4745
4746     /* Determine the result type */
4747     if (V_VT(&varLeft) == VT_I8 || V_VT(&varRight) == VT_I8)
4748     {
4749         if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
4750         {
4751             hRet = DISP_E_TYPEMISMATCH;
4752             goto VarXor_Exit;
4753         }
4754         vt = VT_I8;
4755     }
4756     else
4757     {
4758         switch ((V_VT(&varLeft) << 16) | V_VT(&varRight))
4759         {
4760         case (VT_BOOL  << 16) | VT_BOOL:
4761             vt = VT_BOOL;
4762             break;
4763         case (VT_UI1   << 16) | VT_UI1:
4764             vt = VT_UI1;
4765             break;
4766         case (VT_EMPTY << 16) | VT_EMPTY:
4767         case (VT_EMPTY << 16) | VT_UI1:
4768         case (VT_EMPTY << 16) | VT_I2:
4769         case (VT_EMPTY << 16) | VT_BOOL:
4770         case (VT_UI1   << 16) | VT_EMPTY:
4771         case (VT_UI1   << 16) | VT_I2:
4772         case (VT_UI1   << 16) | VT_BOOL:
4773         case (VT_I2    << 16) | VT_EMPTY:
4774         case (VT_I2    << 16) | VT_UI1:
4775         case (VT_I2    << 16) | VT_I2:
4776         case (VT_I2    << 16) | VT_BOOL:
4777         case (VT_BOOL  << 16) | VT_EMPTY:
4778         case (VT_BOOL  << 16) | VT_UI1:
4779         case (VT_BOOL  << 16) | VT_I2:
4780             vt = VT_I2;
4781             break;
4782         default:
4783             vt = VT_I4;
4784             break;
4785         }
4786     }
4787
4788     /* VT_UI4 does not overflow */
4789     if (vt != VT_I8)
4790     {
4791         if (V_VT(&varLeft) == VT_UI4)
4792             V_VT(&varLeft) = VT_I4;
4793         if (V_VT(&varRight) == VT_UI4)
4794             V_VT(&varRight) = VT_I4;
4795     }
4796
4797     /* Convert our input copies to the result type */
4798     if (V_VT(&varLeft) != vt)
4799         hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
4800     if (FAILED(hRet))
4801         goto VarXor_Exit;
4802
4803     if (V_VT(&varRight) != vt)
4804         hRet = VariantChangeType(&varRight, &varRight, 0, vt);
4805     if (FAILED(hRet))
4806         goto VarXor_Exit;
4807
4808     V_VT(pVarOut) = vt;
4809
4810     /* Calculate the result */
4811     switch (vt)
4812     {
4813     case VT_I8:
4814         V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight);
4815         break;
4816     case VT_I4:
4817         V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight);
4818         break;
4819     case VT_BOOL:
4820     case VT_I2:
4821         V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight);
4822         break;
4823     case VT_UI1:
4824         V_UI1(pVarOut) = V_UI1(&varLeft) ^ V_UI1(&varRight);
4825         break;
4826     }
4827
4828 VarXor_Exit:
4829     VariantClear(&varLeft);
4830     VariantClear(&varRight);
4831     VariantClear(&tempLeft);
4832     VariantClear(&tempRight);
4833     return hRet;
4834 }
4835
4836 /**********************************************************************
4837  *              VarEqv [OLEAUT32.172]
4838  *
4839  * Determine if two variants contain the same value.
4840  *
4841  * PARAMS
4842  *  pVarLeft  [I] First variant to compare
4843  *  pVarRight [I] Variant to compare to pVarLeft
4844  *  pVarOut   [O] Destination for comparison result
4845  *
4846  * RETURNS
4847  *  Success: S_OK. pVarOut contains the result of the comparison (VARIANT_TRUE
4848  *           if equivalent or non-zero otherwise.
4849  *  Failure: An HRESULT error code indicating the error.
4850  *
4851  * NOTES
4852  *  - This function simply calls VarXor() on pVarLeft and pVarRight and inverts
4853  *    the result.
4854  */
4855 HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
4856 {
4857     HRESULT hRet;
4858
4859     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
4860           debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
4861           debugstr_VF(pVarRight), pVarOut);
4862
4863     hRet = VarXor(pVarLeft, pVarRight, pVarOut);
4864     if (SUCCEEDED(hRet))
4865     {
4866         if (V_VT(pVarOut) == VT_I8)
4867             V_I8(pVarOut) = ~V_I8(pVarOut);
4868         else
4869             V_UI4(pVarOut) = ~V_UI4(pVarOut);
4870     }
4871     return hRet;
4872 }
4873
4874 /**********************************************************************
4875  *              VarNeg [OLEAUT32.173]
4876  *
4877  * Negate the value of a variant.
4878  *
4879  * PARAMS
4880  *  pVarIn  [I] Source variant
4881  *  pVarOut [O] Destination for converted value
4882  *
4883  * RETURNS
4884  *  Success: S_OK. pVarOut contains the converted value.
4885  *  Failure: An HRESULT error code indicating the error.
4886  *
4887  * NOTES
4888  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
4889  *    according to the following table:
4890  *| Input Type       Output Type
4891  *| ----------       -----------
4892  *|  VT_EMPTY         VT_I2
4893  *|  VT_UI1           VT_I2
4894  *|  VT_BOOL          VT_I2
4895  *|  VT_BSTR          VT_R8
4896  *|  All Others       Unchanged (unless promoted)
4897  *  - Where the negated value of a variant does not fit in its base type, the type
4898  *    is promoted according to the following table:
4899  *| Input Type       Promoted To
4900  *| ----------       -----------
4901  *|   VT_I2            VT_I4
4902  *|   VT_I4            VT_R8
4903  *|   VT_I8            VT_R8
4904  *  - The native version of this function returns DISP_E_BADVARTYPE for valid
4905  *    variant types that cannot be negated, and returns DISP_E_TYPEMISMATCH
4906  *    for types which are not valid. Since this is in contravention of the
4907  *    meaning of those error codes and unlikely to be relied on by applications,
4908  *    this implementation returns errors consistent with the other high level
4909  *    variant math functions.
4910  */
4911 HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut)
4912 {
4913     HRESULT hRet = S_OK;
4914     VARIANT temp;
4915
4916     VariantInit(&temp);
4917
4918     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
4919           debugstr_VF(pVarIn), pVarOut);
4920
4921     /* Handle VT_DISPATCH by storing and taking address of returned value */
4922     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
4923     {
4924         hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
4925         if (FAILED(hRet)) goto VarNeg_Exit;
4926         pVarIn = &temp;
4927     }
4928     V_VT(pVarOut) = V_VT(pVarIn);
4929
4930     switch (V_VT(pVarIn))
4931     {
4932     case VT_UI1:
4933         V_VT(pVarOut) = VT_I2;
4934         V_I2(pVarOut) = -V_UI1(pVarIn);
4935         break;
4936     case VT_BOOL:
4937         V_VT(pVarOut) = VT_I2;
4938         /* Fall through */
4939     case VT_I2:
4940         if (V_I2(pVarIn) == I2_MIN)
4941         {
4942             V_VT(pVarOut) = VT_I4;
4943             V_I4(pVarOut) = -(int)V_I2(pVarIn);
4944         }
4945         else
4946             V_I2(pVarOut) = -V_I2(pVarIn);
4947         break;
4948     case VT_I4:
4949         if (V_I4(pVarIn) == I4_MIN)
4950         {
4951             V_VT(pVarOut) = VT_R8;
4952             V_R8(pVarOut) = -(double)V_I4(pVarIn);
4953         }
4954         else
4955             V_I4(pVarOut) = -V_I4(pVarIn);
4956         break;
4957     case VT_I8:
4958         if (V_I8(pVarIn) == I8_MIN)
4959         {
4960             V_VT(pVarOut) = VT_R8;
4961             hRet = VarR8FromI8(V_I8(pVarIn), &V_R8(pVarOut));
4962             V_R8(pVarOut) *= -1.0;
4963         }
4964         else
4965             V_I8(pVarOut) = -V_I8(pVarIn);
4966         break;
4967     case VT_R4:
4968         V_R4(pVarOut) = -V_R4(pVarIn);
4969         break;
4970     case VT_DATE:
4971     case VT_R8:
4972         V_R8(pVarOut) = -V_R8(pVarIn);
4973         break;
4974     case VT_CY:
4975         hRet = VarCyNeg(V_CY(pVarIn), &V_CY(pVarOut));
4976         break;
4977     case VT_DECIMAL:
4978         hRet = VarDecNeg(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut));
4979         break;
4980     case VT_BSTR:
4981         V_VT(pVarOut) = VT_R8;
4982         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut));
4983         V_R8(pVarOut) = -V_R8(pVarOut);
4984         break;
4985     case VT_EMPTY:
4986         V_VT(pVarOut) = VT_I2;
4987         V_I2(pVarOut) = 0;
4988         break;
4989     case VT_NULL:
4990         /* No-Op */
4991         break;
4992     default:
4993         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
4994             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
4995             hRet = DISP_E_BADVARTYPE;
4996         else
4997             hRet = DISP_E_TYPEMISMATCH;
4998     }
4999 VarNeg_Exit:
5000     if (FAILED(hRet))
5001       V_VT(pVarOut) = VT_EMPTY;
5002     VariantClear(&temp);
5003
5004     return hRet;
5005 }
5006
5007 /**********************************************************************
5008  *              VarNot [OLEAUT32.174]
5009  *
5010  * Perform a not operation on a variant.
5011  *
5012  * PARAMS
5013  *  pVarIn  [I] Source variant
5014  *  pVarOut [O] Destination for converted value
5015  *
5016  * RETURNS
5017  *  Success: S_OK. pVarOut contains the converted value.
5018  *  Failure: An HRESULT error code indicating the error.
5019  *
5020  * NOTES
5021  *  - Strictly speaking, this function performs a bitwise ones complement
5022  *    on the variants value (after possibly converting to VT_I4, see below).
5023  *    This only behaves like a boolean not operation if the value in
5024  *    pVarIn is either VARIANT_TRUE or VARIANT_FALSE and the type is signed.
5025  *  - To perform a genuine not operation, convert the variant to a VT_BOOL
5026  *    before calling this function.
5027  *  - This function does not process by-reference variants.
5028  *  - The type of the value stored in pVarOut depends on the type of pVarIn,
5029  *    according to the following table:
5030  *| Input Type       Output Type
5031  *| ----------       -----------
5032  *| VT_EMPTY         VT_I2
5033  *| VT_R4            VT_I4
5034  *| VT_R8            VT_I4
5035  *| VT_BSTR          VT_I4
5036  *| VT_DECIMAL       VT_I4
5037  *| VT_CY            VT_I4
5038  *| (All others)     Unchanged
5039  */
5040 HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut)
5041 {
5042     VARIANT varIn;
5043     HRESULT hRet = S_OK;
5044     VARIANT temp;
5045
5046     VariantInit(&temp);
5047
5048     TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn),
5049           debugstr_VF(pVarIn), pVarOut);
5050
5051     /* Handle VT_DISPATCH by storing and taking address of returned value */
5052     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
5053     {
5054         hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
5055         if (FAILED(hRet)) goto VarNot_Exit;
5056         pVarIn = &temp;
5057     }
5058
5059     V_VT(pVarOut) = V_VT(pVarIn);
5060
5061     switch (V_VT(pVarIn))
5062     {
5063     case VT_I1:
5064         V_I4(pVarOut) = ~V_I1(pVarIn);
5065         V_VT(pVarOut) = VT_I4;
5066         break;
5067     case VT_UI1: V_UI1(pVarOut) = ~V_UI1(pVarIn); break;
5068     case VT_BOOL:
5069     case VT_I2:  V_I2(pVarOut) = ~V_I2(pVarIn); break;
5070     case VT_UI2:
5071         V_I4(pVarOut) = ~V_UI2(pVarIn);
5072         V_VT(pVarOut) = VT_I4;
5073         break;
5074     case VT_DECIMAL:
5075         hRet = VarI4FromDec(&V_DECIMAL(pVarIn), &V_I4(&varIn));
5076         if (FAILED(hRet))
5077             break;
5078         pVarIn = &varIn;
5079         /* Fall through ... */
5080     case VT_INT:
5081         V_VT(pVarOut) = VT_I4;
5082         /* Fall through ... */
5083     case VT_I4:  V_I4(pVarOut) = ~V_I4(pVarIn); break;
5084     case VT_UINT:
5085     case VT_UI4:
5086         V_I4(pVarOut) = ~V_UI4(pVarIn);
5087         V_VT(pVarOut) = VT_I4;
5088         break;
5089     case VT_I8:  V_I8(pVarOut) = ~V_I8(pVarIn); break;
5090     case VT_UI8:
5091         V_I4(pVarOut) = ~V_UI8(pVarIn);
5092         V_VT(pVarOut) = VT_I4;
5093         break;
5094     case VT_R4:
5095         hRet = VarI4FromR4(V_R4(pVarIn), &V_I4(pVarOut));
5096         V_I4(pVarOut) = ~V_I4(pVarOut);
5097         V_VT(pVarOut) = VT_I4;
5098         break;
5099     case VT_BSTR:
5100         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
5101         if (FAILED(hRet))
5102             break;
5103         pVarIn = &varIn;
5104         /* Fall through ... */
5105     case VT_DATE:
5106     case VT_R8:
5107         hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut));
5108         V_I4(pVarOut) = ~V_I4(pVarOut);
5109         V_VT(pVarOut) = VT_I4;
5110         break;
5111     case VT_CY:
5112         hRet = VarI4FromCy(V_CY(pVarIn), &V_I4(pVarOut));
5113         V_I4(pVarOut) = ~V_I4(pVarOut);
5114         V_VT(pVarOut) = VT_I4;
5115         break;
5116     case VT_EMPTY:
5117         V_I2(pVarOut) = ~0;
5118         V_VT(pVarOut) = VT_I2;
5119         break;
5120     case VT_NULL:
5121         /* No-Op */
5122         break;
5123     default:
5124         if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */
5125             FAILED(VARIANT_ValidateType(V_VT(pVarIn))))
5126             hRet = DISP_E_BADVARTYPE;
5127         else
5128             hRet = DISP_E_TYPEMISMATCH;
5129     }
5130 VarNot_Exit:
5131     if (FAILED(hRet))
5132       V_VT(pVarOut) = VT_EMPTY;
5133     VariantClear(&temp);
5134
5135     return hRet;
5136 }
5137
5138 /**********************************************************************
5139  *              VarRound [OLEAUT32.175]
5140  *
5141  * Perform a round operation on a variant.
5142  *
5143  * PARAMS
5144  *  pVarIn  [I] Source variant
5145  *  deci    [I] Number of decimals to round to
5146  *  pVarOut [O] Destination for converted value
5147  *
5148  * RETURNS
5149  *  Success: S_OK. pVarOut contains the converted value.
5150  *  Failure: An HRESULT error code indicating the error.
5151  *
5152  * NOTES
5153  *  - Floating point values are rounded to the desired number of decimals.
5154  *  - Some integer types are just copied to the return variable.
5155  *  - Some other integer types are not handled and fail.
5156  */
5157 HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
5158 {
5159     VARIANT varIn;
5160     HRESULT hRet = S_OK;
5161     float factor;
5162     VARIANT temp;
5163
5164     VariantInit(&temp);
5165
5166     TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci);
5167
5168     /* Handle VT_DISPATCH by storing and taking address of returned value */
5169     if ((V_VT(pVarIn) & VT_TYPEMASK) == VT_DISPATCH && ((V_VT(pVarIn) & ~VT_TYPEMASK) == 0))
5170     {
5171         hRet = VARIANT_FetchDispatchValue(pVarIn, &temp);
5172         if (FAILED(hRet)) goto VarRound_Exit;
5173         pVarIn = &temp;
5174     }
5175
5176     switch (V_VT(pVarIn))
5177     {
5178     /* cases that fail on windows */
5179     case VT_I1:
5180     case VT_I8:
5181     case VT_UI2:
5182     case VT_UI4:
5183         hRet = DISP_E_BADVARTYPE;
5184         break;
5185
5186     /* cases just copying in to out */
5187     case VT_UI1:
5188         V_VT(pVarOut) = V_VT(pVarIn);
5189         V_UI1(pVarOut) = V_UI1(pVarIn);
5190         break;
5191     case VT_I2:
5192         V_VT(pVarOut) = V_VT(pVarIn);
5193         V_I2(pVarOut) = V_I2(pVarIn);
5194         break;
5195     case VT_I4:
5196         V_VT(pVarOut) = V_VT(pVarIn);
5197         V_I4(pVarOut) = V_I4(pVarIn);
5198         break;
5199     case VT_NULL:
5200         V_VT(pVarOut) = V_VT(pVarIn);
5201         /* value unchanged */
5202         break;
5203
5204     /* cases that change type */
5205     case VT_EMPTY:
5206         V_VT(pVarOut) = VT_I2;
5207         V_I2(pVarOut) = 0;
5208         break;
5209     case VT_BOOL:
5210         V_VT(pVarOut) = VT_I2;
5211         V_I2(pVarOut) = V_BOOL(pVarIn);
5212         break;
5213     case VT_BSTR:
5214         hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
5215         if (FAILED(hRet))
5216             break;
5217         V_VT(&varIn)=VT_R8;
5218         pVarIn = &varIn;
5219         /* Fall through ... */
5220
5221     /* cases we need to do math */
5222     case VT_R8:
5223         if (V_R8(pVarIn)>0) {
5224             V_R8(pVarOut)=floor(V_R8(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
5225         } else {
5226             V_R8(pVarOut)=ceil(V_R8(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
5227         }
5228         V_VT(pVarOut) = V_VT(pVarIn);
5229         break;
5230     case VT_R4:
5231         if (V_R4(pVarIn)>0) {
5232             V_R4(pVarOut)=floor(V_R4(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
5233         } else {
5234             V_R4(pVarOut)=ceil(V_R4(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
5235         }
5236         V_VT(pVarOut) = V_VT(pVarIn);
5237         break;
5238     case VT_DATE:
5239         if (V_DATE(pVarIn)>0) {
5240             V_DATE(pVarOut)=floor(V_DATE(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
5241         } else {
5242             V_DATE(pVarOut)=ceil(V_DATE(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
5243         }
5244         V_VT(pVarOut) = V_VT(pVarIn);
5245         break;
5246     case VT_CY:
5247         if (deci>3)
5248             factor=1;
5249         else
5250             factor=pow(10, 4-deci);
5251
5252         if (V_CY(pVarIn).int64>0) {
5253             V_CY(pVarOut).int64=floor(V_CY(pVarIn).int64/factor)*factor;
5254         } else {
5255             V_CY(pVarOut).int64=ceil(V_CY(pVarIn).int64/factor)*factor;
5256         }
5257         V_VT(pVarOut) = V_VT(pVarIn);
5258         break;
5259
5260     /* cases we don't know yet */
5261     default:
5262         FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
5263                 V_VT(pVarIn) & VT_TYPEMASK, deci);
5264         hRet = DISP_E_BADVARTYPE;
5265     }
5266 VarRound_Exit:
5267     if (FAILED(hRet))
5268       V_VT(pVarOut) = VT_EMPTY;
5269     VariantClear(&temp);
5270
5271     TRACE("returning 0x%08x (%s%s),%f\n", hRet, debugstr_VT(pVarOut),
5272         debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) :
5273         (V_VT(pVarOut) == VT_R8) ? V_R8(pVarOut) : 0);
5274
5275     return hRet;
5276 }
5277
5278 /**********************************************************************
5279  *              VarIdiv [OLEAUT32.153]
5280  *
5281  * Converts input variants to integers and divides them. 
5282  *
5283  * PARAMS
5284  *  left     [I] Left hand variant
5285  *  right    [I] Right hand variant
5286  *  result   [O] Destination for quotient
5287  *
5288  * RETURNS
5289  *  Success: S_OK.  result contains the quotient.
5290  *  Failure: An HRESULT error code indicating the error.
5291  *
5292  * NOTES
5293  *  If either expression is null, null is returned, as per MSDN
5294  */
5295 HRESULT WINAPI VarIdiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
5296 {
5297     HRESULT hres = S_OK;
5298     VARTYPE resvt = VT_EMPTY;
5299     VARTYPE leftvt,rightvt;
5300     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
5301     VARIANT lv,rv;
5302     VARIANT tempLeft, tempRight;
5303
5304     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
5305           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
5306
5307     VariantInit(&lv);
5308     VariantInit(&rv);
5309     VariantInit(&tempLeft);
5310     VariantInit(&tempRight);
5311
5312     leftvt = V_VT(left)&VT_TYPEMASK;
5313     rightvt = V_VT(right)&VT_TYPEMASK;
5314     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
5315     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
5316
5317     if (leftExtraFlags != rightExtraFlags)
5318     {
5319         hres = DISP_E_BADVARTYPE;
5320         goto end;
5321     }
5322     ExtraFlags = leftExtraFlags;
5323
5324     /* Native VarIdiv always returns an error when using extra
5325      * flags or if the variant combination is I8 and INT.
5326      */
5327     if ((leftvt == VT_I8 && rightvt == VT_INT) ||
5328         (leftvt == VT_INT && rightvt == VT_I8) ||
5329         (rightvt == VT_EMPTY && leftvt != VT_NULL) ||
5330         ExtraFlags != 0)
5331     {
5332         hres = DISP_E_BADVARTYPE;
5333         goto end;
5334     }
5335
5336     /* Determine variant type */
5337     else if (leftvt == VT_NULL || rightvt == VT_NULL)
5338     {
5339         V_VT(result) = VT_NULL;
5340         hres = S_OK;
5341         goto end;
5342     }
5343     else if (leftvt == VT_I8 || rightvt == VT_I8)
5344         resvt = VT_I8;
5345     else if (leftvt == VT_I4 || rightvt == VT_I4 ||
5346         leftvt == VT_INT || rightvt == VT_INT ||
5347         leftvt == VT_UINT || rightvt == VT_UINT ||
5348         leftvt == VT_UI8 || rightvt == VT_UI8 ||
5349         leftvt == VT_UI4 || rightvt == VT_UI4 ||
5350         leftvt == VT_UI2 || rightvt == VT_UI2 ||
5351         leftvt == VT_I1 || rightvt == VT_I1 ||
5352         leftvt == VT_BSTR || rightvt == VT_BSTR ||
5353         leftvt == VT_DATE || rightvt == VT_DATE ||
5354         leftvt == VT_CY || rightvt == VT_CY ||
5355         leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
5356         leftvt == VT_R8 || rightvt == VT_R8 ||
5357         leftvt == VT_R4 || rightvt == VT_R4)
5358         resvt = VT_I4;
5359     else if (leftvt == VT_I2 || rightvt == VT_I2 ||
5360         leftvt == VT_BOOL || rightvt == VT_BOOL ||
5361         leftvt == VT_EMPTY)
5362         resvt = VT_I2;
5363     else if (leftvt == VT_UI1 || rightvt == VT_UI1)
5364         resvt = VT_UI1;
5365     else
5366     {
5367         hres = DISP_E_BADVARTYPE;
5368         goto end;
5369     }
5370
5371     /* coerce to the result type */
5372     hres = VariantChangeType(&lv, left, 0, resvt);
5373     if (hres != S_OK) goto end;
5374     hres = VariantChangeType(&rv, right, 0, resvt);
5375     if (hres != S_OK) goto end;
5376
5377     /* do the math */
5378     V_VT(result) = resvt;
5379     switch (resvt)
5380     {
5381     case VT_UI1:
5382     if (V_UI1(&rv) == 0)
5383     {
5384         hres = DISP_E_DIVBYZERO;
5385         V_VT(result) = VT_EMPTY;
5386     }
5387     else
5388         V_UI1(result) = V_UI1(&lv) / V_UI1(&rv);
5389     break;
5390     case VT_I2:
5391     if (V_I2(&rv) == 0)
5392     {
5393         hres = DISP_E_DIVBYZERO;
5394         V_VT(result) = VT_EMPTY;
5395     }
5396     else
5397         V_I2(result) = V_I2(&lv) / V_I2(&rv);
5398     break;
5399     case VT_I4:
5400     if (V_I4(&rv) == 0)
5401     {
5402         hres = DISP_E_DIVBYZERO;
5403         V_VT(result) = VT_EMPTY;
5404     }
5405     else
5406         V_I4(result) = V_I4(&lv) / V_I4(&rv);
5407     break;
5408     case VT_I8:
5409     if (V_I8(&rv) == 0)
5410     {
5411         hres = DISP_E_DIVBYZERO;
5412         V_VT(result) = VT_EMPTY;
5413     }
5414     else
5415         V_I8(result) = V_I8(&lv) / V_I8(&rv);
5416     break;
5417     default:
5418         FIXME("Couldn't integer divide variant types %d,%d\n",
5419             leftvt,rightvt);
5420     }
5421
5422 end:
5423     VariantClear(&lv);
5424     VariantClear(&rv);
5425     VariantClear(&tempLeft);
5426     VariantClear(&tempRight);
5427
5428     return hres;
5429 }
5430
5431
5432 /**********************************************************************
5433  *              VarMod [OLEAUT32.155]
5434  *
5435  * Perform the modulus operation of the right hand variant on the left
5436  *
5437  * PARAMS
5438  *  left     [I] Left hand variant
5439  *  right    [I] Right hand variant
5440  *  result   [O] Destination for converted value
5441  *
5442  * RETURNS
5443  *  Success: S_OK. result contains the remainder.
5444  *  Failure: An HRESULT error code indicating the error.
5445  *
5446  * NOTE:
5447  *   If an error occurs the type of result will be modified but the value will not be.
5448  *   Doesn't support arrays or any special flags yet.
5449  */
5450 HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
5451 {
5452     BOOL         lOk        = TRUE;
5453     BOOL         rOk        = TRUE;
5454     HRESULT      rc         = E_FAIL;
5455     int          resT = 0;
5456     VARIANT      lv,rv;
5457     VARIANT tempLeft, tempRight;
5458
5459     VariantInit(&tempLeft);
5460     VariantInit(&tempRight);
5461     VariantInit(&lv);
5462     VariantInit(&rv);
5463
5464     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
5465                   debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
5466
5467     /* Handle VT_DISPATCH by storing and taking address of returned value */
5468     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
5469     {
5470         rc = VARIANT_FetchDispatchValue(left, &tempLeft);
5471         if (FAILED(rc)) goto end;
5472         left = &tempLeft;
5473     }
5474     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
5475     {
5476         rc = VARIANT_FetchDispatchValue(right, &tempRight);
5477         if (FAILED(rc)) goto end;
5478         right = &tempRight;
5479     }
5480
5481     /* check for invalid inputs */
5482     lOk = TRUE;
5483     switch (V_VT(left) & VT_TYPEMASK) {
5484     case VT_BOOL :
5485     case VT_I1   :
5486     case VT_I2   :
5487     case VT_I4   :
5488     case VT_I8   :
5489     case VT_INT  :
5490     case VT_UI1  :
5491     case VT_UI2  :
5492     case VT_UI4  :
5493     case VT_UI8  :
5494     case VT_UINT :
5495     case VT_R4   :
5496     case VT_R8   :
5497     case VT_CY   :
5498     case VT_EMPTY:
5499     case VT_DATE :
5500     case VT_BSTR :
5501     case VT_DECIMAL:
5502       break;
5503     case VT_VARIANT:
5504     case VT_UNKNOWN:
5505       V_VT(result) = VT_EMPTY;
5506       rc = DISP_E_TYPEMISMATCH;
5507       goto end;
5508     case VT_ERROR:
5509       rc = DISP_E_TYPEMISMATCH;
5510       goto end;
5511     case VT_RECORD:
5512       V_VT(result) = VT_EMPTY;
5513       rc = DISP_E_TYPEMISMATCH;
5514       goto end;
5515     case VT_NULL:
5516       break;
5517     default:
5518       V_VT(result) = VT_EMPTY;
5519       rc = DISP_E_BADVARTYPE;
5520       goto end;
5521     }
5522
5523
5524     rOk = TRUE;
5525     switch (V_VT(right) & VT_TYPEMASK) {
5526     case VT_BOOL :
5527     case VT_I1   :
5528     case VT_I2   :
5529     case VT_I4   :
5530     case VT_I8   :
5531       if((V_VT(left) == VT_INT) && (V_VT(right) == VT_I8))
5532       {
5533         V_VT(result) = VT_EMPTY;
5534         rc = DISP_E_TYPEMISMATCH;
5535         goto end;
5536       }
5537     case VT_INT  :
5538       if((V_VT(right) == VT_INT) && (V_VT(left) == VT_I8))
5539       {
5540         V_VT(result) = VT_EMPTY;
5541         rc = DISP_E_TYPEMISMATCH;
5542         goto end;
5543       }
5544     case VT_UI1  :
5545     case VT_UI2  :
5546     case VT_UI4  :
5547     case VT_UI8  :
5548     case VT_UINT :
5549     case VT_R4   :
5550     case VT_R8   :
5551     case VT_CY   :
5552       if(V_VT(left) == VT_EMPTY)
5553       {
5554         V_VT(result) = VT_I4;
5555         rc = S_OK;
5556         goto end;
5557       }
5558     case VT_EMPTY:
5559     case VT_DATE :
5560     case VT_DECIMAL:
5561       if(V_VT(left) == VT_ERROR)
5562       {
5563         V_VT(result) = VT_EMPTY;
5564         rc = DISP_E_TYPEMISMATCH;
5565         goto end;
5566       }
5567     case VT_BSTR:
5568       if(V_VT(left) == VT_NULL)
5569       {
5570         V_VT(result) = VT_NULL;
5571         rc = S_OK;
5572         goto end;
5573       }
5574       break;
5575
5576     case VT_VOID:
5577       V_VT(result) = VT_EMPTY;
5578       rc = DISP_E_BADVARTYPE;
5579       goto end;
5580     case VT_NULL:
5581       if(V_VT(left) == VT_VOID)
5582       {
5583         V_VT(result) = VT_EMPTY;
5584         rc = DISP_E_BADVARTYPE;
5585       } else if((V_VT(left) == VT_NULL) || (V_VT(left) == VT_EMPTY) || (V_VT(left) == VT_ERROR) ||
5586                 lOk)
5587       {
5588         V_VT(result) = VT_NULL;
5589         rc = S_OK;
5590       } else
5591       {
5592         V_VT(result) = VT_NULL;
5593         rc = DISP_E_BADVARTYPE;
5594       }
5595       goto end;
5596     case VT_VARIANT:
5597     case VT_UNKNOWN:
5598       V_VT(result) = VT_EMPTY;
5599       rc = DISP_E_TYPEMISMATCH;
5600       goto end;
5601     case VT_ERROR:
5602       rc = DISP_E_TYPEMISMATCH;
5603       goto end;
5604     case VT_RECORD:
5605       if((V_VT(left) == 15) || ((V_VT(left) >= 24) && (V_VT(left) <= 35)) || !lOk)
5606       {
5607         V_VT(result) = VT_EMPTY;
5608         rc = DISP_E_BADVARTYPE;
5609       } else
5610       {
5611         V_VT(result) = VT_EMPTY;
5612         rc = DISP_E_TYPEMISMATCH;
5613       }
5614       goto end;
5615     default:
5616       V_VT(result) = VT_EMPTY;
5617       rc = DISP_E_BADVARTYPE;
5618       goto end;
5619     }
5620
5621     /* determine the result type */
5622     if((V_VT(left) == VT_I8)        || (V_VT(right) == VT_I8))   resT = VT_I8;
5623     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_BOOL)) resT = VT_I2;
5624     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_UI1))  resT = VT_UI1;
5625     else if((V_VT(left) == VT_UI1)  && (V_VT(right) == VT_I2))   resT = VT_I2;
5626     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_BOOL)) resT = VT_I2;
5627     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_UI1))  resT = VT_I2;
5628     else if((V_VT(left) == VT_I2)   && (V_VT(right) == VT_I2))   resT = VT_I2;
5629     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_BOOL)) resT = VT_I2;
5630     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_UI1))  resT = VT_I2;
5631     else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_I2))   resT = VT_I2;
5632     else resT = VT_I4; /* most outputs are I4 */
5633
5634     /* convert to I8 for the modulo */
5635     rc = VariantChangeType(&lv, left, 0, VT_I8);
5636     if(FAILED(rc))
5637     {
5638       FIXME("Could not convert left type %d to %d? rc == 0x%X\n", V_VT(left), VT_I8, rc);
5639       goto end;
5640     }
5641
5642     rc = VariantChangeType(&rv, right, 0, VT_I8);
5643     if(FAILED(rc))
5644     {
5645       FIXME("Could not convert right type %d to %d? rc == 0x%X\n", V_VT(right), VT_I8, rc);
5646       goto end;
5647     }
5648
5649     /* if right is zero set VT_EMPTY and return divide by zero */
5650     if(V_I8(&rv) == 0)
5651     {
5652       V_VT(result) = VT_EMPTY;
5653       rc = DISP_E_DIVBYZERO;
5654       goto end;
5655     }
5656
5657     /* perform the modulo operation */
5658     V_VT(result) = VT_I8;
5659     V_I8(result) = V_I8(&lv) % V_I8(&rv);
5660
5661     TRACE("V_I8(left) == %s, V_I8(right) == %s, V_I8(result) == %s\n",
5662           wine_dbgstr_longlong(V_I8(&lv)), wine_dbgstr_longlong(V_I8(&rv)),
5663           wine_dbgstr_longlong(V_I8(result)));
5664
5665     /* convert left and right to the destination type */
5666     rc = VariantChangeType(result, result, 0, resT);
5667     if(FAILED(rc))
5668     {
5669       FIXME("Could not convert 0x%x to %d?\n", V_VT(result), resT);
5670       /* fall to end of function */
5671     }
5672
5673 end:
5674     VariantClear(&lv);
5675     VariantClear(&rv);
5676     VariantClear(&tempLeft);
5677     VariantClear(&tempRight);
5678     return rc;
5679 }
5680
5681 /**********************************************************************
5682  *              VarPow [OLEAUT32.158]
5683  *
5684  * Computes the power of one variant to another variant.
5685  *
5686  * PARAMS
5687  *  left    [I] First variant
5688  *  right   [I] Second variant
5689  *  result  [O] Result variant
5690  *
5691  * RETURNS
5692  *  Success: S_OK.
5693  *  Failure: An HRESULT error code indicating the error.
5694  */
5695 HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
5696 {
5697     HRESULT hr = S_OK;
5698     VARIANT dl,dr;
5699     VARTYPE resvt = VT_EMPTY;
5700     VARTYPE leftvt,rightvt;
5701     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
5702     VARIANT tempLeft, tempRight;
5703
5704     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), debugstr_VF(left),
5705           right, debugstr_VT(right), debugstr_VF(right), result);
5706
5707     VariantInit(&dl);
5708     VariantInit(&dr);
5709     VariantInit(&tempLeft);
5710     VariantInit(&tempRight);
5711
5712     /* Handle VT_DISPATCH by storing and taking address of returned value */
5713     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
5714     {
5715         hr = VARIANT_FetchDispatchValue(left, &tempLeft);
5716         if (FAILED(hr)) goto end;
5717         left = &tempLeft;
5718     }
5719     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
5720     {
5721         hr = VARIANT_FetchDispatchValue(right, &tempRight);
5722         if (FAILED(hr)) goto end;
5723         right = &tempRight;
5724     }
5725
5726     leftvt = V_VT(left)&VT_TYPEMASK;
5727     rightvt = V_VT(right)&VT_TYPEMASK;
5728     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
5729     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
5730
5731     if (leftExtraFlags != rightExtraFlags)
5732     {
5733         hr = DISP_E_BADVARTYPE;
5734         goto end;
5735     }
5736     ExtraFlags = leftExtraFlags;
5737
5738     /* Native VarPow always returns an error when using extra flags */
5739     if (ExtraFlags != 0)
5740     {
5741         hr = DISP_E_BADVARTYPE;
5742         goto end;
5743     }
5744
5745     /* Determine return type */
5746     else if (leftvt == VT_NULL || rightvt == VT_NULL) {
5747         V_VT(result) = VT_NULL;
5748         hr = S_OK;
5749         goto end;
5750     }
5751     else if ((leftvt == VT_EMPTY || leftvt == VT_I2 ||
5752         leftvt == VT_I4 || leftvt == VT_R4 ||
5753         leftvt == VT_R8 || leftvt == VT_CY ||
5754         leftvt == VT_DATE || leftvt == VT_BSTR ||
5755         leftvt == VT_BOOL || leftvt == VT_DECIMAL ||
5756         (leftvt >= VT_I1 && leftvt <= VT_UINT)) &&
5757         (rightvt == VT_EMPTY || rightvt == VT_I2 ||
5758         rightvt == VT_I4 || rightvt == VT_R4 ||
5759         rightvt == VT_R8 || rightvt == VT_CY ||
5760         rightvt == VT_DATE || rightvt == VT_BSTR ||
5761         rightvt == VT_BOOL || rightvt == VT_DECIMAL ||
5762         (rightvt >= VT_I1 && rightvt <= VT_UINT)))
5763         resvt = VT_R8;
5764     else
5765     {
5766         hr = DISP_E_BADVARTYPE;
5767         goto end;
5768     }
5769
5770     hr = VariantChangeType(&dl,left,0,resvt);
5771     if (FAILED(hr)) {
5772         ERR("Could not change passed left argument to VT_R8, handle it differently.\n");
5773         hr = E_FAIL;
5774         goto end;
5775     }
5776
5777     hr = VariantChangeType(&dr,right,0,resvt);
5778     if (FAILED(hr)) {
5779         ERR("Could not change passed right argument to VT_R8, handle it differently.\n");
5780         hr = E_FAIL;
5781         goto end;
5782     }
5783
5784     V_VT(result) = VT_R8;
5785     V_R8(result) = pow(V_R8(&dl),V_R8(&dr));
5786
5787 end:
5788     VariantClear(&dl);
5789     VariantClear(&dr);
5790     VariantClear(&tempLeft);
5791     VariantClear(&tempRight);
5792
5793     return hr;
5794 }
5795
5796 /**********************************************************************
5797  *              VarImp [OLEAUT32.154]
5798  *
5799  * Bitwise implication of two variants.
5800  *
5801  * PARAMS
5802  *  left    [I] First variant
5803  *  right   [I] Second variant
5804  *  result  [O] Result variant
5805  *
5806  * RETURNS
5807  *  Success: S_OK.
5808  *  Failure: An HRESULT error code indicating the error.
5809  */
5810 HRESULT WINAPI VarImp(LPVARIANT left, LPVARIANT right, LPVARIANT result)
5811 {
5812     HRESULT hres = S_OK;
5813     VARTYPE resvt = VT_EMPTY;
5814     VARTYPE leftvt,rightvt;
5815     VARTYPE rightExtraFlags,leftExtraFlags,ExtraFlags;
5816     VARIANT lv,rv;
5817     double d;
5818     VARIANT tempLeft, tempRight;
5819
5820     VariantInit(&lv);
5821     VariantInit(&rv);
5822     VariantInit(&tempLeft);
5823     VariantInit(&tempRight);
5824
5825     TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
5826           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
5827
5828     /* Handle VT_DISPATCH by storing and taking address of returned value */
5829     if ((V_VT(left) & VT_TYPEMASK) == VT_DISPATCH)
5830     {
5831         hres = VARIANT_FetchDispatchValue(left, &tempLeft);
5832         if (FAILED(hres)) goto VarImp_Exit;
5833         left = &tempLeft;
5834     }
5835     if ((V_VT(right) & VT_TYPEMASK) == VT_DISPATCH)
5836     {
5837         hres = VARIANT_FetchDispatchValue(right, &tempRight);
5838         if (FAILED(hres)) goto VarImp_Exit;
5839         right = &tempRight;
5840     }
5841
5842     leftvt = V_VT(left)&VT_TYPEMASK;
5843     rightvt = V_VT(right)&VT_TYPEMASK;
5844     leftExtraFlags = V_VT(left)&(~VT_TYPEMASK);
5845     rightExtraFlags = V_VT(right)&(~VT_TYPEMASK);
5846
5847     if (leftExtraFlags != rightExtraFlags)
5848     {
5849         hres = DISP_E_BADVARTYPE;
5850         goto VarImp_Exit;
5851     }
5852     ExtraFlags = leftExtraFlags;
5853
5854     /* Native VarImp always returns an error when using extra
5855      * flags or if the variants are I8 and INT.
5856      */
5857     if ((leftvt == VT_I8 && rightvt == VT_INT) ||
5858         ExtraFlags != 0)
5859     {
5860         hres = DISP_E_BADVARTYPE;
5861         goto VarImp_Exit;
5862     }
5863
5864     /* Determine result type */
5865     else if ((leftvt == VT_NULL && rightvt == VT_NULL) ||
5866         (leftvt == VT_NULL && rightvt == VT_EMPTY))
5867     {
5868         V_VT(result) = VT_NULL;
5869         hres = S_OK;
5870         goto VarImp_Exit;
5871     }
5872     else if (leftvt == VT_I8 || rightvt == VT_I8)
5873         resvt = VT_I8;
5874     else if (leftvt == VT_I4 || rightvt == VT_I4 ||
5875         leftvt == VT_INT || rightvt == VT_INT ||
5876         leftvt == VT_UINT || rightvt == VT_UINT ||
5877         leftvt == VT_UI4 || rightvt == VT_UI4 ||
5878         leftvt == VT_UI8 || rightvt == VT_UI8 ||
5879         leftvt == VT_UI2 || rightvt == VT_UI2 ||
5880         leftvt == VT_DECIMAL || rightvt == VT_DECIMAL ||
5881         leftvt == VT_DATE || rightvt == VT_DATE ||
5882         leftvt == VT_CY || rightvt == VT_CY ||
5883         leftvt == VT_R8 || rightvt == VT_R8 ||
5884         leftvt == VT_R4 || rightvt == VT_R4 ||
5885         leftvt == VT_I1 || rightvt == VT_I1)
5886         resvt = VT_I4;
5887     else if ((leftvt == VT_UI1 && rightvt == VT_UI1) ||
5888         (leftvt == VT_UI1 && rightvt == VT_NULL) ||
5889         (leftvt == VT_NULL && rightvt == VT_UI1))
5890         resvt = VT_UI1;
5891     else if (leftvt == VT_EMPTY || rightvt == VT_EMPTY ||
5892         leftvt == VT_I2 || rightvt == VT_I2 ||
5893         leftvt == VT_UI1 || rightvt == VT_UI1)
5894         resvt = VT_I2;
5895     else if (leftvt == VT_BOOL || rightvt == VT_BOOL ||
5896         leftvt == VT_BSTR || rightvt == VT_BSTR)
5897         resvt = VT_BOOL;
5898
5899     /* VT_NULL requires special handling for when the opposite
5900      * variant is equal to something other than -1.
5901      * (NULL Imp 0 = NULL, NULL Imp n = n)
5902      */
5903     if (leftvt == VT_NULL)
5904     {
5905         VARIANT_BOOL b;
5906         switch(rightvt)
5907         {
5908         case VT_I1:   if (!V_I1(right)) resvt = VT_NULL; break;
5909         case VT_UI1:  if (!V_UI1(right)) resvt = VT_NULL; break;
5910         case VT_I2:   if (!V_I2(right)) resvt = VT_NULL; break;
5911         case VT_UI2:  if (!V_UI2(right)) resvt = VT_NULL; break;
5912         case VT_I4:   if (!V_I4(right)) resvt = VT_NULL; break;
5913         case VT_UI4:  if (!V_UI4(right)) resvt = VT_NULL; break;
5914         case VT_I8:   if (!V_I8(right)) resvt = VT_NULL; break;
5915         case VT_UI8:  if (!V_UI8(right)) resvt = VT_NULL; break;
5916         case VT_INT:  if (!V_INT(right)) resvt = VT_NULL; break;
5917         case VT_UINT: if (!V_UINT(right)) resvt = VT_NULL; break;
5918         case VT_BOOL: if (!V_BOOL(right)) resvt = VT_NULL; break;
5919         case VT_R4:   if (!V_R4(right)) resvt = VT_NULL; break;
5920         case VT_R8:   if (!V_R8(right)) resvt = VT_NULL; break;
5921         case VT_DATE: if (!V_DATE(right)) resvt = VT_NULL; break;
5922         case VT_CY:   if (!V_CY(right).int64) resvt = VT_NULL; break;
5923         case VT_DECIMAL:
5924             if (!(DEC_HI32(&V_DECIMAL(right)) || DEC_LO64(&V_DECIMAL(right))))
5925                 resvt = VT_NULL;
5926             break;
5927         case VT_BSTR:
5928             hres = VarBoolFromStr(V_BSTR(right),LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
5929             if (FAILED(hres)) goto VarImp_Exit;
5930             else if (!b)
5931                 V_VT(result) = VT_NULL;
5932             else
5933             {
5934                 V_VT(result) = VT_BOOL;
5935                 V_BOOL(result) = b;
5936             }
5937             goto VarImp_Exit;
5938         }
5939         if (resvt == VT_NULL)
5940         {
5941             V_VT(result) = resvt;
5942             goto VarImp_Exit;
5943         }
5944         else
5945         {
5946             hres = VariantChangeType(result,right,0,resvt);
5947             goto VarImp_Exit;
5948         }
5949     }
5950
5951     /* Special handling is required when NULL is the right variant.
5952      * (-1 Imp NULL = NULL, n Imp NULL = n Imp 0)
5953      */
5954     else if (rightvt == VT_NULL)
5955     {
5956         VARIANT_BOOL b;
5957         switch(leftvt)
5958         {
5959         case VT_I1:     if (V_I1(left) == -1) resvt = VT_NULL; break;
5960         case VT_UI1:    if (V_UI1(left) == 0xff) resvt = VT_NULL; break;
5961         case VT_I2:     if (V_I2(left) == -1) resvt = VT_NULL; break;
5962         case VT_UI2:    if (V_UI2(left) == 0xffff) resvt = VT_NULL; break;
5963         case VT_INT:    if (V_INT(left) == -1) resvt = VT_NULL; break;
5964         case VT_UINT:   if (V_UINT(left) == ~0u) resvt = VT_NULL; break;
5965         case VT_I4:     if (V_I4(left) == -1) resvt = VT_NULL; break;
5966         case VT_UI4:    if (V_UI4(left) == ~0u) resvt = VT_NULL; break;
5967         case VT_I8:     if (V_I8(left) == -1) resvt = VT_NULL; break;
5968         case VT_UI8:    if (V_UI8(left) == ~(ULONGLONG)0) resvt = VT_NULL; break;
5969         case VT_BOOL:   if (V_BOOL(left) == VARIANT_TRUE) resvt = VT_NULL; break;
5970         case VT_R4:     if (V_R4(left) == -1.0) resvt = VT_NULL; break;
5971         case VT_R8:     if (V_R8(left) == -1.0) resvt = VT_NULL; break;
5972         case VT_CY:     if (V_CY(left).int64 == -1) resvt = VT_NULL; break;
5973         case VT_DECIMAL:
5974             if (DEC_HI32(&V_DECIMAL(left)) == 0xffffffff)
5975                 resvt = VT_NULL;
5976             break;
5977         case VT_BSTR:
5978             hres = VarBoolFromStr(V_BSTR(left),LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
5979             if (FAILED(hres)) goto VarImp_Exit;
5980             else if (b == VARIANT_TRUE)
5981                 resvt = VT_NULL;
5982         }
5983         if (resvt == VT_NULL)
5984         {
5985             V_VT(result) = resvt;
5986             goto VarImp_Exit;
5987         }
5988     }
5989
5990     hres = VariantCopy(&lv, left);
5991     if (FAILED(hres)) goto VarImp_Exit;
5992
5993     if (rightvt == VT_NULL)
5994     {
5995         memset( &rv, 0, sizeof(rv) );
5996         V_VT(&rv) = resvt;
5997     }
5998     else
5999     {
6000         hres = VariantCopy(&rv, right);
6001         if (FAILED(hres)) goto VarImp_Exit;
6002     }
6003
6004     if (V_VT(&lv) == VT_BSTR &&
6005         FAILED(VarR8FromStr(V_BSTR(&lv),LOCALE_USER_DEFAULT, 0, &d)))
6006         hres = VariantChangeType(&lv,&lv,VARIANT_LOCALBOOL, VT_BOOL);
6007     if (SUCCEEDED(hres) && V_VT(&lv) != resvt)
6008         hres = VariantChangeType(&lv,&lv,0,resvt);
6009     if (FAILED(hres)) goto VarImp_Exit;
6010
6011     if (V_VT(&rv) == VT_BSTR &&
6012         FAILED(VarR8FromStr(V_BSTR(&rv),LOCALE_USER_DEFAULT, 0, &d)))
6013         hres = VariantChangeType(&rv, &rv,VARIANT_LOCALBOOL, VT_BOOL);
6014     if (SUCCEEDED(hres) && V_VT(&rv) != resvt)
6015         hres = VariantChangeType(&rv, &rv, 0, resvt);
6016     if (FAILED(hres)) goto VarImp_Exit;
6017
6018     /* do the math */
6019     V_VT(result) = resvt;
6020     switch (resvt)
6021     {
6022     case VT_I8:
6023     V_I8(result) = (~V_I8(&lv)) | V_I8(&rv);
6024     break;
6025     case VT_I4:
6026     V_I4(result) = (~V_I4(&lv)) | V_I4(&rv);
6027     break;
6028     case VT_I2:
6029     V_I2(result) = (~V_I2(&lv)) | V_I2(&rv);
6030     break;
6031     case VT_UI1:
6032     V_UI1(result) = (~V_UI1(&lv)) | V_UI1(&rv);
6033     break;
6034     case VT_BOOL:
6035     V_BOOL(result) = (~V_BOOL(&lv)) | V_BOOL(&rv);
6036     break;
6037     default:
6038     FIXME("Couldn't perform bitwise implication on variant types %d,%d\n",
6039         leftvt,rightvt);
6040     }
6041
6042 VarImp_Exit:
6043
6044     VariantClear(&lv);
6045     VariantClear(&rv);
6046     VariantClear(&tempLeft);
6047     VariantClear(&tempRight);
6048
6049     return hres;
6050 }