~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/oleaut32/variant.c

Version: ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * VARIANT
  3  *
  4  * Copyright 1998 Jean-Claude Cote
  5  * Copyright 2003 Jon Griffiths
  6  * Copyright 2005 Daniel Remenak
  7  * Copyright 2006 Google (Benjamin Arai)
  8  *
  9  * The algorithm for conversion from Julian days to day/month/year is based on
 10  * that devised by Henry Fliegel, as implemented in PostgreSQL, which is
 11  * Copyright 1994-7 Regents of the University of California
 12  *
 13  * This library is free software; you can redistribute it and/or
 14  * modify it under the terms of the GNU Lesser General Public
 15  * License as published by the Free Software Foundation; either
 16  * version 2.1 of the License, or (at your option) any later version.
 17  *
 18  * This library is distributed in the hope that it will be useful,
 19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 21  * Lesser General Public License for more details.
 22  *
 23  * You should have received a copy of the GNU Lesser General Public
 24  * License along with this library; if not, write to the Free Software
 25  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 26  */
 27 
 28 #include "config.h"
 29 
 30 #include <string.h>
 31 #include <stdlib.h>
 32 #include <stdarg.h>
 33 
 34 #define COBJMACROS
 35 #define NONAMELESSUNION
 36 #define NONAMELESSSTRUCT
 37 
 38 #include "windef.h"
 39 #include "winbase.h"
 40 #include "wine/unicode.h"
 41 #include "winerror.h"
 42 #include "variant.h"
 43 #include "resource.h"
 44 #include "wine/debug.h"
 45 
 46 WINE_DEFAULT_DEBUG_CHANNEL(variant);
 47 
 48 const char * const wine_vtypes[VT_CLSID+1] =
 49 {
 50   "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
 51   "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
 52   "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8",
 53   "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY",
 54   "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR","32","33","34","35",
 55   "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
 56   "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
 57   "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
 58   "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID"
 59 };
 60 
 61 const char * const wine_vflags[16] =
 62 {
 63  "",
 64  "|VT_VECTOR",
 65  "|VT_ARRAY",
 66  "|VT_VECTOR|VT_ARRAY",
 67  "|VT_BYREF",
 68  "|VT_VECTOR|VT_ARRAY",
 69  "|VT_ARRAY|VT_BYREF",
 70  "|VT_VECTOR|VT_ARRAY|VT_BYREF",
 71  "|VT_HARDTYPE",
 72  "|VT_VECTOR|VT_HARDTYPE",
 73  "|VT_ARRAY|VT_HARDTYPE",
 74  "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
 75  "|VT_BYREF|VT_HARDTYPE",
 76  "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE",
 77  "|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
 78  "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_HARDTYPE",
 79 };
 80 
 81 /* Convert a variant from one type to another */
 82 static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
 83                                      VARIANTARG* ps, VARTYPE vt)
 84 {
 85   HRESULT res = DISP_E_TYPEMISMATCH;
 86   VARTYPE vtFrom =  V_TYPE(ps);
 87   DWORD dwFlags = 0;
 88 
 89   TRACE("(%p->(%s%s),0x%08x,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd),
 90         debugstr_VF(pd), lcid, wFlags, ps, debugstr_VT(ps), debugstr_VF(ps),
 91         debugstr_vt(vt), debugstr_vf(vt));
 92 
 93   if (vt == VT_BSTR || vtFrom == VT_BSTR)
 94   {
 95     /* All flags passed to low level function are only used for
 96      * changing to or from strings. Map these here.
 97      */
 98     if (wFlags & VARIANT_LOCALBOOL)
 99       dwFlags |= VAR_LOCALBOOL;
100     if (wFlags & VARIANT_CALENDAR_HIJRI)
101       dwFlags |= VAR_CALENDAR_HIJRI;
102     if (wFlags & VARIANT_CALENDAR_THAI)
103       dwFlags |= VAR_CALENDAR_THAI;
104     if (wFlags & VARIANT_CALENDAR_GREGORIAN)
105       dwFlags |= VAR_CALENDAR_GREGORIAN;
106     if (wFlags & VARIANT_NOUSEROVERRIDE)
107       dwFlags |= LOCALE_NOUSEROVERRIDE;
108     if (wFlags & VARIANT_USE_NLS)
109       dwFlags |= LOCALE_USE_NLS;
110   }
111 
112   /* Map int/uint to i4/ui4 */
113   if (vt == VT_INT)
114     vt = VT_I4;
115   else if (vt == VT_UINT)
116     vt = VT_UI4;
117 
118   if (vtFrom == VT_INT)
119     vtFrom = VT_I4;
120   else if (vtFrom == VT_UINT)
121     vtFrom = VT_UI4;
122 
123   if (vt == vtFrom)
124      return VariantCopy(pd, ps);
125 
126   if (wFlags & VARIANT_NOVALUEPROP && vtFrom == VT_DISPATCH && vt != VT_UNKNOWN)
127   {
128     /* VARIANT_NOVALUEPROP prevents IDispatch objects from being coerced by
129      * accessing the default object property.
130      */
131     return DISP_E_TYPEMISMATCH;
132   }
133 
134   switch (vt)
135   {
136   case VT_EMPTY:
137     if (vtFrom == VT_NULL)
138       return DISP_E_TYPEMISMATCH;
139     /* ... Fall through */
140   case VT_NULL:
141     if (vtFrom <= VT_UINT && vtFrom != (VARTYPE)15 && vtFrom != VT_ERROR)
142     {
143       res = VariantClear( pd );
144       if (vt == VT_NULL && SUCCEEDED(res))
145         V_VT(pd) = VT_NULL;
146     }
147     return res;
148 
149   case VT_I1:
150     switch (vtFrom)
151     {
152     case VT_EMPTY:    V_I1(pd) = 0; return S_OK;
153     case VT_I2:       return VarI1FromI2(V_I2(ps), &V_I1(pd));
154     case VT_I4:       return VarI1FromI4(V_I4(ps), &V_I1(pd));
155     case VT_UI1:      V_I1(pd) = V_UI1(ps); return S_OK;
156     case VT_UI2:      return VarI1FromUI2(V_UI2(ps), &V_I1(pd));
157     case VT_UI4:      return VarI1FromUI4(V_UI4(ps), &V_I1(pd));
158     case VT_I8:       return VarI1FromI8(V_I8(ps), &V_I1(pd));
159     case VT_UI8:      return VarI1FromUI8(V_UI8(ps), &V_I1(pd));
160     case VT_R4:       return VarI1FromR4(V_R4(ps), &V_I1(pd));
161     case VT_R8:       return VarI1FromR8(V_R8(ps), &V_I1(pd));
162     case VT_DATE:     return VarI1FromDate(V_DATE(ps), &V_I1(pd));
163     case VT_BOOL:     return VarI1FromBool(V_BOOL(ps), &V_I1(pd));
164     case VT_CY:       return VarI1FromCy(V_CY(ps), &V_I1(pd));
165     case VT_DECIMAL:  return VarI1FromDec(&V_DECIMAL(ps), &V_I1(pd) );
166     case VT_DISPATCH: return VarI1FromDisp(V_DISPATCH(ps), lcid, &V_I1(pd) );
167     case VT_BSTR:     return VarI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_I1(pd) );
168     }
169     break;
170 
171   case VT_I2:
172     switch (vtFrom)
173     {
174     case VT_EMPTY:    V_I2(pd) = 0; return S_OK;
175     case VT_I1:       return VarI2FromI1(V_I1(ps), &V_I2(pd));
176     case VT_I4:       return VarI2FromI4(V_I4(ps), &V_I2(pd));
177     case VT_UI1:      return VarI2FromUI1(V_UI1(ps), &V_I2(pd));
178     case VT_UI2:      V_I2(pd) = V_UI2(ps); return S_OK;
179     case VT_UI4:      return VarI2FromUI4(V_UI4(ps), &V_I2(pd));
180     case VT_I8:       return VarI2FromI8(V_I8(ps), &V_I2(pd));
181     case VT_UI8:      return VarI2FromUI8(V_UI8(ps), &V_I2(pd));
182     case VT_R4:       return VarI2FromR4(V_R4(ps), &V_I2(pd));
183     case VT_R8:       return VarI2FromR8(V_R8(ps), &V_I2(pd));
184     case VT_DATE:     return VarI2FromDate(V_DATE(ps), &V_I2(pd));
185     case VT_BOOL:     return VarI2FromBool(V_BOOL(ps), &V_I2(pd));
186     case VT_CY:       return VarI2FromCy(V_CY(ps), &V_I2(pd));
187     case VT_DECIMAL:  return VarI2FromDec(&V_DECIMAL(ps), &V_I2(pd));
188     case VT_DISPATCH: return VarI2FromDisp(V_DISPATCH(ps), lcid, &V_I2(pd));
189     case VT_BSTR:     return VarI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_I2(pd));
190     }
191     break;
192 
193   case VT_I4:
194     switch (vtFrom)
195     {
196     case VT_EMPTY:    V_I4(pd) = 0; return S_OK;
197     case VT_I1:       return VarI4FromI1(V_I1(ps), &V_I4(pd));
198     case VT_I2:       return VarI4FromI2(V_I2(ps), &V_I4(pd));
199     case VT_UI1:      return VarI4FromUI1(V_UI1(ps), &V_I4(pd));
200     case VT_UI2:      return VarI4FromUI2(V_UI2(ps), &V_I4(pd));
201     case VT_UI4:      V_I4(pd) = V_UI4(ps); return S_OK;
202     case VT_I8:       return VarI4FromI8(V_I8(ps), &V_I4(pd));
203     case VT_UI8:      return VarI4FromUI8(V_UI8(ps), &V_I4(pd));
204     case VT_R4:       return VarI4FromR4(V_R4(ps), &V_I4(pd));
205     case VT_R8:       return VarI4FromR8(V_R8(ps), &V_I4(pd));
206     case VT_DATE:     return VarI4FromDate(V_DATE(ps), &V_I4(pd));
207     case VT_BOOL:     return VarI4FromBool(V_BOOL(ps), &V_I4(pd));
208     case VT_CY:       return VarI4FromCy(V_CY(ps), &V_I4(pd));
209     case VT_DECIMAL:  return VarI4FromDec(&V_DECIMAL(ps), &V_I4(pd));
210     case VT_DISPATCH: return VarI4FromDisp(V_DISPATCH(ps), lcid, &V_I4(pd));
211     case VT_BSTR:     return VarI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_I4(pd));
212     }
213     break;
214 
215   case VT_UI1:
216     switch (vtFrom)
217     {
218     case VT_EMPTY:    V_UI1(pd) = 0; return S_OK;
219     case VT_I1:       V_UI1(pd) = V_I1(ps); return S_OK;
220     case VT_I2:       return VarUI1FromI2(V_I2(ps), &V_UI1(pd));
221     case VT_I4:       return VarUI1FromI4(V_I4(ps), &V_UI1(pd));
222     case VT_UI2:      return VarUI1FromUI2(V_UI2(ps), &V_UI1(pd));
223     case VT_UI4:      return VarUI1FromUI4(V_UI4(ps), &V_UI1(pd));
224     case VT_I8:       return VarUI1FromI8(V_I8(ps), &V_UI1(pd));
225     case VT_UI8:      return VarUI1FromUI8(V_UI8(ps), &V_UI1(pd));
226     case VT_R4:       return VarUI1FromR4(V_R4(ps), &V_UI1(pd));
227     case VT_R8:       return VarUI1FromR8(V_R8(ps), &V_UI1(pd));
228     case VT_DATE:     return VarUI1FromDate(V_DATE(ps), &V_UI1(pd));
229     case VT_BOOL:     return VarUI1FromBool(V_BOOL(ps), &V_UI1(pd));
230     case VT_CY:       return VarUI1FromCy(V_CY(ps), &V_UI1(pd));
231     case VT_DECIMAL:  return VarUI1FromDec(&V_DECIMAL(ps), &V_UI1(pd));
232     case VT_DISPATCH: return VarUI1FromDisp(V_DISPATCH(ps), lcid, &V_UI1(pd));
233     case VT_BSTR:     return VarUI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI1(pd));
234     }
235     break;
236 
237   case VT_UI2:
238     switch (vtFrom)
239     {
240     case VT_EMPTY:    V_UI2(pd) = 0; return S_OK;
241     case VT_I1:       return VarUI2FromI1(V_I1(ps), &V_UI2(pd));
242     case VT_I2:       V_UI2(pd) = V_I2(ps); return S_OK;
243     case VT_I4:       return VarUI2FromI4(V_I4(ps), &V_UI2(pd));
244     case VT_UI1:      return VarUI2FromUI1(V_UI1(ps), &V_UI2(pd));
245     case VT_UI4:      return VarUI2FromUI4(V_UI4(ps), &V_UI2(pd));
246     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
247     case VT_UI8:      return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
248     case VT_R4:       return VarUI2FromR4(V_R4(ps), &V_UI2(pd));
249     case VT_R8:       return VarUI2FromR8(V_R8(ps), &V_UI2(pd));
250     case VT_DATE:     return VarUI2FromDate(V_DATE(ps), &V_UI2(pd));
251     case VT_BOOL:     return VarUI2FromBool(V_BOOL(ps), &V_UI2(pd));
252     case VT_CY:       return VarUI2FromCy(V_CY(ps), &V_UI2(pd));
253     case VT_DECIMAL:  return VarUI2FromDec(&V_DECIMAL(ps), &V_UI2(pd));
254     case VT_DISPATCH: return VarUI2FromDisp(V_DISPATCH(ps), lcid, &V_UI2(pd));
255     case VT_BSTR:     return VarUI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI2(pd));
256     }
257     break;
258 
259   case VT_UI4:
260     switch (vtFrom)
261     {
262     case VT_EMPTY:    V_UI4(pd) = 0; return S_OK;
263     case VT_I1:       return VarUI4FromI1(V_I1(ps), &V_UI4(pd));
264     case VT_I2:       return VarUI4FromI2(V_I2(ps), &V_UI4(pd));
265     case VT_I4:       V_UI4(pd) = V_I4(ps); return S_OK;
266     case VT_UI1:      return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd));
267     case VT_UI2:      return VarUI4FromUI2(V_UI2(ps), &V_UI4(pd));
268     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
269     case VT_UI8:      return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd));
270     case VT_R4:       return VarUI4FromR4(V_R4(ps), &V_UI4(pd));
271     case VT_R8:       return VarUI4FromR8(V_R8(ps), &V_UI4(pd));
272     case VT_DATE:     return VarUI4FromDate(V_DATE(ps), &V_UI4(pd));
273     case VT_BOOL:     return VarUI4FromBool(V_BOOL(ps), &V_UI4(pd));
274     case VT_CY:       return VarUI4FromCy(V_CY(ps), &V_UI4(pd));
275     case VT_DECIMAL:  return VarUI4FromDec(&V_DECIMAL(ps), &V_UI4(pd));
276     case VT_DISPATCH: return VarUI4FromDisp(V_DISPATCH(ps), lcid, &V_UI4(pd));
277     case VT_BSTR:     return VarUI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI4(pd));
278     }
279     break;
280 
281   case VT_UI8:
282     switch (vtFrom)
283     {
284     case VT_EMPTY:    V_UI8(pd) = 0; return S_OK;
285     case VT_I4:       if (V_I4(ps) < 0) return DISP_E_OVERFLOW; V_UI8(pd) = V_I4(ps); return S_OK;
286     case VT_I1:       return VarUI8FromI1(V_I1(ps), &V_UI8(pd));
287     case VT_I2:       return VarUI8FromI2(V_I2(ps), &V_UI8(pd));
288     case VT_UI1:      return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd));
289     case VT_UI2:      return VarUI8FromUI2(V_UI2(ps), &V_UI8(pd));
290     case VT_UI4:      return VarUI8FromUI4(V_UI4(ps), &V_UI8(pd));
291     case VT_I8:       V_UI8(pd) = V_I8(ps); return S_OK;
292     case VT_R4:       return VarUI8FromR4(V_R4(ps), &V_UI8(pd));
293     case VT_R8:       return VarUI8FromR8(V_R8(ps), &V_UI8(pd));
294     case VT_DATE:     return VarUI8FromDate(V_DATE(ps), &V_UI8(pd));
295     case VT_BOOL:     return VarUI8FromBool(V_BOOL(ps), &V_UI8(pd));
296     case VT_CY:       return VarUI8FromCy(V_CY(ps), &V_UI8(pd));
297     case VT_DECIMAL:  return VarUI8FromDec(&V_DECIMAL(ps), &V_UI8(pd));
298     case VT_DISPATCH: return VarUI8FromDisp(V_DISPATCH(ps), lcid, &V_UI8(pd));
299     case VT_BSTR:     return VarUI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI8(pd));
300     }
301     break;
302 
303   case VT_I8:
304     switch (vtFrom)
305     {
306     case VT_EMPTY:    V_I8(pd) = 0; return S_OK;
307     case VT_I4:       V_I8(pd) = V_I4(ps); return S_OK;
308     case VT_I1:       return VarI8FromI1(V_I1(ps), &V_I8(pd));
309     case VT_I2:       return VarI8FromI2(V_I2(ps), &V_I8(pd));
310     case VT_UI1:      return VarI8FromUI1(V_UI1(ps), &V_I8(pd));
311     case VT_UI2:      return VarI8FromUI2(V_UI2(ps), &V_I8(pd));
312     case VT_UI4:      return VarI8FromUI4(V_UI4(ps), &V_I8(pd));
313     case VT_UI8:      V_I8(pd) = V_UI8(ps); return S_OK;
314     case VT_R4:       return VarI8FromR4(V_R4(ps), &V_I8(pd));
315     case VT_R8:       return VarI8FromR8(V_R8(ps), &V_I8(pd));
316     case VT_DATE:     return VarI8FromDate(V_DATE(ps), &V_I8(pd));
317     case VT_BOOL:     return VarI8FromBool(V_BOOL(ps), &V_I8(pd));
318     case VT_CY:       return VarI8FromCy(V_CY(ps), &V_I8(pd));
319     case VT_DECIMAL:  return VarI8FromDec(&V_DECIMAL(ps), &V_I8(pd));
320     case VT_DISPATCH: return VarI8FromDisp(V_DISPATCH(ps), lcid, &V_I8(pd));
321     case VT_BSTR:     return VarI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_I8(pd));
322     }
323     break;
324 
325   case VT_R4:
326     switch (vtFrom)
327     {
328     case VT_EMPTY:    V_R4(pd) = 0.0f; return S_OK;
329     case VT_I1:       return VarR4FromI1(V_I1(ps), &V_R4(pd));
330     case VT_I2:       return VarR4FromI2(V_I2(ps), &V_R4(pd));
331     case VT_I4:       return VarR4FromI4(V_I4(ps), &V_R4(pd));
332     case VT_UI1:      return VarR4FromUI1(V_UI1(ps), &V_R4(pd));
333     case VT_UI2:      return VarR4FromUI2(V_UI2(ps), &V_R4(pd));
334     case VT_UI4:      return VarR4FromUI4(V_UI4(ps), &V_R4(pd));
335     case VT_I8:       return VarR4FromI8(V_I8(ps), &V_R4(pd));
336     case VT_UI8:      return VarR4FromUI8(V_UI8(ps), &V_R4(pd));
337     case VT_R8:       return VarR4FromR8(V_R8(ps), &V_R4(pd));
338     case VT_DATE:     return VarR4FromDate(V_DATE(ps), &V_R4(pd));
339     case VT_BOOL:     return VarR4FromBool(V_BOOL(ps), &V_R4(pd));
340     case VT_CY:       return VarR4FromCy(V_CY(ps), &V_R4(pd));
341     case VT_DECIMAL:  return VarR4FromDec(&V_DECIMAL(ps), &V_R4(pd));
342     case VT_DISPATCH: return VarR4FromDisp(V_DISPATCH(ps), lcid, &V_R4(pd));
343     case VT_BSTR:     return VarR4FromStr(V_BSTR(ps), lcid, dwFlags, &V_R4(pd));
344     }
345     break;
346 
347   case VT_R8:
348     switch (vtFrom)
349     {
350     case VT_EMPTY:    V_R8(pd) = 0.0; return S_OK;
351     case VT_I1:       return VarR8FromI1(V_I1(ps), &V_R8(pd));
352     case VT_I2:       return VarR8FromI2(V_I2(ps), &V_R8(pd));
353     case VT_I4:       return VarR8FromI4(V_I4(ps), &V_R8(pd));
354     case VT_UI1:      return VarR8FromUI1(V_UI1(ps), &V_R8(pd));
355     case VT_UI2:      return VarR8FromUI2(V_UI2(ps), &V_R8(pd));
356     case VT_UI4:      return VarR8FromUI4(V_UI4(ps), &V_R8(pd));
357     case VT_I8:       return VarR8FromI8(V_I8(ps), &V_R8(pd));
358     case VT_UI8:      return VarR8FromUI8(V_UI8(ps), &V_R8(pd));
359     case VT_R4:       return VarR8FromR4(V_R4(ps), &V_R8(pd));
360     case VT_DATE:     return VarR8FromDate(V_DATE(ps), &V_R8(pd));
361     case VT_BOOL:     return VarR8FromBool(V_BOOL(ps), &V_R8(pd));
362     case VT_CY:       return VarR8FromCy(V_CY(ps), &V_R8(pd));
363     case VT_DECIMAL:  return VarR8FromDec(&V_DECIMAL(ps), &V_R8(pd));
364     case VT_DISPATCH: return VarR8FromDisp(V_DISPATCH(ps), lcid, &V_R8(pd));
365     case VT_BSTR:     return VarR8FromStr(V_BSTR(ps), lcid, dwFlags, &V_R8(pd));
366     }
367     break;
368 
369   case VT_DATE:
370     switch (vtFrom)
371     {
372     case VT_EMPTY:    V_DATE(pd) = 0.0; return S_OK;
373     case VT_I1:       return VarDateFromI1(V_I1(ps), &V_DATE(pd));
374     case VT_I2:       return VarDateFromI2(V_I2(ps), &V_DATE(pd));
375     case VT_I4:       return VarDateFromI4(V_I4(ps), &V_DATE(pd));
376     case VT_UI1:      return VarDateFromUI1(V_UI1(ps), &V_DATE(pd));
377     case VT_UI2:      return VarDateFromUI2(V_UI2(ps), &V_DATE(pd));
378     case VT_UI4:      return VarDateFromUI4(V_UI4(ps), &V_DATE(pd));
379     case VT_I8:       return VarDateFromI8(V_I8(ps), &V_DATE(pd));
380     case VT_UI8:      return VarDateFromUI8(V_UI8(ps), &V_DATE(pd));
381     case VT_R4:       return VarDateFromR4(V_R4(ps), &V_DATE(pd));
382     case VT_R8:       return VarDateFromR8(V_R8(ps), &V_DATE(pd));
383     case VT_BOOL:     return VarDateFromBool(V_BOOL(ps), &V_DATE(pd));
384     case VT_CY:       return VarDateFromCy(V_CY(ps), &V_DATE(pd));
385     case VT_DECIMAL:  return VarDateFromDec(&V_DECIMAL(ps), &V_DATE(pd));
386     case VT_DISPATCH: return VarDateFromDisp(V_DISPATCH(ps), lcid, &V_DATE(pd));
387     case VT_BSTR:     return VarDateFromStr(V_BSTR(ps), lcid, dwFlags, &V_DATE(pd));
388     }
389     break;
390 
391   case VT_BOOL:
392     switch (vtFrom)
393     {
394     case VT_EMPTY:    V_BOOL(pd) = 0; return S_OK;
395     case VT_I1:       return VarBoolFromI1(V_I1(ps), &V_BOOL(pd));
396     case VT_I2:       return VarBoolFromI2(V_I2(ps), &V_BOOL(pd));
397     case VT_I4:       return VarBoolFromI4(V_I4(ps), &V_BOOL(pd));
398     case VT_UI1:      return VarBoolFromUI1(V_UI1(ps), &V_BOOL(pd));
399     case VT_UI2:      return VarBoolFromUI2(V_UI2(ps), &V_BOOL(pd));
400     case VT_UI4:      return VarBoolFromUI4(V_UI4(ps), &V_BOOL(pd));
401     case VT_I8:       return VarBoolFromI8(V_I8(ps), &V_BOOL(pd));
402     case VT_UI8:      return VarBoolFromUI8(V_UI8(ps), &V_BOOL(pd));
403     case VT_R4:       return VarBoolFromR4(V_R4(ps), &V_BOOL(pd));
404     case VT_R8:       return VarBoolFromR8(V_R8(ps), &V_BOOL(pd));
405     case VT_DATE:     return VarBoolFromDate(V_DATE(ps), &V_BOOL(pd));
406     case VT_CY:       return VarBoolFromCy(V_CY(ps), &V_BOOL(pd));
407     case VT_DECIMAL:  return VarBoolFromDec(&V_DECIMAL(ps), &V_BOOL(pd));
408     case VT_DISPATCH: return VarBoolFromDisp(V_DISPATCH(ps), lcid, &V_BOOL(pd));
409     case VT_BSTR:     return VarBoolFromStr(V_BSTR(ps), lcid, dwFlags, &V_BOOL(pd));
410     }
411     break;
412 
413   case VT_BSTR:
414     switch (vtFrom)
415     {
416     case VT_EMPTY:
417       V_BSTR(pd) = SysAllocStringLen(NULL, 0);
418       return V_BSTR(pd) ? S_OK : E_OUTOFMEMORY;
419     case VT_BOOL:
420       if (wFlags & (VARIANT_ALPHABOOL|VARIANT_LOCALBOOL))
421          return VarBstrFromBool(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
422       return VarBstrFromI2(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd));
423     case VT_I1:       return VarBstrFromI1(V_I1(ps), lcid, dwFlags, &V_BSTR(pd));
424     case VT_I2:       return VarBstrFromI2(V_I2(ps), lcid, dwFlags, &V_BSTR(pd));
425     case VT_I4:       return VarBstrFromI4(V_I4(ps), lcid, dwFlags, &V_BSTR(pd));
426     case VT_UI1:      return VarBstrFromUI1(V_UI1(ps), lcid, dwFlags, &V_BSTR(pd));
427     case VT_UI2:      return VarBstrFromUI2(V_UI2(ps), lcid, dwFlags, &V_BSTR(pd));
428     case VT_UI4:      return VarBstrFromUI4(V_UI4(ps), lcid, dwFlags, &V_BSTR(pd));
429     case VT_I8:       return VarBstrFromI8(V_I8(ps), lcid, dwFlags, &V_BSTR(pd));
430     case VT_UI8:      return VarBstrFromUI8(V_UI8(ps), lcid, dwFlags, &V_BSTR(pd));
431     case VT_R4:       return VarBstrFromR4(V_R4(ps), lcid, dwFlags, &V_BSTR(pd));
432     case VT_R8:       return VarBstrFromR8(V_R8(ps), lcid, dwFlags, &V_BSTR(pd));
433     case VT_DATE:     return VarBstrFromDate(V_DATE(ps), lcid, dwFlags, &V_BSTR(pd));
434     case VT_CY:       return VarBstrFromCy(V_CY(ps), lcid, dwFlags, &V_BSTR(pd));
435     case VT_DECIMAL:  return VarBstrFromDec(&V_DECIMAL(ps), lcid, dwFlags, &V_BSTR(pd));
436     case VT_DISPATCH: return VarBstrFromDisp(V_DISPATCH(ps), lcid, dwFlags, &V_BSTR(pd));
437     }
438     break;
439 
440   case VT_CY:
441     switch (vtFrom)
442     {
443     case VT_EMPTY:    V_CY(pd).int64 = 0; return S_OK;
444     case VT_I1:       return VarCyFromI1(V_I1(ps), &V_CY(pd));
445     case VT_I2:       return VarCyFromI2(V_I2(ps), &V_CY(pd));
446     case VT_I4:       return VarCyFromI4(V_I4(ps), &V_CY(pd));
447     case VT_UI1:      return VarCyFromUI1(V_UI1(ps), &V_CY(pd));
448     case VT_UI2:      return VarCyFromUI2(V_UI2(ps), &V_CY(pd));
449     case VT_UI4:      return VarCyFromUI4(V_UI4(ps), &V_CY(pd));
450     case VT_I8:       return VarCyFromI8(V_I8(ps), &V_CY(pd));
451     case VT_UI8:      return VarCyFromUI8(V_UI8(ps), &V_CY(pd));
452     case VT_R4:       return VarCyFromR4(V_R4(ps), &V_CY(pd));
453     case VT_R8:       return VarCyFromR8(V_R8(ps), &V_CY(pd));
454     case VT_DATE:     return VarCyFromDate(V_DATE(ps), &V_CY(pd));
455     case VT_BOOL:     return VarCyFromBool(V_BOOL(ps), &V_CY(pd));
456     case VT_DECIMAL:  return VarCyFromDec(&V_DECIMAL(ps), &V_CY(pd));
457     case VT_DISPATCH: return VarCyFromDisp(V_DISPATCH(ps), lcid, &V_CY(pd));
458     case VT_BSTR:     return VarCyFromStr(V_BSTR(ps), lcid, dwFlags, &V_CY(pd));
459     }
460     break;
461 
462   case VT_DECIMAL:
463     switch (vtFrom)
464     {
465     case VT_EMPTY:
466     case VT_BOOL:
467        DEC_SIGNSCALE(&V_DECIMAL(pd)) = SIGNSCALE(DECIMAL_POS,0);
468        DEC_HI32(&V_DECIMAL(pd)) = 0;
469        DEC_MID32(&V_DECIMAL(pd)) = 0;
470         /* VarDecFromBool() coerces to -1/0, ChangeTypeEx() coerces to 1/0.
471          * VT_NULL and VT_EMPTY always give a 0 value.
472          */
473        DEC_LO32(&V_DECIMAL(pd)) = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0;
474        return S_OK;
475     case VT_I1:       return VarDecFromI1(V_I1(ps), &V_DECIMAL(pd));
476     case VT_I2:       return VarDecFromI2(V_I2(ps), &V_DECIMAL(pd));
477     case VT_I4:       return VarDecFromI4(V_I4(ps), &V_DECIMAL(pd));
478     case VT_UI1:      return VarDecFromUI1(V_UI1(ps), &V_DECIMAL(pd));
479     case VT_UI2:      return VarDecFromUI2(V_UI2(ps), &V_DECIMAL(pd));
480     case VT_UI4:      return VarDecFromUI4(V_UI4(ps), &V_DECIMAL(pd));
481     case VT_I8:       return VarDecFromI8(V_I8(ps), &V_DECIMAL(pd));
482     case VT_UI8:      return VarDecFromUI8(V_UI8(ps), &V_DECIMAL(pd));
483     case VT_R4:       return VarDecFromR4(V_R4(ps), &V_DECIMAL(pd));
484     case VT_R8:       return VarDecFromR8(V_R8(ps), &V_DECIMAL(pd));
485     case VT_DATE:     return VarDecFromDate(V_DATE(ps), &V_DECIMAL(pd));
486     case VT_CY:       return VarDecFromCy(V_CY(ps), &V_DECIMAL(pd));
487     case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(pd));
488     case VT_BSTR:     return VarDecFromStr(V_BSTR(ps), lcid, dwFlags, &V_DECIMAL(pd));
489     }
490     break;
491 
492   case VT_UNKNOWN:
493     switch (vtFrom)
494     {
495     case VT_DISPATCH:
496       if (V_DISPATCH(ps) == NULL)
497         V_UNKNOWN(pd) = NULL;
498       else
499         res = IDispatch_QueryInterface(V_DISPATCH(ps), &IID_IUnknown, (LPVOID*)&V_UNKNOWN(pd));
500       break;
501     }
502     break;
503 
504   case VT_DISPATCH:
505     switch (vtFrom)
506     {
507     case VT_UNKNOWN:
508       if (V_UNKNOWN(ps) == NULL)
509         V_DISPATCH(pd) = NULL;
510       else
511         res = IUnknown_QueryInterface(V_UNKNOWN(ps), &IID_IDispatch, (LPVOID*)&V_DISPATCH(pd));
512       break;
513     }
514     break;
515 
516   case VT_RECORD:
517     break;
518   }
519   return res;
520 }
521 
522 /* Coerce to/from an array */
523 static inline HRESULT VARIANT_CoerceArray(VARIANTARG* pd, VARIANTARG* ps, VARTYPE vt)
524 {
525   if (vt == VT_BSTR && V_VT(ps) == (VT_ARRAY|VT_UI1))
526     return BstrFromVector(V_ARRAY(ps), &V_BSTR(pd));
527 
528   if (V_VT(ps) == VT_BSTR && vt == (VT_ARRAY|VT_UI1))
529     return VectorFromBstr(V_BSTR(ps), &V_ARRAY(ps));
530 
531   if (V_VT(ps) == vt)
532     return SafeArrayCopy(V_ARRAY(ps), &V_ARRAY(pd));
533 
534   return DISP_E_TYPEMISMATCH;
535 }
536 
537 /******************************************************************************
538  * Check if a variants type is valid.
539  */
540 static inline HRESULT VARIANT_ValidateType(VARTYPE vt)
541 {
542   VARTYPE vtExtra = vt & VT_EXTRA_TYPE;
543 
544   vt &= VT_TYPEMASK;
545 
546   if (!(vtExtra & (VT_VECTOR|VT_RESERVED)))
547   {
548     if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID)
549     {
550       if ((vtExtra & (VT_BYREF|VT_ARRAY)) && vt <= VT_NULL)
551         return DISP_E_BADVARTYPE;
552       if (vt != (VARTYPE)15)
553         return S_OK;
554     }
555   }
556   return DISP_E_BADVARTYPE;
557 }
558 
559 /******************************************************************************
560  *              VariantInit     [OLEAUT32.8]
561  *
562  * Initialise a variant.
563  *
564  * PARAMS
565  *  pVarg [O] Variant to initialise
566  *
567  * RETURNS
568  *  Nothing.
569  *
570  * NOTES
571  *  This function simply sets the type of the variant to VT_EMPTY. It does not
572  *  free any existing value, use VariantClear() for that.
573  */
574 void WINAPI VariantInit(VARIANTARG* pVarg)
575 {
576   TRACE("(%p)\n", pVarg);
577 
578   V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */
579 }
580 
581 /******************************************************************************
582  *              VariantClear    [OLEAUT32.9]
583  *
584  * Clear a variant.
585  *
586  * PARAMS
587  *  pVarg [I/O] Variant to clear
588  *
589  * RETURNS
590  *  Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY.
591  *  Failure: DISP_E_BADVARTYPE, if the variant is a not a valid variant type.
592  */
593 HRESULT WINAPI VariantClear(VARIANTARG* pVarg)
594 {
595   HRESULT hres = S_OK;
596 
597   TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg));
598 
599   hres = VARIANT_ValidateType(V_VT(pVarg));
600 
601   if (SUCCEEDED(hres))
602   {
603     if (!V_ISBYREF(pVarg))
604     {
605       if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY)
606       {
607         if (V_ARRAY(pVarg))
608           hres = SafeArrayDestroy(V_ARRAY(pVarg));
609       }
610       else if (V_VT(pVarg) == VT_BSTR)
611       {
612         SysFreeString(V_BSTR(pVarg));
613       }
614       else if (V_VT(pVarg) == VT_RECORD)
615       {
616         struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
617         if (pBr->pRecInfo)
618         {
619           IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord);
620           IRecordInfo_Release(pBr->pRecInfo);
621         }
622       }
623       else if (V_VT(pVarg) == VT_DISPATCH ||
624                V_VT(pVarg) == VT_UNKNOWN)
625       {
626         if (V_UNKNOWN(pVarg))
627           IUnknown_Release(V_UNKNOWN(pVarg));
628       }
629     }
630     V_VT(pVarg) = VT_EMPTY;
631   }
632   return hres;
633 }
634 
635 /******************************************************************************
636  * Copy an IRecordInfo object contained in a variant.
637  */
638 static HRESULT VARIANT_CopyIRecordInfo(struct __tagBRECORD* pBr)
639 {
640   HRESULT hres = S_OK;
641 
642   if (pBr->pRecInfo)
643   {
644     ULONG ulSize;
645 
646     hres = IRecordInfo_GetSize(pBr->pRecInfo, &ulSize);
647     if (SUCCEEDED(hres))
648     {
649       PVOID pvRecord = HeapAlloc(GetProcessHeap(), 0, ulSize);
650       if (!pvRecord)
651         hres = E_OUTOFMEMORY;
652       else
653       {
654         memcpy(pvRecord, pBr->pvRecord, ulSize);
655         pBr->pvRecord = pvRecord;
656 
657         hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord);
658         if (SUCCEEDED(hres))
659           IRecordInfo_AddRef(pBr->pRecInfo);
660       }
661     }
662   }
663   else if (pBr->pvRecord)
664     hres = E_INVALIDARG;
665   return hres;
666 }
667 
668 /******************************************************************************
669  *    VariantCopy  [OLEAUT32.10]
670  *
671  * Copy a variant.
672  *
673  * PARAMS
674  *  pvargDest [O] Destination for copy
675  *  pvargSrc  [I] Source variant to copy
676  *
677  * RETURNS
678  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
679  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid type.
680  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
681  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
682  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
683  *
684  * NOTES
685  *  - If pvargSrc == pvargDest, this function does nothing, and succeeds if
686  *    pvargSrc is valid. Otherwise, pvargDest is always cleared using
687  *    VariantClear() before pvargSrc is copied to it. If clearing pvargDest
688  *    fails, so does this function.
689  *  - VT_CLSID is a valid type type for pvargSrc, but not for pvargDest.
690  *  - For by-value non-intrinsic types, a deep copy is made, i.e. The whole value
691  *    is copied rather than just any pointers to it.
692  *  - For by-value object types the object pointer is copied and the objects
693  *    reference count increased using IUnknown_AddRef().
694  *  - For all by-reference types, only the referencing pointer is copied.
695  */
696 HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
697 {
698   HRESULT hres = S_OK;
699 
700   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
701         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
702         debugstr_VF(pvargSrc));
703 
704   if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */
705       FAILED(VARIANT_ValidateType(V_VT(pvargSrc))))
706     return DISP_E_BADVARTYPE;
707 
708   if (pvargSrc != pvargDest &&
709       SUCCEEDED(hres = VariantClear(pvargDest)))
710   {
711     *pvargDest = *pvargSrc; /* Shallow copy the value */
712 
713     if (!V_ISBYREF(pvargSrc))
714     {
715       if (V_ISARRAY(pvargSrc))
716       {
717         if (V_ARRAY(pvargSrc))
718           hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest));
719       }
720       else if (V_VT(pvargSrc) == VT_BSTR)
721       {
722         V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc)));
723         if (!V_BSTR(pvargDest))
724         {
725           TRACE("!V_BSTR(pvargDest), SysAllocStringByteLen() failed to allocate %d bytes\n", SysStringByteLen(V_BSTR(pvargSrc)));
726           hres = E_OUTOFMEMORY;
727         }
728       }
729       else if (V_VT(pvargSrc) == VT_RECORD)
730       {
731         hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
732       }
733       else if (V_VT(pvargSrc) == VT_DISPATCH ||
734                V_VT(pvargSrc) == VT_UNKNOWN)
735       {
736         if (V_UNKNOWN(pvargSrc))
737           IUnknown_AddRef(V_UNKNOWN(pvargSrc));
738       }
739     }
740   }
741   return hres;
742 }
743 
744 /* Return the byte size of a variants data */
745 static inline size_t VARIANT_DataSize(const VARIANT* pv)
746 {
747   switch (V_TYPE(pv))
748   {
749   case VT_I1:
750   case VT_UI1:   return sizeof(BYTE);
751   case VT_I2:
752   case VT_UI2:   return sizeof(SHORT);
753   case VT_INT:
754   case VT_UINT:
755   case VT_I4:
756   case VT_UI4:   return sizeof(LONG);
757   case VT_I8:
758   case VT_UI8:   return sizeof(LONGLONG);
759   case VT_R4:    return sizeof(float);
760   case VT_R8:    return sizeof(double);
761   case VT_DATE:  return sizeof(DATE);
762   case VT_BOOL:  return sizeof(VARIANT_BOOL);
763   case VT_DISPATCH:
764   case VT_UNKNOWN:
765   case VT_BSTR:  return sizeof(void*);
766   case VT_CY:    return sizeof(CY);
767   case VT_ERROR: return sizeof(SCODE);
768   }
769   TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv));
770   return 0;
771 }
772 
773 /******************************************************************************
774  *    VariantCopyInd  [OLEAUT32.11]
775  *
776  * Copy a variant, dereferencing it if it is by-reference.
777  *
778  * PARAMS
779  *  pvargDest [O] Destination for copy
780  *  pvargSrc  [I] Source variant to copy
781  *
782  * RETURNS
783  *  Success: S_OK. pvargDest contains a copy of pvargSrc.
784  *  Failure: An HRESULT error code indicating the error.
785  *
786  * NOTES
787  *  Failure: DISP_E_BADVARTYPE, if either variant has an invalid by-value type.
788  *           E_INVALIDARG, if pvargSrc  is an invalid by-reference type.
789  *           E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an
790  *           HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(),
791  *           or IRecordInfo_RecordCopy(), depending on the type of pvargSrc.
792  *
793  * NOTES
794  *  - If pvargSrc is by-value, this function behaves exactly as VariantCopy().
795  *  - If pvargSrc is by-reference, the value copied to pvargDest is the pointed-to
796  *    value.
797  *  - if pvargSrc == pvargDest, this function dereferences in place. Otherwise,
798  *    pvargDest is always cleared using VariantClear() before pvargSrc is copied
799  *    to it. If clearing pvargDest fails, so does this function.
800  */
801 HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
802 {
803   VARIANTARG vTmp, *pSrc = pvargSrc;
804   VARTYPE vt;
805   HRESULT hres = S_OK;
806 
807   TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest),
808         debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc),
809         debugstr_VF(pvargSrc));
810 
811   if (!V_ISBYREF(pvargSrc))
812     return VariantCopy(pvargDest, pvargSrc);
813 
814   /* Argument checking is more lax than VariantCopy()... */
815   vt = V_TYPE(pvargSrc);
816   if (V_ISARRAY(pvargSrc) ||
817      (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID &&
818      !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED))))
819   {
820     /* OK */
821   }
822   else
823     return E_INVALIDARG; /* ...And the return value for invalid types differs too */
824 
825   if (pvargSrc == pvargDest)
826   {
827     /* In place copy. Use a shallow copy of pvargSrc & init pvargDest.
828      * This avoids an expensive VariantCopy() call - e.g. SafeArrayCopy().
829      */
830     vTmp = *pvargSrc;
831     pSrc = &vTmp;
832     V_VT(pvargDest) = VT_EMPTY;
833   }
834   else