Sync to Wine-0_9_3:
[reactos.git] / reactos / lib / oleaut32 / vartype.c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 OLEAUT32_hModule;
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 default:
68 FIXME("VT_ type %d unhandled, please report!\n", vt);
69 }
70 }
71
72 /* Macro to inline conversion from a float or double to any integer type,
73 * rounding according to the 'dutch' convention.
74 */
75 #define VARIANT_DutchRound(typ, value, res) do { \
76 double whole = value < 0 ? ceil(value) : floor(value); \
77 double fract = value - whole; \
78 if (fract > 0.5) res = (typ)whole + (typ)1; \
79 else if (fract == 0.5) { typ is_odd = (typ)whole & 1; res = whole + is_odd; } \
80 else if (fract >= 0.0) res = (typ)whole; \
81 else if (fract == -0.5) { typ is_odd = (typ)whole & 1; res = whole - is_odd; } \
82 else if (fract > -0.5) res = (typ)whole; \
83 else res = (typ)whole - (typ)1; \
84 } while(0);
85
86
87 /* Coerce VT_BSTR to a numeric type */
88 static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags,
89 void* pOut, VARTYPE vt)
90 {
91 VARIANTARG dstVar;
92 HRESULT hRet;
93 NUMPARSE np;
94 BYTE rgb[1024];
95
96 /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
97 np.cDig = sizeof(rgb) / sizeof(BYTE);
98 np.dwInFlags = NUMPRS_STD;
99
100 hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);
101
102 if (SUCCEEDED(hRet))
103 {
104 /* 1 << vt gives us the VTBIT constant for the destination number type */
105 hRet = VarNumFromParseNum(&np, rgb, 1 << vt, &dstVar);
106 if (SUCCEEDED(hRet))
107 VARIANT_CopyData(&dstVar, vt, pOut);
108 }
109 return hRet;
110 }
111
112 /* Coerce VT_DISPATCH to another type */
113 static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut, VARTYPE vt)
114 {
115 static const DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
116 VARIANTARG srcVar, dstVar;
117 HRESULT hRet;
118
119 if (!pdispIn)
120 return DISP_E_BADVARTYPE;
121
122 /* Get the default 'value' property from the IDispatch */
123 hRet = IDispatch_Invoke(pdispIn, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET,
124 (DISPPARAMS*)&emptyParams, &srcVar, NULL, NULL);
125
126 if (SUCCEEDED(hRet))
127 {
128 /* Convert the property to the requested type */
129 V_VT(&dstVar) = VT_EMPTY;
130 hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, 0, vt);
131 VariantClear(&srcVar);
132
133 if (SUCCEEDED(hRet))
134 {
135 VARIANT_CopyData(&dstVar, vt, pOut);
136 VariantClear(&srcVar);
137 }
138 }
139 else
140 hRet = DISP_E_TYPEMISMATCH;
141 return hRet;
142 }
143
144 /* Inline return type */
145 #define RETTYP inline static HRESULT
146
147
148 /* Simple compiler cast from one type to another */
149 #define SIMPLE(dest, src, func) RETTYP _##func(src in, dest* out) { \
150 *out = in; return S_OK; }
151
152 /* Compiler cast where input cannot be negative */
153 #define NEGTST(dest, src, func) RETTYP _##func(src in, dest* out) { \
154 if (in < (src)0) return DISP_E_OVERFLOW; *out = in; return S_OK; }
155
156 /* Compiler cast where input cannot be > some number */
157 #define POSTST(dest, src, func, tst) RETTYP _##func(src in, dest* out) { \
158 if (in > (dest)tst) return DISP_E_OVERFLOW; *out = in; return S_OK; }
159
160 /* Compiler cast where input cannot be < some number or >= some other number */
161 #define BOTHTST(dest, src, func, lo, hi) RETTYP _##func(src in, dest* out) { \
162 if (in < (dest)lo || in > hi) return DISP_E_OVERFLOW; *out = in; return S_OK; }
163
164 /* I1 */
165 POSTST(signed char, BYTE, VarI1FromUI1, I1_MAX);
166 BOTHTST(signed char, SHORT, VarI1FromI2, I1_MIN, I1_MAX);
167 BOTHTST(signed char, LONG, VarI1FromI4, I1_MIN, I1_MAX);
168 SIMPLE(signed char, VARIANT_BOOL, VarI1FromBool);
169 POSTST(signed char, USHORT, VarI1FromUI2, I1_MAX);
170 POSTST(signed char, ULONG, VarI1FromUI4, I1_MAX);
171 BOTHTST(signed char, LONG64, VarI1FromI8, I1_MIN, I1_MAX);
172 POSTST(signed char, ULONG64, VarI1FromUI8, I1_MAX);
173
174 /* UI1 */
175 BOTHTST(BYTE, SHORT, VarUI1FromI2, UI1_MIN, UI1_MAX);
176 SIMPLE(BYTE, VARIANT_BOOL, VarUI1FromBool);
177 NEGTST(BYTE, signed char, VarUI1FromI1);
178 POSTST(BYTE, USHORT, VarUI1FromUI2, UI1_MAX);
179 BOTHTST(BYTE, LONG, VarUI1FromI4, UI1_MIN, UI1_MAX);
180 POSTST(BYTE, ULONG, VarUI1FromUI4, UI1_MAX);
181 BOTHTST(BYTE, LONG64, VarUI1FromI8, UI1_MIN, UI1_MAX);
182 POSTST(BYTE, ULONG64, VarUI1FromUI8, UI1_MAX);
183
184 /* I2 */
185 SIMPLE(SHORT, BYTE, VarI2FromUI1);
186 BOTHTST(SHORT, LONG, VarI2FromI4, I2_MIN, I2_MAX);
187 SIMPLE(SHORT, VARIANT_BOOL, VarI2FromBool);
188 SIMPLE(SHORT, signed char, VarI2FromI1);
189 POSTST(SHORT, USHORT, VarI2FromUI2, I2_MAX);
190 POSTST(SHORT, ULONG, VarI2FromUI4, I2_MAX);
191 BOTHTST(SHORT, LONG64, VarI2FromI8, I2_MIN, I2_MAX);
192 POSTST(SHORT, ULONG64, VarI2FromUI8, I2_MAX);
193
194 /* UI2 */
195 SIMPLE(USHORT, BYTE, VarUI2FromUI1);
196 NEGTST(USHORT, SHORT, VarUI2FromI2);
197 BOTHTST(USHORT, LONG, VarUI2FromI4, UI2_MIN, UI2_MAX);
198 SIMPLE(USHORT, VARIANT_BOOL, VarUI2FromBool);
199 NEGTST(USHORT, signed char, VarUI2FromI1);
200 POSTST(USHORT, ULONG, VarUI2FromUI4, UI2_MAX);
201 BOTHTST(USHORT, LONG64, VarUI2FromI8, UI2_MIN, UI2_MAX);
202 POSTST(USHORT, ULONG64, VarUI2FromUI8, UI2_MAX);
203
204 /* I4 */
205 SIMPLE(LONG, BYTE, VarI4FromUI1);
206 SIMPLE(LONG, SHORT, VarI4FromI2);
207 SIMPLE(LONG, VARIANT_BOOL, VarI4FromBool);
208 SIMPLE(LONG, signed char, VarI4FromI1);
209 SIMPLE(LONG, USHORT, VarI4FromUI2);
210 POSTST(LONG, ULONG, VarI4FromUI4, I4_MAX);
211 BOTHTST(LONG, LONG64, VarI4FromI8, I4_MIN, I4_MAX);
212 POSTST(LONG, ULONG64, VarI4FromUI8, I4_MAX);
213
214 /* UI4 */
215 SIMPLE(ULONG, BYTE, VarUI4FromUI1);
216 NEGTST(ULONG, SHORT, VarUI4FromI2);
217 NEGTST(ULONG, LONG, VarUI4FromI4);
218 SIMPLE(ULONG, VARIANT_BOOL, VarUI4FromBool);
219 NEGTST(ULONG, signed char, VarUI4FromI1);
220 SIMPLE(ULONG, USHORT, VarUI4FromUI2);
221 BOTHTST(ULONG, LONG64, VarUI4FromI8, UI4_MIN, UI4_MAX);
222 POSTST(ULONG, ULONG64, VarUI4FromUI8, UI4_MAX);
223
224 /* I8 */
225 SIMPLE(LONG64, BYTE, VarI8FromUI1);
226 SIMPLE(LONG64, SHORT, VarI8FromI2);
227 SIMPLE(LONG64, signed char, VarI8FromI1);
228 SIMPLE(LONG64, USHORT, VarI8FromUI2);
229 SIMPLE(LONG64, LONG, VarI8FromI4);
230 SIMPLE(LONG64, ULONG, VarI8FromUI4);
231 POSTST(LONG64, ULONG64, VarI8FromUI8, I8_MAX);
232
233 /* UI8 */
234 SIMPLE(ULONG64, BYTE, VarUI8FromUI1);
235 NEGTST(ULONG64, SHORT, VarUI8FromI2);
236 NEGTST(ULONG64, signed char, VarUI8FromI1);
237 SIMPLE(ULONG64, USHORT, VarUI8FromUI2);
238 NEGTST(ULONG64, LONG, VarUI8FromI4);
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);
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);
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);
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 * psOut [O] Destination
1090 *
1091 * RETURNS
1092 * Success: S_OK.
1093 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1094 */
1095 HRESULT WINAPI VarI2FromUI2(USHORT usIn, SHORT* psOut)
1096 {
1097 return _VarI2FromUI2(usIn, psOut);
1098 }
1099
1100 /************************************************************************
1101 * VarI2FromUI4 (OLEAUT32.207)
1102 *
1103 * Convert a VT_UI4 to a VT_I2.
1104 *
1105 * PARAMS
1106 * ulIn [I] Source
1107 * psOut [O] Destination
1108 *
1109 * RETURNS
1110 * Success: S_OK.
1111 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1112 */
1113 HRESULT WINAPI VarI2FromUI4(ULONG ulIn, SHORT* psOut)
1114 {
1115 return _VarI2FromUI4(ulIn, psOut);
1116 }
1117
1118 /************************************************************************
1119 * VarI2FromDec (OLEAUT32.208)
1120 *
1121 * Convert a VT_DECIMAL to a VT_I2.
1122 *
1123 * PARAMS
1124 * pDecIn [I] Source
1125 * psOut [O] Destination
1126 *
1127 * RETURNS
1128 * Success: S_OK.
1129 * Failure: E_INVALIDARG, if the source value is invalid
1130 * DISP_E_OVERFLOW, if the value will not fit in the destination
1131 */
1132 HRESULT WINAPI VarI2FromDec(DECIMAL *pdecIn, SHORT* psOut)
1133 {
1134 LONG64 i64;
1135 HRESULT hRet;
1136
1137 hRet = VarI8FromDec(pdecIn, &i64);
1138
1139 if (SUCCEEDED(hRet))
1140 hRet = _VarI2FromI8(i64, psOut);
1141 return hRet;
1142 }
1143
1144 /************************************************************************
1145 * VarI2FromI8 (OLEAUT32.346)
1146 *
1147 * Convert a VT_I8 to a VT_I2.
1148 *
1149 * PARAMS
1150 * llIn [I] Source
1151 * psOut [O] Destination
1152 *
1153 * RETURNS
1154 * Success: S_OK.
1155 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1156 */
1157 HRESULT WINAPI VarI2FromI8(LONG64 llIn, SHORT* psOut)
1158 {
1159 return _VarI2FromI8(llIn, psOut);
1160 }
1161
1162 /************************************************************************
1163 * VarI2FromUI8 (OLEAUT32.347)
1164 *
1165 * Convert a VT_UI8 to a VT_I2.
1166 *
1167 * PARAMS
1168 * ullIn [I] Source
1169 * psOut [O] Destination
1170 *
1171 * RETURNS
1172 * Success: S_OK.
1173 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1174 */
1175 HRESULT WINAPI VarI2FromUI8(ULONG64 ullIn, SHORT* psOut)
1176 {
1177 return _VarI2FromUI8(ullIn, psOut);
1178 }
1179
1180 /* UI2
1181 */
1182
1183 /************************************************************************
1184 * VarUI2FromUI1 (OLEAUT32.257)
1185 *
1186 * Convert a VT_UI1 to a VT_UI2.
1187 *
1188 * PARAMS
1189 * bIn [I] Source
1190 * pusOut [O] Destination
1191 *
1192 * RETURNS
1193 * S_OK.
1194 */
1195 HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT* pusOut)
1196 {
1197 return _VarUI2FromUI1(bIn, pusOut);
1198 }
1199
1200 /************************************************************************
1201 * VarUI2FromI2 (OLEAUT32.258)
1202 *
1203 * Convert a VT_I2 to a VT_UI2.
1204 *
1205 * PARAMS
1206 * sIn [I] Source
1207 * pusOut [O] Destination
1208 *
1209 * RETURNS
1210 * Success: S_OK.
1211 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1212 */
1213 HRESULT WINAPI VarUI2FromI2(SHORT sIn, USHORT* pusOut)
1214 {
1215 return _VarUI2FromI2(sIn, pusOut);
1216 }
1217
1218 /************************************************************************
1219 * VarUI2FromI4 (OLEAUT32.259)
1220 *
1221 * Convert a VT_I4 to a VT_UI2.
1222 *
1223 * PARAMS
1224 * iIn [I] Source
1225 * pusOut [O] Destination
1226 *
1227 * RETURNS
1228 * Success: S_OK.
1229 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1230 */
1231 HRESULT WINAPI VarUI2FromI4(LONG iIn, USHORT* pusOut)
1232 {
1233 return _VarUI2FromI4(iIn, pusOut);
1234 }
1235
1236 /************************************************************************
1237 * VarUI2FromR4 (OLEAUT32.260)
1238 *
1239 * Convert a VT_R4 to a VT_UI2.
1240 *
1241 * PARAMS
1242 * fltIn [I] Source
1243 * pusOut [O] Destination
1244 *
1245 * RETURNS
1246 * Success: S_OK.
1247 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1248 */
1249 HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* pusOut)
1250 {
1251 return VarUI2FromR8(fltIn, pusOut);
1252 }
1253
1254 /************************************************************************
1255 * VarUI2FromR8 (OLEAUT32.261)
1256 *
1257 * Convert a VT_R8 to a VT_UI2.
1258 *
1259 * PARAMS
1260 * dblIn [I] Source
1261 * pusOut [O] Destination
1262 *
1263 * RETURNS
1264 * Success: S_OK.
1265 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1266 *
1267 * NOTES
1268 * See VarI8FromR8() for details concerning rounding.
1269 */
1270 HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* pusOut)
1271 {
1272 if (dblIn < -0.5 || dblIn > (double)UI2_MAX)
1273 return DISP_E_OVERFLOW;
1274 VARIANT_DutchRound(USHORT, dblIn, *pusOut);
1275 return S_OK;
1276 }
1277
1278 /************************************************************************
1279 * VarUI2FromDate (OLEAUT32.262)
1280 *
1281 * Convert a VT_DATE to a VT_UI2.
1282 *
1283 * PARAMS
1284 * dateIn [I] Source
1285 * pusOut [O] Destination
1286 *
1287 * RETURNS
1288 * Success: S_OK.
1289 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1290 */
1291 HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT* pusOut)
1292 {
1293 return VarUI2FromR8(dateIn, pusOut);
1294 }
1295
1296 /************************************************************************
1297 * VarUI2FromCy (OLEAUT32.263)
1298 *
1299 * Convert a VT_CY to a VT_UI2.
1300 *
1301 * PARAMS
1302 * cyIn [I] Source
1303 * pusOut [O] Destination
1304 *
1305 * RETURNS
1306 * Success: S_OK.
1307 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1308 *
1309 * NOTES
1310 * Negative values >= -5000 will be converted to 0.
1311 */
1312 HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut)
1313 {
1314 ULONG i = UI2_MAX + 1;
1315
1316 VarUI4FromCy(cyIn, &i);
1317 return _VarUI2FromUI4(i, pusOut);
1318 }
1319
1320 /************************************************************************
1321 * VarUI2FromStr (OLEAUT32.264)
1322 *
1323 * Convert a VT_BSTR to a VT_UI2.
1324 *
1325 * PARAMS
1326 * strIn [I] Source
1327 * lcid [I] LCID for the conversion
1328 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1329 * pusOut [O] Destination
1330 *
1331 * RETURNS
1332 * Success: S_OK.
1333 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1334 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1335 */
1336 HRESULT WINAPI VarUI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, USHORT* pusOut)
1337 {
1338 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pusOut, VT_UI2);
1339 }
1340
1341 /************************************************************************
1342 * VarUI2FromDisp (OLEAUT32.265)
1343 *
1344 * Convert a VT_DISPATCH to a VT_UI2.
1345 *
1346 * PARAMS
1347 * pdispIn [I] Source
1348 * lcid [I] LCID for conversion
1349 * pusOut [O] Destination
1350 *
1351 * RETURNS
1352 * Success: S_OK.
1353 * Failure: E_INVALIDARG, if the source value is invalid
1354 * DISP_E_OVERFLOW, if the value will not fit in the destination
1355 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1356 */
1357 HRESULT WINAPI VarUI2FromDisp(IDispatch* pdispIn, LCID lcid, USHORT* pusOut)
1358 {
1359 return VARIANT_FromDisp(pdispIn, lcid, pusOut, VT_UI2);
1360 }
1361
1362 /************************************************************************
1363 * VarUI2FromBool (OLEAUT32.266)
1364 *
1365 * Convert a VT_BOOL to a VT_UI2.
1366 *
1367 * PARAMS
1368 * boolIn [I] Source
1369 * pusOut [O] Destination
1370 *
1371 * RETURNS
1372 * S_OK.
1373 */
1374 HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT* pusOut)
1375 {
1376 return _VarUI2FromBool(boolIn, pusOut);
1377 }
1378
1379 /************************************************************************
1380 * VarUI2FromI1 (OLEAUT32.267)
1381 *
1382 * Convert a VT_I1 to a VT_UI2.
1383 *
1384 * PARAMS
1385 * cIn [I] Source
1386 * pusOut [O] Destination
1387 *
1388 * RETURNS
1389 * Success: S_OK.
1390 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1391 */
1392 HRESULT WINAPI VarUI2FromI1(signed char cIn, USHORT* pusOut)
1393 {
1394 return _VarUI2FromI1(cIn, pusOut);
1395 }
1396
1397 /************************************************************************
1398 * VarUI2FromUI4 (OLEAUT32.268)
1399 *
1400 * Convert a VT_UI4 to a VT_UI2.
1401 *
1402 * PARAMS
1403 * ulIn [I] Source
1404 * pusOut [O] Destination
1405 *
1406 * RETURNS
1407 * Success: S_OK.
1408 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1409 */
1410 HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT* pusOut)
1411 {
1412 return _VarUI2FromUI4(ulIn, pusOut);
1413 }
1414
1415 /************************************************************************
1416 * VarUI2FromDec (OLEAUT32.269)
1417 *
1418 * Convert a VT_DECIMAL to a VT_UI2.
1419 *
1420 * PARAMS
1421 * pDecIn [I] Source
1422 * pusOut [O] Destination
1423 *
1424 * RETURNS
1425 * Success: S_OK.
1426 * Failure: E_INVALIDARG, if the source value is invalid
1427 * DISP_E_OVERFLOW, if the value will not fit in the destination
1428 */
1429 HRESULT WINAPI VarUI2FromDec(DECIMAL *pdecIn, USHORT* pusOut)
1430 {
1431 LONG64 i64;
1432 HRESULT hRet;
1433
1434 hRet = VarI8FromDec(pdecIn, &i64);
1435
1436 if (SUCCEEDED(hRet))
1437 hRet = _VarUI2FromI8(i64, pusOut);
1438 return hRet;
1439 }
1440
1441 /************************************************************************
1442 * VarUI2FromI8 (OLEAUT32.378)
1443 *
1444 * Convert a VT_I8 to a VT_UI2.
1445 *
1446 * PARAMS
1447 * llIn [I] Source
1448 * pusOut [O] Destination
1449 *
1450 * RETURNS
1451 * Success: S_OK.
1452 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1453 */
1454 HRESULT WINAPI VarUI2FromI8(LONG64 llIn, USHORT* pusOut)
1455 {
1456 return _VarUI2FromI8(llIn, pusOut);
1457 }
1458
1459 /************************************************************************
1460 * VarUI2FromUI8 (OLEAUT32.379)
1461 *
1462 * Convert a VT_UI8 to a VT_UI2.
1463 *
1464 * PARAMS
1465 * ullIn [I] Source
1466 * pusOut [O] Destination
1467 *
1468 * RETURNS
1469 * Success: S_OK.
1470 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1471 */
1472 HRESULT WINAPI VarUI2FromUI8(ULONG64 ullIn, USHORT* pusOut)
1473 {
1474 return _VarUI2FromUI8(ullIn, pusOut);
1475 }
1476
1477 /* I4
1478 */
1479
1480 /************************************************************************
1481 * VarI4FromUI1 (OLEAUT32.58)
1482 *
1483 * Convert a VT_UI1 to a VT_I4.
1484 *
1485 * PARAMS
1486 * bIn [I] Source
1487 * piOut [O] Destination
1488 *
1489 * RETURNS
1490 * S_OK.
1491 */
1492 HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG *piOut)
1493 {
1494 return _VarI4FromUI1(bIn, piOut);
1495 }
1496
1497 /************************************************************************
1498 * VarI4FromI2 (OLEAUT32.59)
1499 *
1500 * Convert a VT_I2 to a VT_I4.
1501 *
1502 * PARAMS
1503 * sIn [I] Source
1504 * piOut [O] Destination
1505 *
1506 * RETURNS
1507 * Success: S_OK.
1508 * Failure: E_INVALIDARG, if the source value is invalid
1509 * DISP_E_OVERFLOW, if the value will not fit in the destination
1510 */
1511 HRESULT WINAPI VarI4FromI2(SHORT sIn, LONG *piOut)
1512 {
1513 return _VarI4FromI2(sIn, piOut);
1514 }
1515
1516 /************************************************************************
1517 * VarI4FromR4 (OLEAUT32.60)
1518 *
1519 * Convert a VT_R4 to a VT_I4.
1520 *
1521 * PARAMS
1522 * fltIn [I] Source
1523 * piOut [O] Destination
1524 *
1525 * RETURNS
1526 * Success: S_OK.
1527 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1528 */
1529 HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG *piOut)
1530 {
1531 return VarI4FromR8(fltIn, piOut);
1532 }
1533
1534 /************************************************************************
1535 * VarI4FromR8 (OLEAUT32.61)
1536 *
1537 * Convert a VT_R8 to a VT_I4.
1538 *
1539 * PARAMS
1540 * dblIn [I] Source
1541 * piOut [O] Destination
1542 *
1543 * RETURNS
1544 * Success: S_OK.
1545 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1546 *
1547 * NOTES
1548 * See VarI8FromR8() for details concerning rounding.
1549 */
1550 HRESULT WINAPI VarI4FromR8(double dblIn, LONG *piOut)
1551 {
1552 if (dblIn < (double)I4_MIN || dblIn > (double)I4_MAX)
1553 return DISP_E_OVERFLOW;
1554 VARIANT_DutchRound(LONG, dblIn, *piOut);
1555 return S_OK;
1556 }
1557
1558 /************************************************************************
1559 * VarI4FromCy (OLEAUT32.62)
1560 *
1561 * Convert a VT_CY to a VT_I4.
1562 *
1563 * PARAMS
1564 * cyIn [I] Source
1565 * piOut [O] Destination
1566 *
1567 * RETURNS
1568 * Success: S_OK.
1569 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1570 */
1571 HRESULT WINAPI VarI4FromCy(CY cyIn, LONG *piOut)
1572 {
1573 double d = cyIn.int64 / CY_MULTIPLIER_F;
1574 return VarI4FromR8(d, piOut);
1575 }
1576
1577 /************************************************************************
1578 * VarI4FromDate (OLEAUT32.63)
1579 *
1580 * Convert a VT_DATE to a VT_I4.
1581 *
1582 * PARAMS
1583 * dateIn [I] Source
1584 * piOut [O] Destination
1585 *
1586 * RETURNS
1587 * Success: S_OK.
1588 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1589 */
1590 HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG *piOut)
1591 {
1592 return VarI4FromR8(dateIn, piOut);
1593 }
1594
1595 /************************************************************************
1596 * VarI4FromStr (OLEAUT32.64)
1597 *
1598 * Convert a VT_BSTR to a VT_I4.
1599 *
1600 * PARAMS
1601 * strIn [I] Source
1602 * lcid [I] LCID for the conversion
1603 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1604 * piOut [O] Destination
1605 *
1606 * RETURNS
1607 * Success: S_OK.
1608 * Failure: E_INVALIDARG, if any parameter is invalid
1609 * DISP_E_OVERFLOW, if the value will not fit in the destination
1610 * DISP_E_TYPEMISMATCH, if strIn cannot be converted
1611 */
1612 HRESULT WINAPI VarI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG *piOut)
1613 {
1614 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, piOut, VT_I4);
1615 }
1616
1617 /************************************************************************
1618 * VarI4FromDisp (OLEAUT32.65)
1619 *
1620 * Convert a VT_DISPATCH to a VT_I4.
1621 *
1622 * PARAMS
1623 * pdispIn [I] Source
1624 * lcid [I] LCID for conversion
1625 * piOut [O] Destination
1626 *
1627 * RETURNS
1628 * Success: S_OK.
1629 * Failure: E_INVALIDARG, if the source value is invalid
1630 * DISP_E_OVERFLOW, if the value will not fit in the destination
1631 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1632 */
1633 HRESULT WINAPI VarI4FromDisp(IDispatch* pdispIn, LCID lcid, LONG *piOut)
1634 {
1635 return VARIANT_FromDisp(pdispIn, lcid, piOut, VT_I4);
1636 }
1637
1638 /************************************************************************
1639 * VarI4FromBool (OLEAUT32.66)
1640 *
1641 * Convert a VT_BOOL to a VT_I4.
1642 *
1643 * PARAMS
1644 * boolIn [I] Source
1645 * piOut [O] Destination
1646 *
1647 * RETURNS
1648 * S_OK.
1649 */
1650 HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG *piOut)
1651 {
1652 return _VarI4FromBool(boolIn, piOut);
1653 }
1654
1655 /************************************************************************
1656 * VarI4FromI1 (OLEAUT32.209)
1657 *
1658 * Convert a VT_I4 to a VT_I4.
1659 *
1660 * PARAMS
1661 * cIn [I] Source
1662 * piOut [O] Destination
1663 *
1664 * RETURNS
1665 * S_OK.
1666 */
1667 HRESULT WINAPI VarI4FromI1(signed char cIn, LONG *piOut)
1668 {
1669 return _VarI4FromI1(cIn, piOut);
1670 }
1671
1672 /************************************************************************
1673 * VarI4FromUI2 (OLEAUT32.210)
1674 *
1675 * Convert a VT_UI2 to a VT_I4.
1676 *
1677 * PARAMS
1678 * usIn [I] Source
1679 * piOut [O] Destination
1680 *
1681 * RETURNS
1682 * S_OK.
1683 */
1684 HRESULT WINAPI VarI4FromUI2(USHORT usIn, LONG *piOut)
1685 {
1686 return _VarI4FromUI2(usIn, piOut);
1687 }
1688
1689 /************************************************************************
1690 * VarI4FromUI4 (OLEAUT32.211)
1691 *
1692 * Convert a VT_UI4 to a VT_I4.
1693 *
1694 * PARAMS
1695 * ulIn [I] Source
1696 * piOut [O] Destination
1697 *
1698 * RETURNS
1699 * Success: S_OK.
1700 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1701 */
1702 HRESULT WINAPI VarI4FromUI4(ULONG ulIn, LONG *piOut)
1703 {
1704 return _VarI4FromUI4(ulIn, piOut);
1705 }
1706
1707 /************************************************************************
1708 * VarI4FromDec (OLEAUT32.212)
1709 *
1710 * Convert a VT_DECIMAL to a VT_I4.
1711 *
1712 * PARAMS
1713 * pDecIn [I] Source
1714 * piOut [O] Destination
1715 *
1716 * RETURNS
1717 * Success: S_OK.
1718 * Failure: E_INVALIDARG, if pdecIn is invalid
1719 * DISP_E_OVERFLOW, if the value will not fit in the destination
1720 */
1721 HRESULT WINAPI VarI4FromDec(DECIMAL *pdecIn, LONG *piOut)
1722 {
1723 LONG64 i64;
1724 HRESULT hRet;
1725
1726 hRet = VarI8FromDec(pdecIn, &i64);
1727
1728 if (SUCCEEDED(hRet))
1729 hRet = _VarI4FromI8(i64, piOut);
1730 return hRet;
1731 }
1732
1733 /************************************************************************
1734 * VarI4FromI8 (OLEAUT32.348)
1735 *
1736 * Convert a VT_I8 to a VT_I4.
1737 *
1738 * PARAMS
1739 * llIn [I] Source
1740 * piOut [O] Destination
1741 *
1742 * RETURNS
1743 * Success: S_OK.
1744 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1745 */
1746 HRESULT WINAPI VarI4FromI8(LONG64 llIn, LONG *piOut)
1747 {
1748 return _VarI4FromI8(llIn, piOut);
1749 }
1750
1751 /************************************************************************
1752 * VarI4FromUI8 (OLEAUT32.349)
1753 *
1754 * Convert a VT_UI8 to a VT_I4.
1755 *
1756 * PARAMS
1757 * ullIn [I] Source
1758 * piOut [O] Destination
1759 *
1760 * RETURNS
1761 * Success: S_OK.
1762 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1763 */
1764 HRESULT WINAPI VarI4FromUI8(ULONG64 ullIn, LONG *piOut)
1765 {
1766 return _VarI4FromUI8(ullIn, piOut);
1767 }
1768
1769 /* UI4
1770 */
1771
1772 /************************************************************************
1773 * VarUI4FromUI1 (OLEAUT32.270)
1774 *
1775 * Convert a VT_UI1 to a VT_UI4.
1776 *
1777 * PARAMS
1778 * bIn [I] Source
1779 * pulOut [O] Destination
1780 *
1781 * RETURNS
1782 * S_OK.
1783 */
1784 HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG *pulOut)
1785 {
1786 return _VarUI4FromUI1(bIn, pulOut);
1787 }
1788
1789 /************************************************************************
1790 * VarUI4FromI2 (OLEAUT32.271)
1791 *
1792 * Convert a VT_I2 to a VT_UI4.
1793 *
1794 * PARAMS
1795 * sIn [I] Source
1796 * pulOut [O] Destination
1797 *
1798 * RETURNS
1799 * Success: S_OK.
1800 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1801 */
1802 HRESULT WINAPI VarUI4FromI2(SHORT sIn, ULONG *pulOut)
1803 {
1804 return _VarUI4FromI2(sIn, pulOut);
1805 }
1806
1807 /************************************************************************
1808 * VarUI4FromI4 (OLEAUT32.272)
1809 *
1810 * Convert a VT_I4 to a VT_UI4.
1811 *
1812 * PARAMS
1813 * iIn [I] Source
1814 * pulOut [O] Destination
1815 *
1816 * RETURNS
1817 * Success: S_OK.
1818 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1819 */
1820 HRESULT WINAPI VarUI4FromI4(LONG iIn, ULONG *pulOut)
1821 {
1822 return _VarUI4FromI4(iIn, pulOut);
1823 }
1824
1825 /************************************************************************
1826 * VarUI4FromR4 (OLEAUT32.273)
1827 *
1828 * Convert a VT_R4 to a VT_UI4.
1829 *
1830 * PARAMS
1831 * fltIn [I] Source
1832 * pulOut [O] Destination
1833 *
1834 * RETURNS
1835 * Success: S_OK.
1836 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1837 */
1838 HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG *pulOut)
1839 {
1840 return VarUI4FromR8(fltIn, pulOut);
1841 }
1842
1843 /************************************************************************
1844 * VarUI4FromR8 (OLEAUT32.274)
1845 *
1846 * Convert a VT_R8 to a VT_UI4.
1847 *
1848 * PARAMS
1849 * dblIn [I] Source
1850 * pulOut [O] Destination
1851 *
1852 * RETURNS
1853 * Success: S_OK.
1854 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1855 *
1856 * NOTES
1857 * See VarI8FromR8() for details concerning rounding.
1858 */
1859 HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG *pulOut)
1860 {
1861 if (dblIn < -0.5 || dblIn > (double)UI4_MAX)
1862 return DISP_E_OVERFLOW;
1863 VARIANT_DutchRound(ULONG, dblIn, *pulOut);
1864 return S_OK;
1865 }
1866
1867 /************************************************************************
1868 * VarUI4FromDate (OLEAUT32.275)
1869 *
1870 * Convert a VT_DATE to a VT_UI4.
1871 *
1872 * PARAMS
1873 * dateIn [I] Source
1874 * pulOut [O] Destination
1875 *
1876 * RETURNS
1877 * Success: S_OK.
1878 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1879 */
1880 HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG *pulOut)
1881 {
1882 return VarUI4FromR8(dateIn, pulOut);
1883 }
1884
1885 /************************************************************************
1886 * VarUI4FromCy (OLEAUT32.276)
1887 *
1888 * Convert a VT_CY to a VT_UI4.
1889 *
1890 * PARAMS
1891 * cyIn [I] Source
1892 * pulOut [O] Destination
1893 *
1894 * RETURNS
1895 * Success: S_OK.
1896 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1897 */
1898 HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG *pulOut)
1899 {
1900 double d = cyIn.int64 / CY_MULTIPLIER_F;
1901 return VarUI4FromR8(d, pulOut);
1902 }
1903
1904 /************************************************************************
1905 * VarUI4FromStr (OLEAUT32.277)
1906 *
1907 * Convert a VT_BSTR to a VT_UI4.
1908 *
1909 * PARAMS
1910 * strIn [I] Source
1911 * lcid [I] LCID for the conversion
1912 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1913 * pulOut [O] Destination
1914 *
1915 * RETURNS
1916 * Success: S_OK.
1917 * Failure: E_INVALIDARG, if any parameter is invalid
1918 * DISP_E_OVERFLOW, if the value will not fit in the destination
1919 * DISP_E_TYPEMISMATCH, if strIn cannot be converted
1920 */
1921 HRESULT WINAPI VarUI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG *pulOut)
1922 {
1923 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pulOut, VT_UI4);
1924 }
1925
1926 /************************************************************************
1927 * VarUI4FromDisp (OLEAUT32.278)
1928 *
1929 * Convert a VT_DISPATCH to a VT_UI4.
1930 *
1931 * PARAMS
1932 * pdispIn [I] Source
1933 * lcid [I] LCID for conversion
1934 * pulOut [O] Destination
1935 *
1936 * RETURNS
1937 * Success: S_OK.
1938 * Failure: E_INVALIDARG, if the source value is invalid
1939 * DISP_E_OVERFLOW, if the value will not fit in the destination
1940 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1941 */
1942 HRESULT WINAPI VarUI4FromDisp(IDispatch* pdispIn, LCID lcid, ULONG *pulOut)
1943 {
1944 return VARIANT_FromDisp(pdispIn, lcid, pulOut, VT_UI4);
1945 }
1946
1947 /************************************************************************
1948 * VarUI4FromBool (OLEAUT32.279)
1949 *
1950 * Convert a VT_BOOL to a VT_UI4.
1951 *
1952 * PARAMS
1953 * boolIn [I] Source
1954 * pulOut [O] Destination
1955 *
1956 * RETURNS
1957 * S_OK.
1958 */
1959 HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG *pulOut)
1960 {
1961 return _VarUI4FromBool(boolIn, pulOut);
1962 }
1963
1964 /************************************************************************
1965 * VarUI4FromI1 (OLEAUT32.280)
1966 *
1967 * Convert a VT_I1 to a VT_UI4.
1968 *
1969 * PARAMS
1970 * cIn [I] Source
1971 * pulOut [O] Destination
1972 *
1973 * RETURNS
1974 * Success: S_OK.
1975 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1976 */
1977 HRESULT WINAPI VarUI4FromI1(signed char cIn, ULONG *pulOut)
1978 {
1979 return _VarUI4FromI1(cIn, pulOut);
1980 }
1981
1982 /************************************************************************
1983 * VarUI4FromUI2 (OLEAUT32.281)
1984 *
1985 * Convert a VT_UI2 to a VT_UI4.
1986 *
1987 * PARAMS
1988 * usIn [I] Source
1989 * pulOut [O] Destination
1990 *
1991 * RETURNS
1992 * S_OK.
1993 */
1994 HRESULT WINAPI VarUI4FromUI2(USHORT usIn, ULONG *pulOut)
1995 {
1996 return _VarUI4FromUI2(usIn, pulOut);
1997 }
1998
1999 /************************************************************************
2000 * VarUI4FromDec (OLEAUT32.282)
2001 *
2002 * Convert a VT_DECIMAL to a VT_UI4.
2003 *
2004 * PARAMS
2005 * pDecIn [I] Source
2006 * pulOut [O] Destination
2007 *
2008 * RETURNS
2009 * Success: S_OK.
2010 * Failure: E_INVALIDARG, if pdecIn is invalid
2011 * DISP_E_OVERFLOW, if the value will not fit in the destination
2012 */
2013 HRESULT WINAPI VarUI4FromDec(DECIMAL *pdecIn, ULONG *pulOut)
2014 {
2015 LONG64 i64;
2016 HRESULT hRet;
2017
2018 hRet = VarI8FromDec(pdecIn, &i64);
2019
2020 if (SUCCEEDED(hRet))
2021 hRet = _VarUI4FromI8(i64, pulOut);
2022 return hRet;
2023 }
2024
2025 /************************************************************************
2026 * VarUI4FromI8 (OLEAUT32.425)
2027 *
2028 * Convert a VT_I8 to a VT_UI4.
2029 *
2030 * PARAMS
2031 * llIn [I] Source
2032 * pulOut [O] Destination
2033 *
2034 * RETURNS
2035 * Success: S_OK.
2036 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2037 */
2038 HRESULT WINAPI VarUI4FromI8(LONG64 llIn, ULONG *pulOut)
2039 {
2040 return _VarUI4FromI8(llIn, pulOut);
2041 }
2042
2043 /************************************************************************
2044 * VarUI4FromUI8 (OLEAUT32.426)
2045 *
2046 * Convert a VT_UI8 to a VT_UI4.
2047 *
2048 * PARAMS
2049 * ullIn [I] Source
2050 * pulOut [O] Destination
2051 *
2052 * RETURNS
2053 * Success: S_OK.
2054 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2055 */
2056 HRESULT WINAPI VarUI4FromUI8(ULONG64 ullIn, ULONG *pulOut)
2057 {
2058 return _VarUI4FromUI8(ullIn, pulOut);
2059 }
2060
2061 /* I8
2062 */
2063
2064 /************************************************************************
2065 * VarI8FromUI1 (OLEAUT32.333)
2066 *
2067 * Convert a VT_UI1 to a VT_I8.
2068 *
2069 * PARAMS
2070 * bIn [I] Source
2071 * pi64Out [O] Destination
2072 *
2073 * RETURNS
2074 * S_OK.
2075 */
2076 HRESULT WINAPI VarI8FromUI1(BYTE bIn, LONG64* pi64Out)
2077 {
2078 return _VarI8FromUI1(bIn, pi64Out);
2079 }
2080
2081
2082 /************************************************************************
2083 * VarI8FromI2 (OLEAUT32.334)
2084 *
2085 * Convert a VT_I2 to a VT_I8.
2086 *
2087 * PARAMS
2088 * sIn [I] Source
2089 * pi64Out [O] Destination
2090 *
2091 * RETURNS
2092 * S_OK.
2093 */
2094 HRESULT WINAPI VarI8FromI2(SHORT sIn, LONG64* pi64Out)
2095 {
2096 return _VarI8FromI2(sIn, pi64Out);
2097 }
2098
2099 /************************************************************************
2100 * VarI8FromR4 (OLEAUT32.335)
2101 *
2102 * Convert a VT_R4 to a VT_I8.
2103 *
2104 * PARAMS
2105 * fltIn [I] Source
2106 * pi64Out [O] Destination
2107 *
2108 * RETURNS
2109 * Success: S_OK.
2110 * Failure: E_INVALIDARG, if the source value is invalid
2111 * DISP_E_OVERFLOW, if the value will not fit in the destination
2112 */
2113 HRESULT WINAPI VarI8FromR4(FLOAT fltIn, LONG64* pi64Out)
2114 {
2115 return VarI8FromR8(fltIn, pi64Out);
2116 }
2117
2118 /************************************************************************
2119 * VarI8FromR8 (OLEAUT32.336)
2120 *
2121 * Convert a VT_R8 to a VT_I8.
2122 *
2123 * PARAMS
2124 * dblIn [I] Source
2125 * pi64Out [O] Destination
2126 *
2127 * RETURNS
2128 * Success: S_OK.
2129 * Failure: E_INVALIDARG, if the source value is invalid
2130 * DISP_E_OVERFLOW, if the value will not fit in the destination
2131 *
2132 * NOTES
2133 * Only values that fit into 63 bits are accepted. Due to rounding issues,
2134 * very high or low values will not be accurately converted.
2135 *
2136 * Numbers are rounded using Dutch rounding, as follows:
2137 *
2138 *| Fractional Part Sign Direction Example
2139 *| --------------- ---- --------- -------
2140 *| < 0.5 + Down 0.4 -> 0.0
2141 *| < 0.5 - Up -0.4 -> 0.0
2142 *| > 0.5 + Up 0.6 -> 1.0
2143 *| < 0.5 - Up -0.6 -> -1.0
2144 *| = 0.5 + Up/Down Down if even, Up if odd
2145 *| = 0.5 - Up/Down Up if even, Down if odd
2146 *
2147 * This system is often used in supermarkets.
2148 */
2149 HRESULT WINAPI VarI8FromR8(double dblIn, LONG64* pi64Out)
2150 {
2151 if ( dblIn < -4611686018427387904.0 || dblIn >= 4611686018427387904.0)
2152 return DISP_E_OVERFLOW;
2153 VARIANT_DutchRound(LONG64, dblIn, *pi64Out);
2154 return S_OK;
2155 }
2156
2157 /************************************************************************
2158 * VarI8FromCy (OLEAUT32.337)
2159 *
2160 * Convert a VT_CY to a VT_I8.
2161 *
2162 * PARAMS
2163 * cyIn [I] Source
2164 * pi64Out [O] Destination
2165 *
2166 * RETURNS
2167 * S_OK.
2168 *
2169 * NOTES
2170 * All negative numbers are rounded down by 1, including those that are
2171 * evenly divisible by 10000 (this is a Win32 bug that Wine mimics).
2172 * Positive numbers are rounded using Dutch rounding: See VarI8FromR8()
2173 * for details.
2174 */
2175 HRESULT WINAPI VarI8FromCy(CY cyIn, LONG64* pi64Out)
2176 {
2177 *pi64Out = cyIn.int64 / CY_MULTIPLIER;
2178
2179 if (cyIn.int64 < 0)
2180 (*pi64Out)--; /* Mimic Win32 bug */
2181 else
2182 {
2183 cyIn.int64 -= *pi64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */
2184
2185 if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pi64Out & 0x1)))
2186 (*pi64Out)++;
2187 }
2188 return S_OK;
2189 }
2190
2191 /************************************************************************
2192 * VarI8FromDate (OLEAUT32.338)
2193 *
2194 * Convert a VT_DATE to a VT_I8.
2195 *
2196 * PARAMS
2197 * dateIn [I] Source
2198 * pi64Out [O] Destination
2199 *
2200 * RETURNS
2201 * Success: S_OK.
2202 * Failure: E_INVALIDARG, if the source value is invalid
2203 * DISP_E_OVERFLOW, if the value will not fit in the destination
2204 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2205 */
2206 HRESULT WINAPI VarI8FromDate(DATE dateIn, LONG64* pi64Out)
2207 {
2208 return VarI8FromR8(dateIn, pi64Out);
2209 }
2210
2211 /************************************************************************
2212 * VarI8FromStr (OLEAUT32.339)
2213 *
2214 * Convert a VT_BSTR to a VT_I8.
2215 *
2216 * PARAMS
2217 * strIn [I] Source
2218 * lcid [I] LCID for the conversion
2219 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
2220 * pi64Out [O] Destination
2221 *
2222 * RETURNS
2223 * Success: S_OK.
2224 * Failure: E_INVALIDARG, if the source value is invalid
2225 * DISP_E_OVERFLOW, if the value will not fit in the destination
2226 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2227 */
2228 HRESULT WINAPI VarI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG64* pi64Out)
2229 {
2230 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pi64Out, VT_I8);
2231 }
2232
2233 /************************************************************************
2234 * VarI8FromDisp (OLEAUT32.340)
2235 *
2236 * Convert a VT_DISPATCH to a VT_I8.
2237 *
2238 * PARAMS
2239 * pdispIn [I] Source
2240 * lcid [I] LCID for conversion
2241 * pi64Out [O] Destination
2242 *
2243 * RETURNS
2244 * Success: S_OK.
2245 * Failure: E_INVALIDARG, if the source value is invalid
2246 * DISP_E_OVERFLOW, if the value will not fit in the destination
2247 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2248 */
2249 HRESULT WINAPI VarI8FromDisp(IDispatch* pdispIn, LCID lcid, LONG64* pi64Out)
2250 {
2251 return VARIANT_FromDisp(pdispIn, lcid, pi64Out, VT_I8);
2252 }
2253
2254 /************************************************************************
2255 * VarI8FromBool (OLEAUT32.341)
2256 *
2257 * Convert a VT_BOOL to a VT_I8.
2258 *
2259 * PARAMS
2260 * boolIn [I] Source
2261 * pi64Out [O] Destination
2262 *
2263 * RETURNS
2264 * S_OK.
2265 */
2266 HRESULT WINAPI VarI8FromBool(VARIANT_BOOL boolIn, LONG64* pi64Out)
2267 {
2268 return VarI8FromI2(boolIn, pi64Out);
2269 }
2270
2271 /************************************************************************
2272 * VarI8FromI1 (OLEAUT32.342)
2273 *
2274 * Convert a VT_I1 to a VT_I8.
2275 *
2276 * PARAMS
2277 * cIn [I] Source
2278 * pi64Out [O] Destination
2279 *
2280 * RETURNS
2281 * S_OK.
2282 */
2283 HRESULT WINAPI VarI8FromI1(signed char cIn, LONG64* pi64Out)
2284 {
2285 return _VarI8FromI1(cIn, pi64Out);
2286 }
2287
2288 /************************************************************************
2289 * VarI8FromUI2 (OLEAUT32.343)
2290 *
2291 * Convert a VT_UI2 to a VT_I8.
2292 *
2293 * PARAMS
2294 * usIn [I] Source
2295 * pi64Out [O] Destination
2296 *
2297 * RETURNS
2298 * S_OK.
2299 */
2300 HRESULT WINAPI VarI8FromUI2(USHORT usIn, LONG64* pi64Out)
2301 {
2302 return _VarI8FromUI2(usIn, pi64Out);
2303 }
2304
2305 /************************************************************************
2306 * VarI8FromUI4 (OLEAUT32.344)
2307 *
2308 * Convert a VT_UI4 to a VT_I8.
2309 *
2310 * PARAMS
2311 * ulIn [I] Source
2312 * pi64Out [O] Destination
2313 *
2314 * RETURNS
2315 * S_OK.
2316 */
2317 HRESULT WINAPI VarI8FromUI4(ULONG ulIn, LONG64* pi64Out)
2318 {
2319 return _VarI8FromUI4(ulIn, pi64Out);
2320 }
2321
2322 /************************************************************************
2323 * VarI8FromDec (OLEAUT32.345)
2324 *
2325 * Convert a VT_DECIMAL to a VT_I8.
2326 *
2327 * PARAMS
2328 * pDecIn [I] Source
2329 * pi64Out [O] Destination
2330 *
2331 * RETURNS
2332 * Success: S_OK.
2333 * Failure: E_INVALIDARG, if the source value is invalid
2334 * DISP_E_OVERFLOW, if the value will not fit in the destination
2335 */
2336 HRESULT WINAPI VarI8FromDec(DECIMAL *pdecIn, LONG64* pi64Out)
2337 {
2338 if (!DEC_SCALE(pdecIn))
2339 {
2340 /* This decimal is just a 96 bit integer */
2341 if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
2342 return E_INVALIDARG;
2343
2344 if (DEC_HI32(pdecIn) || DEC_MID32(pdecIn) & 0x80000000)
2345 return DISP_E_OVERFLOW;
2346
2347 if (DEC_SIGN(pdecIn))
2348 *pi64Out = -DEC_LO64(pdecIn);
2349 else
2350 *pi64Out = DEC_LO64(pdecIn);
2351 return S_OK;
2352 }
2353 else
2354 {
2355 /* Decimal contains a floating point number */
2356 HRESULT hRet;
2357 double dbl;
2358
2359 hRet = VarR8FromDec(pdecIn, &dbl);
2360 if (SUCCEEDED(hRet))
2361 hRet = VarI8FromR8(dbl, pi64Out);
2362 return hRet;
2363 }
2364 }
2365
2366 /************************************************************************
2367 * VarI8FromUI8 (OLEAUT32.427)
2368 *
2369 * Convert a VT_UI8 to a VT_I8.
2370 *
2371 * PARAMS
2372 * ullIn [I] Source
2373 * pi64Out [O] Destination
2374 *
2375 * RETURNS
2376 * Success: S_OK.
2377 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2378 */
2379 HRESULT WINAPI VarI8FromUI8(ULONG64 ullIn, LONG64* pi64Out)
2380 {
2381 return _VarI8FromUI8(ullIn, pi64Out);
2382 }
2383
2384 /* UI8
2385 */
2386
2387 /************************************************************************
2388 * VarUI8FromI8 (OLEAUT32.428)
2389 *
2390 * Convert a VT_I8 to a VT_UI8.
2391 *
2392 * PARAMS
2393 * ulIn [I] Source
2394 * pui64Out [O] Destination
2395 *
2396 * RETURNS
2397 * Success: S_OK.
2398 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2399 */
2400 HRESULT WINAPI VarUI8FromI8(LONG64 llIn, ULONG64* pui64Out)
2401 {
2402 return _VarUI8FromI8(llIn, pui64Out);
2403 }
2404
2405 /************************************************************************
2406 * VarUI8FromUI1 (OLEAUT32.429)
2407 *
2408 * Convert a VT_UI1 to a VT_UI8.
2409 *
2410 * PARAMS
2411 * bIn [I] Source
2412 * pui64Out [O] Destination
2413 *
2414 * RETURNS
2415 * S_OK.
2416 */
2417 HRESULT WINAPI VarUI8FromUI1(BYTE bIn, ULONG64* pui64Out)
2418 {
2419 return _VarUI8FromUI1(bIn, pui64Out);
2420 }
2421
2422 /************************************************************************
2423 * VarUI8FromI2 (OLEAUT32.430)
2424 *
2425 * Convert a VT_I2 to a VT_UI8.
2426 *
2427 * PARAMS
2428 * sIn [I] Source
2429 * pui64Out [O] Destination
2430 *
2431 * RETURNS
2432 * S_OK.
2433 */
2434 HRESULT WINAPI VarUI8FromI2(SHORT sIn, ULONG64* pui64Out)
2435 {
2436 return _VarUI8FromI2(sIn, pui64Out);
2437 }
2438
2439 /************************************************************************
2440 * VarUI8FromR4 (OLEAUT32.431)
2441 *
2442 * Convert a VT_R4 to a VT_UI8.
2443 *
2444 * PARAMS
2445 * fltIn [I] Source
2446 * pui64Out [O] Destination
2447 *
2448 * RETURNS
2449 * Success: S_OK.
2450 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2451 */
2452 HRESULT WINAPI VarUI8FromR4(FLOAT fltIn, ULONG64* pui64Out)
2453 {
2454 return VarUI8FromR8(fltIn, pui64Out);
2455 }
2456
2457 /************************************************************************
2458 * VarUI8FromR8 (OLEAUT32.432)
2459 *
2460 * Convert a VT_R8 to a VT_UI8.
2461 *
2462 * PARAMS
2463 * dblIn [I] Source
2464 * pui64Out [O] Destination
2465 *
2466 * RETURNS
2467 * Success: S_OK.
2468 * Failure: E_INVALIDARG, if the source value is invalid
2469 * DISP_E_OVERFLOW, if the value will not fit in the destination
2470 *
2471 * NOTES
2472 * See VarI8FromR8() for details concerning rounding.
2473 */
2474 HRESULT WINAPI VarUI8FromR8(double dblIn, ULONG64* pui64Out)
2475 {
2476 if (dblIn < -0.5 || dblIn > 1.844674407370955e19)
2477 return DISP_E_OVERFLOW;
2478 VARIANT_DutchRound(ULONG64, dblIn, *pui64Out);
2479 return S_OK;
2480 }
2481
2482 /************************************************************************
2483 * VarUI8FromCy (OLEAUT32.433)
2484 *
2485 * Convert a VT_CY to a VT_UI8.
2486 *
2487 * PARAMS
2488 * cyIn [I] Source
2489 * pui64Out [O] Destination
2490 *
2491 * RETURNS
2492 * Success: S_OK.
2493 * Failure: E_INVALIDARG, if the source value is invalid
2494 * DISP_E_OVERFLOW, if the value will not fit in the destination
2495 *
2496 * NOTES
2497 * Negative values >= -5000 will be converted to 0.
2498 */
2499 HRESULT WINAPI VarUI8FromCy(CY cyIn, ULONG64* pui64Out)
2500 {
2501 if (cyIn.int64 < 0)
2502 {
2503 if (cyIn.int64 < -CY_HALF)
2504 return DISP_E_OVERFLOW;
2505 *pui64Out = 0;
2506 }
2507 else
2508 {
2509 *pui64Out = cyIn.int64 / CY_MULTIPLIER;
2510
2511 cyIn.int64 -= *pui64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */
2512
2513 if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pui64Out & 0x1)))
2514 (*pui64Out)++;
2515 }
2516 return S_OK;
2517 }
2518
2519 /************************************************************************
2520 * VarUI8FromDate (OLEAUT32.434)
2521 *
2522 * Convert a VT_DATE to a VT_UI8.
2523 *
2524 * PARAMS
2525 * dateIn [I] Source
2526 * pui64Out [O] Destination
2527 *
2528 * RETURNS
2529 * Success: S_OK.
2530 * Failure: E_INVALIDARG, if the source value is invalid
2531 * DISP_E_OVERFLOW, if the value will not fit in the destination
2532 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2533 */
2534 HRESULT WINAPI VarUI8FromDate(DATE dateIn, ULONG64* pui64Out)
2535 {
2536 return VarUI8FromR8(dateIn, pui64Out);
2537 }
2538
2539 /************************************************************************
2540 * VarUI8FromStr (OLEAUT32.435)
2541 *
2542 * Convert a VT_BSTR to a VT_UI8.
2543 *
2544 * PARAMS
2545 * strIn [I] Source
2546 * lcid [I] LCID for the conversion
2547 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
2548 * pui64Out [O] Destination
2549 *
2550 * RETURNS
2551 * Success: S_OK.
2552 * Failure: E_INVALIDARG, if the source value is invalid
2553 * DISP_E_OVERFLOW, if the value will not fit in the destination
2554 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2555 */
2556 HRESULT WINAPI VarUI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG64* pui64Out)
2557 {
2558 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pui64Out, VT_UI8);
2559 }
2560
2561 /************************************************************************
2562 * VarUI8FromDisp (OLEAUT32.436)
2563 *
2564 * Convert a VT_DISPATCH to a VT_UI8.
2565 *
2566 * PARAMS
2567 * pdispIn [I] Source
2568 * lcid [I] LCID for conversion
2569 * pui64Out [O] Destination
2570 *
2571 * RETURNS
2572 * Success: S_OK.
2573 * Failure: E_INVALIDARG, if the source value is invalid
2574 * DISP_E_OVERFLOW, if the value will not fit in the destination
2575 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2576 */
2577 HRESULT WINAPI VarUI8FromDisp(IDispatch* pdispIn, LCID lcid, ULONG64* pui64Out)
2578 {
2579 return VARIANT_FromDisp(pdispIn, lcid, pui64Out, VT_UI8);
2580 }
2581
2582 /************************************************************************
2583 * VarUI8FromBool (OLEAUT32.437)
2584 *
2585 * Convert a VT_BOOL to a VT_UI8.
2586 *
2587 * PARAMS
2588 * boolIn [I] Source
2589 * pui64Out [O] Destination
2590 *
2591 * RETURNS
2592 * Success: S_OK.
2593 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2594 */
2595 HRESULT WINAPI VarUI8FromBool(VARIANT_BOOL boolIn, ULONG64* pui64Out)
2596 {
2597 return VarI8FromI2(boolIn, (LONG64 *)pui64Out);
2598 }
2599 /************************************************************************
2600 * VarUI8FromI1 (OLEAUT32.438)
2601 *
2602 * Convert a VT_I1 to a VT_UI8.
2603 *
2604 * PARAMS
2605 * cIn [I] Source
2606 * pui64Out [O] Destination
2607 *
2608 * RETURNS
2609 * Success: S_OK.
2610 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2611 */
2612 HRESULT WINAPI VarUI8FromI1(signed char cIn, ULONG64* pui64Out)
2613 {
2614 return _VarUI8FromI1(cIn, pui64Out);
2615 }
2616
2617 /************************************************************************
2618 * VarUI8FromUI2 (OLEAUT32.439)
2619 *
2620 * Convert a VT_UI2 to a VT_UI8.
2621 *
2622 * PARAMS
2623 * usIn [I] Source
2624 * pui64Out [O] Destination
2625 *
2626 * RETURNS
2627 * S_OK.
2628 */
2629 HRESULT WINAPI VarUI8FromUI2(USHORT usIn, ULONG64* pui64Out)
2630 {
2631 return _VarUI8FromUI2(usIn, pui64Out);
2632 }
2633
2634 /************************************************************************
2635 * VarUI8FromUI4 (OLEAUT32.440)
2636 *
2637 * Convert a VT_UI4 to a VT_UI8.
2638 *
2639 * PARAMS
2640 * ulIn [I] Source
2641 * pui64Out [O] Destination
2642 *
2643 * RETURNS
2644 * S_OK.
2645 */
2646 HRESULT WINAPI VarUI8FromUI4(ULONG ulIn, ULONG64* pui64Out)
2647 {
2648 return _VarUI8FromUI4(ulIn, pui64Out);
2649 }
2650
2651 /************************************************************************
2652 * VarUI8FromDec (OLEAUT32.441)
2653 *
2654 * Convert a VT_DECIMAL to a VT_UI8.
2655 *
2656 * PARAMS
2657 * pDecIn [I] Source
2658 * pui64Out [O] Destination
2659 *
2660 * RETURNS
2661 * Success: S_OK.
2662 * Failure: E_INVALIDARG, if the source value is invalid
2663 * DISP_E_OVERFLOW, if the value will not fit in the destination
2664 *
2665 * NOTES
2666 * Under native Win32, if the source value has a scale of 0, its sign is
2667 * ignored, i.e. this function takes the absolute value rather than fail
2668 * with DISP_E_OVERFLOW. This bug has been fixed in Wine's implementation
2669 * (use VarAbs() on pDecIn first if you really want this behaviour).
2670 */
2671 HRESULT WINAPI VarUI8FromDec(DECIMAL *pdecIn, ULONG64* pui64Out)
2672 {
2673 if (!DEC_SCALE(pdecIn))
2674 {
2675 /* This decimal is just a 96 bit integer */
2676 if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
2677 return E_INVALIDARG;
2678
2679 if (DEC_HI32(pdecIn))
2680 return DISP_E_OVERFLOW;
2681
2682 if (DEC_SIGN(pdecIn))
2683 {
2684 WARN("Sign would be ignored under Win32!\n");
2685 return DISP_E_OVERFLOW;
2686 }
2687
2688 *pui64Out = DEC_LO64(pdecIn);
2689 return S_OK;
2690 }
2691 else
2692 {
2693 /* Decimal contains a floating point number */
2694 HRESULT hRet;
2695 double dbl;
2696
2697 hRet = VarR8FromDec(pdecIn, &dbl);
2698 if (SUCCEEDED(hRet))
2699 hRet = VarUI8FromR8(dbl, pui64Out);
2700 return hRet;
2701 }
2702 }
2703
2704 /* R4
2705 */
2706
2707 /************************************************************************
2708 * VarR4FromUI1 (OLEAUT32.68)
2709 *
2710 * Convert a VT_UI1 to a VT_R4.
2711 *
2712 * PARAMS
2713 * bIn [I] Source
2714 * pFltOut [O] Destination
2715 *
2716 * RETURNS
2717 * S_OK.
2718 */
2719 HRESULT WINAPI VarR4FromUI1(BYTE bIn, float *pFltOut)
2720 {
2721 return _VarR4FromUI1(bIn, pFltOut);
2722 }
2723
2724 /************************************************************************
2725 * VarR4FromI2 (OLEAUT32.69)
2726 *
2727 * Convert a VT_I2 to a VT_R4.
2728 *
2729 * PARAMS
2730 * sIn [I] Source
2731 * pFltOut [O] Destination
2732 *
2733 * RETURNS
2734 * S_OK.
2735 */
2736 HRESULT WINAPI VarR4FromI2(SHORT sIn, float *pFltOut)
2737 {
2738 return _VarR4FromI2(sIn, pFltOut);
2739 }
2740
2741 /************************************************************************
2742 * VarR4FromI4 (OLEAUT32.70)
2743 *
2744 * Convert a VT_I4 to a VT_R4.
2745 *
2746 * PARAMS
2747 * sIn [I] Source
2748 * pFltOut [O] Destination
2749 *
2750 * RETURNS
2751 * S_OK.
2752 */
2753 HRESULT WINAPI VarR4FromI4(LONG lIn, float *pFltOut)
2754 {
2755 return _VarR4FromI4(lIn, pFltOut);
2756 }
2757
2758 /************************************************************************
2759 * VarR4FromR8 (OLEAUT32.71)
2760 *
2761 * Convert a VT_R8 to a VT_R4.
2762 *
2763 * PARAMS
2764 * dblIn [I] Source
2765 * pFltOut [O] Destination
2766 *
2767 * RETURNS
2768 * Success: S_OK.
2769 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination.
2770 */
2771 HRESULT WINAPI VarR4FromR8(double dblIn, float *pFltOut)
2772 {
2773 double d = dblIn < 0.0 ? -dblIn : dblIn;
2774 if (d > R4_MAX) return DISP_E_OVERFLOW;
2775 *pFltOut = dblIn;
2776 return S_OK;
2777 }
2778
2779 /************************************************************************
2780 * VarR4FromCy (OLEAUT32.72)
2781 *
2782 * Convert a VT_CY to a VT_R4.
2783 *
2784 * PARAMS
2785 * cyIn [I] Source
2786 * pFltOut [O] Destination
2787 *
2788 * RETURNS
2789 * S_OK.
2790 */
2791 HRESULT WINAPI VarR4FromCy(CY cyIn, float *pFltOut)
2792 {
2793 *pFltOut = (double)cyIn.int64 / CY_MULTIPLIER_F;
2794 return S_OK;
2795 }
2796
2797 /************************************************************************
2798 * VarR4FromDate (OLEAUT32.73)
2799 *
2800 * Convert a VT_DATE to a VT_R4.
2801 *
2802 * PARAMS
2803 * dateIn [I] Source
2804 * pFltOut [O] Destination
2805 *
2806 * RETURNS
2807 * Success: S_OK.
2808 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination.
2809 */
2810 HRESULT WINAPI VarR4FromDate(DATE dateIn, float *pFltOut)
2811 {
2812 return VarR4FromR8(dateIn, pFltOut);
2813 }
2814
2815 /************************************************************************
2816 * VarR4FromStr (OLEAUT32.74)
2817 *
2818 * Convert a VT_BSTR to a VT_R4.
2819 *
2820 * PARAMS
2821 * strIn [I] Source
2822 * lcid [I] LCID for the conversion
2823 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
2824 * pFltOut [O] Destination
2825 *
2826 * RETURNS
2827 * Success: S_OK.
2828 * Failure: E_INVALIDARG, if strIn or pFltOut is invalid.
2829 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2830 */
2831 HRESULT WINAPI VarR4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, float *pFltOut)
2832 {
2833 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pFltOut, VT_R4);
2834 }
2835
2836 /************************************************************************
2837 * VarR4FromDisp (OLEAUT32.75)
2838 *
2839 * Convert a VT_DISPATCH to a VT_R4.
2840 *
2841 * PARAMS
2842 * pdispIn [I] Source
2843 * lcid [I] LCID for conversion
2844 * pFltOut [O] Destination
2845 *
2846 * RETURNS
2847 * Success: S_OK.
2848 * Failure: E_INVALIDARG, if the source value is invalid
2849 * DISP_E_OVERFLOW, if the value will not fit in the destination
2850 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2851 */
2852 HRESULT WINAPI VarR4FromDisp(IDispatch* pdispIn, LCID lcid, float *pFltOut)
2853 {
2854 return VARIANT_FromDisp(pdispIn, lcid, pFltOut, VT_R4);
2855 }
2856
2857 /************************************************************************
2858 * VarR4FromBool (OLEAUT32.76)
2859 *
2860 * Convert a VT_BOOL to a VT_R4.
2861 *
2862 * PARAMS
2863 * boolIn [I] Source
2864 * pFltOut [O] Destination
2865 *
2866 * RETURNS
2867 * S_OK.
2868 */
2869 HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, float *pFltOut)
2870 {
2871 return VarR4FromI2(boolIn, pFltOut);
2872 }
2873
2874 /************************************************************************
2875 * VarR4FromI1 (OLEAUT32.213)
2876 *
2877 * Convert a VT_I1 to a VT_R4.
2878 *
2879 * PARAMS
2880 * cIn [I] Source
2881 * pFltOut [O] Destination
2882 *
2883 * RETURNS
2884 * Success: S_OK.
2885 * Failure: E_INVALIDARG, if the source value is invalid
2886 * DISP_E_OVERFLOW, if the value will not fit in the destination
2887 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2888 */
2889 HRESULT WINAPI VarR4FromI1(signed char cIn, float *pFltOut)
2890 {
2891 return _VarR4FromI1(cIn, pFltOut);
2892 }
2893
2894 /************************************************************************
2895 * VarR4FromUI2 (OLEAUT32.214)
2896 *
2897 * Convert a VT_UI2 to a VT_R4.
2898 *
2899 * PARAMS
2900 * usIn [I] Source
2901 * pFltOut [O] Destination
2902 *
2903 * RETURNS
2904 * Success: S_OK.
2905 * Failure: E_INVALIDARG, if the source value is invalid
2906 * DISP_E_OVERFLOW, if the value will not fit in the destination
2907 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2908 */
2909 HRESULT WINAPI VarR4FromUI2(USHORT usIn, float *pFltOut)
2910 {
2911 return _VarR4FromUI2(usIn, pFltOut);
2912 }
2913
2914 /************************************************************************
2915 * VarR4FromUI4 (OLEAUT32.215)
2916 *
2917 * Convert a VT_UI4 to a VT_R4.
2918 *
2919 * PARAMS
2920 * ulIn [I] Source
2921 * pFltOut [O] Destination
2922 *
2923 * RETURNS
2924 * Success: S_OK.
2925 * Failure: E_INVALIDARG, if the source value is invalid
2926 * DISP_E_OVERFLOW, if the value will not fit in the destination
2927 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2928 */
2929 HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut)
2930 {
2931 return _VarR4FromUI4(ulIn, pFltOut);
2932 }
2933
2934 /************************************************************************
2935 * VarR4FromDec (OLEAUT32.216)
2936 *
2937 * Convert a VT_DECIMAL to a VT_R4.
2938 *
2939 * PARAMS
2940 * pDecIn [I] Source
2941 * pFltOut [O] Destination
2942 *
2943 * RETURNS
2944 * Success: S_OK.
2945 * Failure: E_INVALIDARG, if the source value is invalid.
2946 */
2947 HRESULT WINAPI VarR4FromDec(DECIMAL* pDecIn, float *pFltOut)
2948 {
2949 BYTE scale = DEC_SCALE(pDecIn);
2950 int divisor = 1;
2951 double highPart;
2952
2953 if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
2954 return E_INVALIDARG;
2955
2956 while (scale--)
2957 divisor *= 10;
2958
2959 if (DEC_SIGN(pDecIn))
2960 divisor = -divisor;
2961
2962 if (DEC_HI32(pDecIn))
2963 {
2964 highPart = (double)DEC_HI32(pDecIn) / (double)divisor;
2965 highPart *= 4294967296.0F;
2966 highPart *= 4294967296.0F;
2967 }
2968 else
2969 highPart = 0.0;
2970
2971 *pFltOut = (double)DEC_LO64(pDecIn) / (double)divisor + highPart;
2972 return S_OK;
2973 }
2974
2975 /************************************************************************
2976 * VarR4FromI8 (OLEAUT32.360)
2977 *
2978 * Convert a VT_I8 to a VT_R4.
2979 *
2980 * PARAMS
2981 * ullIn [I] Source
2982 * pFltOut [O] Destination
2983 *
2984 * RETURNS
2985 * S_OK.
2986 */
2987 HRESULT WINAPI VarR4FromI8(LONG64 llIn, float *pFltOut)
2988 {
2989 return _VarR4FromI8(llIn, pFltOut);
2990 }
2991
2992 /************************************************************************
2993 * VarR4FromUI8 (OLEAUT32.361)
2994 *
2995 * Convert a VT_UI8 to a VT_R4.
2996 *
2997 * PARAMS
2998 * ullIn [I] Source
2999 * pFltOut [O] Destination
3000 *
3001 * RETURNS
3002 * S_OK.
3003 */
3004 HRESULT WINAPI VarR4FromUI8(ULONG64 ullIn, float *pFltOut)
3005 {
3006 return _VarR4FromUI8(ullIn, pFltOut);
3007 }
3008
3009 /************************************************************************
3010 * VarR4CmpR8 (OLEAUT32.316)
3011 *
3012 * Compare a VT_R4 to a VT_R8.
3013 *
3014 * PARAMS
3015 * fltLeft [I] Source
3016 * dblRight [I] Value to compare
3017 *
3018 * RETURNS
3019 * VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that fltLeft is less than,
3020 * equal to or greater than dblRight respectively.
3021 */
3022 HRESULT WINAPI VarR4CmpR8(float fltLeft, double dblRight)
3023 {
3024 if (fltLeft < dblRight)
3025 return VARCMP_LT;
3026 else if (fltLeft > dblRight)
3027 return VARCMP_GT;
3028 return VARCMP_EQ;
3029 }
3030
3031 /* R8
3032 */
3033
3034 /************************************************************************
3035 * VarR8FromUI1 (OLEAUT32.78)
3036 *
3037 * Convert a VT_UI1 to a VT_R8.
3038 *
3039 * PARAMS
3040 * bIn [I] Source
3041 * pDblOut [O] Destination
3042 *
3043 * RETURNS
3044 * S_OK.
3045 */
3046 HRESULT WINAPI VarR8FromUI1(BYTE bIn, double *pDblOut)
3047 {
3048 return _VarR8FromUI1(bIn, pDblOut);
3049 }
3050
3051 /************************************************************************
3052 * VarR8FromI2 (OLEAUT32.79)
3053 *
3054 * Convert a VT_I2 to a VT_R8.
3055 *
3056 * PARAMS
3057 * sIn [I] Source
3058 * pDblOut [O] Destination
3059 *
3060 * RETURNS
3061 * S_OK.
3062 */
3063 HRESULT WINAPI VarR8FromI2(SHORT sIn, double *pDblOut)
3064 {
3065 return _VarR8FromI2(sIn, pDblOut);
3066 }
3067
3068 /************************************************************************
3069 * VarR8FromI4 (OLEAUT32.80)
3070 *
3071 * Convert a VT_I4 to a VT_R8.
3072 *
3073 * PARAMS
3074 * sIn [I] Source
3075 * pDblOut [O] Destination
3076 *
3077 * RETURNS
3078 * S_OK.
3079 */
3080 HRESULT WINAPI VarR8FromI4(LONG lIn, double *pDblOut)
3081 {
3082 return _VarR8FromI4(lIn, pDblOut);
3083 }
3084
3085 /************************************************************************
3086 * VarR8FromR4 (OLEAUT32.81)
3087 *
3088 * Convert a VT_R4 to a VT_R8.
3089 *
3090 * PARAMS
3091 * fltIn [I] Source
3092 * pDblOut [O] Destination
3093 *
3094 * RETURNS
3095 * S_OK.
3096 */
3097 HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double *pDblOut)
3098 {
3099 return _VarR8FromR4(fltIn, pDblOut);
3100 }
3101
3102 /************************************************************************
3103 * VarR8FromCy (OLEAUT32.82)
3104 *
3105 * Convert a VT_CY to a VT_R8.
3106 *
3107 * PARAMS
3108 * cyIn [I] Source
3109 * pDblOut [O] Destination
3110 *
3111 * RETURNS
3112 * S_OK.
3113 */
3114 HRESULT WINAPI VarR8FromCy(CY cyIn, double *pDblOut)
3115 {
3116 return _VarR8FromCy(cyIn, pDblOut);
3117 }
3118
3119 /************************************************************************
3120 * VarR8FromDate (OLEAUT32.83)
3121 *
3122 * Convert a VT_DATE to a VT_R8.
3123 *
3124 * PARAMS
3125 * dateIn [I] Source
3126 * pDblOut [O] Destination
3127 *
3128 * RETURNS
3129 * S_OK.
3130 */
3131 HRESULT WINAPI VarR8FromDate(DATE dateIn, double *pDblOut)
3132 {
3133 return _VarR8FromDate(dateIn, pDblOut);
3134 }
3135
3136 /************************************************************************
3137 * VarR8FromStr (OLEAUT32.84)
3138 *
3139 * Convert a VT_BSTR to a VT_R8.
3140 *
3141 * PARAMS
3142 * strIn [I] Source
3143 * lcid [I] LCID for the conversion
3144 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
3145 * pDblOut [O] Destination
3146 *
3147 * RETURNS
3148 * Success: S_OK.
3149 * Failure: E_INVALIDARG, if strIn or pDblOut is invalid.
3150 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3151 */
3152 HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double *pDblOut)
3153 {
3154 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pDblOut, VT_R8);
3155 }
3156
3157 /************************************************************************
3158 * VarR8FromDisp (OLEAUT32.85)
3159 *
3160 * Convert a VT_DISPATCH to a VT_R8.
3161 *
3162 * PARAMS
3163 * pdispIn [I] Source
3164 * lcid [I] LCID for conversion
3165 * pDblOut [O] Destination
3166 *
3167 * RETURNS
3168 * Success: S_OK.
3169 * Failure: E_INVALIDARG, if the source value is invalid
3170 * DISP_E_OVERFLOW, if the value will not fit in the destination
3171 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3172 */
3173 HRESULT WINAPI VarR8FromDisp(IDispatch* pdispIn, LCID lcid, double *pDblOut)
3174 {
3175 return VARIANT_FromDisp(pdispIn, lcid, pDblOut, VT_R8);
3176 }
3177
3178 /************************************************************************
3179 * VarR8FromBool (OLEAUT32.86)
3180 *
3181 * Convert a VT_BOOL to a VT_R8.
3182 *
3183 * PARAMS
3184 * boolIn [I] Source
3185 * pDblOut [O] Destination
3186 *
3187 * RETURNS
3188 * S_OK.
3189 */
3190 HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double *pDblOut)
3191 {
3192 return VarR8FromI2(boolIn, pDblOut);
3193 }
3194
3195 /************************************************************************
3196 * VarR8FromI1 (OLEAUT32.217)
3197 *
3198 * Convert a VT_I1 to a VT_R8.
3199 *
3200 * PARAMS
3201 * cIn [I] Source
3202 * pDblOut [O] Destination
3203 *
3204 * RETURNS
3205 * Success: S_OK.
3206 * Failure: E_INVALIDARG, if the source value is invalid
3207 * DISP_E_OVERFLOW, if the value will not fit in the destination
3208 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3209 */
3210 HRESULT WINAPI VarR8FromI1(signed char cIn, double *pDblOut)
3211 {
3212 return _VarR8FromI1(cIn, pDblOut);
3213 }
3214
3215 /************************************************************************
3216 * VarR8FromUI2 (OLEAUT32.218)
3217 *
3218 * Convert a VT_UI2 to a VT_R8.
3219 *
3220 * PARAMS
3221 * usIn [I] Source
3222 * pDblOut [O] Destination
3223 *
3224 * RETURNS
3225 * Success: S_OK.
3226 * Failure: E_INVALIDARG, if the source value is invalid
3227 * DISP_E_OVERFLOW, if the value will not fit in the destination
3228 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3229 */
3230 HRESULT WINAPI VarR8FromUI2(USHORT usIn, double *pDblOut)
3231 {
3232 return _VarR8FromUI2(usIn, pDblOut);
3233 }
3234
3235 /************************************************************************
3236 * VarR8FromUI4 (OLEAUT32.219)
3237 *
3238 * Convert a VT_UI4 to a VT_R8.
3239 *
3240 * PARAMS
3241 * ulIn [I] Source
3242 * pDblOut [O] Destination
3243 *
3244 * RETURNS
3245 * Success: S_OK.
3246 * Failure: E_INVALIDARG, if the source value is invalid
3247 * DISP_E_OVERFLOW, if the value will not fit in the destination
3248 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3249 */
3250 HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double *pDblOut)
3251 {
3252 return _VarR8FromUI4(ulIn, pDblOut);
3253 }
3254
3255 /************************************************************************
3256 * VarR8FromDec (OLEAUT32.220)
3257 *
3258 * Convert a VT_DECIMAL to a VT_R8.
3259 *
3260 * PARAMS
3261 * pDecIn [I] Source
3262 * pDblOut [O] Destination
3263 *
3264 * RETURNS
3265 * Success: S_OK.
3266 * Failure: E_INVALIDARG, if the source value is invalid.
3267 */
3268 HRESULT WINAPI VarR8FromDec(DECIMAL* pDecIn, double *pDblOut)
3269 {
3270 BYTE scale = DEC_SCALE(pDecIn);
3271 double divisor = 1.0, highPart;
3272
3273 if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
3274 return E_INVALIDARG;
3275
3276 while (scale--)
3277 divisor *= 10;
3278
3279 if (DEC_SIGN(pDecIn))
3280 divisor = -divisor;
3281
3282 if (DEC_HI32(pDecIn))
3283 {
3284 highPart = (double)DEC_HI32(pDecIn) / divisor;
3285 highPart *= 4294967296.0F;
3286 highPart *= 4294967296.0F;
3287 }
3288 else
3289 highPart = 0.0;
3290
3291 *pDblOut = (double)DEC_LO64(pDecIn) / divisor + highPart;
3292 return S_OK;
3293 }
3294
3295 /************************************************************************
3296 * VarR8FromI8 (OLEAUT32.362)
3297 *
3298 * Convert a VT_I8 to a VT_R8.
3299 *
3300 * PARAMS
3301 * ullIn [I] Source
3302 * pDblOut [O] Destination
3303 *
3304 * RETURNS
3305 * S_OK.
3306 */
3307 HRESULT WINAPI VarR8FromI8(LONG64 llIn, double *pDblOut)
3308 {
3309 return _VarR8FromI8(llIn, pDblOut);
3310 }
3311
3312 /************************************************************************
3313 * VarR8FromUI8 (OLEAUT32.363)
3314 *
3315 * Convert a VT_UI8 to a VT_R8.
3316 *
3317 * PARAMS
3318 * ullIn [I] Source
3319 * pDblOut [O] Destination
3320 *
3321 * RETURNS
3322 * S_OK.
3323 */
3324 HRESULT WINAPI VarR8FromUI8(ULONG64 ullIn, double *pDblOut)
3325 {
3326 return _VarR8FromUI8(ullIn, pDblOut);
3327 }
3328
3329 /************************************************************************
3330 * VarR8Pow (OLEAUT32.315)
3331 *
3332 * Raise a VT_R8 to a power.
3333 *
3334 * PARAMS
3335 * dblLeft [I] Source
3336 * dblPow [I] Power to raise dblLeft by
3337 * pDblOut [O] Destination
3338 *
3339 * RETURNS
3340 * S_OK. pDblOut contains dblLeft to the power of dblRight.
3341 */
3342 HRESULT WINAPI VarR8Pow(double dblLeft, double dblPow, double *pDblOut)
3343 {
3344 *pDblOut = pow(dblLeft, dblPow);
3345 return S_OK;
3346 }
3347
3348 /************************************************************************
3349 * VarR8Round (OLEAUT32.317)
3350 *
3351 * Round a VT_R8 to a given number of decimal points.
3352 *
3353 * PARAMS
3354 * dblIn [I] Source
3355 * nDig [I] Number of decimal points to round to
3356 * pDblOut [O] Destination for rounded number
3357 *
3358 * RETURNS
3359 * Success: S_OK. pDblOut is rounded to nDig digits.
3360 * Failure: E_INVALIDARG, if cDecimals is less than 0.
3361 *
3362 * NOTES
3363 * The native version of this function rounds using the internal
3364 * binary representation of the number. Wine uses the dutch rounding
3365 * convention, so therefore small differences can occur in the value returned.
3366 * MSDN says that you should use your own rounding function if you want
3367 * rounding to be predictable in your application.
3368 */
3369 HRESULT WINAPI VarR8Round(double dblIn, int nDig, double *pDblOut)
3370 {
3371 double scale, whole, fract;
3372
3373 if (nDig < 0)
3374 return E_INVALIDARG;
3375
3376 scale = pow(10.0, nDig);
3377
3378 dblIn *= scale;
3379 whole = dblIn < 0 ? ceil(dblIn) : floor(dblIn);
3380 fract = dblIn - whole;
3381
3382 if (fract > 0.5)
3383 dblIn = whole + 1.0;
3384 else if (fract == 0.5)
3385 dblIn = whole + fmod(whole, 2.0);
3386 else if (fract >= 0.0)
3387 dblIn = whole;
3388 else if (fract == -0.5)
3389 dblIn = whole - fmod(whole, 2.0);
3390 else if (fract > -0.5)
3391 dblIn = whole;
3392 else
3393 dblIn = whole - 1.0;
3394
3395 *pDblOut = dblIn / scale;
3396 return S_OK;
3397 }
3398
3399 /* CY
3400 */
3401
3402 /* Powers of 10 from 0..4 D.P. */
3403 static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000,
3404 CY_MULTIPLIER/100, CY_MULTIPLIER/10, CY_MULTIPLIER };
3405
3406 /************************************************************************
3407 * VarCyFromUI1 (OLEAUT32.98)
3408 *
3409 * Convert a VT_UI1 to a VT_CY.
3410 *
3411 * PARAMS
3412 * bIn [I] Source
3413 * pCyOut [O] Destination
3414 *
3415 * RETURNS
3416 * Success: S_OK.
3417 * Failure: E_INVALIDARG, if the source value is invalid
3418 * DISP_E_OVERFLOW, if the value will not fit in the destination
3419 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3420 */
3421 HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
3422 {
3423 return VarCyFromR8(bIn, pCyOut);
3424 }
3425
3426 /************************************************************************
3427 * VarCyFromI2 (OLEAUT32.99)
3428 *
3429 * Convert a VT_I2 to a VT_CY.
3430 *
3431 * PARAMS
3432 * sIn [I] Source
3433 * pCyOut [O] Destination
3434 *
3435 * RETURNS
3436 * Success: S_OK.
3437 * Failure: E_INVALIDARG, if the source value is invalid
3438 * DISP_E_OVERFLOW, if the value will not fit in the destination
3439 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3440 */
3441 HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
3442 {
3443 return VarCyFromR8(sIn, pCyOut);
3444 }
3445
3446 /************************************************************************
3447 * VarCyFromI4 (OLEAUT32.100)
3448 *
3449 * Convert a VT_I4 to a VT_CY.
3450 *
3451 * PARAMS
3452 * sIn [I] Source
3453 * pCyOut [O] Destination
3454 *
3455 * RETURNS
3456 * Success: S_OK.
3457 * Failure: E_INVALIDARG, if the source value is invalid
3458 * DISP_E_OVERFLOW, if the value will not fit in the destination
3459 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3460 */
3461 HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
3462 {
3463 return VarCyFromR8(lIn, pCyOut);
3464 }
3465
3466 /************************************************************************
3467 * VarCyFromR4 (OLEAUT32.101)
3468 *
3469 * Convert a VT_R4 to a VT_CY.
3470 *
3471 * PARAMS
3472 * fltIn [I] Source
3473 * pCyOut [O] Destination
3474 *
3475 * RETURNS
3476 * Success: S_OK.
3477 * Failure: E_INVALIDARG, if the source value is invalid
3478 * DISP_E_OVERFLOW, if the value will not fit in the destination
3479 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3480 */
3481 HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pCyOut)
3482 {
3483 return VarCyFromR8(fltIn, pCyOut);
3484 }
3485
3486 /************************************************************************
3487 * VarCyFromR8 (OLEAUT32.102)
3488 *
3489 * Convert a VT_R8 to a VT_CY.
3490 *
3491 * PARAMS
3492 * dblIn [I] Source
3493 * pCyOut [O] Destination
3494 *
3495 * RETURNS
3496 * Success: S_OK.
3497 * Failure: E_INVALIDARG, if the source value is invalid
3498 * DISP_E_OVERFLOW, if the value will not fit in the destination
3499 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3500 */
3501 HRESULT WINAPI VarCyFromR8(double dblIn, CY* pCyOut)
3502 {
3503 #if defined(__GNUC__) && defined(__i386__)
3504 /* This code gives identical results to Win32 on Intel.
3505 * Here we use fp exceptions to catch overflows when storing the value.
3506 */
3507 static const unsigned short r8_fpcontrol = 0x137f;
3508 static const double r8_multiplier = CY_MULTIPLIER_F;
3509 unsigned short old_fpcontrol, result_fpstatus;
3510
3511 /* Clear exceptions, save the old fp state and load the new state */
3512 __asm__ __volatile__( "fnclex" );
3513 __asm__ __volatile__( "fstcw %0" : "=m" (old_fpcontrol) : );
3514 __asm__ __volatile__( "fldcw %0" : : "m" (r8_fpcontrol) );
3515 /* Perform the conversion. */
3516 __asm__ __volatile__( "fldl %0" : : "m" (dblIn) );
3517 __asm__ __volatile__( "fmull %0" : : "m" (r8_multiplier) );
3518 __asm__ __volatile__( "fistpll %0" : : "m" (*pCyOut) );
3519 /* Save the resulting fp state, load the old state and clear exceptions */
3520 __asm__ __volatile__( "fstsw %0" : "=m" (result_fpstatus) : );
3521 __asm__ __volatile__( "fnclex" );
3522 __asm__ __volatile__( "fldcw %0" : : "m" (old_fpcontrol) );
3523
3524 if (result_fpstatus & 0x9) /* Overflow | Invalid */
3525 return DISP_E_OVERFLOW;
3526 return S_OK;
3527 #else
3528 /* This version produces slightly different results for boundary cases */
3529 if (dblIn < -922337203685477.5807 || dblIn >= 922337203685477.5807)
3530 return DISP_E_OVERFLOW;
3531 dblIn *= CY_MULTIPLIER_F;
3532 VARIANT_DutchRound(LONG64, dblIn, pCyOut->int64);
3533 #endif
3534 return S_OK;
3535 }
3536
3537 /************************************************************************
3538 * VarCyFromDate (OLEAUT32.103)
3539 *
3540 * Convert a VT_DATE to a VT_CY.
3541 *
3542 * PARAMS
3543 * dateIn [I] Source
3544 * pCyOut [O] Destination
3545 *
3546 * RETURNS
3547 * Success: S_OK.
3548 * Failure: E_INVALIDARG, if the source value is invalid
3549 * DISP_E_OVERFLOW, if the value will not fit in the destination
3550 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3551 */
3552 HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pCyOut)
3553 {
3554 return VarCyFromR8(dateIn, pCyOut);
3555 }
3556
3557 /************************************************************************
3558 * VarCyFromStr (OLEAUT32.104)
3559 *
3560 * Convert a VT_BSTR to a VT_CY.
3561 *
3562 * PARAMS
3563 * strIn [I] Source
3564 * lcid [I] LCID for the conversion
3565 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
3566 * pCyOut [O] Destination
3567 *
3568 * RETURNS
3569 * Success: S_OK.
3570 * Failure: E_INVALIDARG, if the source value is invalid
3571 * DISP_E_OVERFLOW, if the value will not fit in the destination
3572 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3573 */
3574 HRESULT WINAPI VarCyFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CY* pCyOut)
3575 {
3576 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pCyOut, VT_CY);
3577 }
3578
3579 /************************************************************************
3580 * VarCyFromDisp (OLEAUT32.105)
3581 *
3582 * Convert a VT_DISPATCH to a VT_CY.
3583 *
3584 * PARAMS
3585 * pdispIn [I] Source
3586 * lcid [I] LCID for conversion
3587 * pCyOut [O] Destination
3588 *
3589 * RETURNS
3590 * Success: S_OK.
3591 * Failure: E_INVALIDARG, if the source value is invalid
3592 * DISP_E_OVERFLOW, if the value will not fit in the destination
3593 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3594 */
3595 HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
3596 {
3597 return VARIANT_FromDisp(pdispIn, lcid, pCyOut, VT_CY);
3598 }
3599
3600 /************************************************************************
3601 * VarCyFromBool (OLEAUT32.106)
3602 *
3603 * Convert a VT_BOOL to a VT_CY.
3604 *
3605 * PARAMS
3606 * boolIn [I] Source
3607 * pCyOut [O] Destination
3608 *
3609 * RETURNS
3610 * Success: S_OK.
3611 * Failure: E_INVALIDARG, if the source value is invalid
3612 * DISP_E_OVERFLOW, if the value will not fit in the destination
3613 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3614 *
3615 * NOTES
3616 * While the sign of the boolean is stored in the currency, the value is
3617 * converted to either 0 or 1.</