1 /*
2 * Low level variant functions
3 *
4 * Copyright 2003 Jon Griffiths
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define COBJMACROS
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
24
25 #include "wine/debug.h"
26 #include "wine/unicode.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnt.h"
30 #include "variant.h"
31 #include "resource.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(variant);
34
35 extern HMODULE hProxyDll DECLSPEC_HIDDEN;
36
37 #define CY_MULTIPLIER 10000 /* 4 dp of precision */
38 #define CY_MULTIPLIER_F 10000.0
39 #define CY_HALF (CY_MULTIPLIER/2) /* 0.5 */
40 #define CY_HALF_F (CY_MULTIPLIER_F/2.0)
41
42 static const WCHAR szFloatFormatW[] = { '%','.','7','G','\0' };
43 static const WCHAR szDoubleFormatW[] = { '%','.','1','5','G','\0' };
44
45 /* Copy data from one variant to another. */
46 static inline void VARIANT_CopyData(const VARIANT *srcVar, VARTYPE vt, void *pOut)
47 {
48 switch (vt)
49 {
50 case VT_I1:
51 case VT_UI1: memcpy(pOut, &V_UI1(srcVar), sizeof(BYTE)); break;
52 case VT_BOOL:
53 case VT_I2:
54 case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT)); break;
55 case VT_R4:
56 case VT_INT:
57 case VT_I4:
58 case VT_UINT:
59 case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG)); break;
60 case VT_R8:
61 case VT_DATE:
62 case VT_CY:
63 case VT_I8:
64 case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONG64)); break;
65 case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break;
66 case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break;
67 case VT_BSTR: memcpy(pOut, &V_BSTR(srcVar), sizeof(BSTR)); break;
68 default:
69 FIXME("VT_ type %d unhandled, please report!\n", vt);
70 }
71 }
72
73 /* Macro to inline conversion from a float or double to any integer type,
74 * rounding according to the 'dutch' convention.
75 */
76 #define VARIANT_DutchRound(typ, value, res) do { \
77 double whole = value < 0 ? ceil(value) : floor(value); \
78 double fract = value - whole; \
79 if (fract > 0.5) res = (typ)whole + (typ)1; \
80 else if (fract == 0.5) { typ is_odd = (typ)whole & 1; res = whole + is_odd; } \
81 else if (fract >= 0.0) res = (typ)whole; \
82 else if (fract == -0.5) { typ is_odd = (typ)whole & 1; res = whole - is_odd; } \
83 else if (fract > -0.5) res = (typ)whole; \
84 else res = (typ)whole - (typ)1; \
85 } while(0)
86
87
88 /* Coerce VT_BSTR to a numeric type */
89 static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags,
90 void* pOut, VARTYPE vt)
91 {
92 VARIANTARG dstVar;
93 HRESULT hRet;
94 NUMPARSE np;
95 BYTE rgb[1024];
96
97 /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
98 np.cDig = sizeof(rgb) / sizeof(BYTE);
99 np.dwInFlags = NUMPRS_STD;
100
101 hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);
102
103 if (SUCCEEDED(hRet))
104 {
105 /* 1 << vt gives us the VTBIT constant for the destination number type */
106 hRet = VarNumFromParseNum(&np, rgb, 1 << vt, &dstVar);
107 if (SUCCEEDED(hRet))
108 VARIANT_CopyData(&dstVar, vt, pOut);
109 }
110 return hRet;
111 }
112
113 /* Coerce VT_DISPATCH to another type */
114 static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut,
115 VARTYPE vt, DWORD dwFlags)
116 {
117 static DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
118 VARIANTARG srcVar, dstVar;
119 HRESULT hRet;
120
121 if (!pdispIn)
122 return DISP_E_BADVARTYPE;
123
124 /* Get the default 'value' property from the IDispatch */
125 hRet = IDispatch_Invoke(pdispIn, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET,
126 &emptyParams, &srcVar, NULL, NULL);
127
128 if (SUCCEEDED(hRet))
129 {
130 /* Convert the property to the requested type */
131 V_VT(&dstVar) = VT_EMPTY;
132 hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, dwFlags, vt);
133 VariantClear(&srcVar);
134
135 if (SUCCEEDED(hRet))
136 {
137 VARIANT_CopyData(&dstVar, vt, pOut);
138 VariantClear(&srcVar);
139 }
140 }
141 else
142 hRet = DISP_E_TYPEMISMATCH;
143 return hRet;
144 }
145
146 /* Inline return type */
147 #define RETTYP static inline HRESULT
148
149
150 /* Simple compiler cast from one type to another */
151 #define SIMPLE(dest, src, func) RETTYP _##func(src in, dest* out) { \
152 *out = in; return S_OK; }
153
154 /* Compiler cast where input cannot be negative */
155 #define NEGTST(dest, src, func) RETTYP _##func(src in, dest* out) { \
156 if (in < 0) return DISP_E_OVERFLOW; *out = in; return S_OK; }
157
158 /* Compiler cast where input cannot be > some number */
159 #define POSTST(dest, src, func, tst) RETTYP _##func(src in, dest* out) { \
160 if (in > (dest)tst) return DISP_E_OVERFLOW; *out = in; return S_OK; }
161
162 /* Compiler cast where input cannot be < some number or >= some other number */
163 #define BOTHTST(dest, src, func, lo, hi) RETTYP _##func(src in, dest* out) { \
164 if (in < (dest)lo || in > hi) return DISP_E_OVERFLOW; *out = in; return S_OK; }
165
166 /* I1 */
167 POSTST(signed char, BYTE, VarI1FromUI1, I1_MAX)
168 BOTHTST(signed char, SHORT, VarI1FromI2, I1_MIN, I1_MAX)
169 BOTHTST(signed char, LONG, VarI1FromI4, I1_MIN, I1_MAX)
170 SIMPLE(signed char, VARIANT_BOOL, VarI1FromBool)
171 POSTST(signed char, USHORT, VarI1FromUI2, I1_MAX)
172 POSTST(signed char, ULONG, VarI1FromUI4, I1_MAX)
173 BOTHTST(signed char, LONG64, VarI1FromI8, I1_MIN, I1_MAX)
174 POSTST(signed char, ULONG64, VarI1FromUI8, I1_MAX)
175
176 /* UI1 */
177 BOTHTST(BYTE, SHORT, VarUI1FromI2, UI1_MIN, UI1_MAX)
178 SIMPLE(BYTE, VARIANT_BOOL, VarUI1FromBool)
179 NEGTST(BYTE, signed char, VarUI1FromI1)
180 POSTST(BYTE, USHORT, VarUI1FromUI2, UI1_MAX)
181 BOTHTST(BYTE, LONG, VarUI1FromI4, UI1_MIN, UI1_MAX)
182 POSTST(BYTE, ULONG, VarUI1FromUI4, UI1_MAX)
183 BOTHTST(BYTE, LONG64, VarUI1FromI8, UI1_MIN, UI1_MAX)
184 POSTST(BYTE, ULONG64, VarUI1FromUI8, UI1_MAX)
185
186 /* I2 */
187 SIMPLE(SHORT, BYTE, VarI2FromUI1)
188 BOTHTST(SHORT, LONG, VarI2FromI4, I2_MIN, I2_MAX)
189 SIMPLE(SHORT, VARIANT_BOOL, VarI2FromBool)
190 SIMPLE(SHORT, signed char, VarI2FromI1)
191 POSTST(SHORT, USHORT, VarI2FromUI2, I2_MAX)
192 POSTST(SHORT, ULONG, VarI2FromUI4, I2_MAX)
193 BOTHTST(SHORT, LONG64, VarI2FromI8, I2_MIN, I2_MAX)
194 POSTST(SHORT, ULONG64, VarI2FromUI8, I2_MAX)
195
196 /* UI2 */
197 SIMPLE(USHORT, BYTE, VarUI2FromUI1)
198 NEGTST(USHORT, SHORT, VarUI2FromI2)
199 BOTHTST(USHORT, LONG, VarUI2FromI4, UI2_MIN, UI2_MAX)
200 SIMPLE(USHORT, VARIANT_BOOL, VarUI2FromBool)
201 NEGTST(USHORT, signed char, VarUI2FromI1)
202 POSTST(USHORT, ULONG, VarUI2FromUI4, UI2_MAX)
203 BOTHTST(USHORT, LONG64, VarUI2FromI8, UI2_MIN, UI2_MAX)
204 POSTST(USHORT, ULONG64, VarUI2FromUI8, UI2_MAX)
205
206 /* I4 */
207 SIMPLE(LONG, BYTE, VarI4FromUI1)
208 SIMPLE(LONG, SHORT, VarI4FromI2)
209 SIMPLE(LONG, VARIANT_BOOL, VarI4FromBool)
210 SIMPLE(LONG, signed char, VarI4FromI1)
211 SIMPLE(LONG, USHORT, VarI4FromUI2)
212 POSTST(LONG, ULONG, VarI4FromUI4, I4_MAX)
213 BOTHTST(LONG, LONG64, VarI4FromI8, I4_MIN, I4_MAX)
214 POSTST(LONG, ULONG64, VarI4FromUI8, I4_MAX)
215
216 /* UI4 */
217 SIMPLE(ULONG, BYTE, VarUI4FromUI1)
218 NEGTST(ULONG, SHORT, VarUI4FromI2)
219 NEGTST(ULONG, LONG, VarUI4FromI4)
220 SIMPLE(ULONG, VARIANT_BOOL, VarUI4FromBool)
221 NEGTST(ULONG, signed char, VarUI4FromI1)
222 SIMPLE(ULONG, USHORT, VarUI4FromUI2)
223 BOTHTST(ULONG, LONG64, VarUI4FromI8, UI4_MIN, UI4_MAX)
224 POSTST(ULONG, ULONG64, VarUI4FromUI8, UI4_MAX)
225
226 /* I8 */
227 SIMPLE(LONG64, BYTE, VarI8FromUI1)
228 SIMPLE(LONG64, SHORT, VarI8FromI2)
229 SIMPLE(LONG64, signed char, VarI8FromI1)
230 SIMPLE(LONG64, USHORT, VarI8FromUI2)
231 SIMPLE(LONG64, ULONG, VarI8FromUI4)
232 POSTST(LONG64, ULONG64, VarI8FromUI8, I8_MAX)
233
234 /* UI8 */
235 SIMPLE(ULONG64, BYTE, VarUI8FromUI1)
236 NEGTST(ULONG64, SHORT, VarUI8FromI2)
237 NEGTST(ULONG64, signed char, VarUI8FromI1)
238 SIMPLE(ULONG64, USHORT, VarUI8FromUI2)
239 SIMPLE(ULONG64, ULONG, VarUI8FromUI4)
240 NEGTST(ULONG64, LONG64, VarUI8FromI8)
241
242 /* R4 (float) */
243 SIMPLE(float, BYTE, VarR4FromUI1)
244 SIMPLE(float, SHORT, VarR4FromI2)
245 SIMPLE(float, signed char, VarR4FromI1)
246 SIMPLE(float, USHORT, VarR4FromUI2)
247 SIMPLE(float, LONG, VarR4FromI4)
248 SIMPLE(float, ULONG, VarR4FromUI4)
249 SIMPLE(float, LONG64, VarR4FromI8)
250 SIMPLE(float, ULONG64, VarR4FromUI8)
251
252 /* R8 (double) */
253 SIMPLE(double, BYTE, VarR8FromUI1)
254 SIMPLE(double, SHORT, VarR8FromI2)
255 SIMPLE(double, float, VarR8FromR4)
256 RETTYP _VarR8FromCy(CY i, double* o) { *o = (double)i.int64 / CY_MULTIPLIER_F; return S_OK; }
257 SIMPLE(double, DATE, VarR8FromDate)
258 SIMPLE(double, signed char, VarR8FromI1)
259 SIMPLE(double, USHORT, VarR8FromUI2)
260 SIMPLE(double, LONG, VarR8FromI4)
261 SIMPLE(double, ULONG, VarR8FromUI4)
262 SIMPLE(double, LONG64, VarR8FromI8)
263 SIMPLE(double, ULONG64, VarR8FromUI8)
264
265
266 /* I1
267 */
268
269 /************************************************************************
270 * VarI1FromUI1 (OLEAUT32.244)
271 *
272 * Convert a VT_UI1 to a VT_I1.
273 *
274 * PARAMS
275 * bIn [I] Source
276 * pcOut [O] Destination
277 *
278 * RETURNS
279 * Success: S_OK.
280 * Failure: E_INVALIDARG, if the source value is invalid
281 * DISP_E_OVERFLOW, if the value will not fit in the destination
282 */
283 HRESULT WINAPI VarI1FromUI1(BYTE bIn, signed char* pcOut)
284 {
285 return _VarI1FromUI1(bIn, pcOut);
286 }
287
288 /************************************************************************
289 * VarI1FromI2 (OLEAUT32.245)
290 *
291 * Convert a VT_I2 to a VT_I1.
292 *
293 * PARAMS
294 * sIn [I] Source
295 * pcOut [O] Destination
296 *
297 * RETURNS
298 * Success: S_OK.
299 * Failure: E_INVALIDARG, if the source value is invalid
300 * DISP_E_OVERFLOW, if the value will not fit in the destination
301 */
302 HRESULT WINAPI VarI1FromI2(SHORT sIn, signed char* pcOut)
303 {
304 return _VarI1FromI2(sIn, pcOut);
305 }
306
307 /************************************************************************
308 * VarI1FromI4 (OLEAUT32.246)
309 *
310 * Convert a VT_I4 to a VT_I1.
311 *
312 * PARAMS
313 * iIn [I] Source
314 * pcOut [O] Destination
315 *
316 * RETURNS
317 * Success: S_OK.
318 * Failure: E_INVALIDARG, if the source value is invalid
319 * DISP_E_OVERFLOW, if the value will not fit in the destination
320 */
321 HRESULT WINAPI VarI1FromI4(LONG iIn, signed char* pcOut)
322 {
323 return _VarI1FromI4(iIn, pcOut);
324 }
325
326 /************************************************************************
327 * VarI1FromR4 (OLEAUT32.247)
328 *
329 * Convert a VT_R4 to a VT_I1.
330 *
331 * PARAMS
332 * fltIn [I] Source
333 * pcOut [O] Destination
334 *
335 * RETURNS
336 * Success: S_OK.
337 * Failure: E_INVALIDARG, if the source value is invalid
338 * DISP_E_OVERFLOW, if the value will not fit in the destination
339 */
340 HRESULT WINAPI VarI1FromR4(FLOAT fltIn, signed char* pcOut)
341 {
342 return VarI1FromR8(fltIn, pcOut);
343 }
344
345 /************************************************************************
346 * VarI1FromR8 (OLEAUT32.248)
347 *
348 * Convert a VT_R8 to a VT_I1.
349 *
350 * PARAMS
351 * dblIn [I] Source
352 * pcOut [O] Destination
353 *
354 * RETURNS
355 * Success: S_OK.
356 * Failure: E_INVALIDARG, if the source value is invalid
357 * DISP_E_OVERFLOW, if the value will not fit in the destination
358 *
359 * NOTES
360 * See VarI8FromR8() for details concerning rounding.
361 */
362 HRESULT WINAPI VarI1FromR8(double dblIn, signed char* pcOut)
363 {
364 if (dblIn < (double)I1_MIN || dblIn > (double)I1_MAX)
365 return DISP_E_OVERFLOW;
366 VARIANT_DutchRound(CHAR, dblIn, *pcOut);
367 return S_OK;
368 }
369
370 /************************************************************************
371 * VarI1FromDate (OLEAUT32.249)
372 *
373 * Convert a VT_DATE to a VT_I1.
374 *
375 * PARAMS
376 * dateIn [I] Source
377 * pcOut [O] Destination
378 *
379 * RETURNS
380 * Success: S_OK.
381 * Failure: E_INVALIDARG, if the source value is invalid
382 * DISP_E_OVERFLOW, if the value will not fit in the destination
383 */
384 HRESULT WINAPI VarI1FromDate(DATE dateIn, signed char* pcOut)
385 {
386 return VarI1FromR8(dateIn, pcOut);
387 }
388
389 /************************************************************************
390 * VarI1FromCy (OLEAUT32.250)
391 *
392 * Convert a VT_CY to a VT_I1.
393 *
394 * PARAMS
395 * cyIn [I] Source
396 * pcOut [O] Destination
397 *
398 * RETURNS
399 * Success: S_OK.
400 * Failure: E_INVALIDARG, if the source value is invalid
401 * DISP_E_OVERFLOW, if the value will not fit in the destination
402 */
403 HRESULT WINAPI VarI1FromCy(CY cyIn, signed char* pcOut)
404 {
405 LONG i = I1_MAX + 1;
406
407 VarI4FromCy(cyIn, &i);
408 return _VarI1FromI4(i, pcOut);
409 }
410
411 /************************************************************************
412 * VarI1FromStr (OLEAUT32.251)
413 *
414 * Convert a VT_BSTR to a VT_I1.
415 *
416 * PARAMS
417 * strIn [I] Source
418 * lcid [I] LCID for the conversion
419 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
420 * pcOut [O] Destination
421 *
422 * RETURNS
423 * Success: S_OK.
424 * Failure: E_INVALIDARG, if the source value is invalid
425 * DISP_E_OVERFLOW, if the value will not fit in the destination
426 * DISP_E_TYPEMISMATCH, if the type cannot be converted
427 */
428 HRESULT WINAPI VarI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, signed char* pcOut)
429 {
430 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pcOut, VT_I1);
431 }
432
433 /************************************************************************
434 * VarI1FromDisp (OLEAUT32.252)
435 *
436 * Convert a VT_DISPATCH to a VT_I1.
437 *
438 * PARAMS
439 * pdispIn [I] Source
440 * lcid [I] LCID for conversion
441 * pcOut [O] Destination
442 *
443 * RETURNS
444 * Success: S_OK.
445 * Failure: E_INVALIDARG, if the source value is invalid
446 * DISP_E_OVERFLOW, if the value will not fit in the destination
447 * DISP_E_TYPEMISMATCH, if the type cannot be converted
448 */
449 HRESULT WINAPI VarI1FromDisp(IDispatch* pdispIn, LCID lcid, signed char* pcOut)
450 {
451 return VARIANT_FromDisp(pdispIn, lcid, pcOut, VT_I1, 0);
452 }
453
454 /************************************************************************
455 * VarI1FromBool (OLEAUT32.253)
456 *
457 * Convert a VT_BOOL to a VT_I1.
458 *
459 * PARAMS
460 * boolIn [I] Source
461 * pcOut [O] Destination
462 *
463 * RETURNS
464 * S_OK.
465 */
466 HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, signed char* pcOut)
467 {
468 return _VarI1FromBool(boolIn, pcOut);
469 }
470
471 /************************************************************************
472 * VarI1FromUI2 (OLEAUT32.254)
473 *
474 * Convert a VT_UI2 to a VT_I1.
475 *
476 * PARAMS
477 * usIn [I] Source
478 * pcOut [O] Destination
479 *
480 * RETURNS
481 * Success: S_OK.
482 * Failure: E_INVALIDARG, if the source value is invalid
483 * DISP_E_OVERFLOW, if the value will not fit in the destination
484 */
485 HRESULT WINAPI VarI1FromUI2(USHORT usIn, signed char* pcOut)
486 {
487 return _VarI1FromUI2(usIn, pcOut);
488 }
489
490 /************************************************************************
491 * VarI1FromUI4 (OLEAUT32.255)
492 *
493 * Convert a VT_UI4 to a VT_I1.
494 *
495 * PARAMS
496 * ulIn [I] Source
497 * pcOut [O] Destination
498 *
499 * RETURNS
500 * Success: S_OK.
501 * Failure: E_INVALIDARG, if the source value is invalid
502 * DISP_E_OVERFLOW, if the value will not fit in the destination
503 * DISP_E_TYPEMISMATCH, if the type cannot be converted
504 */
505 HRESULT WINAPI VarI1FromUI4(ULONG ulIn, signed char* pcOut)
506 {
507 return _VarI1FromUI4(ulIn, pcOut);
508 }
509
510 /************************************************************************
511 * VarI1FromDec (OLEAUT32.256)
512 *
513 * Convert a VT_DECIMAL to a VT_I1.
514 *
515 * PARAMS
516 * pDecIn [I] Source
517 * pcOut [O] Destination
518 *
519 * RETURNS
520 * Success: S_OK.
521 * Failure: E_INVALIDARG, if the source value is invalid
522 * DISP_E_OVERFLOW, if the value will not fit in the destination
523 */
524 HRESULT WINAPI VarI1FromDec(DECIMAL *pdecIn, signed char* pcOut)
525 {
526 LONG64 i64;
527 HRESULT hRet;
528
529 hRet = VarI8FromDec(pdecIn, &i64);
530
531 if (SUCCEEDED(hRet))
532 hRet = _VarI1FromI8(i64, pcOut);
533 return hRet;
534 }
535
536 /************************************************************************
537 * VarI1FromI8 (OLEAUT32.376)
538 *
539 * Convert a VT_I8 to a VT_I1.
540 *
541 * PARAMS
542 * llIn [I] Source
543 * pcOut [O] Destination
544 *
545 * RETURNS
546 * Success: S_OK.
547 * Failure: E_INVALIDARG, if the source value is invalid
548 * DISP_E_OVERFLOW, if the value will not fit in the destination
549 */
550 HRESULT WINAPI VarI1FromI8(LONG64 llIn, signed char* pcOut)
551 {
552 return _VarI1FromI8(llIn, pcOut);
553 }
554
555 /************************************************************************
556 * VarI1FromUI8 (OLEAUT32.377)
557 *
558 * Convert a VT_UI8 to a VT_I1.
559 *
560 * PARAMS
561 * ullIn [I] Source
562 * pcOut [O] Destination
563 *
564 * RETURNS
565 * Success: S_OK.
566 * Failure: E_INVALIDARG, if the source value is invalid
567 * DISP_E_OVERFLOW, if the value will not fit in the destination
568 */
569 HRESULT WINAPI VarI1FromUI8(ULONG64 ullIn, signed char* pcOut)
570 {
571 return _VarI1FromUI8(ullIn, pcOut);
572 }
573
574 /* UI1
575 */
576
577 /************************************************************************
578 * VarUI1FromI2 (OLEAUT32.130)
579 *
580 * Convert a VT_I2 to a VT_UI1.
581 *
582 * PARAMS
583 * sIn [I] Source
584 * pbOut [O] Destination
585 *
586 * RETURNS
587 * Success: S_OK.
588 * Failure: E_INVALIDARG, if the source value is invalid
589 * DISP_E_OVERFLOW, if the value will not fit in the destination
590 */
591 HRESULT WINAPI VarUI1FromI2(SHORT sIn, BYTE* pbOut)
592 {
593 return _VarUI1FromI2(sIn, pbOut);
594 }
595
596 /************************************************************************
597 * VarUI1FromI4 (OLEAUT32.131)
598 *
599 * Convert a VT_I4 to a VT_UI1.
600 *
601 * PARAMS
602 * iIn [I] Source
603 * pbOut [O] Destination
604 *
605 * RETURNS
606 * Success: S_OK.
607 * Failure: E_INVALIDARG, if the source value is invalid
608 * DISP_E_OVERFLOW, if the value will not fit in the destination
609 */
610 HRESULT WINAPI VarUI1FromI4(LONG iIn, BYTE* pbOut)
611 {
612 return _VarUI1FromI4(iIn, pbOut);
613 }
614
615 /************************************************************************
616 * VarUI1FromR4 (OLEAUT32.132)
617 *
618 * Convert a VT_R4 to a VT_UI1.
619 *
620 * PARAMS
621 * fltIn [I] Source
622 * pbOut [O] Destination
623 *
624 * RETURNS
625 * Success: S_OK.
626 * Failure: E_INVALIDARG, if the source value is invalid
627 * DISP_E_OVERFLOW, if the value will not fit in the destination
628 * DISP_E_TYPEMISMATCH, if the type cannot be converted
629 */
630 HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut)
631 {
632 return VarUI1FromR8(fltIn, pbOut);
633 }
634
635 /************************************************************************
636 * VarUI1FromR8 (OLEAUT32.133)
637 *
638 * Convert a VT_R8 to a VT_UI1.
639 *
640 * PARAMS
641 * dblIn [I] Source
642 * pbOut [O] Destination
643 *
644 * RETURNS
645 * Success: S_OK.
646 * Failure: E_INVALIDARG, if the source value is invalid
647 * DISP_E_OVERFLOW, if the value will not fit in the destination
648 *
649 * NOTES
650 * See VarI8FromR8() for details concerning rounding.
651 */
652 HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut)
653 {
654 if (dblIn < -0.5 || dblIn > (double)UI1_MAX)
655 return DISP_E_OVERFLOW;
656 VARIANT_DutchRound(BYTE, dblIn, *pbOut);
657 return S_OK;
658 }
659
660 /************************************************************************
661 * VarUI1FromCy (OLEAUT32.134)
662 *
663 * Convert a VT_CY to a VT_UI1.
664 *
665 * PARAMS
666 * cyIn [I] Source
667 * pbOut [O] Destination
668 *
669 * RETURNS
670 * Success: S_OK.
671 * Failure: E_INVALIDARG, if the source value is invalid
672 * DISP_E_OVERFLOW, if the value will not fit in the destination
673 *
674 * NOTES
675 * Negative values >= -5000 will be converted to 0.
676 */
677 HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut)
678 {
679 ULONG i = UI1_MAX + 1;
680
681 VarUI4FromCy(cyIn, &i);
682 return _VarUI1FromUI4(i, pbOut);
683 }
684
685 /************************************************************************
686 * VarUI1FromDate (OLEAUT32.135)
687 *
688 * Convert a VT_DATE to a VT_UI1.
689 *
690 * PARAMS
691 * dateIn [I] Source
692 * pbOut [O] Destination
693 *
694 * RETURNS
695 * Success: S_OK.
696 * Failure: E_INVALIDARG, if the source value is invalid
697 * DISP_E_OVERFLOW, if the value will not fit in the destination
698 */
699 HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE* pbOut)
700 {
701 return VarUI1FromR8(dateIn, pbOut);
702 }
703
704 /************************************************************************
705 * VarUI1FromStr (OLEAUT32.136)
706 *
707 * Convert a VT_BSTR to a VT_UI1.
708 *
709 * PARAMS
710 * strIn [I] Source
711 * lcid [I] LCID for the conversion
712 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
713 * pbOut [O] Destination
714 *
715 * RETURNS
716 * Success: S_OK.
717 * Failure: E_INVALIDARG, if the source value is invalid
718 * DISP_E_OVERFLOW, if the value will not fit in the destination
719 * DISP_E_TYPEMISMATCH, if the type cannot be converted
720 */
721 HRESULT WINAPI VarUI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
722 {
723 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pbOut, VT_UI1);
724 }
725
726 /************************************************************************
727 * VarUI1FromDisp (OLEAUT32.137)
728 *
729 * Convert a VT_DISPATCH to a VT_UI1.
730 *
731 * PARAMS
732 * pdispIn [I] Source
733 * lcid [I] LCID for conversion
734 * pbOut [O] Destination
735 *
736 * RETURNS
737 * Success: S_OK.
738 * Failure: E_INVALIDARG, if the source value is invalid
739 * DISP_E_OVERFLOW, if the value will not fit in the destination
740 * DISP_E_TYPEMISMATCH, if the type cannot be converted
741 */
742 HRESULT WINAPI VarUI1FromDisp(IDispatch* pdispIn, LCID lcid, BYTE* pbOut)
743 {
744 return VARIANT_FromDisp(pdispIn, lcid, pbOut, VT_UI1, 0);
745 }
746
747 /************************************************************************
748 * VarUI1FromBool (OLEAUT32.138)
749 *
750 * Convert a VT_BOOL to a VT_UI1.
751 *
752 * PARAMS
753 * boolIn [I] Source
754 * pbOut [O] Destination
755 *
756 * RETURNS
757 * S_OK.
758 */
759 HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE* pbOut)
760 {
761 return _VarUI1FromBool(boolIn, pbOut);
762 }
763
764 /************************************************************************
765 * VarUI1FromI1 (OLEAUT32.237)
766 *
767 * Convert a VT_I1 to a VT_UI1.
768 *
769 * PARAMS
770 * cIn [I] Source
771 * pbOut [O] Destination
772 *
773 * RETURNS
774 * Success: S_OK.
775 * Failure: E_INVALIDARG, if the source value is invalid
776 * DISP_E_OVERFLOW, if the value will not fit in the destination
777 */
778 HRESULT WINAPI VarUI1FromI1(signed char cIn, BYTE* pbOut)
779 {
780 return _VarUI1FromI1(cIn, pbOut);
781 }
782
783 /************************************************************************
784 * VarUI1FromUI2 (OLEAUT32.238)
785 *
786 * Convert a VT_UI2 to a VT_UI1.
787 *
788 * PARAMS
789 * usIn [I] Source
790 * pbOut [O] Destination
791 *
792 * RETURNS
793 * Success: S_OK.
794 * Failure: E_INVALIDARG, if the source value is invalid
795 * DISP_E_OVERFLOW, if the value will not fit in the destination
796 */
797 HRESULT WINAPI VarUI1FromUI2(USHORT usIn, BYTE* pbOut)
798 {
799 return _VarUI1FromUI2(usIn, pbOut);
800 }
801
802 /************************************************************************
803 * VarUI1FromUI4 (OLEAUT32.239)
804 *
805 * Convert a VT_UI4 to a VT_UI1.
806 *
807 * PARAMS
808 * ulIn [I] Source
809 * pbOut [O] Destination
810 *
811 * RETURNS
812 * Success: S_OK.
813 * Failure: E_INVALIDARG, if the source value is invalid
814 * DISP_E_OVERFLOW, if the value will not fit in the destination
815 */
816 HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE* pbOut)
817 {
818 return _VarUI1FromUI4(ulIn, pbOut);
819 }
820
821 /************************************************************************
822 * VarUI1FromDec (OLEAUT32.240)
823 *
824 * Convert a VT_DECIMAL to a VT_UI1.
825 *
826 * PARAMS
827 * pDecIn [I] Source
828 * pbOut [O] Destination
829 *
830 * RETURNS
831 * Success: S_OK.
832 * Failure: E_INVALIDARG, if the source value is invalid
833 * DISP_E_OVERFLOW, if the value will not fit in the destination
834 */
835 HRESULT WINAPI VarUI1FromDec(DECIMAL *pdecIn, BYTE* pbOut)
836 {
837 LONG64 i64;
838 HRESULT hRet;
839
840 hRet = VarI8FromDec(pdecIn, &i64);
841
842 if (SUCCEEDED(hRet))
843 hRet = _VarUI1FromI8(i64, pbOut);
844 return hRet;
845 }
846
847 /************************************************************************
848 * VarUI1FromI8 (OLEAUT32.372)
849 *
850 * Convert a VT_I8 to a VT_UI1.
851 *
852 * PARAMS
853 * llIn [I] Source
854 * pbOut [O] Destination
855 *
856 * RETURNS
857 * Success: S_OK.
858 * Failure: E_INVALIDARG, if the source value is invalid
859 * DISP_E_OVERFLOW, if the value will not fit in the destination
860 */
861 HRESULT WINAPI VarUI1FromI8(LONG64 llIn, BYTE* pbOut)
862 {
863 return _VarUI1FromI8(llIn, pbOut);
864 }
865
866 /************************************************************************
867 * VarUI1FromUI8 (OLEAUT32.373)
868 *
869 * Convert a VT_UI8 to a VT_UI1.
870 *
871 * PARAMS
872 * ullIn [I] Source
873 * pbOut [O] Destination
874 *
875 * RETURNS
876 * Success: S_OK.
877 * Failure: E_INVALIDARG, if the source value is invalid
878 * DISP_E_OVERFLOW, if the value will not fit in the destination
879 */
880 HRESULT WINAPI VarUI1FromUI8(ULONG64 ullIn, BYTE* pbOut)
881 {
882 return _VarUI1FromUI8(ullIn, pbOut);
883 }
884
885
886 /* I2
887 */
888
889 /************************************************************************
890 * VarI2FromUI1 (OLEAUT32.48)
891 *
892 * Convert a VT_UI2 to a VT_I2.
893 *
894 * PARAMS
895 * bIn [I] Source
896 * psOut [O] Destination
897 *
898 * RETURNS
899 * S_OK.
900 */
901 HRESULT WINAPI VarI2FromUI1(BYTE bIn, SHORT* psOut)
902 {
903 return _VarI2FromUI1(bIn, psOut);
904 }
905
906 /************************************************************************
907 * VarI2FromI4 (OLEAUT32.49)
908 *
909 * Convert a VT_I4 to a VT_I2.
910 *
911 * PARAMS
912 * iIn [I] Source
913 * psOut [O] Destination
914 *
915 * RETURNS
916 * Success: S_OK.
917 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
918 */
919 HRESULT WINAPI VarI2FromI4(LONG iIn, SHORT* psOut)
920 {
921 return _VarI2FromI4(iIn, psOut);
922 }
923
924 /************************************************************************
925 * VarI2FromR4 (OLEAUT32.50)
926 *
927 * Convert a VT_R4 to a VT_I2.
928 *
929 * PARAMS
930 * fltIn [I] Source
931 * psOut [O] Destination
932 *
933 * RETURNS
934 * Success: S_OK.
935 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
936 */
937 HRESULT WINAPI VarI2FromR4(FLOAT fltIn, SHORT* psOut)
938 {
939 return VarI2FromR8(fltIn, psOut);
940 }
941
942 /************************************************************************
943 * VarI2FromR8 (OLEAUT32.51)
944 *
945 * Convert a VT_R8 to a VT_I2.
946 *
947 * PARAMS
948 * dblIn [I] Source
949 * psOut [O] Destination
950 *
951 * RETURNS
952 * Success: S_OK.
953 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
954 *
955 * NOTES
956 * See VarI8FromR8() for details concerning rounding.
957 */
958 HRESULT WINAPI VarI2FromR8(double dblIn, SHORT* psOut)
959 {
960 if (dblIn < (double)I2_MIN || dblIn > (double)I2_MAX)
961 return DISP_E_OVERFLOW;
962 VARIANT_DutchRound(SHORT, dblIn, *psOut);
963 return S_OK;
964 }
965
966 /************************************************************************
967 * VarI2FromCy (OLEAUT32.52)
968 *
969 * Convert a VT_CY to a VT_I2.
970 *
971 * PARAMS
972 * cyIn [I] Source
973 * psOut [O] Destination
974 *
975 * RETURNS
976 * Success: S_OK.
977 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
978 */
979 HRESULT WINAPI VarI2FromCy(CY cyIn, SHORT* psOut)
980 {
981 LONG i = I2_MAX + 1;
982
983 VarI4FromCy(cyIn, &i);
984 return _VarI2FromI4(i, psOut);
985 }
986
987 /************************************************************************
988 * VarI2FromDate (OLEAUT32.53)
989 *
990 * Convert a VT_DATE to a VT_I2.
991 *
992 * PARAMS
993 * dateIn [I] Source
994 * psOut [O] Destination
995 *
996 * RETURNS
997 * Success: S_OK.
998 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
999 */
1000 HRESULT WINAPI VarI2FromDate(DATE dateIn, SHORT* psOut)
1001 {
1002 return VarI2FromR8(dateIn, psOut);
1003 }
1004
1005 /************************************************************************
1006 * VarI2FromStr (OLEAUT32.54)
1007 *
1008 * Convert a VT_BSTR to a VT_I2.
1009 *
1010 * PARAMS
1011 * strIn [I] Source
1012 * lcid [I] LCID for the conversion
1013 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1014 * psOut [O] Destination
1015 *
1016 * RETURNS
1017 * Success: S_OK.
1018 * Failure: E_INVALIDARG, if any parameter is invalid
1019 * DISP_E_OVERFLOW, if the value will not fit in the destination
1020 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1021 */
1022 HRESULT WINAPI VarI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, SHORT* psOut)
1023 {
1024 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, psOut, VT_I2);
1025 }
1026
1027 /************************************************************************
1028 * VarI2FromDisp (OLEAUT32.55)
1029 *
1030 * Convert a VT_DISPATCH to a VT_I2.
1031 *
1032 * PARAMS
1033 * pdispIn [I] Source
1034 * lcid [I] LCID for conversion
1035 * psOut [O] Destination
1036 *
1037 * RETURNS
1038 * Success: S_OK.
1039 * Failure: E_INVALIDARG, if pdispIn is invalid,
1040 * DISP_E_OVERFLOW, if the value will not fit in the destination,
1041 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1042 */
1043 HRESULT WINAPI VarI2FromDisp(IDispatch* pdispIn, LCID lcid, SHORT* psOut)
1044 {
1045 return VARIANT_FromDisp(pdispIn, lcid, psOut, VT_I2, 0);
1046 }
1047
1048 /************************************************************************
1049 * VarI2FromBool (OLEAUT32.56)
1050 *
1051 * Convert a VT_BOOL to a VT_I2.
1052 *
1053 * PARAMS
1054 * boolIn [I] Source
1055 * psOut [O] Destination
1056 *
1057 * RETURNS
1058 * S_OK.
1059 */
1060 HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, SHORT* psOut)
1061 {
1062 return _VarI2FromBool(boolIn, psOut);
1063 }
1064
1065 /************************************************************************
1066 * VarI2FromI1 (OLEAUT32.205)
1067 *
1068 * Convert a VT_I1 to a VT_I2.
1069 *
1070 * PARAMS
1071 * cIn [I] Source
1072 * psOut [O] Destination
1073 *
1074 * RETURNS
1075 * S_OK.
1076 */
1077 HRESULT WINAPI VarI2FromI1(signed char cIn, SHORT* psOut)
1078 {
1079 return _VarI2FromI1(cIn, psOut);
1080 }
1081
1082 /************************************************************************
1083 * VarI2FromUI2 (OLEAUT32.206)
1084 *
1085 * Convert a VT_UI2 to a VT_I2.
1086 *
1087 * PARAMS
1088 * usIn [I] Source
1089 * psOu