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

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

Version: ~ [ 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 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

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