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