[OLEAUT32] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / dll / win32 / 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define COBJMACROS
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
24
25 #include <wchar.h>
26
27 #include "wine/debug.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winnt.h"
31 #include "variant.h"
32 #include "resource.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(variant);
35
36 extern HMODULE hProxyDll DECLSPEC_HIDDEN;
37
38 #define CY_MULTIPLIER 10000 /* 4 dp of precision */
39 #define CY_MULTIPLIER_F 10000.0
40 #define CY_HALF (CY_MULTIPLIER/2) /* 0.5 */
41 #define CY_HALF_F (CY_MULTIPLIER_F/2.0)
42
43 static const WCHAR szFloatFormatW[] = { '%','.','7','G','\0' };
44 static const WCHAR szDoubleFormatW[] = { '%','.','1','5','G','\0' };
45
46 /* Copy data from one variant to another. */
47 static inline void VARIANT_CopyData(const VARIANT *srcVar, VARTYPE vt, void *pOut)
48 {
49 switch (vt)
50 {
51 case VT_I1:
52 case VT_UI1: memcpy(pOut, &V_UI1(srcVar), sizeof(BYTE)); break;
53 case VT_BOOL:
54 case VT_I2:
55 case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT)); break;
56 case VT_R4:
57 case VT_INT:
58 case VT_I4:
59 case VT_UINT:
60 case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG)); break;
61 case VT_R8:
62 case VT_DATE:
63 case VT_CY:
64 case VT_I8:
65 case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONG64)); break;
66 case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break;
67 case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break;
68 case VT_BSTR: memcpy(pOut, &V_BSTR(srcVar), sizeof(BSTR)); break;
69 default:
70 FIXME("VT_ type %d unhandled, please report!\n", vt);
71 }
72 }
73
74 /* Macro to inline conversion from a float or double to any integer type,
75 * rounding according to the 'dutch' convention.
76 */
77 #define VARIANT_DutchRound(typ, value, res) do { \
78 double whole = value < 0 ? ceil(value) : floor(value); \
79 double fract = value - whole; \
80 if (fract > 0.5) res = (typ)whole + (typ)1; \
81 else if (fract == 0.5) { typ is_odd = (typ)whole & 1; res = whole + is_odd; } \
82 else if (fract >= 0.0) res = (typ)whole; \
83 else if (fract == -0.5) { typ is_odd = (typ)whole & 1; res = whole - is_odd; } \
84 else if (fract > -0.5) res = (typ)whole; \
85 else res = (typ)whole - (typ)1; \
86 } while(0)
87
88
89 /* Coerce VT_BSTR to a numeric type */
90 static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags,
91 void* pOut, VARTYPE vt)
92 {
93 VARIANTARG dstVar;
94 HRESULT hRet;
95 NUMPARSE np;
96 BYTE rgb[1024];
97
98 /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
99 np.cDig = ARRAY_SIZE(rgb);
100 np.dwInFlags = NUMPRS_STD;
101
102 hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);
103
104 if (SUCCEEDED(hRet))
105 {
106 /* 1 << vt gives us the VTBIT constant for the destination number type */
107 hRet = VarNumFromParseNum(&np, rgb, 1 << vt, &dstVar);
108 if (SUCCEEDED(hRet))
109 VARIANT_CopyData(&dstVar, vt, pOut);
110 }
111 return hRet;
112 }
113
114 /* Coerce VT_DISPATCH to another type */
115 static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut,
116 VARTYPE vt, DWORD dwFlags)
117 {
118 static DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
119 VARIANTARG srcVar, dstVar;
120 HRESULT hRet;
121
122 if (!pdispIn)
123 return DISP_E_BADVARTYPE;
124
125 /* Get the default 'value' property from the IDispatch */
126 VariantInit(&srcVar);
127 hRet = IDispatch_Invoke(pdispIn, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET,
128 &emptyParams, &srcVar, NULL, NULL);
129
130 if (SUCCEEDED(hRet))
131 {
132 /* Convert the property to the requested type */
133 VariantInit(&dstVar);
134 hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, dwFlags, vt);
135 VariantClear(&srcVar);
136
137 if (SUCCEEDED(hRet))
138 VARIANT_CopyData(&dstVar, vt, pOut);
139 }
140 else
141 hRet = DISP_E_TYPEMISMATCH;
142 return hRet;
143 }
144
145 /* Inline return type */
146 #define RETTYP static inline HRESULT
147
148
149 /* Simple compiler cast from one type to another */
150 #define SIMPLE(dest, src, func) RETTYP _##func(src in, dest* out) { \
151 *out = in; return S_OK; }
152
153 /* Compiler cast where input cannot be negative */
154 #define NEGTST(dest, src, func) RETTYP _##func(src in, dest* out) { \
155 if (in < 0) return DISP_E_OVERFLOW; *out = in; return S_OK; }
156
157 /* Compiler cast where input cannot be > some number */
158 #define POSTST(dest, src, func, tst) RETTYP _##func(src in, dest* out) { \
159 if (in > (dest)tst) return DISP_E_OVERFLOW; *out = in; return S_OK; }
160
161 /* Compiler cast where input cannot be < some number or >= some other number */
162 #define BOTHTST(dest, src, func, lo, hi) RETTYP _##func(src in, dest* out) { \
163 if (in < (dest)lo || in > hi) return DISP_E_OVERFLOW; *out = in; return S_OK; }
164
165 /* I1 */
166 POSTST(signed char, BYTE, VarI1FromUI1, I1_MAX)
167 BOTHTST(signed char, SHORT, VarI1FromI2, I1_MIN, I1_MAX)
168 BOTHTST(signed char, LONG, VarI1FromI4, I1_MIN, I1_MAX)
169 SIMPLE(signed char, VARIANT_BOOL, VarI1FromBool)
170 POSTST(signed char, USHORT, VarI1FromUI2, I1_MAX)
171 POSTST(signed char, ULONG, VarI1FromUI4, I1_MAX)
172 BOTHTST(signed char, LONG64, VarI1FromI8, I1_MIN, I1_MAX)
173 POSTST(signed char, ULONG64, VarI1FromUI8, I1_MAX)
174
175 /* UI1 */
176 BOTHTST(BYTE, SHORT, VarUI1FromI2, UI1_MIN, UI1_MAX)
177 SIMPLE(BYTE, VARIANT_BOOL, VarUI1FromBool)
178 NEGTST(BYTE, signed char, VarUI1FromI1)
179 POSTST(BYTE, USHORT, VarUI1FromUI2, UI1_MAX)
180 BOTHTST(BYTE, LONG, VarUI1FromI4, UI1_MIN, UI1_MAX)
181 POSTST(BYTE, ULONG, VarUI1FromUI4, UI1_MAX)
182 BOTHTST(BYTE, LONG64, VarUI1FromI8, UI1_MIN, UI1_MAX)
183 POSTST(BYTE, ULONG64, VarUI1FromUI8, UI1_MAX)
184
185 /* I2 */
186 SIMPLE(SHORT, BYTE, VarI2FromUI1)
187 BOTHTST(SHORT, LONG, VarI2FromI4, I2_MIN, I2_MAX)
188 SIMPLE(SHORT, VARIANT_BOOL, VarI2FromBool)
189 SIMPLE(SHORT, signed char, VarI2FromI1)
190 POSTST(SHORT, USHORT, VarI2FromUI2, I2_MAX)
191 POSTST(SHORT, ULONG, VarI2FromUI4, I2_MAX)
192 BOTHTST(SHORT, LONG64, VarI2FromI8, I2_MIN, I2_MAX)
193 POSTST(SHORT, ULONG64, VarI2FromUI8, I2_MAX)
194
195 /* UI2 */
196 SIMPLE(USHORT, BYTE, VarUI2FromUI1)
197 NEGTST(USHORT, SHORT, VarUI2FromI2)
198 BOTHTST(USHORT, LONG, VarUI2FromI4, UI2_MIN, UI2_MAX)
199 SIMPLE(USHORT, VARIANT_BOOL, VarUI2FromBool)
200 NEGTST(USHORT, signed char, VarUI2FromI1)
201 POSTST(USHORT, ULONG, VarUI2FromUI4, UI2_MAX)
202 BOTHTST(USHORT, LONG64, VarUI2FromI8, UI2_MIN, UI2_MAX)
203 POSTST(USHORT, ULONG64, VarUI2FromUI8, UI2_MAX)
204
205 /* I4 */
206 SIMPLE(LONG, BYTE, VarI4FromUI1)
207 SIMPLE(LONG, SHORT, VarI4FromI2)
208 SIMPLE(LONG, VARIANT_BOOL, VarI4FromBool)
209 SIMPLE(LONG, signed char, VarI4FromI1)
210 SIMPLE(LONG, USHORT, VarI4FromUI2)
211 POSTST(LONG, ULONG, VarI4FromUI4, I4_MAX)
212 BOTHTST(LONG, LONG64, VarI4FromI8, I4_MIN, I4_MAX)
213 POSTST(LONG, ULONG64, VarI4FromUI8, I4_MAX)
214
215 /* UI4 */
216 SIMPLE(ULONG, BYTE, VarUI4FromUI1)
217 NEGTST(ULONG, SHORT, VarUI4FromI2)
218 NEGTST(ULONG, LONG, VarUI4FromI4)
219 SIMPLE(ULONG, VARIANT_BOOL, VarUI4FromBool)
220 NEGTST(ULONG, signed char, VarUI4FromI1)
221 SIMPLE(ULONG, USHORT, VarUI4FromUI2)
222 BOTHTST(ULONG, LONG64, VarUI4FromI8, UI4_MIN, UI4_MAX)
223 POSTST(ULONG, ULONG64, VarUI4FromUI8, UI4_MAX)
224
225 /* I8 */
226 SIMPLE(LONG64, BYTE, VarI8FromUI1)
227 SIMPLE(LONG64, SHORT, VarI8FromI2)
228 SIMPLE(LONG64, signed char, VarI8FromI1)
229 SIMPLE(LONG64, USHORT, VarI8FromUI2)
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 SIMPLE(ULONG64, ULONG, VarUI8FromUI4)
239 NEGTST(ULONG64, LONG64, VarUI8FromI8)
240
241 /* R4 (float) */
242 SIMPLE(float, BYTE, VarR4FromUI1)
243 SIMPLE(float, SHORT, VarR4FromI2)
244 SIMPLE(float, signed char, VarR4FromI1)
245 SIMPLE(float, USHORT, VarR4FromUI2)
246 SIMPLE(float, LONG, VarR4FromI4)
247 SIMPLE(float, ULONG, VarR4FromUI4)
248 SIMPLE(float, LONG64, VarR4FromI8)
249 SIMPLE(float, ULONG64, VarR4FromUI8)
250
251 /* R8 (double) */
252 SIMPLE(double, BYTE, VarR8FromUI1)
253 SIMPLE(double, SHORT, VarR8FromI2)
254 SIMPLE(double, float, VarR8FromR4)
255 RETTYP _VarR8FromCy(CY i, double* o) { *o = (double)i.int64 / CY_MULTIPLIER_F; return S_OK; }
256 SIMPLE(double, DATE, VarR8FromDate)
257 SIMPLE(double, signed char, VarR8FromI1)
258 SIMPLE(double, USHORT, VarR8FromUI2)
259 SIMPLE(double, LONG, VarR8FromI4)
260 SIMPLE(double, ULONG, VarR8FromUI4)
261 SIMPLE(double, LONG64, VarR8FromI8)
262 SIMPLE(double, ULONG64, VarR8FromUI8)
263
264
265 /* I1
266 */
267
268 /************************************************************************
269 * VarI1FromUI1 (OLEAUT32.244)
270 *
271 * Convert a VT_UI1 to a VT_I1.
272 *
273 * PARAMS
274 * bIn [I] Source
275 * pcOut [O] Destination
276 *
277 * RETURNS
278 * Success: S_OK.
279 * Failure: E_INVALIDARG, if the source value is invalid
280 * DISP_E_OVERFLOW, if the value will not fit in the destination
281 */
282 HRESULT WINAPI VarI1FromUI1(BYTE bIn, signed char* pcOut)
283 {
284 return _VarI1FromUI1(bIn, pcOut);
285 }
286
287 /************************************************************************
288 * VarI1FromI2 (OLEAUT32.245)
289 *
290 * Convert a VT_I2 to a VT_I1.
291 *
292 * PARAMS
293 * sIn [I] Source
294 * pcOut [O] Destination
295 *
296 * RETURNS
297 * Success: S_OK.
298 * Failure: E_INVALIDARG, if the source value is invalid
299 * DISP_E_OVERFLOW, if the value will not fit in the destination
300 */
301 HRESULT WINAPI VarI1FromI2(SHORT sIn, signed char* pcOut)
302 {
303 return _VarI1FromI2(sIn, pcOut);
304 }
305
306 /************************************************************************
307 * VarI1FromI4 (OLEAUT32.246)
308 *
309 * Convert a VT_I4 to a VT_I1.
310 *
311 * PARAMS
312 * iIn [I] Source
313 * pcOut [O] Destination
314 *
315 * RETURNS
316 * Success: S_OK.
317 * Failure: E_INVALIDARG, if the source value is invalid
318 * DISP_E_OVERFLOW, if the value will not fit in the destination
319 */
320 HRESULT WINAPI VarI1FromI4(LONG iIn, signed char* pcOut)
321 {
322 return _VarI1FromI4(iIn, pcOut);
323 }
324
325 /************************************************************************
326 * VarI1FromR4 (OLEAUT32.247)
327 *
328 * Convert a VT_R4 to a VT_I1.
329 *
330 * PARAMS
331 * fltIn [I] Source
332 * pcOut [O] Destination
333 *
334 * RETURNS
335 * Success: S_OK.
336 * Failure: E_INVALIDARG, if the source value is invalid
337 * DISP_E_OVERFLOW, if the value will not fit in the destination
338 */
339 HRESULT WINAPI VarI1FromR4(FLOAT fltIn, signed char* pcOut)
340 {
341 return VarI1FromR8(fltIn, pcOut);
342 }
343
344 /************************************************************************
345 * VarI1FromR8 (OLEAUT32.248)
346 *
347 * Convert a VT_R8 to a VT_I1.
348 *
349 * PARAMS
350 * dblIn [I] Source
351 * pcOut [O] Destination
352 *
353 * RETURNS
354 * Success: S_OK.
355 * Failure: E_INVALIDARG, if the source value is invalid
356 * DISP_E_OVERFLOW, if the value will not fit in the destination
357 *
358 * NOTES
359 * See VarI8FromR8() for details concerning rounding.
360 */
361 HRESULT WINAPI VarI1FromR8(double dblIn, signed char* pcOut)
362 {
363 if (dblIn < I1_MIN - 0.5 || dblIn >= I1_MAX + 0.5)
364 return DISP_E_OVERFLOW;
365 VARIANT_DutchRound(CHAR, dblIn, *pcOut);
366 return S_OK;
367 }
368
369 /************************************************************************
370 * VarI1FromDate (OLEAUT32.249)
371 *
372 * Convert a VT_DATE to a VT_I1.
373 *
374 * PARAMS
375 * dateIn [I] Source
376 * pcOut [O] Destination
377 *
378 * RETURNS
379 * Success: S_OK.
380 * Failure: E_INVALIDARG, if the source value is invalid
381 * DISP_E_OVERFLOW, if the value will not fit in the destination
382 */
383 HRESULT WINAPI VarI1FromDate(DATE dateIn, signed char* pcOut)
384 {
385 return VarI1FromR8(dateIn, pcOut);
386 }
387
388 /************************************************************************
389 * VarI1FromCy (OLEAUT32.250)
390 *
391 * Convert a VT_CY to a VT_I1.
392 *
393 * PARAMS
394 * cyIn [I] Source
395 * pcOut [O] Destination
396 *
397 * RETURNS
398 * Success: S_OK.
399 * Failure: E_INVALIDARG, if the source value is invalid
400 * DISP_E_OVERFLOW, if the value will not fit in the destination
401 */
402 HRESULT WINAPI VarI1FromCy(CY cyIn, signed char* pcOut)
403 {
404 LONG i = I1_MAX + 1;
405
406 VarI4FromCy(cyIn, &i);
407 return _VarI1FromI4(i, pcOut);
408 }
409
410 /************************************************************************
411 * VarI1FromStr (OLEAUT32.251)
412 *
413 * Convert a VT_BSTR to a VT_I1.
414 *
415 * PARAMS
416 * strIn [I] Source
417 * lcid [I] LCID for the conversion
418 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
419 * pcOut [O] Destination
420 *
421 * RETURNS
422 * Success: S_OK.
423 * Failure: E_INVALIDARG, if the source value is invalid
424 * DISP_E_OVERFLOW, if the value will not fit in the destination
425 * DISP_E_TYPEMISMATCH, if the type cannot be converted
426 */
427 HRESULT WINAPI VarI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, signed char* pcOut)
428 {
429 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pcOut, VT_I1);
430 }
431
432 /************************************************************************
433 * VarI1FromDisp (OLEAUT32.252)
434 *
435 * Convert a VT_DISPATCH to a VT_I1.
436 *
437 * PARAMS
438 * pdispIn [I] Source
439 * lcid [I] LCID for conversion
440 * pcOut [O] Destination
441 *
442 * RETURNS
443 * Success: S_OK.
444 * Failure: E_INVALIDARG, if the source value is invalid
445 * DISP_E_OVERFLOW, if the value will not fit in the destination
446 * DISP_E_TYPEMISMATCH, if the type cannot be converted
447 */
448 HRESULT WINAPI VarI1FromDisp(IDispatch* pdispIn, LCID lcid, signed char* pcOut)
449 {
450 return VARIANT_FromDisp(pdispIn, lcid, pcOut, VT_I1, 0);
451 }
452
453 /************************************************************************
454 * VarI1FromBool (OLEAUT32.253)
455 *
456 * Convert a VT_BOOL to a VT_I1.
457 *
458 * PARAMS
459 * boolIn [I] Source
460 * pcOut [O] Destination
461 *
462 * RETURNS
463 * S_OK.
464 */
465 HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, signed char* pcOut)
466 {
467 return _VarI1FromBool(boolIn, pcOut);
468 }
469
470 /************************************************************************
471 * VarI1FromUI2 (OLEAUT32.254)
472 *
473 * Convert a VT_UI2 to a VT_I1.
474 *
475 * PARAMS
476 * usIn [I] Source
477 * pcOut [O] Destination
478 *
479 * RETURNS
480 * Success: S_OK.
481 * Failure: E_INVALIDARG, if the source value is invalid
482 * DISP_E_OVERFLOW, if the value will not fit in the destination
483 */
484 HRESULT WINAPI VarI1FromUI2(USHORT usIn, signed char* pcOut)
485 {
486 return _VarI1FromUI2(usIn, pcOut);
487 }
488
489 /************************************************************************
490 * VarI1FromUI4 (OLEAUT32.255)
491 *
492 * Convert a VT_UI4 to a VT_I1.
493 *
494 * PARAMS
495 * ulIn [I] Source
496 * pcOut [O] Destination
497 *
498 * RETURNS
499 * Success: S_OK.
500 * Failure: E_INVALIDARG, if the source value is invalid
501 * DISP_E_OVERFLOW, if the value will not fit in the destination
502 * DISP_E_TYPEMISMATCH, if the type cannot be converted
503 */
504 HRESULT WINAPI VarI1FromUI4(ULONG ulIn, signed char* pcOut)
505 {
506 return _VarI1FromUI4(ulIn, pcOut);
507 }
508
509 /************************************************************************
510 * VarI1FromDec (OLEAUT32.256)
511 *
512 * Convert a VT_DECIMAL to a VT_I1.
513 *
514 * PARAMS
515 * pDecIn [I] Source
516 * pcOut [O] Destination
517 *
518 * RETURNS
519 * Success: S_OK.
520 * Failure: E_INVALIDARG, if the source value is invalid
521 * DISP_E_OVERFLOW, if the value will not fit in the destination
522 */
523 HRESULT WINAPI VarI1FromDec(DECIMAL *pdecIn, signed char* pcOut)
524 {
525 LONG64 i64;
526 HRESULT hRet;
527
528 hRet = VarI8FromDec(pdecIn, &i64);
529
530 if (SUCCEEDED(hRet))
531 hRet = _VarI1FromI8(i64, pcOut);
532 return hRet;
533 }
534
535 /************************************************************************
536 * VarI1FromI8 (OLEAUT32.376)
537 *
538 * Convert a VT_I8 to a VT_I1.
539 *
540 * PARAMS
541 * llIn [I] Source
542 * pcOut [O] Destination
543 *
544 * RETURNS
545 * Success: S_OK.
546 * Failure: E_INVALIDARG, if the source value is invalid
547 * DISP_E_OVERFLOW, if the value will not fit in the destination
548 */
549 HRESULT WINAPI VarI1FromI8(LONG64 llIn, signed char* pcOut)
550 {
551 return _VarI1FromI8(llIn, pcOut);
552 }
553
554 /************************************************************************
555 * VarI1FromUI8 (OLEAUT32.377)
556 *
557 * Convert a VT_UI8 to a VT_I1.
558 *
559 * PARAMS
560 * ullIn [I] Source
561 * pcOut [O] Destination
562 *
563 * RETURNS
564 * Success: S_OK.
565 * Failure: E_INVALIDARG, if the source value is invalid
566 * DISP_E_OVERFLOW, if the value will not fit in the destination
567 */
568 HRESULT WINAPI VarI1FromUI8(ULONG64 ullIn, signed char* pcOut)
569 {
570 return _VarI1FromUI8(ullIn, pcOut);
571 }
572
573 /* UI1
574 */
575
576 /************************************************************************
577 * VarUI1FromI2 (OLEAUT32.130)
578 *
579 * Convert a VT_I2 to a VT_UI1.
580 *
581 * PARAMS
582 * sIn [I] Source
583 * pbOut [O] Destination
584 *
585 * RETURNS
586 * Success: S_OK.
587 * Failure: E_INVALIDARG, if the source value is invalid
588 * DISP_E_OVERFLOW, if the value will not fit in the destination
589 */
590 HRESULT WINAPI VarUI1FromI2(SHORT sIn, BYTE* pbOut)
591 {
592 return _VarUI1FromI2(sIn, pbOut);
593 }
594
595 /************************************************************************
596 * VarUI1FromI4 (OLEAUT32.131)
597 *
598 * Convert a VT_I4 to a VT_UI1.
599 *
600 * PARAMS
601 * iIn [I] Source
602 * pbOut [O] Destination
603 *
604 * RETURNS
605 * Success: S_OK.
606 * Failure: E_INVALIDARG, if the source value is invalid
607 * DISP_E_OVERFLOW, if the value will not fit in the destination
608 */
609 HRESULT WINAPI VarUI1FromI4(LONG iIn, BYTE* pbOut)
610 {
611 return _VarUI1FromI4(iIn, pbOut);
612 }
613
614 /************************************************************************
615 * VarUI1FromR4 (OLEAUT32.132)
616 *
617 * Convert a VT_R4 to a VT_UI1.
618 *
619 * PARAMS
620 * fltIn [I] Source
621 * pbOut [O] Destination
622 *
623 * RETURNS
624 * Success: S_OK.
625 * Failure: E_INVALIDARG, if the source value is invalid
626 * DISP_E_OVERFLOW, if the value will not fit in the destination
627 * DISP_E_TYPEMISMATCH, if the type cannot be converted
628 */
629 HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut)
630 {
631 return VarUI1FromR8(fltIn, pbOut);
632 }
633
634 /************************************************************************
635 * VarUI1FromR8 (OLEAUT32.133)
636 *
637 * Convert a VT_R8 to a VT_UI1.
638 *
639 * PARAMS
640 * dblIn [I] Source
641 * pbOut [O] Destination
642 *
643 * RETURNS
644 * Success: S_OK.
645 * Failure: E_INVALIDARG, if the source value is invalid
646 * DISP_E_OVERFLOW, if the value will not fit in the destination
647 *
648 * NOTES
649 * See VarI8FromR8() for details concerning rounding.
650 */
651 HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut)
652 {
653 if (dblIn < -0.5 || dblIn >= UI1_MAX + 0.5)
654 return DISP_E_OVERFLOW;
655 VARIANT_DutchRound(BYTE, dblIn, *pbOut);
656 return S_OK;
657 }
658
659 /************************************************************************
660 * VarUI1FromCy (OLEAUT32.134)
661 *
662 * Convert a VT_CY to a VT_UI1.
663 *
664 * PARAMS
665 * cyIn [I] Source
666 * pbOut [O] Destination
667 *
668 * RETURNS
669 * Success: S_OK.
670 * Failure: E_INVALIDARG, if the source value is invalid
671 * DISP_E_OVERFLOW, if the value will not fit in the destination
672 *
673 * NOTES
674 * Negative values >= -5000 will be converted to 0.
675 */
676 HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut)
677 {
678 ULONG i = UI1_MAX + 1;
679
680 VarUI4FromCy(cyIn, &i);
681 return _VarUI1FromUI4(i, pbOut);
682 }
683
684 /************************************************************************
685 * VarUI1FromDate (OLEAUT32.135)
686 *
687 * Convert a VT_DATE to a VT_UI1.
688 *
689 * PARAMS
690 * dateIn [I] Source
691 * pbOut [O] Destination
692 *
693 * RETURNS
694 * Success: S_OK.
695 * Failure: E_INVALIDARG, if the source value is invalid
696 * DISP_E_OVERFLOW, if the value will not fit in the destination
697 */
698 HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE* pbOut)
699 {
700 return VarUI1FromR8(dateIn, pbOut);
701 }
702
703 /************************************************************************
704 * VarUI1FromStr (OLEAUT32.136)
705 *
706 * Convert a VT_BSTR to a VT_UI1.
707 *
708 * PARAMS
709 * strIn [I] Source
710 * lcid [I] LCID for the conversion
711 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
712 * pbOut [O] Destination
713 *
714 * RETURNS
715 * Success: S_OK.
716 * Failure: E_INVALIDARG, if the source value is invalid
717 * DISP_E_OVERFLOW, if the value will not fit in the destination
718 * DISP_E_TYPEMISMATCH, if the type cannot be converted
719 */
720 HRESULT WINAPI VarUI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
721 {
722 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pbOut, VT_UI1);
723 }
724
725 /************************************************************************
726 * VarUI1FromDisp (OLEAUT32.137)
727 *
728 * Convert a VT_DISPATCH to a VT_UI1.
729 *
730 * PARAMS
731 * pdispIn [I] Source
732 * lcid [I] LCID for conversion
733 * pbOut [O] Destination
734 *
735 * RETURNS
736 * Success: S_OK.
737 * Failure: E_INVALIDARG, if the source value is invalid
738 * DISP_E_OVERFLOW, if the value will not fit in the destination
739 * DISP_E_TYPEMISMATCH, if the type cannot be converted
740 */
741 HRESULT WINAPI VarUI1FromDisp(IDispatch* pdispIn, LCID lcid, BYTE* pbOut)
742 {
743 return VARIANT_FromDisp(pdispIn, lcid, pbOut, VT_UI1, 0);
744 }
745
746 /************************************************************************
747 * VarUI1FromBool (OLEAUT32.138)
748 *
749 * Convert a VT_BOOL to a VT_UI1.
750 *
751 * PARAMS
752 * boolIn [I] Source
753 * pbOut [O] Destination
754 *
755 * RETURNS
756 * S_OK.
757 */
758 HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE* pbOut)
759 {
760 return _VarUI1FromBool(boolIn, pbOut);
761 }
762
763 /************************************************************************
764 * VarUI1FromI1 (OLEAUT32.237)
765 *
766 * Convert a VT_I1 to a VT_UI1.
767 *
768 * PARAMS
769 * cIn [I] Source
770 * pbOut [O] Destination
771 *
772 * RETURNS
773 * Success: S_OK.
774 * Failure: E_INVALIDARG, if the source value is invalid
775 * DISP_E_OVERFLOW, if the value will not fit in the destination
776 */
777 HRESULT WINAPI VarUI1FromI1(signed char cIn, BYTE* pbOut)
778 {
779 return _VarUI1FromI1(cIn, pbOut);
780 }
781
782 /************************************************************************
783 * VarUI1FromUI2 (OLEAUT32.238)
784 *
785 * Convert a VT_UI2 to a VT_UI1.
786 *
787 * PARAMS
788 * usIn [I] Source
789 * pbOut [O] Destination
790 *
791 * RETURNS
792 * Success: S_OK.
793 * Failure: E_INVALIDARG, if the source value is invalid
794 * DISP_E_OVERFLOW, if the value will not fit in the destination
795 */
796 HRESULT WINAPI VarUI1FromUI2(USHORT usIn, BYTE* pbOut)
797 {
798 return _VarUI1FromUI2(usIn, pbOut);
799 }
800
801 /************************************************************************
802 * VarUI1FromUI4 (OLEAUT32.239)
803 *
804 * Convert a VT_UI4 to a VT_UI1.
805 *
806 * PARAMS
807 * ulIn [I] Source
808 * pbOut [O] Destination
809 *
810 * RETURNS
811 * Success: S_OK.
812 * Failure: E_INVALIDARG, if the source value is invalid
813 * DISP_E_OVERFLOW, if the value will not fit in the destination
814 */
815 HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE* pbOut)
816 {
817 return _VarUI1FromUI4(ulIn, pbOut);
818 }
819
820 /************************************************************************
821 * VarUI1FromDec (OLEAUT32.240)
822 *
823 * Convert a VT_DECIMAL to a VT_UI1.
824 *
825 * PARAMS
826 * pDecIn [I] Source
827 * pbOut [O] Destination
828 *
829 * RETURNS
830 * Success: S_OK.
831 * Failure: E_INVALIDARG, if the source value is invalid
832 * DISP_E_OVERFLOW, if the value will not fit in the destination
833 */
834 HRESULT WINAPI VarUI1FromDec(DECIMAL *pdecIn, BYTE* pbOut)
835 {
836 LONG64 i64;
837 HRESULT hRet;
838
839 hRet = VarI8FromDec(pdecIn, &i64);
840
841 if (SUCCEEDED(hRet))
842 hRet = _VarUI1FromI8(i64, pbOut);
843 return hRet;
844 }
845
846 /************************************************************************
847 * VarUI1FromI8 (OLEAUT32.372)
848 *
849 * Convert a VT_I8 to a VT_UI1.
850 *
851 * PARAMS
852 * llIn [I] Source
853 * pbOut [O] Destination
854 *
855 * RETURNS
856 * Success: S_OK.
857 * Failure: E_INVALIDARG, if the source value is invalid
858 * DISP_E_OVERFLOW, if the value will not fit in the destination
859 */
860 HRESULT WINAPI VarUI1FromI8(LONG64 llIn, BYTE* pbOut)
861 {
862 return _VarUI1FromI8(llIn, pbOut);
863 }
864
865 /************************************************************************
866 * VarUI1FromUI8 (OLEAUT32.373)
867 *
868 * Convert a VT_UI8 to a VT_UI1.
869 *
870 * PARAMS
871 * ullIn [I] Source
872 * pbOut [O] Destination
873 *
874 * RETURNS
875 * Success: S_OK.
876 * Failure: E_INVALIDARG, if the source value is invalid
877 * DISP_E_OVERFLOW, if the value will not fit in the destination
878 */
879 HRESULT WINAPI VarUI1FromUI8(ULONG64 ullIn, BYTE* pbOut)
880 {
881 return _VarUI1FromUI8(ullIn, pbOut);
882 }
883
884
885 /* I2
886 */
887
888 /************************************************************************
889 * VarI2FromUI1 (OLEAUT32.48)
890 *
891 * Convert a VT_UI2 to a VT_I2.
892 *
893 * PARAMS
894 * bIn [I] Source
895 * psOut [O] Destination
896 *
897 * RETURNS
898 * S_OK.
899 */
900 HRESULT WINAPI VarI2FromUI1(BYTE bIn, SHORT* psOut)
901 {
902 return _VarI2FromUI1(bIn, psOut);
903 }
904
905 /************************************************************************
906 * VarI2FromI4 (OLEAUT32.49)
907 *
908 * Convert a VT_I4 to a VT_I2.
909 *
910 * PARAMS
911 * iIn [I] Source
912 * psOut [O] Destination
913 *
914 * RETURNS
915 * Success: S_OK.
916 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
917 */
918 HRESULT WINAPI VarI2FromI4(LONG iIn, SHORT* psOut)
919 {
920 return _VarI2FromI4(iIn, psOut);
921 }
922
923 /************************************************************************
924 * VarI2FromR4 (OLEAUT32.50)
925 *
926 * Convert a VT_R4 to a VT_I2.
927 *
928 * PARAMS
929 * fltIn [I] Source
930 * psOut [O] Destination
931 *
932 * RETURNS
933 * Success: S_OK.
934 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
935 */
936 HRESULT WINAPI VarI2FromR4(FLOAT fltIn, SHORT* psOut)
937 {
938 return VarI2FromR8(fltIn, psOut);
939 }
940
941 /************************************************************************
942 * VarI2FromR8 (OLEAUT32.51)
943 *
944 * Convert a VT_R8 to a VT_I2.
945 *
946 * PARAMS
947 * dblIn [I] Source
948 * psOut [O] Destination
949 *
950 * RETURNS
951 * Success: S_OK.
952 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
953 *
954 * NOTES
955 * See VarI8FromR8() for details concerning rounding.
956 */
957 HRESULT WINAPI VarI2FromR8(double dblIn, SHORT* psOut)
958 {
959 if (dblIn < I2_MIN - 0.5 || dblIn >= I2_MAX + 0.5)
960 return DISP_E_OVERFLOW;
961 VARIANT_DutchRound(SHORT, dblIn, *psOut);
962 return S_OK;
963 }
964
965 /************************************************************************
966 * VarI2FromCy (OLEAUT32.52)
967 *
968 * Convert a VT_CY to a VT_I2.
969 *
970 * PARAMS
971 * cyIn [I] Source
972 * psOut [O] Destination
973 *
974 * RETURNS
975 * Success: S_OK.
976 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
977 */
978 HRESULT WINAPI VarI2FromCy(CY cyIn, SHORT* psOut)
979 {
980 LONG i = I2_MAX + 1;
981
982 VarI4FromCy(cyIn, &i);
983 return _VarI2FromI4(i, psOut);
984 }
985
986 /************************************************************************
987 * VarI2FromDate (OLEAUT32.53)
988 *
989 * Convert a VT_DATE to a VT_I2.
990 *
991 * PARAMS
992 * dateIn [I] Source
993 * psOut [O] Destination
994 *
995 * RETURNS
996 * Success: S_OK.
997 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
998 */
999 HRESULT WINAPI VarI2FromDate(DATE dateIn, SHORT* psOut)
1000 {
1001 return VarI2FromR8(dateIn, psOut);
1002 }
1003
1004 /************************************************************************
1005 * VarI2FromStr (OLEAUT32.54)
1006 *
1007 * Convert a VT_BSTR to a VT_I2.
1008 *
1009 * PARAMS
1010 * strIn [I] Source
1011 * lcid [I] LCID for the conversion
1012 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1013 * psOut [O] Destination
1014 *
1015 * RETURNS
1016 * Success: S_OK.
1017 * Failure: E_INVALIDARG, if any parameter is invalid
1018 * DISP_E_OVERFLOW, if the value will not fit in the destination
1019 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1020 */
1021 HRESULT WINAPI VarI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, SHORT* psOut)
1022 {
1023 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, psOut, VT_I2);
1024 }
1025
1026 /************************************************************************
1027 * VarI2FromDisp (OLEAUT32.55)
1028 *
1029 * Convert a VT_DISPATCH to a VT_I2.
1030 *
1031 * PARAMS
1032 * pdispIn [I] Source
1033 * lcid [I] LCID for conversion
1034 * psOut [O] Destination
1035 *
1036 * RETURNS
1037 * Success: S_OK.
1038 * Failure: E_INVALIDARG, if pdispIn is invalid,
1039 * DISP_E_OVERFLOW, if the value will not fit in the destination,
1040 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1041 */
1042 HRESULT WINAPI VarI2FromDisp(IDispatch* pdispIn, LCID lcid, SHORT* psOut)
1043 {
1044 return VARIANT_FromDisp(pdispIn, lcid, psOut, VT_I2, 0);
1045 }
1046
1047 /************************************************************************
1048 * VarI2FromBool (OLEAUT32.56)
1049 *
1050 * Convert a VT_BOOL to a VT_I2.
1051 *
1052 * PARAMS
1053 * boolIn [I] Source
1054 * psOut [O] Destination
1055 *
1056 * RETURNS
1057 * S_OK.
1058 */
1059 HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, SHORT* psOut)
1060 {
1061 return _VarI2FromBool(boolIn, psOut);
1062 }
1063
1064 /************************************************************************
1065 * VarI2FromI1 (OLEAUT32.205)
1066 *
1067 * Convert a VT_I1 to a VT_I2.
1068 *
1069 * PARAMS
1070 * cIn [I] Source
1071 * psOut [O] Destination
1072 *
1073 * RETURNS
1074 * S_OK.
1075 */
1076 HRESULT WINAPI VarI2FromI1(signed char cIn, SHORT* psOut)
1077 {
1078 return _VarI2FromI1(cIn, psOut);
1079 }
1080
1081 /************************************************************************
1082 * VarI2FromUI2 (OLEAUT32.206)
1083 *
1084 * Convert a VT_UI2 to a VT_I2.
1085 *
1086 * PARAMS
1087 * usIn [I] Source
1088 * psOut [O] Destination
1089 *
1090 * RETURNS
1091 * Success: S_OK.
1092 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1093 */
1094 HRESULT WINAPI VarI2FromUI2(USHORT usIn, SHORT* psOut)
1095 {
1096 return _VarI2FromUI2(usIn, psOut);
1097 }
1098
1099 /************************************************************************
1100 * VarI2FromUI4 (OLEAUT32.207)
1101 *
1102 * Convert a VT_UI4 to a VT_I2.
1103 *
1104 * PARAMS
1105 * ulIn [I] Source
1106 * psOut [O] Destination
1107 *
1108 * RETURNS
1109 * Success: S_OK.
1110 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1111 */
1112 HRESULT WINAPI VarI2FromUI4(ULONG ulIn, SHORT* psOut)
1113 {
1114 return _VarI2FromUI4(ulIn, psOut);
1115 }
1116
1117 /************************************************************************
1118 * VarI2FromDec (OLEAUT32.208)
1119 *
1120 * Convert a VT_DECIMAL to a VT_I2.
1121 *
1122 * PARAMS
1123 * pDecIn [I] Source
1124 * psOut [O] Destination
1125 *
1126 * RETURNS
1127 * Success: S_OK.
1128 * Failure: E_INVALIDARG, if the source value is invalid
1129 * DISP_E_OVERFLOW, if the value will not fit in the destination
1130 */
1131 HRESULT WINAPI VarI2FromDec(DECIMAL *pdecIn, SHORT* psOut)
1132 {
1133 LONG64 i64;
1134 HRESULT hRet;
1135
1136 hRet = VarI8FromDec(pdecIn, &i64);
1137
1138 if (SUCCEEDED(hRet))
1139 hRet = _VarI2FromI8(i64, psOut);
1140 return hRet;
1141 }
1142
1143 /************************************************************************
1144 * VarI2FromI8 (OLEAUT32.346)
1145 *
1146 * Convert a VT_I8 to a VT_I2.
1147 *
1148 * PARAMS
1149 * llIn [I] Source
1150 * psOut [O] Destination
1151 *
1152 * RETURNS
1153 * Success: S_OK.
1154 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1155 */
1156 HRESULT WINAPI VarI2FromI8(LONG64 llIn, SHORT* psOut)
1157 {
1158 return _VarI2FromI8(llIn, psOut);
1159 }
1160
1161 /************************************************************************
1162 * VarI2FromUI8 (OLEAUT32.347)
1163 *
1164 * Convert a VT_UI8 to a VT_I2.
1165 *
1166 * PARAMS
1167 * ullIn [I] Source
1168 * psOut [O] Destination
1169 *
1170 * RETURNS
1171 * Success: S_OK.
1172 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1173 */
1174 HRESULT WINAPI VarI2FromUI8(ULONG64 ullIn, SHORT* psOut)
1175 {
1176 return _VarI2FromUI8(ullIn, psOut);
1177 }
1178
1179 /* UI2
1180 */
1181
1182 /************************************************************************
1183 * VarUI2FromUI1 (OLEAUT32.257)
1184 *
1185 * Convert a VT_UI1 to a VT_UI2.
1186 *
1187 * PARAMS
1188 * bIn [I] Source
1189 * pusOut [O] Destination
1190 *
1191 * RETURNS
1192 * S_OK.
1193 */
1194 HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT* pusOut)
1195 {
1196 return _VarUI2FromUI1(bIn, pusOut);
1197 }
1198
1199 /************************************************************************
1200 * VarUI2FromI2 (OLEAUT32.258)
1201 *
1202 * Convert a VT_I2 to a VT_UI2.
1203 *
1204 * PARAMS
1205 * sIn [I] Source
1206 * pusOut [O] Destination
1207 *
1208 * RETURNS
1209 * Success: S_OK.
1210 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1211 */
1212 HRESULT WINAPI VarUI2FromI2(SHORT sIn, USHORT* pusOut)
1213 {
1214 return _VarUI2FromI2(sIn, pusOut);
1215 }
1216
1217 /************************************************************************
1218 * VarUI2FromI4 (OLEAUT32.259)
1219 *
1220 * Convert a VT_I4 to a VT_UI2.
1221 *
1222 * PARAMS
1223 * iIn [I] Source
1224 * pusOut [O] Destination
1225 *
1226 * RETURNS
1227 * Success: S_OK.
1228 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1229 */
1230 HRESULT WINAPI VarUI2FromI4(LONG iIn, USHORT* pusOut)
1231 {
1232 return _VarUI2FromI4(iIn, pusOut);
1233 }
1234
1235 /************************************************************************
1236 * VarUI2FromR4 (OLEAUT32.260)
1237 *
1238 * Convert a VT_R4 to a VT_UI2.
1239 *
1240 * PARAMS
1241 * fltIn [I] Source
1242 * pusOut [O] Destination
1243 *
1244 * RETURNS
1245 * Success: S_OK.
1246 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1247 */
1248 HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* pusOut)
1249 {
1250 return VarUI2FromR8(fltIn, pusOut);
1251 }
1252
1253 /************************************************************************
1254 * VarUI2FromR8 (OLEAUT32.261)
1255 *
1256 * Convert a VT_R8 to a VT_UI2.
1257 *
1258 * PARAMS
1259 * dblIn [I] Source
1260 * pusOut [O] Destination
1261 *
1262 * RETURNS
1263 * Success: S_OK.
1264 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1265 *
1266 * NOTES
1267 * See VarI8FromR8() for details concerning rounding.
1268 */
1269 HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* pusOut)
1270 {
1271 if (dblIn < -0.5 || dblIn >= UI2_MAX + 0.5)
1272 return DISP_E_OVERFLOW;
1273 VARIANT_DutchRound(USHORT, dblIn, *pusOut);
1274 return S_OK;
1275 }
1276
1277 /************************************************************************
1278 * VarUI2FromDate (OLEAUT32.262)
1279 *
1280 * Convert a VT_DATE to a VT_UI2.
1281 *
1282 * PARAMS
1283 * dateIn [I] Source
1284 * pusOut [O] Destination
1285 *
1286 * RETURNS
1287 * Success: S_OK.
1288 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1289 */
1290 HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT* pusOut)
1291 {
1292 return VarUI2FromR8(dateIn, pusOut);
1293 }
1294
1295 /************************************************************************
1296 * VarUI2FromCy (OLEAUT32.263)
1297 *
1298 * Convert a VT_CY to a VT_UI2.
1299 *
1300 * PARAMS
1301 * cyIn [I] Source
1302 * pusOut [O] Destination
1303 *
1304 * RETURNS
1305 * Success: S_OK.
1306 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1307 *
1308 * NOTES
1309 * Negative values >= -5000 will be converted to 0.
1310 */
1311 HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut)
1312 {
1313 ULONG i = UI2_MAX + 1;
1314
1315 VarUI4FromCy(cyIn, &i);
1316 return _VarUI2FromUI4(i, pusOut);
1317 }
1318
1319 /************************************************************************
1320 * VarUI2FromStr (OLEAUT32.264)
1321 *
1322 * Convert a VT_BSTR to a VT_UI2.
1323 *
1324 * PARAMS
1325 * strIn [I] Source
1326 * lcid [I] LCID for the conversion
1327 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1328 * pusOut [O] Destination
1329 *
1330 * RETURNS
1331 * Success: S_OK.
1332 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1333 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1334 */
1335 HRESULT WINAPI VarUI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, USHORT* pusOut)
1336 {
1337 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pusOut, VT_UI2);
1338 }
1339
1340 /************************************************************************
1341 * VarUI2FromDisp (OLEAUT32.265)
1342 *
1343 * Convert a VT_DISPATCH to a VT_UI2.
1344 *
1345 * PARAMS
1346 * pdispIn [I] Source
1347 * lcid [I] LCID for conversion
1348 * pusOut [O] Destination
1349 *
1350 * RETURNS
1351 * Success: S_OK.
1352 * Failure: E_INVALIDARG, if the source value is invalid
1353 * DISP_E_OVERFLOW, if the value will not fit in the destination
1354 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1355 */
1356 HRESULT WINAPI VarUI2FromDisp(IDispatch* pdispIn, LCID lcid, USHORT* pusOut)
1357 {
1358 return VARIANT_FromDisp(pdispIn, lcid, pusOut, VT_UI2, 0);
1359 }
1360
1361 /************************************************************************
1362 * VarUI2FromBool (OLEAUT32.266)
1363 *
1364 * Convert a VT_BOOL to a VT_UI2.
1365 *
1366 * PARAMS
1367 * boolIn [I] Source
1368 * pusOut [O] Destination
1369 *
1370 * RETURNS
1371 * S_OK.
1372 */
1373 HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT* pusOut)
1374 {
1375 return _VarUI2FromBool(boolIn, pusOut);
1376 }
1377
1378 /************************************************************************
1379 * VarUI2FromI1 (OLEAUT32.267)
1380 *
1381 * Convert a VT_I1 to a VT_UI2.
1382 *
1383 * PARAMS
1384 * cIn [I] Source
1385 * pusOut [O] Destination
1386 *
1387 * RETURNS
1388 * Success: S_OK.
1389 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1390 */
1391 HRESULT WINAPI VarUI2FromI1(signed char cIn, USHORT* pusOut)
1392 {
1393 return _VarUI2FromI1(cIn, pusOut);
1394 }
1395
1396 /************************************************************************
1397 * VarUI2FromUI4 (OLEAUT32.268)
1398 *
1399 * Convert a VT_UI4 to a VT_UI2.
1400 *
1401 * PARAMS
1402 * ulIn [I] Source
1403 * pusOut [O] Destination
1404 *
1405 * RETURNS
1406 * Success: S_OK.
1407 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1408 */
1409 HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT* pusOut)
1410 {
1411 return _VarUI2FromUI4(ulIn, pusOut);
1412 }
1413
1414 /************************************************************************
1415 * VarUI2FromDec (OLEAUT32.269)
1416 *
1417 * Convert a VT_DECIMAL to a VT_UI2.
1418 *
1419 * PARAMS
1420 * pDecIn [I] Source
1421 * pusOut [O] Destination
1422 *
1423 * RETURNS
1424 * Success: S_OK.
1425 * Failure: E_INVALIDARG, if the source value is invalid
1426 * DISP_E_OVERFLOW, if the value will not fit in the destination
1427 */
1428 HRESULT WINAPI VarUI2FromDec(DECIMAL *pdecIn, USHORT* pusOut)
1429 {
1430 LONG64 i64;
1431 HRESULT hRet;
1432
1433 hRet = VarI8FromDec(pdecIn, &i64);
1434
1435 if (SUCCEEDED(hRet))
1436 hRet = _VarUI2FromI8(i64, pusOut);
1437 return hRet;
1438 }
1439
1440 /************************************************************************
1441 * VarUI2FromI8 (OLEAUT32.378)
1442 *
1443 * Convert a VT_I8 to a VT_UI2.
1444 *
1445 * PARAMS
1446 * llIn [I] Source
1447 * pusOut [O] Destination
1448 *
1449 * RETURNS
1450 * Success: S_OK.
1451 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1452 */
1453 HRESULT WINAPI VarUI2FromI8(LONG64 llIn, USHORT* pusOut)
1454 {
1455 return _VarUI2FromI8(llIn, pusOut);
1456 }
1457
1458 /************************************************************************
1459 * VarUI2FromUI8 (OLEAUT32.379)
1460 *
1461 * Convert a VT_UI8 to a VT_UI2.
1462 *
1463 * PARAMS
1464 * ullIn [I] Source
1465 * pusOut [O] Destination
1466 *
1467 * RETURNS
1468 * Success: S_OK.
1469 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1470 */
1471 HRESULT WINAPI VarUI2FromUI8(ULONG64 ullIn, USHORT* pusOut)
1472 {
1473 return _VarUI2FromUI8(ullIn, pusOut);
1474 }
1475
1476 /* I4
1477 */
1478
1479 /************************************************************************
1480 * VarI4FromUI1 (OLEAUT32.58)
1481 *
1482 * Convert a VT_UI1 to a VT_I4.
1483 *
1484 * PARAMS
1485 * bIn [I] Source
1486 * piOut [O] Destination
1487 *
1488 * RETURNS
1489 * S_OK.
1490 */
1491 HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG *piOut)
1492 {
1493 return _VarI4FromUI1(bIn, piOut);
1494 }
1495
1496 /************************************************************************
1497 * VarI4FromI2 (OLEAUT32.59)
1498 *
1499 * Convert a VT_I2 to a VT_I4.
1500 *
1501 * PARAMS
1502 * sIn [I] Source
1503 * piOut [O] Destination
1504 *
1505 * RETURNS
1506 * Success: S_OK.
1507 * Failure: E_INVALIDARG, if the source value is invalid
1508 * DISP_E_OVERFLOW, if the value will not fit in the destination
1509 */
1510 HRESULT WINAPI VarI4FromI2(SHORT sIn, LONG *piOut)
1511 {
1512 return _VarI4FromI2(sIn, piOut);
1513 }
1514
1515 /************************************************************************
1516 * VarI4FromR4 (OLEAUT32.60)
1517 *
1518 * Convert a VT_R4 to a VT_I4.
1519 *
1520 * PARAMS
1521 * fltIn [I] Source
1522 * piOut [O] Destination
1523 *
1524 * RETURNS
1525 * Success: S_OK.
1526 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1527 */
1528 HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG *piOut)
1529 {
1530 return VarI4FromR8(fltIn, piOut);
1531 }
1532
1533 /************************************************************************
1534 * VarI4FromR8 (OLEAUT32.61)
1535 *
1536 * Convert a VT_R8 to a VT_I4.
1537 *
1538 * PARAMS
1539 * dblIn [I] Source
1540 * piOut [O] Destination
1541 *
1542 * RETURNS
1543 * Success: S_OK.
1544 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1545 *
1546 * NOTES
1547 * See VarI8FromR8() for details concerning rounding.
1548 */
1549 HRESULT WINAPI VarI4FromR8(double dblIn, LONG *piOut)
1550 {
1551 if (dblIn < I4_MIN - 0.5 || dblIn >= I4_MAX + 0.5)
1552 return DISP_E_OVERFLOW;
1553 VARIANT_DutchRound(LONG, dblIn, *piOut);
1554 return S_OK;
1555 }
1556
1557 /************************************************************************
1558 * VarI4FromCy (OLEAUT32.62)
1559 *
1560 * Convert a VT_CY to a VT_I4.
1561 *
1562 * PARAMS
1563 * cyIn [I] Source
1564 * piOut [O] Destination
1565 *
1566 * RETURNS
1567 * Success: S_OK.
1568 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1569 */
1570 HRESULT WINAPI VarI4FromCy(CY cyIn, LONG *piOut)
1571 {
1572 double d = cyIn.int64 / CY_MULTIPLIER_F;
1573 return VarI4FromR8(d, piOut);
1574 }
1575
1576 /************************************************************************
1577 * VarI4FromDate (OLEAUT32.63)
1578 *
1579 * Convert a VT_DATE to a VT_I4.
1580 *
1581 * PARAMS
1582 * dateIn [I] Source
1583 * piOut [O] Destination
1584 *
1585 * RETURNS
1586 * Success: S_OK.
1587 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1588 */
1589 HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG *piOut)
1590 {
1591 return VarI4FromR8(dateIn, piOut);
1592 }
1593
1594 /************************************************************************
1595 * VarI4FromStr (OLEAUT32.64)
1596 *
1597 * Convert a VT_BSTR to a VT_I4.
1598 *
1599 * PARAMS
1600 * strIn [I] Source
1601 * lcid [I] LCID for the conversion
1602 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1603 * piOut [O] Destination
1604 *
1605 * RETURNS
1606 * Success: S_OK.
1607 * Failure: E_INVALIDARG, if any parameter is invalid
1608 * DISP_E_OVERFLOW, if the value will not fit in the destination
1609 * DISP_E_TYPEMISMATCH, if strIn cannot be converted
1610 */
1611 HRESULT WINAPI VarI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG *piOut)
1612 {
1613 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, piOut, VT_I4);
1614 }
1615
1616 /************************************************************************
1617 * VarI4FromDisp (OLEAUT32.65)
1618 *
1619 * Convert a VT_DISPATCH to a VT_I4.
1620 *
1621 * PARAMS
1622 * pdispIn [I] Source
1623 * lcid [I] LCID for conversion
1624 * piOut [O] Destination
1625 *
1626 * RETURNS
1627 * Success: S_OK.
1628 * Failure: E_INVALIDARG, if the source value is invalid
1629 * DISP_E_OVERFLOW, if the value will not fit in the destination
1630 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1631 */
1632 HRESULT WINAPI VarI4FromDisp(IDispatch* pdispIn, LCID lcid, LONG *piOut)
1633 {
1634 return VARIANT_FromDisp(pdispIn, lcid, piOut, VT_I4, 0);
1635 }
1636
1637 /************************************************************************
1638 * VarI4FromBool (OLEAUT32.66)
1639 *
1640 * Convert a VT_BOOL to a VT_I4.
1641 *
1642 * PARAMS
1643 * boolIn [I] Source
1644 * piOut [O] Destination
1645 *
1646 * RETURNS
1647 * S_OK.
1648 */
1649 HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG *piOut)
1650 {
1651 return _VarI4FromBool(boolIn, piOut);
1652 }
1653
1654 /************************************************************************
1655 * VarI4FromI1 (OLEAUT32.209)
1656 *
1657 * Convert a VT_I1 to a VT_I4.
1658 *
1659 * PARAMS
1660 * cIn [I] Source
1661 * piOut [O] Destination
1662 *
1663 * RETURNS
1664 * S_OK.
1665 */
1666 HRESULT WINAPI VarI4FromI1(signed char cIn, LONG *piOut)
1667 {
1668 return _VarI4FromI1(cIn, piOut);
1669 }
1670
1671 /************************************************************************
1672 * VarI4FromUI2 (OLEAUT32.210)
1673 *
1674 * Convert a VT_UI2 to a VT_I4.
1675 *
1676 * PARAMS
1677 * usIn [I] Source
1678 * piOut [O] Destination
1679 *
1680 * RETURNS
1681 * S_OK.
1682 */
1683 HRESULT WINAPI VarI4FromUI2(USHORT usIn, LONG *piOut)
1684 {
1685 return _VarI4FromUI2(usIn, piOut);
1686 }
1687
1688 /************************************************************************
1689 * VarI4FromUI4 (OLEAUT32.211)
1690 *
1691 * Convert a VT_UI4 to a VT_I4.
1692 *
1693 * PARAMS
1694 * ulIn [I] Source
1695 * piOut [O] Destination
1696 *
1697 * RETURNS
1698 * Success: S_OK.
1699 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1700 */
1701 HRESULT WINAPI VarI4FromUI4(ULONG ulIn, LONG *piOut)
1702 {
1703 return _VarI4FromUI4(ulIn, piOut);
1704 }
1705
1706 /************************************************************************
1707 * VarI4FromDec (OLEAUT32.212)
1708 *
1709 * Convert a VT_DECIMAL to a VT_I4.
1710 *
1711 * PARAMS
1712 * pDecIn [I] Source
1713 * piOut [O] Destination
1714 *
1715 * RETURNS
1716 * Success: S_OK.
1717 * Failure: E_INVALIDARG, if pdecIn is invalid
1718 * DISP_E_OVERFLOW, if the value will not fit in the destination
1719 */
1720 HRESULT WINAPI VarI4FromDec(DECIMAL *pdecIn, LONG *piOut)
1721 {
1722 LONG64 i64;
1723 HRESULT hRet;
1724
1725 hRet = VarI8FromDec(pdecIn, &i64);
1726
1727 if (SUCCEEDED(hRet))
1728 hRet = _VarI4FromI8(i64, piOut);
1729 return hRet;
1730 }
1731
1732 /************************************************************************
1733 * VarI4FromI8 (OLEAUT32.348)
1734 *
1735 * Convert a VT_I8 to a VT_I4.
1736 *
1737 * PARAMS
1738 * llIn [I] Source
1739 * piOut [O] Destination
1740 *
1741 * RETURNS
1742 * Success: S_OK.
1743 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1744 */
1745 HRESULT WINAPI VarI4FromI8(LONG64 llIn, LONG *piOut)
1746 {
1747 return _VarI4FromI8(llIn, piOut);
1748 }
1749
1750 /************************************************************************
1751 * VarI4FromUI8 (OLEAUT32.349)
1752 *
1753 * Convert a VT_UI8 to a VT_I4.
1754 *
1755 * PARAMS
1756 * ullIn [I] Source
1757 * piOut [O] Destination
1758 *
1759 * RETURNS
1760 * Success: S_OK.
1761 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1762 */
1763 HRESULT WINAPI VarI4FromUI8(ULONG64 ullIn, LONG *piOut)
1764 {
1765 return _VarI4FromUI8(ullIn, piOut);
1766 }
1767
1768 /* UI4
1769 */
1770
1771 /************************************************************************
1772 * VarUI4FromUI1 (OLEAUT32.270)
1773 *
1774 * Convert a VT_UI1 to a VT_UI4.
1775 *
1776 * PARAMS
1777 * bIn [I] Source
1778 * pulOut [O] Destination
1779 *
1780 * RETURNS
1781 * S_OK.
1782 */
1783 HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG *pulOut)
1784 {
1785 return _VarUI4FromUI1(bIn, pulOut);
1786 }
1787
1788 /************************************************************************
1789 * VarUI4FromI2 (OLEAUT32.271)
1790 *
1791 * Convert a VT_I2 to a VT_UI4.
1792 *
1793 * PARAMS
1794 * sIn [I] Source
1795 * pulOut [O] Destination
1796 *
1797 * RETURNS
1798 * Success: S_OK.
1799 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1800 */
1801 HRESULT WINAPI VarUI4FromI2(SHORT sIn, ULONG *pulOut)
1802 {
1803 return _VarUI4FromI2(sIn, pulOut);
1804 }
1805
1806 /************************************************************************
1807 * VarUI4FromI4 (OLEAUT32.272)
1808 *
1809 * Convert a VT_I4 to a VT_UI4.
1810 *
1811 * PARAMS
1812 * iIn [I] Source
1813 * pulOut [O] Destination
1814 *
1815 * RETURNS
1816 * Success: S_OK.
1817 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1818 */
1819 HRESULT WINAPI VarUI4FromI4(LONG iIn, ULONG *pulOut)
1820 {
1821 return _VarUI4FromI4(iIn, pulOut);
1822 }
1823
1824 /************************************************************************
1825 * VarUI4FromR4 (OLEAUT32.273)
1826 *
1827 * Convert a VT_R4 to a VT_UI4.
1828 *
1829 * PARAMS
1830 * fltIn [I] Source
1831 * pulOut [O] Destination
1832 *
1833 * RETURNS
1834 * Success: S_OK.
1835 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1836 */
1837 HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG *pulOut)
1838 {
1839 return VarUI4FromR8(fltIn, pulOut);
1840 }
1841
1842 /************************************************************************
1843 * VarUI4FromR8 (OLEAUT32.274)
1844 *
1845 * Convert a VT_R8 to a VT_UI4.
1846 *
1847 * PARAMS
1848 * dblIn [I] Source
1849 * pulOut [O] Destination
1850 *
1851 * RETURNS
1852 * Success: S_OK.
1853 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1854 *
1855 * NOTES
1856 * See VarI8FromR8() for details concerning rounding.
1857 */
1858 HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG *pulOut)
1859 {
1860 if (dblIn < -0.5 || dblIn >= UI4_MAX + 0.5)
1861 return DISP_E_OVERFLOW;
1862 VARIANT_DutchRound(ULONG, dblIn, *pulOut);
1863 return S_OK;
1864 }
1865
1866 /************************************************************************
1867 * VarUI4FromDate (OLEAUT32.275)
1868 *
1869 * Convert a VT_DATE to a VT_UI4.
1870 *
1871 * PARAMS
1872 * dateIn [I] Source
1873 * pulOut [O] Destination
1874 *
1875 * RETURNS
1876 * Success: S_OK.
1877 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1878 */
1879 HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG *pulOut)
1880 {
1881 return VarUI4FromR8(dateIn, pulOut);
1882 }
1883
1884 /************************************************************************
1885 * VarUI4FromCy (OLEAUT32.276)
1886 *
1887 * Convert a VT_CY to a VT_UI4.
1888 *
1889 * PARAMS
1890 * cyIn [I] Source
1891 * pulOut [O] Destination
1892 *
1893 * RETURNS
1894 * Success: S_OK.
1895 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1896 */
1897 HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG *pulOut)
1898 {
1899 double d = cyIn.int64 / CY_MULTIPLIER_F;
1900 return VarUI4FromR8(d, pulOut);
1901 }
1902
1903 /************************************************************************
1904 * VarUI4FromStr (OLEAUT32.277)
1905 *
1906 * Convert a VT_BSTR to a VT_UI4.
1907 *
1908 * PARAMS
1909 * strIn [I] Source
1910 * lcid [I] LCID for the conversion
1911 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
1912 * pulOut [O] Destination
1913 *
1914 * RETURNS
1915 * Success: S_OK.
1916 * Failure: E_INVALIDARG, if any parameter is invalid
1917 * DISP_E_OVERFLOW, if the value will not fit in the destination
1918 * DISP_E_TYPEMISMATCH, if strIn cannot be converted
1919 */
1920 HRESULT WINAPI VarUI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG *pulOut)
1921 {
1922 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pulOut, VT_UI4);
1923 }
1924
1925 /************************************************************************
1926 * VarUI4FromDisp (OLEAUT32.278)
1927 *
1928 * Convert a VT_DISPATCH to a VT_UI4.
1929 *
1930 * PARAMS
1931 * pdispIn [I] Source
1932 * lcid [I] LCID for conversion
1933 * pulOut [O] Destination
1934 *
1935 * RETURNS
1936 * Success: S_OK.
1937 * Failure: E_INVALIDARG, if the source value is invalid
1938 * DISP_E_OVERFLOW, if the value will not fit in the destination
1939 * DISP_E_TYPEMISMATCH, if the type cannot be converted
1940 */
1941 HRESULT WINAPI VarUI4FromDisp(IDispatch* pdispIn, LCID lcid, ULONG *pulOut)
1942 {
1943 return VARIANT_FromDisp(pdispIn, lcid, pulOut, VT_UI4, 0);
1944 }
1945
1946 /************************************************************************
1947 * VarUI4FromBool (OLEAUT32.279)
1948 *
1949 * Convert a VT_BOOL to a VT_UI4.
1950 *
1951 * PARAMS
1952 * boolIn [I] Source
1953 * pulOut [O] Destination
1954 *
1955 * RETURNS
1956 * S_OK.
1957 */
1958 HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG *pulOut)
1959 {
1960 return _VarUI4FromBool(boolIn, pulOut);
1961 }
1962
1963 /************************************************************************
1964 * VarUI4FromI1 (OLEAUT32.280)
1965 *
1966 * Convert a VT_I1 to a VT_UI4.
1967 *
1968 * PARAMS
1969 * cIn [I] Source
1970 * pulOut [O] Destination
1971 *
1972 * RETURNS
1973 * Success: S_OK.
1974 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
1975 */
1976 HRESULT WINAPI VarUI4FromI1(signed char cIn, ULONG *pulOut)
1977 {
1978 return _VarUI4FromI1(cIn, pulOut);
1979 }
1980
1981 /************************************************************************
1982 * VarUI4FromUI2 (OLEAUT32.281)
1983 *
1984 * Convert a VT_UI2 to a VT_UI4.
1985 *
1986 * PARAMS
1987 * usIn [I] Source
1988 * pulOut [O] Destination
1989 *
1990 * RETURNS
1991 * S_OK.
1992 */
1993 HRESULT WINAPI VarUI4FromUI2(USHORT usIn, ULONG *pulOut)
1994 {
1995 return _VarUI4FromUI2(usIn, pulOut);
1996 }
1997
1998 /************************************************************************
1999 * VarUI4FromDec (OLEAUT32.282)
2000 *
2001 * Convert a VT_DECIMAL to a VT_UI4.
2002 *
2003 * PARAMS
2004 * pDecIn [I] Source
2005 * pulOut [O] Destination
2006 *
2007 * RETURNS
2008 * Success: S_OK.
2009 * Failure: E_INVALIDARG, if pdecIn is invalid
2010 * DISP_E_OVERFLOW, if the value will not fit in the destination
2011 */
2012 HRESULT WINAPI VarUI4FromDec(DECIMAL *pdecIn, ULONG *pulOut)
2013 {
2014 LONG64 i64;
2015 HRESULT hRet;
2016
2017 hRet = VarI8FromDec(pdecIn, &i64);
2018
2019 if (SUCCEEDED(hRet))
2020 hRet = _VarUI4FromI8(i64, pulOut);
2021 return hRet;
2022 }
2023
2024 /************************************************************************
2025 * VarUI4FromI8 (OLEAUT32.425)
2026 *
2027 * Convert a VT_I8 to a VT_UI4.
2028 *
2029 * PARAMS
2030 * llIn [I] Source
2031 * pulOut [O] Destination
2032 *
2033 * RETURNS
2034 * Success: S_OK.
2035 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2036 */
2037 HRESULT WINAPI VarUI4FromI8(LONG64 llIn, ULONG *pulOut)
2038 {
2039 return _VarUI4FromI8(llIn, pulOut);
2040 }
2041
2042 /************************************************************************
2043 * VarUI4FromUI8 (OLEAUT32.426)
2044 *
2045 * Convert a VT_UI8 to a VT_UI4.
2046 *
2047 * PARAMS
2048 * ullIn [I] Source
2049 * pulOut [O] Destination
2050 *
2051 * RETURNS
2052 * Success: S_OK.
2053 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2054 */
2055 HRESULT WINAPI VarUI4FromUI8(ULONG64 ullIn, ULONG *pulOut)
2056 {
2057 return _VarUI4FromUI8(ullIn, pulOut);
2058 }
2059
2060 /* I8
2061 */
2062
2063 /************************************************************************
2064 * VarI8FromUI1 (OLEAUT32.333)
2065 *
2066 * Convert a VT_UI1 to a VT_I8.
2067 *
2068 * PARAMS
2069 * bIn [I] Source
2070 * pi64Out [O] Destination
2071 *
2072 * RETURNS
2073 * S_OK.
2074 */
2075 HRESULT WINAPI VarI8FromUI1(BYTE bIn, LONG64* pi64Out)
2076 {
2077 return _VarI8FromUI1(bIn, pi64Out);
2078 }
2079
2080
2081 /************************************************************************
2082 * VarI8FromI2 (OLEAUT32.334)
2083 *
2084 * Convert a VT_I2 to a VT_I8.
2085 *
2086 * PARAMS
2087 * sIn [I] Source
2088 * pi64Out [O] Destination
2089 *
2090 * RETURNS
2091 * S_OK.
2092 */
2093 HRESULT WINAPI VarI8FromI2(SHORT sIn, LONG64* pi64Out)
2094 {
2095 return _VarI8FromI2(sIn, pi64Out);
2096 }
2097
2098 /************************************************************************
2099 * VarI8FromR4 (OLEAUT32.335)
2100 *
2101 * Convert a VT_R4 to a VT_I8.
2102 *
2103 * PARAMS
2104 * fltIn [I] Source
2105 * pi64Out [O] Destination
2106 *
2107 * RETURNS
2108 * Success: S_OK.
2109 * Failure: E_INVALIDARG, if the source value is invalid
2110 * DISP_E_OVERFLOW, if the value will not fit in the destination
2111 */
2112 HRESULT WINAPI VarI8FromR4(FLOAT fltIn, LONG64* pi64Out)
2113 {
2114 return VarI8FromR8(fltIn, pi64Out);
2115 }
2116
2117 /************************************************************************
2118 * VarI8FromR8 (OLEAUT32.336)
2119 *
2120 * Convert a VT_R8 to a VT_I8.
2121 *
2122 * PARAMS
2123 * dblIn [I] Source
2124 * pi64Out [O] Destination
2125 *
2126 * RETURNS
2127 * Success: S_OK.
2128 * Failure: E_INVALIDARG, if the source value is invalid
2129 * DISP_E_OVERFLOW, if the value will not fit in the destination
2130 *
2131 * NOTES
2132 * Only values that fit into 63 bits are accepted. Due to rounding issues,
2133 * very high or low values will not be accurately converted.
2134 *
2135 * Numbers are rounded using Dutch rounding, as follows:
2136 *
2137 *| Fractional Part Sign Direction Example
2138 *| --------------- ---- --------- -------
2139 *| < 0.5 + Down 0.4 -> 0.0
2140 *| < 0.5 - Up -0.4 -> 0.0
2141 *| > 0.5 + Up 0.6 -> 1.0
2142 *| < 0.5 - Up -0.6 -> -1.0
2143 *| = 0.5 + Up/Down Down if even, Up if odd
2144 *| = 0.5 - Up/Down Up if even, Down if odd
2145 *
2146 * This system is often used in supermarkets.
2147 */
2148 HRESULT WINAPI VarI8FromR8(double dblIn, LONG64* pi64Out)
2149 {
2150 if ( dblIn < -4611686018427387904.0 || dblIn >= 4611686018427387904.0)
2151 return DISP_E_OVERFLOW;
2152 VARIANT_DutchRound(LONG64, dblIn, *pi64Out);
2153 return S_OK;
2154 }
2155
2156 /************************************************************************
2157 * VarI8FromCy (OLEAUT32.337)
2158 *
2159 * Convert a VT_CY to a VT_I8.
2160 *
2161 * PARAMS
2162 * cyIn [I] Source
2163 * pi64Out [O] Destination
2164 *
2165 * RETURNS
2166 * S_OK.
2167 *
2168 * NOTES
2169 * All negative numbers are rounded down by 1, including those that are
2170 * evenly divisible by 10000 (this is a Win32 bug that Wine mimics).
2171 * Positive numbers are rounded using Dutch rounding: See VarI8FromR8()
2172 * for details.
2173 */
2174 HRESULT WINAPI VarI8FromCy(CY cyIn, LONG64* pi64Out)
2175 {
2176 *pi64Out = cyIn.int64 / CY_MULTIPLIER;
2177
2178 if (cyIn.int64 < 0)
2179 (*pi64Out)--; /* Mimic Win32 bug */
2180 else
2181 {
2182 cyIn.int64 -= *pi64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */
2183
2184 if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pi64Out & 0x1)))
2185 (*pi64Out)++;
2186 }
2187 return S_OK;
2188 }
2189
2190 /************************************************************************
2191 * VarI8FromDate (OLEAUT32.338)
2192 *
2193 * Convert a VT_DATE to a VT_I8.
2194 *
2195 * PARAMS
2196 * dateIn [I] Source
2197 * pi64Out [O] Destination
2198 *
2199 * RETURNS
2200 * Success: S_OK.
2201 * Failure: E_INVALIDARG, if the source value is invalid
2202 * DISP_E_OVERFLOW, if the value will not fit in the destination
2203 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2204 */
2205 HRESULT WINAPI VarI8FromDate(DATE dateIn, LONG64* pi64Out)
2206 {
2207 return VarI8FromR8(dateIn, pi64Out);
2208 }
2209
2210 /************************************************************************
2211 * VarI8FromStr (OLEAUT32.339)
2212 *
2213 * Convert a VT_BSTR to a VT_I8.
2214 *
2215 * PARAMS
2216 * strIn [I] Source
2217 * lcid [I] LCID for the conversion
2218 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
2219 * pi64Out [O] Destination
2220 *
2221 * RETURNS
2222 * Success: S_OK.
2223 * Failure: E_INVALIDARG, if the source value is invalid
2224 * DISP_E_OVERFLOW, if the value will not fit in the destination
2225 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2226 */
2227 HRESULT WINAPI VarI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG64* pi64Out)
2228 {
2229 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pi64Out, VT_I8);
2230 }
2231
2232 /************************************************************************
2233 * VarI8FromDisp (OLEAUT32.340)
2234 *
2235 * Convert a VT_DISPATCH to a VT_I8.
2236 *
2237 * PARAMS
2238 * pdispIn [I] Source
2239 * lcid [I] LCID for conversion
2240 * pi64Out [O] Destination
2241 *
2242 * RETURNS
2243 * Success: S_OK.
2244 * Failure: E_INVALIDARG, if the source value is invalid
2245 * DISP_E_OVERFLOW, if the value will not fit in the destination
2246 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2247 */
2248 HRESULT WINAPI VarI8FromDisp(IDispatch* pdispIn, LCID lcid, LONG64* pi64Out)
2249 {
2250 return VARIANT_FromDisp(pdispIn, lcid, pi64Out, VT_I8, 0);
2251 }
2252
2253 /************************************************************************
2254 * VarI8FromBool (OLEAUT32.341)
2255 *
2256 * Convert a VT_BOOL to a VT_I8.
2257 *
2258 * PARAMS
2259 * boolIn [I] Source
2260 * pi64Out [O] Destination
2261 *
2262 * RETURNS
2263 * S_OK.
2264 */
2265 HRESULT WINAPI VarI8FromBool(VARIANT_BOOL boolIn, LONG64* pi64Out)
2266 {
2267 return VarI8FromI2(boolIn, pi64Out);
2268 }
2269
2270 /************************************************************************
2271 * VarI8FromI1 (OLEAUT32.342)
2272 *
2273 * Convert a VT_I1 to a VT_I8.
2274 *
2275 * PARAMS
2276 * cIn [I] Source
2277 * pi64Out [O] Destination
2278 *
2279 * RETURNS
2280 * S_OK.
2281 */
2282 HRESULT WINAPI VarI8FromI1(signed char cIn, LONG64* pi64Out)
2283 {
2284 return _VarI8FromI1(cIn, pi64Out);
2285 }
2286
2287 /************************************************************************
2288 * VarI8FromUI2 (OLEAUT32.343)
2289 *
2290 * Convert a VT_UI2 to a VT_I8.
2291 *
2292 * PARAMS
2293 * usIn [I] Source
2294 * pi64Out [O] Destination
2295 *
2296 * RETURNS
2297 * S_OK.
2298 */
2299 HRESULT WINAPI VarI8FromUI2(USHORT usIn, LONG64* pi64Out)
2300 {
2301 return _VarI8FromUI2(usIn, pi64Out);
2302 }
2303
2304 /************************************************************************
2305 * VarI8FromUI4 (OLEAUT32.344)
2306 *
2307 * Convert a VT_UI4 to a VT_I8.
2308 *
2309 * PARAMS
2310 * ulIn [I] Source
2311 * pi64Out [O] Destination
2312 *
2313 * RETURNS
2314 * S_OK.
2315 */
2316 HRESULT WINAPI VarI8FromUI4(ULONG ulIn, LONG64* pi64Out)
2317 {
2318 return _VarI8FromUI4(ulIn, pi64Out);
2319 }
2320
2321 /************************************************************************
2322 * VarI8FromDec (OLEAUT32.345)
2323 *
2324 * Convert a VT_DECIMAL to a VT_I8.
2325 *
2326 * PARAMS
2327 * pDecIn [I] Source
2328 * pi64Out [O] Destination
2329 *
2330 * RETURNS
2331 * Success: S_OK.
2332 * Failure: E_INVALIDARG, if the source value is invalid
2333 * DISP_E_OVERFLOW, if the value will not fit in the destination
2334 */
2335 HRESULT WINAPI VarI8FromDec(DECIMAL *pdecIn, LONG64* pi64Out)
2336 {
2337 if (!DEC_SCALE(pdecIn))
2338 {
2339 /* This decimal is just a 96 bit integer */
2340 if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
2341 return E_INVALIDARG;
2342
2343 if (DEC_HI32(pdecIn) || DEC_MID32(pdecIn) & 0x80000000)
2344 return DISP_E_OVERFLOW;
2345
2346 if (DEC_SIGN(pdecIn))
2347 *pi64Out = -DEC_LO64(pdecIn);
2348 else
2349 *pi64Out = DEC_LO64(pdecIn);
2350 return S_OK;
2351 }
2352 else
2353 {
2354 /* Decimal contains a floating point number */
2355 HRESULT hRet;
2356 double dbl;
2357
2358 hRet = VarR8FromDec(pdecIn, &dbl);
2359 if (SUCCEEDED(hRet))
2360 hRet = VarI8FromR8(dbl, pi64Out);
2361 return hRet;
2362 }
2363 }
2364
2365 /************************************************************************
2366 * VarI8FromUI8 (OLEAUT32.427)
2367 *
2368 * Convert a VT_UI8 to a VT_I8.
2369 *
2370 * PARAMS
2371 * ullIn [I] Source
2372 * pi64Out [O] Destination
2373 *
2374 * RETURNS
2375 * Success: S_OK.
2376 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2377 */
2378 HRESULT WINAPI VarI8FromUI8(ULONG64 ullIn, LONG64* pi64Out)
2379 {
2380 return _VarI8FromUI8(ullIn, pi64Out);
2381 }
2382
2383 /* UI8
2384 */
2385
2386 /************************************************************************
2387 * VarUI8FromI8 (OLEAUT32.428)
2388 *
2389 * Convert a VT_I8 to a VT_UI8.
2390 *
2391 * PARAMS
2392 * ulIn [I] Source
2393 * pui64Out [O] Destination
2394 *
2395 * RETURNS
2396 * Success: S_OK.
2397 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2398 */
2399 HRESULT WINAPI VarUI8FromI8(LONG64 llIn, ULONG64* pui64Out)
2400 {
2401 return _VarUI8FromI8(llIn, pui64Out);
2402 }
2403
2404 /************************************************************************
2405 * VarUI8FromUI1 (OLEAUT32.429)
2406 *
2407 * Convert a VT_UI1 to a VT_UI8.
2408 *
2409 * PARAMS
2410 * bIn [I] Source
2411 * pui64Out [O] Destination
2412 *
2413 * RETURNS
2414 * S_OK.
2415 */
2416 HRESULT WINAPI VarUI8FromUI1(BYTE bIn, ULONG64* pui64Out)
2417 {
2418 return _VarUI8FromUI1(bIn, pui64Out);
2419 }
2420
2421 /************************************************************************
2422 * VarUI8FromI2 (OLEAUT32.430)
2423 *
2424 * Convert a VT_I2 to a VT_UI8.
2425 *
2426 * PARAMS
2427 * sIn [I] Source
2428 * pui64Out [O] Destination
2429 *
2430 * RETURNS
2431 * S_OK.
2432 */
2433 HRESULT WINAPI VarUI8FromI2(SHORT sIn, ULONG64* pui64Out)
2434 {
2435 return _VarUI8FromI2(sIn, pui64Out);
2436 }
2437
2438 /************************************************************************
2439 * VarUI8FromR4 (OLEAUT32.431)
2440 *
2441 * Convert a VT_R4 to a VT_UI8.
2442 *
2443 * PARAMS
2444 * fltIn [I] Source
2445 * pui64Out [O] Destination
2446 *
2447 * RETURNS
2448 * Success: S_OK.
2449 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2450 */
2451 HRESULT WINAPI VarUI8FromR4(FLOAT fltIn, ULONG64* pui64Out)
2452 {
2453 return VarUI8FromR8(fltIn, pui64Out);
2454 }
2455
2456 /************************************************************************
2457 * VarUI8FromR8 (OLEAUT32.432)
2458 *
2459 * Convert a VT_R8 to a VT_UI8.
2460 *
2461 * PARAMS
2462 * dblIn [I] Source
2463 * pui64Out [O] Destination
2464 *
2465 * RETURNS
2466 * Success: S_OK.
2467 * Failure: E_INVALIDARG, if the source value is invalid
2468 * DISP_E_OVERFLOW, if the value will not fit in the destination
2469 *
2470 * NOTES
2471 * See VarI8FromR8() for details concerning rounding.
2472 */
2473 HRESULT WINAPI VarUI8FromR8(double dblIn, ULONG64* pui64Out)
2474 {
2475 if (dblIn < -0.5 || dblIn > 1.844674407370955e19)
2476 return DISP_E_OVERFLOW;
2477 VARIANT_DutchRound(ULONG64, dblIn, *pui64Out);
2478 return S_OK;
2479 }
2480
2481 /************************************************************************
2482 * VarUI8FromCy (OLEAUT32.433)
2483 *
2484 * Convert a VT_CY to a VT_UI8.
2485 *
2486 * PARAMS
2487 * cyIn [I] Source
2488 * pui64Out [O] Destination
2489 *
2490 * RETURNS
2491 * Success: S_OK.
2492 * Failure: E_INVALIDARG, if the source value is invalid
2493 * DISP_E_OVERFLOW, if the value will not fit in the destination
2494 *
2495 * NOTES
2496 * Negative values >= -5000 will be converted to 0.
2497 */
2498 HRESULT WINAPI VarUI8FromCy(CY cyIn, ULONG64* pui64Out)
2499 {
2500 if (cyIn.int64 < 0)
2501 {
2502 if (cyIn.int64 < -CY_HALF)
2503 return DISP_E_OVERFLOW;
2504 *pui64Out = 0;
2505 }
2506 else
2507 {
2508 *pui64Out = cyIn.int64 / CY_MULTIPLIER;
2509
2510 cyIn.int64 -= *pui64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */
2511
2512 if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pui64Out & 0x1)))
2513 (*pui64Out)++;
2514 }
2515 return S_OK;
2516 }
2517
2518 /************************************************************************
2519 * VarUI8FromDate (OLEAUT32.434)
2520 *
2521 * Convert a VT_DATE to a VT_UI8.
2522 *
2523 * PARAMS
2524 * dateIn [I] Source
2525 * pui64Out [O] Destination
2526 *
2527 * RETURNS
2528 * Success: S_OK.
2529 * Failure: E_INVALIDARG, if the source value is invalid
2530 * DISP_E_OVERFLOW, if the value will not fit in the destination
2531 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2532 */
2533 HRESULT WINAPI VarUI8FromDate(DATE dateIn, ULONG64* pui64Out)
2534 {
2535 return VarUI8FromR8(dateIn, pui64Out);
2536 }
2537
2538 /************************************************************************
2539 * VarUI8FromStr (OLEAUT32.435)
2540 *
2541 * Convert a VT_BSTR to a VT_UI8.
2542 *
2543 * PARAMS
2544 * strIn [I] Source
2545 * lcid [I] LCID for the conversion
2546 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
2547 * pui64Out [O] Destination
2548 *
2549 * RETURNS
2550 * Success: S_OK.
2551 * Failure: E_INVALIDARG, if the source value is invalid
2552 * DISP_E_OVERFLOW, if the value will not fit in the destination
2553 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2554 */
2555 HRESULT WINAPI VarUI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG64* pui64Out)
2556 {
2557 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pui64Out, VT_UI8);
2558 }
2559
2560 /************************************************************************
2561 * VarUI8FromDisp (OLEAUT32.436)
2562 *
2563 * Convert a VT_DISPATCH to a VT_UI8.
2564 *
2565 * PARAMS
2566 * pdispIn [I] Source
2567 * lcid [I] LCID for conversion
2568 * pui64Out [O] Destination
2569 *
2570 * RETURNS
2571 * Success: S_OK.
2572 * Failure: E_INVALIDARG, if the source value is invalid
2573 * DISP_E_OVERFLOW, if the value will not fit in the destination
2574 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2575 */
2576 HRESULT WINAPI VarUI8FromDisp(IDispatch* pdispIn, LCID lcid, ULONG64* pui64Out)
2577 {
2578 return VARIANT_FromDisp(pdispIn, lcid, pui64Out, VT_UI8, 0);
2579 }
2580
2581 /************************************************************************
2582 * VarUI8FromBool (OLEAUT32.437)
2583 *
2584 * Convert a VT_BOOL to a VT_UI8.
2585 *
2586 * PARAMS
2587 * boolIn [I] Source
2588 * pui64Out [O] Destination
2589 *
2590 * RETURNS
2591 * Success: S_OK.
2592 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2593 */
2594 HRESULT WINAPI VarUI8FromBool(VARIANT_BOOL boolIn, ULONG64* pui64Out)
2595 {
2596 return VarI8FromI2(boolIn, (LONG64 *)pui64Out);
2597 }
2598 /************************************************************************
2599 * VarUI8FromI1 (OLEAUT32.438)
2600 *
2601 * Convert a VT_I1 to a VT_UI8.
2602 *
2603 * PARAMS
2604 * cIn [I] Source
2605 * pui64Out [O] Destination
2606 *
2607 * RETURNS
2608 * Success: S_OK.
2609 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
2610 */
2611 HRESULT WINAPI VarUI8FromI1(signed char cIn, ULONG64* pui64Out)
2612 {
2613 return _VarUI8FromI1(cIn, pui64Out);
2614 }
2615
2616 /************************************************************************
2617 * VarUI8FromUI2 (OLEAUT32.439)
2618 *
2619 * Convert a VT_UI2 to a VT_UI8.
2620 *
2621 * PARAMS
2622 * usIn [I] Source
2623 * pui64Out [O] Destination
2624 *
2625 * RETURNS
2626 * S_OK.
2627 */
2628 HRESULT WINAPI VarUI8FromUI2(USHORT usIn, ULONG64* pui64Out)
2629 {
2630 return _VarUI8FromUI2(usIn, pui64Out);
2631 }
2632
2633 /************************************************************************
2634 * VarUI8FromUI4 (OLEAUT32.440)
2635 *
2636 * Convert a VT_UI4 to a VT_UI8.
2637 *
2638 * PARAMS
2639 * ulIn [I] Source
2640 * pui64Out [O] Destination
2641 *
2642 * RETURNS
2643 * S_OK.
2644 */
2645 HRESULT WINAPI VarUI8FromUI4(ULONG ulIn, ULONG64* pui64Out)
2646 {
2647 return _VarUI8FromUI4(ulIn, pui64Out);
2648 }
2649
2650 /************************************************************************
2651 * VarUI8FromDec (OLEAUT32.441)
2652 *
2653 * Convert a VT_DECIMAL to a VT_UI8.
2654 *
2655 * PARAMS
2656 * pDecIn [I] Source
2657 * pui64Out [O] Destination
2658 *
2659 * RETURNS
2660 * Success: S_OK.
2661 * Failure: E_INVALIDARG, if the source value is invalid
2662 * DISP_E_OVERFLOW, if the value will not fit in the destination
2663 *
2664 * NOTES
2665 * Under native Win32, if the source value has a scale of 0, its sign is
2666 * ignored, i.e. this function takes the absolute value rather than fail
2667 * with DISP_E_OVERFLOW. This bug has been fixed in Wine's implementation
2668 * (use VarAbs() on pDecIn first if you really want this behaviour).
2669 */
2670 HRESULT WINAPI VarUI8FromDec(DECIMAL *pdecIn, ULONG64* pui64Out)
2671 {
2672 if (!DEC_SCALE(pdecIn))
2673 {
2674 /* This decimal is just a 96 bit integer */
2675 if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
2676 return E_INVALIDARG;
2677
2678 if (DEC_HI32(pdecIn))
2679 return DISP_E_OVERFLOW;
2680
2681 if (DEC_SIGN(pdecIn))
2682 {
2683 WARN("Sign would be ignored under Win32!\n");
2684 return DISP_E_OVERFLOW;
2685 }
2686
2687 *pui64Out = DEC_LO64(pdecIn);
2688 return S_OK;
2689 }
2690 else
2691 {
2692 /* Decimal contains a floating point number */
2693 HRESULT hRet;
2694 double dbl;
2695
2696 hRet = VarR8FromDec(pdecIn, &dbl);
2697 if (SUCCEEDED(hRet))
2698 hRet = VarUI8FromR8(dbl, pui64Out);
2699 return hRet;
2700 }
2701 }
2702
2703 /* R4
2704 */
2705
2706 /************************************************************************
2707 * VarR4FromUI1 (OLEAUT32.68)
2708 *
2709 * Convert a VT_UI1 to a VT_R4.
2710 *
2711 * PARAMS
2712 * bIn [I] Source
2713 * pFltOut [O] Destination
2714 *
2715 * RETURNS
2716 * S_OK.
2717 */
2718 HRESULT WINAPI VarR4FromUI1(BYTE bIn, float *pFltOut)
2719 {
2720 return _VarR4FromUI1(bIn, pFltOut);
2721 }
2722
2723 /************************************************************************
2724 * VarR4FromI2 (OLEAUT32.69)
2725 *
2726 * Convert a VT_I2 to a VT_R4.
2727 *
2728 * PARAMS
2729 * sIn [I] Source
2730 * pFltOut [O] Destination
2731 *
2732 * RETURNS
2733 * S_OK.
2734 */
2735 HRESULT WINAPI VarR4FromI2(SHORT sIn, float *pFltOut)
2736 {
2737 return _VarR4FromI2(sIn, pFltOut);
2738 }
2739
2740 /************************************************************************
2741 * VarR4FromI4 (OLEAUT32.70)
2742 *
2743 * Convert a VT_I4 to a VT_R4.
2744 *
2745 * PARAMS
2746 * sIn [I] Source
2747 * pFltOut [O] Destination
2748 *
2749 * RETURNS
2750 * S_OK.
2751 */
2752 HRESULT WINAPI VarR4FromI4(LONG lIn, float *pFltOut)
2753 {
2754 return _VarR4FromI4(lIn, pFltOut);
2755 }
2756
2757 /************************************************************************
2758 * VarR4FromR8 (OLEAUT32.71)
2759 *
2760 * Convert a VT_R8 to a VT_R4.
2761 *
2762 * PARAMS
2763 * dblIn [I] Source
2764 * pFltOut [O] Destination
2765 *
2766 * RETURNS
2767 * Success: S_OK.
2768 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination.
2769 */
2770 HRESULT WINAPI VarR4FromR8(double dblIn, float *pFltOut)
2771 {
2772 double d = dblIn < 0.0 ? -dblIn : dblIn;
2773 if (d > R4_MAX) return DISP_E_OVERFLOW;
2774 *pFltOut = dblIn;
2775 return S_OK;
2776 }
2777
2778 /************************************************************************
2779 * VarR4FromCy (OLEAUT32.72)
2780 *
2781 * Convert a VT_CY to a VT_R4.
2782 *
2783 * PARAMS
2784 * cyIn [I] Source
2785 * pFltOut [O] Destination
2786 *
2787 * RETURNS
2788 * S_OK.
2789 */
2790 HRESULT WINAPI VarR4FromCy(CY cyIn, float *pFltOut)
2791 {
2792 *pFltOut = (double)cyIn.int64 / CY_MULTIPLIER_F;
2793 return S_OK;
2794 }
2795
2796 /************************************************************************
2797 * VarR4FromDate (OLEAUT32.73)
2798 *
2799 * Convert a VT_DATE to a VT_R4.
2800 *
2801 * PARAMS
2802 * dateIn [I] Source
2803 * pFltOut [O] Destination
2804 *
2805 * RETURNS
2806 * Success: S_OK.
2807 * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination.
2808 */
2809 HRESULT WINAPI VarR4FromDate(DATE dateIn, float *pFltOut)
2810 {
2811 return VarR4FromR8(dateIn, pFltOut);
2812 }
2813
2814 /************************************************************************
2815 * VarR4FromStr (OLEAUT32.74)
2816 *
2817 * Convert a VT_BSTR to a VT_R4.
2818 *
2819 * PARAMS
2820 * strIn [I] Source
2821 * lcid [I] LCID for the conversion
2822 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
2823 * pFltOut [O] Destination
2824 *
2825 * RETURNS
2826 * Success: S_OK.
2827 * Failure: E_INVALIDARG, if strIn or pFltOut is invalid.
2828 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2829 */
2830 HRESULT WINAPI VarR4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, float *pFltOut)
2831 {
2832 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pFltOut, VT_R4);
2833 }
2834
2835 /************************************************************************
2836 * VarR4FromDisp (OLEAUT32.75)
2837 *
2838 * Convert a VT_DISPATCH to a VT_R4.
2839 *
2840 * PARAMS
2841 * pdispIn [I] Source
2842 * lcid [I] LCID for conversion
2843 * pFltOut [O] Destination
2844 *
2845 * RETURNS
2846 * Success: S_OK.
2847 * Failure: E_INVALIDARG, if the source value is invalid
2848 * DISP_E_OVERFLOW, if the value will not fit in the destination
2849 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2850 */
2851 HRESULT WINAPI VarR4FromDisp(IDispatch* pdispIn, LCID lcid, float *pFltOut)
2852 {
2853 return VARIANT_FromDisp(pdispIn, lcid, pFltOut, VT_R4, 0);
2854 }
2855
2856 /************************************************************************
2857 * VarR4FromBool (OLEAUT32.76)
2858 *
2859 * Convert a VT_BOOL to a VT_R4.
2860 *
2861 * PARAMS
2862 * boolIn [I] Source
2863 * pFltOut [O] Destination
2864 *
2865 * RETURNS
2866 * S_OK.
2867 */
2868 HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, float *pFltOut)
2869 {
2870 return VarR4FromI2(boolIn, pFltOut);
2871 }
2872
2873 /************************************************************************
2874 * VarR4FromI1 (OLEAUT32.213)
2875 *
2876 * Convert a VT_I1 to a VT_R4.
2877 *
2878 * PARAMS
2879 * cIn [I] Source
2880 * pFltOut [O] Destination
2881 *
2882 * RETURNS
2883 * Success: S_OK.
2884 * Failure: E_INVALIDARG, if the source value is invalid
2885 * DISP_E_OVERFLOW, if the value will not fit in the destination
2886 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2887 */
2888 HRESULT WINAPI VarR4FromI1(signed char cIn, float *pFltOut)
2889 {
2890 return _VarR4FromI1(cIn, pFltOut);
2891 }
2892
2893 /************************************************************************
2894 * VarR4FromUI2 (OLEAUT32.214)
2895 *
2896 * Convert a VT_UI2 to a VT_R4.
2897 *
2898 * PARAMS
2899 * usIn [I] Source
2900 * pFltOut [O] Destination
2901 *
2902 * RETURNS
2903 * Success: S_OK.
2904 * Failure: E_INVALIDARG, if the source value is invalid
2905 * DISP_E_OVERFLOW, if the value will not fit in the destination
2906 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2907 */
2908 HRESULT WINAPI VarR4FromUI2(USHORT usIn, float *pFltOut)
2909 {
2910 return _VarR4FromUI2(usIn, pFltOut);
2911 }
2912
2913 /************************************************************************
2914 * VarR4FromUI4 (OLEAUT32.215)
2915 *
2916 * Convert a VT_UI4 to a VT_R4.
2917 *
2918 * PARAMS
2919 * ulIn [I] Source
2920 * pFltOut [O] Destination
2921 *
2922 * RETURNS
2923 * Success: S_OK.
2924 * Failure: E_INVALIDARG, if the source value is invalid
2925 * DISP_E_OVERFLOW, if the value will not fit in the destination
2926 * DISP_E_TYPEMISMATCH, if the type cannot be converted
2927 */
2928 HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut)
2929 {
2930 return _VarR4FromUI4(ulIn, pFltOut);
2931 }
2932
2933 /************************************************************************
2934 * VarR4FromDec (OLEAUT32.216)
2935 *
2936 * Convert a VT_DECIMAL to a VT_R4.
2937 *
2938 * PARAMS
2939 * pDecIn [I] Source
2940 * pFltOut [O] Destination
2941 *
2942 * RETURNS
2943 * Success: S_OK.
2944 * Failure: E_INVALIDARG, if the source value is invalid.
2945 */
2946 HRESULT WINAPI VarR4FromDec(DECIMAL* pDecIn, float *pFltOut)
2947 {
2948 BYTE scale = DEC_SCALE(pDecIn);
2949 double divisor = 1.0;
2950 double highPart;
2951
2952 if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
2953 return E_INVALIDARG;
2954
2955 while (scale--)
2956 divisor *= 10.0;
2957
2958 if (DEC_SIGN(pDecIn))
2959 divisor = -divisor;
2960
2961 if (DEC_HI32(pDecIn))
2962 {
2963 highPart = (double)DEC_HI32(pDecIn) / divisor;
2964 highPart *= 4294967296.0F;
2965 highPart *= 4294967296.0F;
2966 }
2967 else
2968 highPart = 0.0;
2969
2970 *pFltOut = (double)DEC_LO64(pDecIn) / divisor + highPart;
2971 return S_OK;
2972 }
2973
2974 /************************************************************************
2975 * VarR4FromI8 (OLEAUT32.360)
2976 *
2977 * Convert a VT_I8 to a VT_R4.
2978 *
2979 * PARAMS
2980 * ullIn [I] Source
2981 * pFltOut [O] Destination
2982 *
2983 * RETURNS
2984 * S_OK.
2985 */
2986 HRESULT WINAPI VarR4FromI8(LONG64 llIn, float *pFltOut)
2987 {
2988 return _VarR4FromI8(llIn, pFltOut);
2989 }
2990
2991 /************************************************************************
2992 * VarR4FromUI8 (OLEAUT32.361)
2993 *
2994 * Convert a VT_UI8 to a VT_R4.
2995 *
2996 * PARAMS
2997 * ullIn [I] Source
2998 * pFltOut [O] Destination
2999 *
3000 * RETURNS
3001 * S_OK.
3002 */
3003 HRESULT WINAPI VarR4FromUI8(ULONG64 ullIn, float *pFltOut)
3004 {
3005 return _VarR4FromUI8(ullIn, pFltOut);
3006 }
3007
3008 /************************************************************************
3009 * VarR4CmpR8 (OLEAUT32.316)
3010 *
3011 * Compare a VT_R4 to a VT_R8.
3012 *
3013 * PARAMS
3014 * fltLeft [I] Source
3015 * dblRight [I] Value to compare
3016 *
3017 * RETURNS
3018 * VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that fltLeft is less than,
3019 * equal to or greater than dblRight respectively.
3020 */
3021 HRESULT WINAPI VarR4CmpR8(float fltLeft, double dblRight)
3022 {
3023 if (fltLeft < dblRight)
3024 return VARCMP_LT;
3025 else if (fltLeft > dblRight)
3026 return VARCMP_GT;
3027 return VARCMP_EQ;
3028 }
3029
3030 /* R8
3031 */
3032
3033 /************************************************************************
3034 * VarR8FromUI1 (OLEAUT32.78)
3035 *
3036 * Convert a VT_UI1 to a VT_R8.
3037 *
3038 * PARAMS
3039 * bIn [I] Source
3040 * pDblOut [O] Destination
3041 *
3042 * RETURNS
3043 * S_OK.
3044 */
3045 HRESULT WINAPI VarR8FromUI1(BYTE bIn, double *pDblOut)
3046 {
3047 return _VarR8FromUI1(bIn, pDblOut);
3048 }
3049
3050 /************************************************************************
3051 * VarR8FromI2 (OLEAUT32.79)
3052 *
3053 * Convert a VT_I2 to a VT_R8.
3054 *
3055 * PARAMS
3056 * sIn [I] Source
3057 * pDblOut [O] Destination
3058 *
3059 * RETURNS
3060 * S_OK.
3061 */
3062 HRESULT WINAPI VarR8FromI2(SHORT sIn, double *pDblOut)
3063 {
3064 return _VarR8FromI2(sIn, pDblOut);
3065 }
3066
3067 /************************************************************************
3068 * VarR8FromI4 (OLEAUT32.80)
3069 *
3070 * Convert a VT_I4 to a VT_R8.
3071 *
3072 * PARAMS
3073 * sIn [I] Source
3074 * pDblOut [O] Destination
3075 *
3076 * RETURNS
3077 * S_OK.
3078 */
3079 HRESULT WINAPI VarR8FromI4(LONG lIn, double *pDblOut)
3080 {
3081 return _VarR8FromI4(lIn, pDblOut);
3082 }
3083
3084 /************************************************************************
3085 * VarR8FromR4 (OLEAUT32.81)
3086 *
3087 * Convert a VT_R4 to a VT_R8.
3088 *
3089 * PARAMS
3090 * fltIn [I] Source
3091 * pDblOut [O] Destination
3092 *
3093 * RETURNS
3094 * S_OK.
3095 */
3096 HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double *pDblOut)
3097 {
3098 return _VarR8FromR4(fltIn, pDblOut);
3099 }
3100
3101 /************************************************************************
3102 * VarR8FromCy (OLEAUT32.82)
3103 *
3104 * Convert a VT_CY to a VT_R8.
3105 *
3106 * PARAMS
3107 * cyIn [I] Source
3108 * pDblOut [O] Destination
3109 *
3110 * RETURNS
3111 * S_OK.
3112 */
3113 HRESULT WINAPI VarR8FromCy(CY cyIn, double *pDblOut)
3114 {
3115 return _VarR8FromCy(cyIn, pDblOut);
3116 }
3117
3118 /************************************************************************
3119 * VarR8FromDate (OLEAUT32.83)
3120 *
3121 * Convert a VT_DATE to a VT_R8.
3122 *
3123 * PARAMS
3124 * dateIn [I] Source
3125 * pDblOut [O] Destination
3126 *
3127 * RETURNS
3128 * S_OK.
3129 */
3130 HRESULT WINAPI VarR8FromDate(DATE dateIn, double *pDblOut)
3131 {
3132 return _VarR8FromDate(dateIn, pDblOut);
3133 }
3134
3135 /************************************************************************
3136 * VarR8FromStr (OLEAUT32.84)
3137 *
3138 * Convert a VT_BSTR to a VT_R8.
3139 *
3140 * PARAMS
3141 * strIn [I] Source
3142 * lcid [I] LCID for the conversion
3143 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
3144 * pDblOut [O] Destination
3145 *
3146 * RETURNS
3147 * Success: S_OK.
3148 * Failure: E_INVALIDARG, if strIn or pDblOut is invalid.
3149 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3150 */
3151 HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double *pDblOut)
3152 {
3153 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pDblOut, VT_R8);
3154 }
3155
3156 /************************************************************************
3157 * VarR8FromDisp (OLEAUT32.85)
3158 *
3159 * Convert a VT_DISPATCH to a VT_R8.
3160 *
3161 * PARAMS
3162 * pdispIn [I] Source
3163 * lcid [I] LCID for conversion
3164 * pDblOut [O] Destination
3165 *
3166 * RETURNS
3167 * Success: S_OK.
3168 * Failure: E_INVALIDARG, if the source value is invalid
3169 * DISP_E_OVERFLOW, if the value will not fit in the destination
3170 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3171 */
3172 HRESULT WINAPI VarR8FromDisp(IDispatch* pdispIn, LCID lcid, double *pDblOut)
3173 {
3174 return VARIANT_FromDisp(pdispIn, lcid, pDblOut, VT_R8, 0);
3175 }
3176
3177 /************************************************************************
3178 * VarR8FromBool (OLEAUT32.86)
3179 *
3180 * Convert a VT_BOOL to a VT_R8.
3181 *
3182 * PARAMS
3183 * boolIn [I] Source
3184 * pDblOut [O] Destination
3185 *
3186 * RETURNS
3187 * S_OK.
3188 */
3189 HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double *pDblOut)
3190 {
3191 return VarR8FromI2(boolIn, pDblOut);
3192 }
3193
3194 /************************************************************************
3195 * VarR8FromI1 (OLEAUT32.217)
3196 *
3197 * Convert a VT_I1 to a VT_R8.
3198 *
3199 * PARAMS
3200 * cIn [I] Source
3201 * pDblOut [O] Destination
3202 *
3203 * RETURNS
3204 * Success: S_OK.
3205 * Failure: E_INVALIDARG, if the source value is invalid
3206 * DISP_E_OVERFLOW, if the value will not fit in the destination
3207 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3208 */
3209 HRESULT WINAPI VarR8FromI1(signed char cIn, double *pDblOut)
3210 {
3211 return _VarR8FromI1(cIn, pDblOut);
3212 }
3213
3214 /************************************************************************
3215 * VarR8FromUI2 (OLEAUT32.218)
3216 *
3217 * Convert a VT_UI2 to a VT_R8.
3218 *
3219 * PARAMS
3220 * usIn [I] Source
3221 * pDblOut [O] Destination
3222 *
3223 * RETURNS
3224 * Success: S_OK.
3225 * Failure: E_INVALIDARG, if the source value is invalid
3226 * DISP_E_OVERFLOW, if the value will not fit in the destination
3227 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3228 */
3229 HRESULT WINAPI VarR8FromUI2(USHORT usIn, double *pDblOut)
3230 {
3231 return _VarR8FromUI2(usIn, pDblOut);
3232 }
3233
3234 /************************************************************************
3235 * VarR8FromUI4 (OLEAUT32.219)
3236 *
3237 * Convert a VT_UI4 to a VT_R8.
3238 *
3239 * PARAMS
3240 * ulIn [I] Source
3241 * pDblOut [O] Destination
3242 *
3243 * RETURNS
3244 * Success: S_OK.
3245 * Failure: E_INVALIDARG, if the source value is invalid
3246 * DISP_E_OVERFLOW, if the value will not fit in the destination
3247 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3248 */
3249 HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double *pDblOut)
3250 {
3251 return _VarR8FromUI4(ulIn, pDblOut);
3252 }
3253
3254 /************************************************************************
3255 * VarR8FromDec (OLEAUT32.220)
3256 *
3257 * Convert a VT_DECIMAL to a VT_R8.
3258 *
3259 * PARAMS
3260 * pDecIn [I] Source
3261 * pDblOut [O] Destination
3262 *
3263 * RETURNS
3264 * Success: S_OK.
3265 * Failure: E_INVALIDARG, if the source value is invalid.
3266 */
3267 HRESULT WINAPI VarR8FromDec(const DECIMAL* pDecIn, double *pDblOut)
3268 {
3269 BYTE scale = DEC_SCALE(pDecIn);
3270 double divisor = 1.0, highPart;
3271
3272 if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
3273 return E_INVALIDARG;
3274
3275 while (scale--)
3276 divisor *= 10;
3277
3278 if (DEC_SIGN(pDecIn))
3279 divisor = -divisor;
3280
3281 if (DEC_HI32(pDecIn))
3282 {
3283 highPart = (double)DEC_HI32(pDecIn) / divisor;
3284 highPart *= 4294967296.0F;
3285 highPart *= 4294967296.0F;
3286 }
3287 else
3288 highPart = 0.0;
3289
3290 *pDblOut = (double)DEC_LO64(pDecIn) / divisor + highPart;
3291 return S_OK;
3292 }
3293
3294 /************************************************************************
3295 * VarR8FromI8 (OLEAUT32.362)
3296 *
3297 * Convert a VT_I8 to a VT_R8.
3298 *
3299 * PARAMS
3300 * ullIn [I] Source
3301 * pDblOut [O] Destination
3302 *
3303 * RETURNS
3304 * S_OK.
3305 */
3306 HRESULT WINAPI VarR8FromI8(LONG64 llIn, double *pDblOut)
3307 {
3308 return _VarR8FromI8(llIn, pDblOut);
3309 }
3310
3311 /************************************************************************
3312 * VarR8FromUI8 (OLEAUT32.363)
3313 *
3314 * Convert a VT_UI8 to a VT_R8.
3315 *
3316 * PARAMS
3317 * ullIn [I] Source
3318 * pDblOut [O] Destination
3319 *
3320 * RETURNS
3321 * S_OK.
3322 */
3323 HRESULT WINAPI VarR8FromUI8(ULONG64 ullIn, double *pDblOut)
3324 {
3325 return _VarR8FromUI8(ullIn, pDblOut);
3326 }
3327
3328 /************************************************************************
3329 * VarR8Pow (OLEAUT32.315)
3330 *
3331 * Raise a VT_R8 to a power.
3332 *
3333 * PARAMS
3334 * dblLeft [I] Source
3335 * dblPow [I] Power to raise dblLeft by
3336 * pDblOut [O] Destination
3337 *
3338 * RETURNS
3339 * S_OK. pDblOut contains dblLeft to the power of dblRight.
3340 */
3341 HRESULT WINAPI VarR8Pow(double dblLeft, double dblPow, double *pDblOut)
3342 {
3343 *pDblOut = pow(dblLeft, dblPow);
3344 return S_OK;
3345 }
3346
3347 /************************************************************************
3348 * VarR8Round (OLEAUT32.317)
3349 *
3350 * Round a VT_R8 to a given number of decimal points.
3351 *
3352 * PARAMS
3353 * dblIn [I] Source
3354 * nDig [I] Number of decimal points to round to
3355 * pDblOut [O] Destination for rounded number
3356 *
3357 * RETURNS
3358 * Success: S_OK. pDblOut is rounded to nDig digits.
3359 * Failure: E_INVALIDARG, if cDecimals is less than 0.
3360 *
3361 * NOTES
3362 * The native version of this function rounds using the internal
3363 * binary representation of the number. Wine uses the dutch rounding
3364 * convention, so therefore small differences can occur in the value returned.
3365 * MSDN says that you should use your own rounding function if you want
3366 * rounding to be predictable in your application.
3367 */
3368 HRESULT WINAPI VarR8Round(double dblIn, int nDig, double *pDblOut)
3369 {
3370 double scale, whole, fract;
3371
3372 if (nDig < 0)
3373 return E_INVALIDARG;
3374
3375 scale = pow(10.0, nDig);
3376
3377 dblIn *= scale;
3378 whole = dblIn < 0 ? ceil(dblIn) : floor(dblIn);
3379 fract = dblIn - whole;
3380
3381 if (fract > 0.5)
3382 dblIn = whole + 1.0;
3383 else if (fract == 0.5)
3384 dblIn = whole + fmod(whole, 2.0);
3385 else if (fract >= 0.0)
3386 dblIn = whole;
3387 else if (fract == -0.5)
3388 dblIn = whole - fmod(whole, 2.0);
3389 else if (fract > -0.5)
3390 dblIn = whole;
3391 else
3392 dblIn = whole - 1.0;
3393
3394 *pDblOut = dblIn / scale;
3395 return S_OK;
3396 }
3397
3398 /* CY
3399 */
3400
3401 /* Powers of 10 from 0..4 D.P. */
3402 static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000,
3403 CY_MULTIPLIER/100, CY_MULTIPLIER/10, CY_MULTIPLIER };
3404
3405 /************************************************************************
3406 * VarCyFromUI1 (OLEAUT32.98)
3407 *
3408 * Convert a VT_UI1 to a VT_CY.
3409 *
3410 * PARAMS
3411 * bIn [I] Source
3412 * pCyOut [O] Destination
3413 *
3414 * RETURNS
3415 * Success: S_OK.
3416 * Failure: E_INVALIDARG, if the source value is invalid
3417 * DISP_E_OVERFLOW, if the value will not fit in the destination
3418 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3419 */
3420 HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
3421 {
3422 pCyOut->int64 = (ULONG64)bIn * CY_MULTIPLIER;
3423 return S_OK;
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 pCyOut->int64 = (LONG64)sIn * CY_MULTIPLIER;
3444 return S_OK;
3445 }
3446
3447 /************************************************************************
3448 * VarCyFromI4 (OLEAUT32.100)
3449 *
3450 * Convert a VT_I4 to a VT_CY.
3451 *
3452 * PARAMS
3453 * sIn [I] Source
3454 * pCyOut [O] Destination
3455 *
3456 * RETURNS
3457 * Success: S_OK.
3458 * Failure: E_INVALIDARG, if the source value is invalid
3459 * DISP_E_OVERFLOW, if the value will not fit in the destination
3460 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3461 */
3462 HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
3463 {
3464 pCyOut->int64 = (LONG64)lIn * CY_MULTIPLIER;
3465 return S_OK;
3466 }
3467
3468 /************************************************************************
3469 * VarCyFromR4 (OLEAUT32.101)
3470 *
3471 * Convert a VT_R4 to a VT_CY.
3472 *
3473 * PARAMS
3474 * fltIn [I] Source
3475 * pCyOut [O] Destination
3476 *
3477 * RETURNS
3478 * Success: S_OK.
3479 * Failure: E_INVALIDARG, if the source value is invalid
3480 * DISP_E_OVERFLOW, if the value will not fit in the destination
3481 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3482 */
3483 HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pCyOut)
3484 {
3485 return VarCyFromR8(fltIn, pCyOut);
3486 }
3487
3488 /************************************************************************
3489 * VarCyFromR8 (OLEAUT32.102)
3490 *
3491 * Convert a VT_R8 to a VT_CY.
3492 *
3493 * PARAMS
3494 * dblIn [I] Source
3495 * pCyOut [O] Destination
3496 *
3497 * RETURNS
3498 * Success: S_OK.
3499 * Failure: E_INVALIDARG, if the source value is invalid
3500 * DISP_E_OVERFLOW, if the value will not fit in the destination
3501 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3502 */
3503 HRESULT WINAPI VarCyFromR8(double dblIn, CY* pCyOut)
3504 {
3505 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3506 /* This code gives identical results to Win32 on Intel.
3507 * Here we use fp exceptions to catch overflows when storing the value.
3508 */
3509 static const unsigned short r8_fpcontrol = 0x137f;
3510 static const double r8_multiplier = CY_MULTIPLIER_F;
3511 unsigned short old_fpcontrol, result_fpstatus;
3512
3513 /* Clear exceptions, save the old fp state and load the new state */
3514 __asm__ __volatile__( "fnclex" );
3515 __asm__ __volatile__( "fstcw %0" : "=m" (old_fpcontrol) : );
3516 __asm__ __volatile__( "fldcw %0" : : "m" (r8_fpcontrol) );
3517 /* Perform the conversion. */
3518 __asm__ __volatile__( "fldl %0" : : "m" (dblIn) );
3519 __asm__ __volatile__( "fmull %0" : : "m" (r8_multiplier) );
3520 __asm__ __volatile__( "fistpll %0" : : "m" (*pCyOut) );
3521 /* Save the resulting fp state, load the old state and clear exceptions */
3522 __asm__ __volatile__( "fstsw %0" : "=m" (result_fpstatus) : );
3523 __asm__ __volatile__( "fnclex" );
3524 __asm__ __volatile__( "fldcw %0" : : "m" (old_fpcontrol) );
3525
3526 if (result_fpstatus & 0x9) /* Overflow | Invalid */
3527 return DISP_E_OVERFLOW;
3528 #else
3529 /* This version produces slightly different results for boundary cases */
3530 if (dblIn < -922337203685477.5807 || dblIn >= 922337203685477.5807)
3531 return DISP_E_OVERFLOW;
3532 dblIn *= CY_MULTIPLIER_F;
3533 VARIANT_DutchRound(LONG64, dblIn, pCyOut->int64);
3534 #endif
3535 return S_OK;
3536 }
3537
3538 /************************************************************************
3539 * VarCyFromDate (OLEAUT32.103)
3540 *
3541 * Convert a VT_DATE to a VT_CY.
3542 *
3543 * PARAMS
3544 * dateIn [I] Source
3545 * pCyOut [O] Destination
3546 *
3547 * RETURNS
3548 * Success: S_OK.
3549 * Failure: E_INVALIDARG, if the source value is invalid
3550 * DISP_E_OVERFLOW, if the value will not fit in the destination
3551 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3552 */
3553 HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pCyOut)
3554 {
3555 return VarCyFromR8(dateIn, pCyOut);
3556 }
3557
3558 /************************************************************************
3559 * VarCyFromStr (OLEAUT32.104)
3560 *
3561 * Convert a VT_BSTR to a VT_CY.
3562 *
3563 * PARAMS
3564 * strIn [I] Source
3565 * lcid [I] LCID for the conversion
3566 * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
3567 * pCyOut [O] Destination
3568 *
3569 * RETURNS
3570 * Success: S_OK.
3571 * Failure: E_INVALIDARG, if the source value is invalid
3572 * DISP_E_OVERFLOW, if the value will not fit in the destination
3573 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3574 */
3575 HRESULT WINAPI VarCyFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CY* pCyOut)
3576 {
3577 return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pCyOut, VT_CY);
3578 }
3579
3580 /************************************************************************
3581 * VarCyFromDisp (OLEAUT32.105)
3582 *
3583 * Convert a VT_DISPATCH to a VT_CY.
3584 *
3585 * PARAMS
3586 * pdispIn [I] Source
3587 * lcid [I] LCID for conversion
3588 * pCyOut [O] Destination
3589 *
3590 * RETURNS
3591 * Success: S_OK.
3592 * Failure: E_INVALIDARG, if the source value is invalid
3593 * DISP_E_OVERFLOW, if the value will not fit in the destination
3594 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3595 */
3596 HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
3597 {
3598 return VARIANT_FromDisp(pdispIn, lcid, pCyOut, VT_CY, 0);
3599 }
3600
3601 /************************************************************************
3602 * VarCyFromBool (OLEAUT32.106)
3603 *
3604 * Convert a VT_BOOL to a VT_CY.
3605 *
3606 * PARAMS
3607 * boolIn [I] Source
3608 * pCyOut [O] Destination
3609 *
3610 * RETURNS
3611 * Success: S_OK.
3612 * Failure: E_INVALIDARG, if the source value is invalid
3613 * DISP_E_OVERFLOW, if the value will not fit in the destination
3614 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3615 *
3616 * NOTES
3617 * While the sign of the boolean is stored in the currency, the value is
3618 * converted to either 0 or 1.
3619 */
3620 HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
3621 {
3622 pCyOut->int64 = (LONG64)boolIn * CY_MULTIPLIER;
3623 return S_OK;
3624 }
3625
3626 /************************************************************************
3627 * VarCyFromI1 (OLEAUT32.225)
3628 *
3629 * Convert a VT_I1 to a VT_CY.
3630 *
3631 * PARAMS
3632 * cIn [I] Source
3633 * pCyOut [O] Destination
3634 *
3635 * RETURNS
3636 * Success: S_OK.
3637 * Failure: E_INVALIDARG, if the source value is invalid
3638 * DISP_E_OVERFLOW, if the value will not fit in the destination
3639 * DISP_E_TYPEMISMATCH, if the type cannot be converted
3640 */
3641 HRESULT WINAPI VarCyFromI1(signed char cIn