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