Moved DPMI wrapper allocation code to dosmem.c to REALLY make the
[wine/multimedia.git] / ole / variant.c
blob7eaf58d27ac876aa37dc96f7b463344903dc09b7
1 /*
2 * VARIANT
4 * Copyright 1998 Jean-Claude Cote
6 * NOTES
7 * This implements the low-level and hi-level APIs for manipulating VARIANTs.
8 * The low-level APIs are used to do data coercion between different data types.
9 * The hi-level APIs are built on top of these low-level APIs and handle
10 * initialization, copying, destroying and changing the type of VARIANTs.
12 * TODO:
13 * - The Variant APIs are do not support international languages, currency
14 * types, number formating and calendar. They only support U.S. English format.
15 * - The Variant APIs do not the following types: IUknown, IDispatch, DECIMAL and SafeArray.
16 * The prototypes for these are commented out in the oleauto.h file. They need
17 * to be implemented and cases need to be added to the switches of the existing APIs.
18 * - The parsing of date for the VarDateFromStr still needs to be done. I'm currently
19 * working on this.
22 #include "wintypes.h"
23 #include "oleauto.h"
24 #include "heap.h"
25 #include "debug.h"
26 #include "winerror.h"
27 #include "mapidefs.h"
29 #include <string.h>
30 #include <stdlib.h>
31 #include <math.h>
32 #include <time.h>
35 static const char CHAR_MAX = 127;
36 static const char CHAR_MIN = -128;
37 static const BYTE UI1_MAX = 255;
38 static const BYTE UI1_MIN = 0;
39 static const unsigned short UI2_MAX = 65535;
40 static const unsigned short UI2_MIN = 0;
41 static const short I2_MAX = 32767;
42 static const short I2_MIN = -32768;
43 static const unsigned long UI4_MAX = 4294967295;
44 static const unsigned long UI4_MIN = 0;
45 static const long I4_MAX = 2147483647;
46 static const long I4_MIN = -2147483648;
47 static const DATE DATE_MIN = -657434;
48 static const DATE DATE_MAX = 2958465;
51 /* This mask is used to set a flag in wReserved1 of
52 * the VARIANTARG structure. The flag indicates if
53 * the API function is using an inner variant or not.
55 #define PROCESSING_INNER_VARIANT 0x0001
57 /* General use buffer.
59 #define BUFFER_MAX 1024
60 static char pBuffer[BUFFER_MAX];
64 /******************************************************************************
65 * SizeOfVariantData [INTERNAL]
67 * This function finds the size of the data referenced by a Variant based
68 * the type "vt" of the Variant.
70 static int SizeOfVariantData( VARIANT* parg )
72 int size = 0;
73 switch( parg->vt & VT_TYPEMASK )
75 case( VT_I2 ):
76 size = sizeof(short);
77 break;
78 case( VT_INT ):
79 size = sizeof(int);
80 break;
81 case( VT_I4 ):
82 size = sizeof(long);
83 break;
84 case( VT_UI1 ):
85 size = sizeof(BYTE);
86 break;
87 case( VT_UI2 ):
88 size = sizeof(unsigned short);
89 break;
90 case( VT_UINT ):
91 size = sizeof(unsigned int);
92 break;
93 case( VT_UI4 ):
94 size = sizeof(unsigned long);
95 break;
96 case( VT_R4 ):
97 size = sizeof(float);
98 break;
99 case( VT_R8 ):
100 size = sizeof(double);
101 break;
102 case( VT_DATE ):
103 size = sizeof(DATE);
104 break;
105 case( VT_BOOL ):
106 size = sizeof(VARIANT_BOOL);
107 break;
108 case( VT_BSTR ):
109 size = sizeof(void*);
110 break;
111 case( VT_CY ):
112 case( VT_DISPATCH ):
113 case( VT_UNKNOWN ):
114 case( VT_DECIMAL ):
115 default:
116 FIXME(ole,"Add size information for type vt=%d\n", parg->vt & VT_TYPEMASK );
117 break;
120 return size;
122 /******************************************************************************
123 * StringDupAtoBstr [INTERNAL]
126 static BSTR32 StringDupAtoBstr( char* strIn )
128 BSTR32 bstr = NULL;
129 OLECHAR32* pNewString = NULL;
130 pNewString = HEAP_strdupAtoW( GetProcessHeap(), 0, strIn );
131 bstr = SysAllocString32( pNewString );
132 HeapFree( GetProcessHeap(), 0, pNewString );
133 return bstr;
136 /******************************************************************************
137 * round [INTERNAL]
139 * Round the double value to the nearest integer value.
141 static double round( double d )
143 double decimals = 0.0, integerValue = 0.0, roundedValue = 0.0;
144 BOOL32 bEvenNumber = FALSE;
145 int nSign = 0;
147 /* Save the sign of the number
149 nSign = (d >= 0.0) ? 1 : -1;
150 d = fabs( d );
152 /* Remove the decimals.
154 integerValue = floor( d );
156 /* Set the Even flag. This is used to round the number when
157 * the decimals are exactly 1/2. If the integer part is
158 * odd the number is rounded up. If the integer part
159 * is even the number is rounded down. Using this method
160 * numbers are rounded up|down half the time.
162 bEvenNumber = (((short)fmod(integerValue, 2)) == 0) ? TRUE : FALSE;
164 /* Remove the integral part of the number.
166 decimals = d - integerValue;
168 /* Note: Ceil returns the smallest integer that is greater that x.
169 * and floor returns the largest integer that is less than or equal to x.
171 if( decimals > 0.5 )
173 /* If the decimal part is greater than 1/2
175 roundedValue = ceil( d );
177 else if( decimals < 0.5 )
179 /* If the decimal part is smaller than 1/2
181 roundedValue = floor( d );
183 else
185 /* the decimals are exactly 1/2 so round according to
186 * the bEvenNumber flag.
188 if( bEvenNumber )
190 roundedValue = floor( d );
192 else
194 roundedValue = ceil( d );
198 return roundedValue * nSign;
201 /******************************************************************************
202 * RemoveCharacterFromString [INTERNAL]
204 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
206 static void RemoveCharacterFromString( LPSTR str, LPSTR strOfCharToRemove )
208 LPSTR pNewString = NULL;
209 LPSTR strToken = NULL;
212 /* Check if we have a valid argument
214 if( str != NULL )
216 pNewString = strdup( str );
217 str[0] = '\0';
218 strToken = strtok( pNewString, strOfCharToRemove );
219 while( strToken != NULL ) {
220 strcat( str, strToken );
221 strToken = strtok( NULL, strOfCharToRemove );
223 free( pNewString );
225 return;
228 /******************************************************************************
229 * GetValidRealString [INTERNAL]
231 * Checks if the string is of proper format to be converted to a real value.
233 static BOOL32 IsValidRealString( LPSTR strRealString )
235 /* Real values that have a decimal point are required to either have
236 * digits before or after the decimal point. We will assume that
237 * we do not have any digits at either position. If we do encounter
238 * some we will disable this flag.
240 BOOL32 bDigitsRequired = TRUE;
241 /* Processed fields in the string representation of the real number.
243 BOOL32 bWhiteSpaceProcessed = FALSE;
244 BOOL32 bFirstSignProcessed = FALSE;
245 BOOL32 bFirstDigitsProcessed = FALSE;
246 BOOL32 bDecimalPointProcessed = FALSE;
247 BOOL32 bSecondDigitsProcessed = FALSE;
248 BOOL32 bExponentProcessed = FALSE;
249 BOOL32 bSecondSignProcessed = FALSE;
250 BOOL32 bThirdDigitsProcessed = FALSE;
251 /* Assume string parameter "strRealString" is valid and try to disprove it.
253 BOOL32 bValidRealString = TRUE;
255 /* Used to count the number of tokens in the "strRealString".
257 LPSTR strToken = NULL;
258 int nTokens = 0;
259 LPSTR pChar = NULL;
261 /* Check if we have a valid argument
263 if( strRealString == NULL )
265 bValidRealString = FALSE;
268 if( bValidRealString == TRUE )
270 /* Make sure we only have ONE token in the string.
272 strToken = strtok( strRealString, " " );
273 while( strToken != NULL ) {
274 nTokens++;
275 strToken = strtok( NULL, " " );
278 if( nTokens != 1 )
280 bValidRealString = FALSE;
285 /* Make sure this token contains only valid characters.
286 * The string argument to atof has the following form:
287 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
288 * Whitespace consists of space and|or <TAB> characters, which are ignored.
289 * Sign is either plus '+' or minus '-'.
290 * Digits are one or more decimal digits.
291 * Note: If no digits appear before the decimal point, at least one must
292 * appear after the decimal point.
293 * The decimal digits may be followed by an exponent.
294 * An Exponent consists of an introductory letter ( D, d, E, or e) and
295 * an optionally signed decimal integer.
297 pChar = strRealString;
298 while( bValidRealString == TRUE && *pChar != '\0' )
300 switch( *pChar )
302 /* If whitespace...
304 case ' ':
305 case '\t':
306 if( bWhiteSpaceProcessed ||
307 bFirstSignProcessed ||
308 bFirstDigitsProcessed ||
309 bDecimalPointProcessed ||
310 bSecondDigitsProcessed ||
311 bExponentProcessed ||
312 bSecondSignProcessed ||
313 bThirdDigitsProcessed )
315 bValidRealString = FALSE;
317 break;
318 /* If sign...
320 case '+':
321 case '-':
322 if( bFirstSignProcessed == FALSE )
324 if( bFirstDigitsProcessed ||
325 bDecimalPointProcessed ||
326 bSecondDigitsProcessed ||
327 bExponentProcessed ||
328 bSecondSignProcessed ||
329 bThirdDigitsProcessed )
331 bValidRealString = FALSE;
333 bWhiteSpaceProcessed = TRUE;
334 bFirstSignProcessed = TRUE;
336 else if( bSecondSignProcessed == FALSE )
338 /* Note: The exponent must be present in
339 * order to accept the second sign...
341 if( bExponentProcessed == FALSE ||
342 bThirdDigitsProcessed ||
343 bDigitsRequired )
345 bValidRealString = FALSE;
347 bFirstSignProcessed = TRUE;
348 bWhiteSpaceProcessed = TRUE;
349 bFirstDigitsProcessed = TRUE;
350 bDecimalPointProcessed = TRUE;
351 bSecondDigitsProcessed = TRUE;
352 bSecondSignProcessed = TRUE;
354 break;
356 /* If decimals...
358 case '0':
359 case '1':
360 case '2':
361 case '3':
362 case '4':
363 case '5':
364 case '6':
365 case '7':
366 case '8':
367 case '9':
368 if( bFirstDigitsProcessed == FALSE )
370 if( bDecimalPointProcessed ||
371 bSecondDigitsProcessed ||
372 bExponentProcessed ||
373 bSecondSignProcessed ||
374 bThirdDigitsProcessed )
376 bValidRealString = FALSE;
378 bFirstSignProcessed = TRUE;
379 bWhiteSpaceProcessed = TRUE;
380 /* We have found some digits before the decimal point
381 * so disable the "Digits required" flag.
383 bDigitsRequired = FALSE;
385 else if( bSecondDigitsProcessed == FALSE )
387 if( bExponentProcessed ||
388 bSecondSignProcessed ||
389 bThirdDigitsProcessed )
391 bValidRealString = FALSE;
393 bFirstSignProcessed = TRUE;
394 bWhiteSpaceProcessed = TRUE;
395 bFirstDigitsProcessed = TRUE;
396 bDecimalPointProcessed = TRUE;
397 /* We have found some digits after the decimal point
398 * so disable the "Digits required" flag.
400 bDigitsRequired = FALSE;
402 else if( bThirdDigitsProcessed == FALSE )
404 /* Getting here means everything else should be processed.
405 * If we get anything else than a decimal following this
406 * digit it will be flagged by the other cases, so
407 * we do not really need to do anything in here.
410 break;
411 /* If DecimalPoint...
413 case '.':
414 if( bDecimalPointProcessed ||
415 bSecondDigitsProcessed ||
416 bExponentProcessed ||
417 bSecondSignProcessed ||
418 bThirdDigitsProcessed )
420 bValidRealString = FALSE;
422 bFirstSignProcessed = TRUE;
423 bWhiteSpaceProcessed = TRUE;
424 bFirstDigitsProcessed = TRUE;
425 bDecimalPointProcessed = TRUE;
426 break;
427 /* If Exponent...
429 case 'e':
430 case 'E':
431 case 'd':
432 case 'D':
433 if( bExponentProcessed ||
434 bSecondSignProcessed ||
435 bThirdDigitsProcessed ||
436 bDigitsRequired )
438 bValidRealString = FALSE;
440 bFirstSignProcessed = TRUE;
441 bWhiteSpaceProcessed = TRUE;
442 bFirstDigitsProcessed = TRUE;
443 bDecimalPointProcessed = TRUE;
444 bSecondDigitsProcessed = TRUE;
445 bExponentProcessed = TRUE;
446 break;
447 default:
448 bValidRealString = FALSE;
449 break;
451 /* Process next character.
453 pChar++;
456 /* If the required digits were not present we have an invalid
457 * string representation of a real number.
459 if( bDigitsRequired == TRUE )
461 bValidRealString = FALSE;
464 return bValidRealString;
468 /******************************************************************************
469 * Coerce [INTERNAL]
471 * This function dispatches execution to the proper conversion API
472 * to do the necessary coercion.
474 static HRESULT Coerce( VARIANTARG* pd, LCID lcid, ULONG dwFlags, VARIANTARG* ps, VARTYPE vt )
476 HRESULT res = S_OK;
477 unsigned short vtFrom = 0;
478 vtFrom = ps->vt & VT_TYPEMASK;
480 /* Note: Since "long" and "int" values both have 4 bytes and are both signed integers
481 * "int" will be treated as "long" in the following code.
482 * The same goes for there unsigned versions.
485 switch( vt )
488 case( VT_EMPTY ):
489 res = VariantClear32( pd );
490 break;
491 case( VT_NULL ):
492 res = VariantClear32( pd );
493 if( res == S_OK )
495 pd->vt = VT_NULL;
497 break;
498 case( VT_I1 ):
499 switch( vtFrom )
501 case( VT_I1 ):
502 res = VariantCopy32( pd, ps );
503 break;
504 case( VT_I2 ):
505 res = VarI1FromI232( ps->u.iVal, &(pd->u.cVal) );
506 break;
507 case( VT_INT ):
508 case( VT_I4 ):
509 res = VarI1FromI432( ps->u.lVal, &(pd->u.cVal) );
510 break;
511 case( VT_UI1 ):
512 res = VarI1FromUI132( ps->u.bVal, &(pd->u.cVal) );
513 break;
514 case( VT_UI2 ):
515 res = VarI1FromUI232( ps->u.uiVal, &(pd->u.cVal) );
516 break;
517 case( VT_UINT ):
518 case( VT_UI4 ):
519 res = VarI1FromUI432( ps->u.ulVal, &(pd->u.cVal) );
520 break;
521 case( VT_R4 ):
522 res = VarI1FromR432( ps->u.fltVal, &(pd->u.cVal) );
523 break;
524 case( VT_R8 ):
525 res = VarI1FromR832( ps->u.dblVal, &(pd->u.cVal) );
526 break;
527 case( VT_DATE ):
528 res = VarI1FromDate32( ps->u.date, &(pd->u.cVal) );
529 break;
530 case( VT_BOOL ):
531 res = VarI1FromBool32( ps->u.boolVal, &(pd->u.cVal) );
532 break;
533 case( VT_BSTR ):
534 res = VarI1FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cVal) );
535 break;
536 case( VT_CY ):
537 res = VarI1FromCy32( ps->u.cyVal, &(pd->u.cVal) );
538 case( VT_DISPATCH ):
539 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
540 case( VT_UNKNOWN ):
541 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
542 case( VT_DECIMAL ):
543 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
544 default:
545 res = DISP_E_TYPEMISMATCH;
546 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
547 break;
549 break;
551 case( VT_I2 ):
552 switch( vtFrom )
554 case( VT_I1 ):
555 res = VarI2FromI132( ps->u.cVal, &(pd->u.iVal) );
556 break;
557 case( VT_I2 ):
558 res = VariantCopy32( pd, ps );
559 break;
560 case( VT_INT ):
561 case( VT_I4 ):
562 res = VarI2FromI432( ps->u.lVal, &(pd->u.iVal) );
563 break;
564 case( VT_UI1 ):
565 res = VarI2FromUI132( ps->u.bVal, &(pd->u.iVal) );
566 break;
567 case( VT_UI2 ):
568 res = VarI2FromUI232( ps->u.uiVal, &(pd->u.iVal) );
569 break;
570 case( VT_UINT ):
571 case( VT_UI4 ):
572 res = VarI2FromUI432( ps->u.ulVal, &(pd->u.iVal) );
573 break;
574 case( VT_R4 ):
575 res = VarI2FromR432( ps->u.fltVal, &(pd->u.iVal) );
576 break;
577 case( VT_R8 ):
578 res = VarI2FromR832( ps->u.dblVal, &(pd->u.iVal) );
579 break;
580 case( VT_DATE ):
581 res = VarI2FromDate32( ps->u.date, &(pd->u.iVal) );
582 break;
583 case( VT_BOOL ):
584 res = VarI2FromBool32( ps->u.boolVal, &(pd->u.iVal) );
585 break;
586 case( VT_BSTR ):
587 res = VarI2FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.iVal) );
588 break;
589 case( VT_CY ):
590 res = VarI2FromCy32( ps->u.cyVal, &(pd->u.iVal) );
591 case( VT_DISPATCH ):
592 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
593 case( VT_UNKNOWN ):
594 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
595 case( VT_DECIMAL ):
596 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
597 default:
598 res = DISP_E_TYPEMISMATCH;
599 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
600 break;
602 break;
604 case( VT_INT ):
605 case( VT_I4 ):
606 switch( vtFrom )
608 case( VT_I1 ):
609 res = VarI4FromI132( ps->u.cVal, &(pd->u.lVal) );
610 break;
611 case( VT_I2 ):
612 res = VarI4FromI232( ps->u.iVal, &(pd->u.lVal) );
613 break;
614 case( VT_INT ):
615 case( VT_I4 ):
616 res = VariantCopy32( pd, ps );
617 break;
618 case( VT_UI1 ):
619 res = VarI4FromUI132( ps->u.bVal, &(pd->u.lVal) );
620 break;
621 case( VT_UI2 ):
622 res = VarI4FromUI232( ps->u.uiVal, &(pd->u.lVal) );
623 break;
624 case( VT_UINT ):
625 case( VT_UI4 ):
626 res = VarI4FromUI432( ps->u.ulVal, &(pd->u.lVal) );
627 break;
628 case( VT_R4 ):
629 res = VarI4FromR432( ps->u.fltVal, &(pd->u.lVal) );
630 break;
631 case( VT_R8 ):
632 res = VarI4FromR832( ps->u.dblVal, &(pd->u.lVal) );
633 break;
634 case( VT_DATE ):
635 res = VarI4FromDate32( ps->u.date, &(pd->u.lVal) );
636 break;
637 case( VT_BOOL ):
638 res = VarI4FromBool32( ps->u.boolVal, &(pd->u.lVal) );
639 break;
640 case( VT_BSTR ):
641 res = VarI4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.lVal) );
642 break;
643 case( VT_CY ):
644 res = VarI4FromCy32( ps->u.cyVal, &(pd->u.lVal) );
645 case( VT_DISPATCH ):
646 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
647 case( VT_UNKNOWN ):
648 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
649 case( VT_DECIMAL ):
650 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
651 default:
652 res = DISP_E_TYPEMISMATCH;
653 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
654 break;
656 break;
658 case( VT_UI1 ):
659 switch( vtFrom )
661 case( VT_I1 ):
662 res = VarUI1FromI132( ps->u.cVal, &(pd->u.bVal) );
663 break;
664 case( VT_I2 ):
665 res = VarUI1FromI232( ps->u.iVal, &(pd->u.bVal) );
666 break;
667 case( VT_INT ):
668 case( VT_I4 ):
669 res = VarUI1FromI432( ps->u.lVal, &(pd->u.bVal) );
670 break;
671 case( VT_UI1 ):
672 res = VariantCopy32( pd, ps );
673 break;
674 case( VT_UI2 ):
675 res = VarUI1FromUI232( ps->u.uiVal, &(pd->u.bVal) );
676 break;
677 case( VT_UINT ):
678 case( VT_UI4 ):
679 res = VarUI1FromUI432( ps->u.ulVal, &(pd->u.bVal) );
680 break;
681 case( VT_R4 ):
682 res = VarUI1FromR432( ps->u.fltVal, &(pd->u.bVal) );
683 break;
684 case( VT_R8 ):
685 res = VarUI1FromR832( ps->u.dblVal, &(pd->u.bVal) );
686 break;
687 case( VT_DATE ):
688 res = VarUI1FromDate32( ps->u.date, &(pd->u.bVal) );
689 break;
690 case( VT_BOOL ):
691 res = VarUI1FromBool32( ps->u.boolVal, &(pd->u.bVal) );
692 break;
693 case( VT_BSTR ):
694 res = VarUI1FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.bVal) );
695 break;
696 case( VT_CY ):
697 res = VarUI1FromCy32( ps->u.cyVal, &(pd->u.bVal) );
698 case( VT_DISPATCH ):
699 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
700 case( VT_UNKNOWN ):
701 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
702 case( VT_DECIMAL ):
703 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
704 default:
705 res = DISP_E_TYPEMISMATCH;
706 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
707 break;
709 break;
711 case( VT_UI2 ):
712 switch( vtFrom )
714 case( VT_I1 ):
715 res = VarUI2FromI132( ps->u.cVal, &(pd->u.uiVal) );
716 break;
717 case( VT_I2 ):
718 res = VarUI2FromI232( ps->u.iVal, &(pd->u.uiVal) );
719 break;
720 case( VT_INT ):
721 case( VT_I4 ):
722 res = VarUI2FromI432( ps->u.lVal, &(pd->u.uiVal) );
723 break;
724 case( VT_UI1 ):
725 res = VarUI2FromUI132( ps->u.bVal, &(pd->u.uiVal) );
726 break;
727 case( VT_UI2 ):
728 res = VariantCopy32( pd, ps );
729 break;
730 case( VT_UINT ):
731 case( VT_UI4 ):
732 res = VarUI2FromUI432( ps->u.ulVal, &(pd->u.uiVal) );
733 break;
734 case( VT_R4 ):
735 res = VarUI2FromR432( ps->u.fltVal, &(pd->u.uiVal) );
736 break;
737 case( VT_R8 ):
738 res = VarUI2FromR832( ps->u.dblVal, &(pd->u.uiVal) );
739 break;
740 case( VT_DATE ):
741 res = VarUI2FromDate32( ps->u.date, &(pd->u.uiVal) );
742 break;
743 case( VT_BOOL ):
744 res = VarUI2FromBool32( ps->u.boolVal, &(pd->u.uiVal) );
745 break;
746 case( VT_BSTR ):
747 res = VarUI2FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.uiVal) );
748 break;
749 case( VT_CY ):
750 res = VarUI2FromCy32( ps->u.cyVal, &(pd->u.uiVal) );
751 case( VT_DISPATCH ):
752 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
753 case( VT_UNKNOWN ):
754 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
755 case( VT_DECIMAL ):
756 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
757 default:
758 res = DISP_E_TYPEMISMATCH;
759 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
760 break;
762 break;
764 case( VT_UINT ):
765 case( VT_UI4 ):
766 switch( vtFrom )
768 case( VT_I1 ):
769 res = VarUI4FromI132( ps->u.cVal, &(pd->u.ulVal) );
770 break;
771 case( VT_I2 ):
772 res = VarUI4FromI232( ps->u.iVal, &(pd->u.ulVal) );
773 break;
774 case( VT_INT ):
775 case( VT_I4 ):
776 res = VarUI4FromI432( ps->u.lVal, &(pd->u.ulVal) );
777 break;
778 case( VT_UI1 ):
779 res = VarUI4FromUI132( ps->u.bVal, &(pd->u.ulVal) );
780 break;
781 case( VT_UI2 ):
782 res = VarUI4FromUI232( ps->u.uiVal, &(pd->u.ulVal) );
783 break;
784 case( VT_UI4 ):
785 res = VariantCopy32( pd, ps );
786 break;
787 case( VT_R4 ):
788 res = VarUI4FromR432( ps->u.fltVal, &(pd->u.ulVal) );
789 break;
790 case( VT_R8 ):
791 res = VarUI4FromR832( ps->u.dblVal, &(pd->u.ulVal) );
792 break;
793 case( VT_DATE ):
794 res = VarUI4FromDate32( ps->u.date, &(pd->u.ulVal) );
795 break;
796 case( VT_BOOL ):
797 res = VarUI4FromBool32( ps->u.boolVal, &(pd->u.ulVal) );
798 break;
799 case( VT_BSTR ):
800 res = VarUI4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.ulVal) );
801 break;
802 case( VT_CY ):
803 res = VarUI4FromCy32( ps->u.cyVal, &(pd->u.ulVal) );
804 case( VT_DISPATCH ):
805 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
806 case( VT_UNKNOWN ):
807 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
808 case( VT_DECIMAL ):
809 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
810 default:
811 res = DISP_E_TYPEMISMATCH;
812 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
813 break;
815 break;
817 case( VT_R4 ):
818 switch( vtFrom )
820 case( VT_I1 ):
821 res = VarR4FromI132( ps->u.cVal, &(pd->u.fltVal) );
822 break;
823 case( VT_I2 ):
824 res = VarR4FromI232( ps->u.iVal, &(pd->u.fltVal) );
825 break;
826 case( VT_INT ):
827 case( VT_I4 ):
828 res = VarR4FromI432( ps->u.lVal, &(pd->u.fltVal) );
829 break;
830 case( VT_UI1 ):
831 res = VarR4FromUI132( ps->u.bVal, &(pd->u.fltVal) );
832 break;
833 case( VT_UI2 ):
834 res = VarR4FromUI232( ps->u.uiVal, &(pd->u.fltVal) );
835 break;
836 case( VT_UINT ):
837 case( VT_UI4 ):
838 res = VarR4FromUI432( ps->u.ulVal, &(pd->u.fltVal) );
839 break;
840 case( VT_R4 ):
841 res = VariantCopy32( pd, ps );
842 break;
843 case( VT_R8 ):
844 res = VarR4FromR832( ps->u.dblVal, &(pd->u.fltVal) );
845 break;
846 case( VT_DATE ):
847 res = VarR4FromDate32( ps->u.date, &(pd->u.fltVal) );
848 break;
849 case( VT_BOOL ):
850 res = VarR4FromBool32( ps->u.boolVal, &(pd->u.fltVal) );
851 break;
852 case( VT_BSTR ):
853 res = VarR4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.fltVal) );
854 break;
855 case( VT_CY ):
856 res = VarR4FromCy32( ps->u.cyVal, &(pd->u.fltVal) );
857 case( VT_DISPATCH ):
858 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
859 case( VT_UNKNOWN ):
860 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
861 case( VT_DECIMAL ):
862 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
863 default:
864 res = DISP_E_TYPEMISMATCH;
865 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
866 break;
868 break;
870 case( VT_R8 ):
871 switch( vtFrom )
873 case( VT_I1 ):
874 res = VarR8FromI132( ps->u.cVal, &(pd->u.dblVal) );
875 break;
876 case( VT_I2 ):
877 res = VarR8FromI232( ps->u.iVal, &(pd->u.dblVal) );
878 break;
879 case( VT_INT ):
880 case( VT_I4 ):
881 res = VarR8FromI432( ps->u.lVal, &(pd->u.dblVal) );
882 break;
883 case( VT_UI1 ):
884 res = VarR8FromUI132( ps->u.bVal, &(pd->u.dblVal) );
885 break;
886 case( VT_UI2 ):
887 res = VarR8FromUI232( ps->u.uiVal, &(pd->u.dblVal) );
888 break;
889 case( VT_UINT ):
890 case( VT_UI4 ):
891 res = VarR8FromUI432( ps->u.ulVal, &(pd->u.dblVal) );
892 break;
893 case( VT_R4 ):
894 res = VarR8FromR432( ps->u.fltVal, &(pd->u.dblVal) );
895 break;
896 case( VT_R8 ):
897 res = VariantCopy32( pd, ps );
898 break;
899 case( VT_DATE ):
900 res = VarR8FromDate32( ps->u.date, &(pd->u.dblVal) );
901 break;
902 case( VT_BOOL ):
903 res = VarR8FromBool32( ps->u.boolVal, &(pd->u.dblVal) );
904 break;
905 case( VT_BSTR ):
906 res = VarR8FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.dblVal) );
907 break;
908 case( VT_CY ):
909 res = VarR8FromCy32( ps->u.cyVal, &(pd->u.dblVal) );
910 case( VT_DISPATCH ):
911 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
912 case( VT_UNKNOWN ):
913 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
914 case( VT_DECIMAL ):
915 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
916 default:
917 res = DISP_E_TYPEMISMATCH;
918 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
919 break;
921 break;
923 case( VT_DATE ):
924 switch( vtFrom )
926 case( VT_I1 ):
927 res = VarDateFromI132( ps->u.cVal, &(pd->u.date) );
928 break;
929 case( VT_I2 ):
930 res = VarDateFromI232( ps->u.iVal, &(pd->u.date) );
931 break;
932 case( VT_INT ):
933 res = VarDateFromInt32( ps->u.intVal, &(pd->u.date) );
934 break;
935 case( VT_I4 ):
936 res = VarDateFromI432( ps->u.lVal, &(pd->u.date) );
937 break;
938 case( VT_UI1 ):
939 res = VarDateFromUI132( ps->u.bVal, &(pd->u.date) );
940 break;
941 case( VT_UI2 ):
942 res = VarDateFromUI232( ps->u.uiVal, &(pd->u.date) );
943 break;
944 case( VT_UINT ):
945 res = VarDateFromUint32( ps->u.uintVal, &(pd->u.date) );
946 break;
947 case( VT_UI4 ):
948 res = VarDateFromUI432( ps->u.ulVal, &(pd->u.date) );
949 break;
950 case( VT_R4 ):
951 res = VarDateFromR432( ps->u.fltVal, &(pd->u.date) );
952 break;
953 case( VT_R8 ):
954 res = VarDateFromR832( ps->u.dblVal, &(pd->u.date) );
955 break;
956 case( VT_DATE ):
957 res = VariantCopy32( pd, ps );
958 break;
959 case( VT_BOOL ):
960 res = VarDateFromBool32( ps->u.boolVal, &(pd->u.date) );
961 break;
962 case( VT_BSTR ):
963 res = VarDateFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.date) );
964 break;
965 case( VT_CY ):
966 res = VarDateFromCy32( ps->u.cyVal, &(pd->u.date) );
967 case( VT_DISPATCH ):
968 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
969 case( VT_UNKNOWN ):
970 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
971 case( VT_DECIMAL ):
972 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
973 default:
974 res = DISP_E_TYPEMISMATCH;
975 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
976 break;
978 break;
980 case( VT_BOOL ):
981 switch( vtFrom )
983 case( VT_I1 ):
984 res = VarBoolFromI132( ps->u.cVal, &(pd->u.boolVal) );
985 break;
986 case( VT_I2 ):
987 res = VarBoolFromI232( ps->u.iVal, &(pd->u.boolVal) );
988 break;
989 case( VT_INT ):
990 res = VarBoolFromInt32( ps->u.intVal, &(pd->u.boolVal) );
991 break;
992 case( VT_I4 ):
993 res = VarBoolFromI432( ps->u.lVal, &(pd->u.boolVal) );
994 break;
995 case( VT_UI1 ):
996 res = VarBoolFromUI132( ps->u.bVal, &(pd->u.boolVal) );
997 break;
998 case( VT_UI2 ):
999 res = VarBoolFromUI232( ps->u.uiVal, &(pd->u.boolVal) );
1000 break;
1001 case( VT_UINT ):
1002 res = VarBoolFromUint32( ps->u.uintVal, &(pd->u.boolVal) );
1003 break;
1004 case( VT_UI4 ):
1005 res = VarBoolFromUI432( ps->u.ulVal, &(pd->u.boolVal) );
1006 break;
1007 case( VT_R4 ):
1008 res = VarBoolFromR432( ps->u.fltVal, &(pd->u.boolVal) );
1009 break;
1010 case( VT_R8 ):
1011 res = VarBoolFromR832( ps->u.dblVal, &(pd->u.boolVal) );
1012 break;
1013 case( VT_DATE ):
1014 res = VarBoolFromDate32( ps->u.date, &(pd->u.boolVal) );
1015 break;
1016 case( VT_BOOL ):
1017 res = VariantCopy32( pd, ps );
1018 break;
1019 case( VT_BSTR ):
1020 res = VarBoolFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.boolVal) );
1021 break;
1022 case( VT_CY ):
1023 res = VarBoolFromCy32( ps->u.cyVal, &(pd->u.boolVal) );
1024 case( VT_DISPATCH ):
1025 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1026 case( VT_UNKNOWN ):
1027 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1028 case( VT_DECIMAL ):
1029 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1030 default:
1031 res = DISP_E_TYPEMISMATCH;
1032 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1033 break;
1035 break;
1037 case( VT_BSTR ):
1038 switch( vtFrom )
1040 case( VT_I1 ):
1041 res = VarBstrFromI132( ps->u.cVal, lcid, dwFlags, &(pd->u.bstrVal) );
1042 break;
1043 case( VT_I2 ):
1044 res = VarBstrFromI232( ps->u.iVal, lcid, dwFlags, &(pd->u.bstrVal) );
1045 break;
1046 case( VT_INT ):
1047 res = VarBstrFromInt32( ps->u.intVal, lcid, dwFlags, &(pd->u.bstrVal) );
1048 break;
1049 case( VT_I4 ):
1050 res = VarBstrFromI432( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );
1051 break;
1052 case( VT_UI1 ):
1053 res = VarBstrFromUI132( ps->u.bVal, lcid, dwFlags, &(pd->u.bstrVal) );
1054 break;
1055 case( VT_UI2 ):
1056 res = VarBstrFromUI232( ps->u.uiVal, lcid, dwFlags, &(pd->u.bstrVal) );
1057 break;
1058 case( VT_UINT ):
1059 res = VarBstrFromUint32( ps->u.uintVal, lcid, dwFlags, &(pd->u.bstrVal) );
1060 break;
1061 case( VT_UI4 ):
1062 res = VarBstrFromUI432( ps->u.ulVal, lcid, dwFlags, &(pd->u.bstrVal) );
1063 break;
1064 case( VT_R4 ):
1065 res = VarBstrFromR432( ps->u.fltVal, lcid, dwFlags, &(pd->u.bstrVal) );
1066 break;
1067 case( VT_R8 ):
1068 res = VarBstrFromR832( ps->u.dblVal, lcid, dwFlags, &(pd->u.bstrVal) );
1069 break;
1070 case( VT_DATE ):
1071 res = VarBstrFromDate32( ps->u.date, lcid, dwFlags, &(pd->u.bstrVal) );
1072 break;
1073 case( VT_BOOL ):
1074 res = VarBstrFromBool32( ps->u.boolVal, lcid, dwFlags, &(pd->u.bstrVal) );
1075 break;
1076 case( VT_BSTR ):
1077 res = VariantCopy32( pd, ps );
1078 break;
1079 case( VT_CY ):
1080 /*res = VarBstrFromCy32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1081 case( VT_DISPATCH ):
1082 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1083 case( VT_UNKNOWN ):
1084 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1085 case( VT_DECIMAL ):
1086 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1087 default:
1088 res = DISP_E_TYPEMISMATCH;
1089 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1090 break;
1092 break;
1094 case( VT_CY ):
1095 switch( vtFrom )
1097 case( VT_I1 ):
1098 res = VarCyFromI132( ps->u.cVal, &(pd->u.cyVal) );
1099 break;
1100 case( VT_I2 ):
1101 res = VarCyFromI232( ps->u.iVal, &(pd->u.cyVal) );
1102 break;
1103 case( VT_INT ):
1104 res = VarCyFromInt32( ps->u.intVal, &(pd->u.cyVal) );
1105 break;
1106 case( VT_I4 ):
1107 res = VarCyFromI432( ps->u.lVal, &(pd->u.cyVal) );
1108 break;
1109 case( VT_UI1 ):
1110 res = VarCyFromUI132( ps->u.bVal, &(pd->u.cyVal) );
1111 break;
1112 case( VT_UI2 ):
1113 res = VarCyFromUI232( ps->u.uiVal, &(pd->u.cyVal) );
1114 break;
1115 case( VT_UINT ):
1116 res = VarCyFromUint32( ps->u.uintVal, &(pd->u.cyVal) );
1117 break;
1118 case( VT_UI4 ):
1119 res = VarCyFromUI432( ps->u.ulVal, &(pd->u.cyVal) );
1120 break;
1121 case( VT_R4 ):
1122 res = VarCyFromR432( ps->u.fltVal, &(pd->u.cyVal) );
1123 break;
1124 case( VT_R8 ):
1125 res = VarCyFromR832( ps->u.dblVal, &(pd->u.cyVal) );
1126 break;
1127 case( VT_DATE ):
1128 res = VarCyFromDate32( ps->u.date, &(pd->u.cyVal) );
1129 break;
1130 case( VT_BOOL ):
1131 res = VarCyFromBool32( ps->u.date, &(pd->u.cyVal) );
1132 break;
1133 case( VT_CY ):
1134 res = VariantCopy32( pd, ps );
1135 break;
1136 case( VT_BSTR ):
1137 /*res = VarCyFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cyVal) );*/
1138 case( VT_DISPATCH ):
1139 /*res = VarCyFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1140 case( VT_UNKNOWN ):
1141 /*res = VarCyFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1142 case( VT_DECIMAL ):
1143 /*res = VarCyFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1144 default:
1145 res = DISP_E_TYPEMISMATCH;
1146 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1147 break;
1149 break;
1151 default:
1152 res = DISP_E_TYPEMISMATCH;
1153 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1154 break;
1157 return res;
1160 /******************************************************************************
1161 * ValidateVtRange [INTERNAL]
1163 * Used internally by the hi-level Variant API to determine
1164 * if the vartypes are valid.
1166 static HRESULT WINAPI ValidateVtRange( VARTYPE vt )
1168 /* if by value we must make sure it is in the
1169 * range of the valid types.
1171 if( ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1173 return DISP_E_BADVARTYPE;
1175 return S_OK;
1179 /******************************************************************************
1180 * ValidateVartype [INTERNAL]
1182 * Used internally by the hi-level Variant API to determine
1183 * if the vartypes are valid.
1185 static HRESULT WINAPI ValidateVariantType( VARTYPE vt )
1187 HRESULT res = S_OK;
1189 /* check if we have a valid argument.
1191 if( vt & VT_BYREF )
1193 /* if by reference check that the type is in
1194 * the valid range and that it is not of empty or null type
1196 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1197 ( vt & VT_TYPEMASK ) == VT_NULL ||
1198 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1200 res = E_INVALIDARG;
1204 else
1206 res = ValidateVtRange( vt );
1209 return res;
1212 /******************************************************************************
1213 * ValidateVt [INTERNAL]
1215 * Used internally by the hi-level Variant API to determine
1216 * if the vartypes are valid.
1218 static HRESULT WINAPI ValidateVt( VARTYPE vt )
1220 HRESULT res = S_OK;
1222 /* check if we have a valid argument.
1224 if( vt & VT_BYREF )
1226 /* if by reference check that the type is in
1227 * the valid range and that it is not of empty or null type
1229 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1230 ( vt & VT_TYPEMASK ) == VT_NULL ||
1231 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1233 res = DISP_E_BADVARTYPE;
1237 else
1239 res = ValidateVtRange( vt );
1242 return res;
1249 /******************************************************************************
1250 * VariantInit32 [OLEAUT32.8]
1252 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1253 * contents of the Variant.
1255 void WINAPI VariantInit32(VARIANTARG* pvarg)
1257 TRACE(ole,"(%p),stub\n",pvarg);
1259 pvarg->vt = VT_EMPTY;
1260 pvarg->wReserved1 = 0;
1261 pvarg->wReserved2= 0;
1262 pvarg->wReserved3= 0;
1264 return;
1267 /******************************************************************************
1268 * VariantClear32 [OLEAUT32.9]
1270 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1271 * sets the wReservedX field to 0. The current contents of the VARIANT are
1272 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1273 * released. If VT_ARRAY the array is freed.
1275 HRESULT WINAPI VariantClear32(VARIANTARG* pvarg)
1277 HRESULT res = S_OK;
1278 TRACE(ole,"(%p),stub\n",pvarg);
1280 res = ValidateVariantType( pvarg->vt );
1281 if( res == S_OK )
1283 if( !( pvarg->vt & VT_BYREF ) )
1285 switch( pvarg->vt & VT_TYPEMASK )
1287 case( VT_BSTR ):
1288 SysFreeString32( pvarg->u.bstrVal );
1289 break;
1290 case( VT_DISPATCH ):
1291 break;
1292 case( VT_VARIANT ):
1293 break;
1294 case( VT_UNKNOWN ):
1295 break;
1296 case( VT_SAFEARRAY ):
1297 break;
1298 default:
1299 break;
1303 /* Set the fields to empty.
1305 pvarg->wReserved1 = 0;
1306 pvarg->wReserved2 = 0;
1307 pvarg->wReserved3 = 0;
1308 pvarg->vt = VT_EMPTY;
1311 return res;
1314 /******************************************************************************
1315 * VariantCopy32 [OLEAUT32.10]
1317 * Frees up the designation variant and makes a copy of the source.
1319 HRESULT WINAPI VariantCopy32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
1321 HRESULT res = S_OK;
1322 TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
1324 res = ValidateVariantType( pvargSrc->vt );
1325 /* If the pointer are to the same variant we don't need
1326 * to do anything.
1328 if( pvargDest != pvargSrc && res == S_OK )
1330 res = VariantClear32( pvargDest );
1332 if( res == S_OK )
1334 if( pvargSrc->vt & VT_BYREF )
1336 /* In the case of byreference we only need
1337 * to copy the pointer.
1339 pvargDest->u = pvargSrc->u;
1340 pvargDest->vt = pvargSrc->vt;
1342 else
1344 /* In the case of by value we need to
1345 * copy the actuall value. In the case of
1346 * VT_BSTR a copy of the string is made,
1347 * if VT_ARRAY the entire array is copied
1348 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1349 * called to increment the object's reference count.
1351 switch( pvargSrc->vt & VT_TYPEMASK )
1353 case( VT_BSTR ):
1354 pvargDest->u.bstrVal = SysAllocString32( pvargSrc->u.bstrVal );
1355 break;
1356 case( VT_DISPATCH ):
1357 break;
1358 case( VT_VARIANT ):
1359 break;
1360 case( VT_UNKNOWN ):
1361 break;
1362 case( VT_SAFEARRAY ):
1363 break;
1364 default:
1365 pvargDest->u = pvargSrc->u;
1366 break;
1368 pvargDest->vt = pvargSrc->vt;
1373 return res;
1377 /******************************************************************************
1378 * VariantCopyInd32 [OLEAUT32.11]
1380 * Frees up the destination variant and makes a copy of the source. If
1381 * the source is of type VT_BYREF it performs the necessary indirections.
1383 HRESULT WINAPI VariantCopyInd32(VARIANT* pvargDest, VARIANTARG* pvargSrc)
1385 HRESULT res = S_OK;
1386 TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
1388 res = ValidateVariantType( pvargSrc->vt );
1389 if( res != S_OK )
1390 return res;
1392 if( pvargSrc->vt & VT_BYREF )
1394 VARIANTARG varg;
1395 VariantInit32( &varg );
1396 /* handle the in place copy.
1398 if( pvargDest == pvargSrc )
1400 /* we will use a copy of the source instead.
1402 res = VariantCopy32( &varg, pvargSrc );
1403 pvargSrc = &varg;
1405 if( res == S_OK )
1407 res = VariantClear32( pvargDest );
1408 if( res == S_OK )
1410 /* In the case of by reference we need
1411 * to copy the date pointed to by the variant.
1413 /* Get the variant type.
1415 switch( pvargSrc->vt & VT_TYPEMASK )
1417 case( VT_BSTR ):
1418 pvargDest->u.bstrVal = SysAllocString32( *(pvargSrc->u.pbstrVal) );
1419 break;
1420 case( VT_DISPATCH ):
1421 break;
1422 case( VT_VARIANT ):
1424 /* Prevent from cycling. According to tests on
1425 * VariantCopyInd in Windows and the documentation
1426 * this API dereferences the inner Variants to only one depth.
1427 * If the inner Variant itself contains an
1428 * other inner variant the E_INVALIDARG error is
1429 * returned.
1431 if( pvargSrc->wReserved1 & PROCESSING_INNER_VARIANT )
1433 /* If we get here we are attempting to deference
1434 * an inner variant that that is itself contained
1435 * in an inner variant so report E_INVALIDARG error.
1437 res = E_INVALIDARG;
1439 else
1441 /* Set the processing inner variant flag.
1442 * We will set this flag in the inner variant
1443 * that will be passed to the VariantCopyInd function.
1445 (pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
1446 /* Dereference the inner variant.
1448 res = VariantCopyInd32( pvargDest, pvargSrc->u.pvarVal );
1451 break;
1452 case( VT_UNKNOWN ):
1453 break;
1454 case( VT_SAFEARRAY ):
1455 break;
1456 default:
1457 /* This is a by reference Variant which means that the union
1458 * part of the Variant contains a pointer to some data of
1459 * type "pvargSrc->vt & VT_TYPEMASK".
1460 * We will deference this data in a generic fashion using
1461 * the void pointer "Variant.u.byref".
1462 * We will copy this data into the union of the destination
1463 * Variant.
1465 memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
1466 break;
1468 pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
1471 /* this should not fail.
1473 VariantClear32( &varg );
1475 else
1477 res = VariantCopy32( pvargDest, pvargSrc );
1479 return res;
1482 /******************************************************************************
1483 * VariantChangeType32 [OLEAUT32.12]
1485 HRESULT WINAPI VariantChangeType32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
1486 USHORT wFlags, VARTYPE vt)
1488 return VariantChangeTypeEx32( pvargDest, pvargSrc, 0, wFlags, vt );
1491 /******************************************************************************
1492 * VariantChangeTypeEx32 [OLEAUT32.147]
1494 HRESULT WINAPI VariantChangeTypeEx32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
1495 LCID lcid, USHORT wFlags, VARTYPE vt)
1497 HRESULT res = S_OK;
1498 VARIANTARG varg;
1499 VariantInit32( &varg );
1501 TRACE(ole,"(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
1503 /* validate our source argument.
1505 res = ValidateVariantType( pvargSrc->vt );
1507 /* validate the vartype.
1509 if( res == S_OK )
1511 res = ValidateVt( vt );
1514 /* if we are doing an in-place conversion make a copy of the source.
1516 if( res == S_OK && pvargDest == pvargSrc )
1518 res = VariantCopy32( &varg, pvargSrc );
1519 pvargSrc = &varg;
1522 if( res == S_OK )
1524 /* free up the destination variant.
1526 res = VariantClear32( pvargDest );
1529 if( res == S_OK )
1531 if( pvargSrc->vt & VT_BYREF )
1533 /* Convert the source variant to a "byvalue" variant.
1535 VARIANTARG Variant;
1536 VariantInit32( &Variant );
1537 res = VariantCopyInd32( &Variant, pvargSrc );
1538 if( res == S_OK )
1540 res = Coerce( pvargDest, lcid, wFlags, &Variant, vt );
1541 /* this should not fail.
1543 VariantClear32( &Variant );
1547 else
1549 /* Use the current "byvalue" source variant.
1551 res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
1554 /* this should not fail.
1556 VariantClear32( &varg );
1558 return res;
1564 /******************************************************************************
1565 * VarUI1FromI232 [OLEAUT32.130]
1567 HRESULT WINAPI VarUI1FromI232(short sIn, BYTE* pbOut)
1569 TRACE( ole, "( %d, %p ), stub\n", sIn, pbOut );
1571 /* Check range of value.
1573 if( sIn < UI1_MIN || sIn > UI1_MAX )
1575 return DISP_E_OVERFLOW;
1578 *pbOut = (BYTE) sIn;
1580 return S_OK;
1583 /******************************************************************************
1584 * VarUI1FromI432 [OLEAUT32.131]
1586 HRESULT WINAPI VarUI1FromI432(LONG lIn, BYTE* pbOut)
1588 TRACE( ole, "( %ld, %p ), stub\n", lIn, pbOut );
1590 /* Check range of value.
1592 if( lIn < UI1_MIN || lIn > UI1_MAX )
1594 return DISP_E_OVERFLOW;
1597 *pbOut = (BYTE) lIn;
1599 return S_OK;
1603 /******************************************************************************
1604 * VarUI1FromR432 [OLEAUT32.132]
1606 HRESULT WINAPI VarUI1FromR432(FLOAT fltIn, BYTE* pbOut)
1608 TRACE( ole, "( %f, %p ), stub\n", fltIn, pbOut );
1610 /* Check range of value.
1612 fltIn = round( fltIn );
1613 if( fltIn < UI1_MIN || fltIn > UI1_MAX )
1615 return DISP_E_OVERFLOW;
1618 *pbOut = (BYTE) fltIn;
1620 return S_OK;
1623 /******************************************************************************
1624 * VarUI1FromR832 [OLEAUT32.133]
1626 HRESULT WINAPI VarUI1FromR832(double dblIn, BYTE* pbOut)
1628 TRACE( ole, "( %f, %p ), stub\n", dblIn, pbOut );
1630 /* Check range of value.
1632 dblIn = round( dblIn );
1633 if( dblIn < UI1_MIN || dblIn > UI1_MAX )
1635 return DISP_E_OVERFLOW;
1638 *pbOut = (BYTE) dblIn;
1640 return S_OK;
1643 /******************************************************************************
1644 * VarUI1FromDate32 [OLEAUT32.135]
1646 HRESULT WINAPI VarUI1FromDate32(DATE dateIn, BYTE* pbOut)
1648 TRACE( ole, "( %f, %p ), stub\n", dateIn, pbOut );
1650 /* Check range of value.
1652 dateIn = round( dateIn );
1653 if( dateIn < UI1_MIN || dateIn > UI1_MAX )
1655 return DISP_E_OVERFLOW;
1658 *pbOut = (BYTE) dateIn;
1660 return S_OK;
1663 /******************************************************************************
1664 * VarUI1FromBool32 [OLEAUT32.138]
1666 HRESULT WINAPI VarUI1FromBool32(VARIANT_BOOL boolIn, BYTE* pbOut)
1668 TRACE( ole, "( %d, %p ), stub\n", boolIn, pbOut );
1670 *pbOut = (BYTE) boolIn;
1672 return S_OK;
1675 /******************************************************************************
1676 * VarUI1FromI132 [OLEAUT32.237]
1678 HRESULT WINAPI VarUI1FromI132(CHAR cIn, BYTE* pbOut)
1680 TRACE( ole, "( %c, %p ), stub\n", cIn, pbOut );
1682 *pbOut = cIn;
1684 return S_OK;
1687 /******************************************************************************
1688 * VarUI1FromUI232 [OLEAUT32.238]
1690 HRESULT WINAPI VarUI1FromUI232(USHORT uiIn, BYTE* pbOut)
1692 TRACE( ole, "( %d, %p ), stub\n", uiIn, pbOut );
1694 /* Check range of value.
1696 if( uiIn > UI1_MAX )
1698 return DISP_E_OVERFLOW;
1701 *pbOut = (BYTE) uiIn;
1703 return S_OK;
1706 /******************************************************************************
1707 * VarUI1FromUI432 [OLEAUT32.239]
1709 HRESULT WINAPI VarUI1FromUI432(ULONG ulIn, BYTE* pbOut)
1711 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pbOut );
1713 /* Check range of value.
1715 if( ulIn > UI1_MAX )
1717 return DISP_E_OVERFLOW;
1720 *pbOut = (BYTE) ulIn;
1722 return S_OK;
1726 /******************************************************************************
1727 * VarUI1FromStr32 [OLEAUT32.54]
1729 HRESULT WINAPI VarUI1FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
1731 double dValue = 0.0;
1732 LPSTR pNewString = NULL;
1734 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, pbOut );
1736 /* Check if we have a valid argument
1738 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
1739 RemoveCharacterFromString( pNewString, "," );
1740 if( IsValidRealString( pNewString ) == FALSE )
1742 return DISP_E_TYPEMISMATCH;
1745 /* Convert the valid string to a floating point number.
1747 dValue = atof( pNewString );
1749 /* We don't need the string anymore so free it.
1751 HeapFree( GetProcessHeap(), 0 , pNewString );
1753 /* Check range of value.
1755 dValue = round( dValue );
1756 if( dValue < UI1_MIN || dValue > UI1_MAX )
1758 return DISP_E_OVERFLOW;
1761 *pbOut = (BYTE) dValue;
1763 return S_OK;
1766 /**********************************************************************
1767 * VarUI1FromCy32 [OLEAUT32.134]
1768 * Convert currency to unsigned char
1770 HRESULT WINAPI VarUI1FromCy32(CY cyIn, BYTE* pbOut) {
1771 double t = round((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
1773 if (t > UI1_MAX || t < UI1_MIN) return DISP_E_OVERFLOW;
1775 *pbOut = (BYTE)t;
1776 return S_OK;
1779 /******************************************************************************
1780 * VarI2FromUI132 [OLEAUT32.48]
1782 HRESULT WINAPI VarI2FromUI132(BYTE bIn, short* psOut)
1784 TRACE( ole, "( 0x%08x, %p ), stub\n", bIn, psOut );
1786 *psOut = (short) bIn;
1788 return S_OK;
1791 /******************************************************************************
1792 * VarI2FromI432 [OLEAUT32.49]
1794 HRESULT WINAPI VarI2FromI432(LONG lIn, short* psOut)
1796 TRACE( ole, "( %lx, %p ), stub\n", lIn, psOut );
1798 /* Check range of value.
1800 if( lIn < I2_MIN || lIn > I2_MAX )
1802 return DISP_E_OVERFLOW;
1805 *psOut = (short) lIn;
1807 return S_OK;
1810 /******************************************************************************
1811 * VarI2FromR432 [OLEAUT32.50]
1813 HRESULT WINAPI VarI2FromR432(FLOAT fltIn, short* psOut)
1815 TRACE( ole, "( %f, %p ), stub\n", fltIn, psOut );
1817 /* Check range of value.
1819 fltIn = round( fltIn );
1820 if( fltIn < I2_MIN || fltIn > I2_MAX )
1822 return DISP_E_OVERFLOW;
1825 *psOut = (short) fltIn;
1827 return S_OK;
1830 /******************************************************************************
1831 * VarI2FromR832 [OLEAUT32.51]
1833 HRESULT WINAPI VarI2FromR832(double dblIn, short* psOut)
1835 TRACE( ole, "( %f, %p ), stub\n", dblIn, psOut );
1837 /* Check range of value.
1839 dblIn = round( dblIn );
1840 if( dblIn < I2_MIN || dblIn > I2_MAX )
1842 return DISP_E_OVERFLOW;
1845 *psOut = (short) dblIn;
1847 return S_OK;
1850 /******************************************************************************
1851 * VarI2FromDate32 [OLEAUT32.53]
1853 HRESULT WINAPI VarI2FromDate32(DATE dateIn, short* psOut)
1855 TRACE( ole, "( %f, %p ), stub\n", dateIn, psOut );
1857 /* Check range of value.
1859 dateIn = round( dateIn );
1860 if( dateIn < I2_MIN || dateIn > I2_MAX )
1862 return DISP_E_OVERFLOW;
1865 *psOut = (short) dateIn;
1867 return S_OK;
1870 /******************************************************************************
1871 * VarI2FromBool32 [OLEAUT32.56]
1873 HRESULT WINAPI VarI2FromBool32(VARIANT_BOOL boolIn, short* psOut)
1875 TRACE( ole, "( %d, %p ), stub\n", boolIn, psOut );
1877 *psOut = (short) boolIn;
1879 return S_OK;
1882 /******************************************************************************
1883 * VarI2FromI132 [OLEAUT32.48]
1885 HRESULT WINAPI VarI2FromI132(CHAR cIn, short* psOut)
1887 TRACE( ole, "( %c, %p ), stub\n", cIn, psOut );
1889 *psOut = (short) cIn;
1891 return S_OK;
1894 /******************************************************************************
1895 * VarI2FromUI232 [OLEAUT32.206]
1897 HRESULT WINAPI VarI2FromUI232(USHORT uiIn, short* psOut)
1899 TRACE( ole, "( %d, %p ), stub\n", uiIn, psOut );
1901 /* Check range of value.
1903 if( uiIn > I2_MAX )
1905 return DISP_E_OVERFLOW;
1908 *psOut = (short) uiIn;
1910 return S_OK;
1913 /******************************************************************************
1914 * VarI2FromUI432 [OLEAUT32.49]
1916 HRESULT WINAPI VarI2FromUI432(ULONG ulIn, short* psOut)
1918 TRACE( ole, "( %lx, %p ), stub\n", ulIn, psOut );
1920 /* Check range of value.
1922 if( ulIn < I2_MIN || ulIn > I2_MAX )
1924 return DISP_E_OVERFLOW;
1927 *psOut = (short) ulIn;
1929 return S_OK;
1932 /******************************************************************************
1933 * VarI2FromStr32 [OLEAUT32.54]
1935 HRESULT WINAPI VarI2FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, short* psOut)
1937 double dValue = 0.0;
1938 LPSTR pNewString = NULL;
1940 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, psOut );
1942 /* Check if we have a valid argument
1944 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
1945 RemoveCharacterFromString( pNewString, "," );
1946 if( IsValidRealString( pNewString ) == FALSE )
1948 return DISP_E_TYPEMISMATCH;
1951 /* Convert the valid string to a floating point number.
1953 dValue = atof( pNewString );
1955 /* We don't need the string anymore so free it.
1957 HeapFree( GetProcessHeap(), 0, pNewString );
1959 /* Check range of value.
1961 dValue = round( dValue );
1962 if( dValue < I2_MIN || dValue > I2_MAX )
1964 return DISP_E_OVERFLOW;
1967 *psOut = (short) dValue;
1969 return S_OK;
1972 /**********************************************************************
1973 * VarI2FromCy32 [OLEAUT32.52]
1974 * Convert currency to signed short
1976 HRESULT WINAPI VarI2FromCy32(CY cyIn, short* psOut) {
1977 double t = round((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
1979 if (t > I2_MAX || t < I2_MIN) return DISP_E_OVERFLOW;
1981 *psOut = (SHORT)t;
1982 return S_OK;
1985 /******************************************************************************
1986 * VarI4FromUI132 [OLEAUT32.58]
1988 HRESULT WINAPI VarI4FromUI132(BYTE bIn, LONG* plOut)
1990 TRACE( ole, "( %X, %p ), stub\n", bIn, plOut );
1992 *plOut = (LONG) bIn;
1994 return S_OK;
1998 /******************************************************************************
1999 * VarI4FromR432 [OLEAUT32.60]
2001 HRESULT WINAPI VarI4FromR432(FLOAT fltIn, LONG* plOut)
2003 TRACE( ole, "( %f, %p ), stub\n", fltIn, plOut );
2005 /* Check range of value.
2007 fltIn = round( fltIn );
2008 if( fltIn < I4_MIN || fltIn > I4_MAX )
2010 return DISP_E_OVERFLOW;
2013 *plOut = (LONG) fltIn;
2015 return S_OK;
2018 /******************************************************************************
2019 * VarI4FromR832 [OLEAUT32.61]
2021 HRESULT WINAPI VarI4FromR832(double dblIn, LONG* plOut)
2023 TRACE( ole, "( %f, %p ), stub\n", dblIn, plOut );
2025 /* Check range of value.
2027 dblIn = round( dblIn );
2028 if( dblIn < I4_MIN || dblIn > I4_MAX )
2030 return DISP_E_OVERFLOW;
2033 *plOut = (LONG) dblIn;
2035 return S_OK;
2038 /******************************************************************************
2039 * VarI4FromDate32 [OLEAUT32.63]
2041 HRESULT WINAPI VarI4FromDate32(DATE dateIn, LONG* plOut)
2043 TRACE( ole, "( %f, %p ), stub\n", dateIn, plOut );
2045 /* Check range of value.
2047 dateIn = round( dateIn );
2048 if( dateIn < I4_MIN || dateIn > I4_MAX )
2050 return DISP_E_OVERFLOW;
2053 *plOut = (LONG) dateIn;
2055 return S_OK;
2058 /******************************************************************************
2059 * VarI4FromBool32 [OLEAUT32.66]
2061 HRESULT WINAPI VarI4FromBool32(VARIANT_BOOL boolIn, LONG* plOut)
2063 TRACE( ole, "( %d, %p ), stub\n", boolIn, plOut );
2065 *plOut = (LONG) boolIn;
2067 return S_OK;
2070 /******************************************************************************
2071 * VarI4FromI132 [OLEAUT32.209]
2073 HRESULT WINAPI VarI4FromI132(CHAR cIn, LONG* plOut)
2075 TRACE( ole, "( %c, %p ), stub\n", cIn, plOut );
2077 *plOut = (LONG) cIn;
2079 return S_OK;
2082 /******************************************************************************
2083 * VarI4FromUI232 [OLEAUT32.210]
2085 HRESULT WINAPI VarI4FromUI232(USHORT uiIn, LONG* plOut)
2087 TRACE( ole, "( %d, %p ), stub\n", uiIn, plOut );
2089 *plOut = (LONG) uiIn;
2091 return S_OK;
2094 /******************************************************************************
2095 * VarI4FromUI432 [OLEAUT32.211]
2097 HRESULT WINAPI VarI4FromUI432(ULONG ulIn, LONG* plOut)
2099 TRACE( ole, "( %lx, %p ), stub\n", ulIn, plOut );
2101 /* Check range of value.
2103 if( ulIn < I4_MIN || ulIn > I4_MAX )
2105 return DISP_E_OVERFLOW;
2108 *plOut = (LONG) ulIn;
2110 return S_OK;
2113 /******************************************************************************
2114 * VarI4FromI232 [OLEAUT32.59]
2116 HRESULT WINAPI VarI4FromI232(short sIn, LONG* plOut)
2118 TRACE( ole, "( %d, %p ), stub\n", sIn, plOut );
2120 *plOut = (LONG) sIn;
2122 return S_OK;
2125 /******************************************************************************
2126 * VarI4FromStr32 [OLEAUT32.64]
2128 HRESULT WINAPI VarI4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, LONG* plOut)
2130 double dValue = 0.0;
2131 LPSTR pNewString = NULL;
2133 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, plOut );
2135 /* Check if we have a valid argument
2137 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2138 RemoveCharacterFromString( pNewString, "," );
2139 if( IsValidRealString( pNewString ) == FALSE )
2141 return DISP_E_TYPEMISMATCH;
2144 /* Convert the valid string to a floating point number.
2146 dValue = atof( pNewString );
2148 /* We don't need the string anymore so free it.
2150 HeapFree( GetProcessHeap(), 0, pNewString );
2152 /* Check range of value.
2154 dValue = round( dValue );
2155 if( dValue < I4_MIN || dValue > I4_MAX )
2157 return DISP_E_OVERFLOW;
2160 *plOut = (LONG) dValue;
2162 return S_OK;
2165 /**********************************************************************
2166 * VarI4FromCy32 [OLEAUT32.62]
2167 * Convert currency to signed long
2169 HRESULT WINAPI VarI4FromCy32(CY cyIn, LONG* plOut) {
2170 double t = round((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
2172 if (t > I4_MAX || t < I4_MIN) return DISP_E_OVERFLOW;
2174 *plOut = (LONG)t;
2175 return S_OK;
2178 /******************************************************************************
2179 * VarR4FromUI132 [OLEAUT32.68]
2181 HRESULT WINAPI VarR4FromUI132(BYTE bIn, FLOAT* pfltOut)
2183 TRACE( ole, "( %X, %p ), stub\n", bIn, pfltOut );
2185 *pfltOut = (FLOAT) bIn;
2187 return S_OK;
2190 /******************************************************************************
2191 * VarR4FromI232 [OLEAUT32.69]
2193 HRESULT WINAPI VarR4FromI232(short sIn, FLOAT* pfltOut)
2195 TRACE( ole, "( %d, %p ), stub\n", sIn, pfltOut );
2197 *pfltOut = (FLOAT) sIn;
2199 return S_OK;
2202 /******************************************************************************
2203 * VarR4FromI432 [OLEAUT32.70]
2205 HRESULT WINAPI VarR4FromI432(LONG lIn, FLOAT* pfltOut)
2207 TRACE( ole, "( %lx, %p ), stub\n", lIn, pfltOut );
2209 *pfltOut = (FLOAT) lIn;
2211 return S_OK;
2214 /******************************************************************************
2215 * VarR4FromR832 [OLEAUT32.71]
2217 HRESULT WINAPI VarR4FromR832(double dblIn, FLOAT* pfltOut)
2219 TRACE( ole, "( %f, %p ), stub\n", dblIn, pfltOut );
2221 /* Check range of value.
2223 if( dblIn < -(FLT_MAX) || dblIn > FLT_MAX )
2225 return DISP_E_OVERFLOW;
2228 *pfltOut = (FLOAT) dblIn;
2230 return S_OK;
2233 /******************************************************************************
2234 * VarR4FromDate32 [OLEAUT32.73]
2236 HRESULT WINAPI VarR4FromDate32(DATE dateIn, FLOAT* pfltOut)
2238 TRACE( ole, "( %f, %p ), stub\n", dateIn, pfltOut );
2240 /* Check range of value.
2242 if( dateIn < -(FLT_MAX) || dateIn > FLT_MAX )
2244 return DISP_E_OVERFLOW;
2247 *pfltOut = (FLOAT) dateIn;
2249 return S_OK;
2252 /******************************************************************************
2253 * VarR4FromBool32 [OLEAUT32.76]
2255 HRESULT WINAPI VarR4FromBool32(VARIANT_BOOL boolIn, FLOAT* pfltOut)
2257 TRACE( ole, "( %d, %p ), stub\n", boolIn, pfltOut );
2259 *pfltOut = (FLOAT) boolIn;
2261 return S_OK;
2264 /******************************************************************************
2265 * VarR4FromI132 [OLEAUT32.213]
2267 HRESULT WINAPI VarR4FromI132(CHAR cIn, FLOAT* pfltOut)
2269 TRACE( ole, "( %c, %p ), stub\n", cIn, pfltOut );
2271 *pfltOut = (FLOAT) cIn;
2273 return S_OK;
2276 /******************************************************************************
2277 * VarR4FromUI232 [OLEAUT32.214]
2279 HRESULT WINAPI VarR4FromUI232(USHORT uiIn, FLOAT* pfltOut)
2281 TRACE( ole, "( %d, %p ), stub\n", uiIn, pfltOut );
2283 *pfltOut = (FLOAT) uiIn;
2285 return S_OK;
2288 /******************************************************************************
2289 * VarR4FromUI432 [OLEAUT32.215]
2291 HRESULT WINAPI VarR4FromUI432(ULONG ulIn, FLOAT* pfltOut)
2293 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pfltOut );
2295 *pfltOut = (FLOAT) ulIn;
2297 return S_OK;
2300 /******************************************************************************
2301 * VarR4FromStr32 [OLEAUT32.74]
2303 HRESULT WINAPI VarR4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, FLOAT* pfltOut)
2305 double dValue = 0.0;
2306 LPSTR pNewString = NULL;
2308 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pfltOut );
2310 /* Check if we have a valid argument
2312 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2313 RemoveCharacterFromString( pNewString, "," );
2314 if( IsValidRealString( pNewString ) == FALSE )
2316 return DISP_E_TYPEMISMATCH;
2319 /* Convert the valid string to a floating point number.
2321 dValue = atof( pNewString );
2323 /* We don't need the string anymore so free it.
2325 HeapFree( GetProcessHeap(), 0, pNewString );
2327 /* Check range of value.
2329 if( dValue < -(FLT_MAX) || dValue > FLT_MAX )
2331 return DISP_E_OVERFLOW;
2334 *pfltOut = (FLOAT) dValue;
2336 return S_OK;
2339 /**********************************************************************
2340 * VarR4FromCy32 [OLEAUT32.72]
2341 * Convert currency to float
2343 HRESULT WINAPI VarR4FromCy32(CY cyIn, FLOAT* pfltOut) {
2344 *pfltOut = (FLOAT)((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
2346 return S_OK;
2349 /******************************************************************************
2350 * VarR8FromUI132 [OLEAUT32.68]
2352 HRESULT WINAPI VarR8FromUI132(BYTE bIn, double* pdblOut)
2354 TRACE( ole, "( %d, %p ), stub\n", bIn, pdblOut );
2356 *pdblOut = (double) bIn;
2358 return S_OK;
2361 /******************************************************************************
2362 * VarR8FromI232 [OLEAUT32.69]
2364 HRESULT WINAPI VarR8FromI232(short sIn, double* pdblOut)
2366 TRACE( ole, "( %d, %p ), stub\n", sIn, pdblOut );
2368 *pdblOut = (double) sIn;
2370 return S_OK;
2373 /******************************************************************************
2374 * VarR8FromI432 [OLEAUT32.70]
2376 HRESULT WINAPI VarR8FromI432(LONG lIn, double* pdblOut)
2378 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdblOut );
2380 *pdblOut = (double) lIn;
2382 return S_OK;
2385 /******************************************************************************
2386 * VarR8FromR432 [OLEAUT32.81]
2388 HRESULT WINAPI VarR8FromR432(FLOAT fltIn, double* pdblOut)
2390 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdblOut );
2392 *pdblOut = (double) fltIn;
2394 return S_OK;
2397 /******************************************************************************
2398 * VarR8FromDate32 [OLEAUT32.83]
2400 HRESULT WINAPI VarR8FromDate32(DATE dateIn, double* pdblOut)
2402 TRACE( ole, "( %f, %p ), stub\n", dateIn, pdblOut );
2404 *pdblOut = (double) dateIn;
2406 return S_OK;
2409 /******************************************************************************
2410 * VarR8FromBool32 [OLEAUT32.86]
2412 HRESULT WINAPI VarR8FromBool32(VARIANT_BOOL boolIn, double* pdblOut)
2414 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdblOut );
2416 *pdblOut = (double) boolIn;
2418 return S_OK;
2421 /******************************************************************************
2422 * VarR8FromI132 [OLEAUT32.217]
2424 HRESULT WINAPI VarR8FromI132(CHAR cIn, double* pdblOut)
2426 TRACE( ole, "( %c, %p ), stub\n", cIn, pdblOut );
2428 *pdblOut = (double) cIn;
2430 return S_OK;
2433 /******************************************************************************
2434 * VarR8FromUI232 [OLEAUT32.218]
2436 HRESULT WINAPI VarR8FromUI232(USHORT uiIn, double* pdblOut)
2438 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdblOut );
2440 *pdblOut = (double) uiIn;
2442 return S_OK;
2445 /******************************************************************************
2446 * VarR8FromUI432 [OLEAUT32.219]
2448 HRESULT WINAPI VarR8FromUI432(ULONG ulIn, double* pdblOut)
2450 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdblOut );
2452 *pdblOut = (double) ulIn;
2454 return S_OK;
2457 /******************************************************************************
2458 * VarR8FromStr32 [OLEAUT32.84]
2460 HRESULT WINAPI VarR8FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, double* pdblOut)
2462 double dValue = 0.0;
2463 LPSTR pNewString = NULL;
2465 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pdblOut );
2467 /* Check if we have a valid argument
2469 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2470 RemoveCharacterFromString( pNewString, "," );
2471 if( IsValidRealString( pNewString ) == FALSE )
2473 return DISP_E_TYPEMISMATCH;
2476 /* Convert the valid string to a floating point number.
2478 dValue = atof( pNewString );
2480 /* We don't need the string anymore so free it.
2482 HeapFree( GetProcessHeap(), 0, pNewString );
2484 *pdblOut = dValue;
2486 return S_OK;
2489 /**********************************************************************
2490 * VarR8FromCy32 [OLEAUT32.82]
2491 * Convert currency to double
2493 HRESULT WINAPI VarR8FromCy32(CY cyIn, double* pdblOut) {
2494 *pdblOut = (double)((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
2496 return S_OK;
2499 /******************************************************************************
2500 * VarDateFromUI132 [OLEAUT32.]
2502 HRESULT WINAPI VarDateFromUI132(BYTE bIn, DATE* pdateOut)
2504 TRACE( ole, "( %d, %p ), stub\n", bIn, pdateOut );
2506 *pdateOut = (DATE) bIn;
2508 return S_OK;
2511 /******************************************************************************
2512 * VarDateFromI232 [OLEAUT32.222]
2514 HRESULT WINAPI VarDateFromI232(short sIn, DATE* pdateOut)
2516 TRACE( ole, "( %d, %p ), stub\n", sIn, pdateOut );
2518 *pdateOut = (DATE) sIn;
2520 return S_OK;
2523 /******************************************************************************
2524 * VarDateFromI432 [OLEAUT32.90]
2526 HRESULT WINAPI VarDateFromI432(LONG lIn, DATE* pdateOut)
2528 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdateOut );
2530 if( lIn < DATE_MIN || lIn > DATE_MAX )
2532 return DISP_E_OVERFLOW;
2535 *pdateOut = (DATE) lIn;
2537 return S_OK;
2540 /******************************************************************************
2541 * VarDateFromR432 [OLEAUT32.91]
2543 HRESULT WINAPI VarDateFromR432(FLOAT fltIn, DATE* pdateOut)
2545 unsigned long test = 0;
2547 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdateOut );
2549 test = (unsigned long) fltIn;
2550 if( test < DATE_MIN || test > DATE_MAX )
2552 return DISP_E_OVERFLOW;
2555 *pdateOut = (DATE) fltIn;
2557 return S_OK;
2560 /******************************************************************************
2561 * VarDateFromR832 [OLEAUT32.92]
2563 HRESULT WINAPI VarDateFromR832(double dblIn, DATE* pdateOut)
2565 unsigned long test = 0;
2567 TRACE( ole, "( %f, %p ), stub\n", dblIn, pdateOut );
2569 test = (unsigned long) dblIn;
2570 if( test < DATE_MIN || test > DATE_MAX )
2572 return DISP_E_OVERFLOW;
2575 *pdateOut = (DATE) dblIn;
2577 return S_OK;
2580 /******************************************************************************
2581 * VarDateFromStr32 [OLEAUT32.94]
2582 * The string representing the date is composed of two parts, a date and time.
2584 * The format of the time is has follows:
2585 * hh[:mm][:ss][AM|PM]
2586 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
2587 * of space and/or tab characters, which are ignored.
2589 * The formats for the date part are has follows:
2590 * mm/[dd/][yy]yy
2591 * [dd/]mm/[yy]yy
2592 * [yy]yy/mm/dd
2593 * January dd[,] [yy]yy
2594 * dd January [yy]yy
2595 * [yy]yy January dd
2596 * Whitespace can be inserted anywhere between these tokens.
2598 * The formats for the date and time string are has follows.
2599 * date[whitespace][time]
2600 * [time][whitespace]date
2602 * These are the only characters allowed in a string representing a date and time:
2603 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
2605 HRESULT WINAPI VarDateFromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut)
2607 HRESULT ret = S_OK;
2609 FIXME( ole, "( %p, %lx, %lx, %p ), stub\n", strIn, lcid, dwFlags, pdateOut );
2611 return ret;
2614 /******************************************************************************
2615 * VarDateFromI132 [OLEAUT32.221]
2617 HRESULT WINAPI VarDateFromI132(CHAR cIn, DATE* pdateOut)
2619 TRACE( ole, "( %c, %p ), stub\n", cIn, pdateOut );
2621 *pdateOut = (DATE) cIn;
2623 return S_OK;
2626 /******************************************************************************
2627 * VarDateFromUI232 [OLEAUT32.222]
2629 HRESULT WINAPI VarDateFromUI232(USHORT uiIn, DATE* pdateOut)
2631 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdateOut );
2633 if( uiIn > DATE_MAX )
2635 return DISP_E_OVERFLOW;
2638 *pdateOut = (DATE) uiIn;
2640 return S_OK;
2643 /******************************************************************************
2644 * VarDateFromUI432 [OLEAUT32.223]
2646 HRESULT WINAPI VarDateFromUI432(ULONG ulIn, DATE* pdateOut)
2648 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdateOut );
2650 if( ulIn < DATE_MIN || ulIn > DATE_MAX )
2652 return DISP_E_OVERFLOW;
2655 *pdateOut = (DATE) ulIn;
2657 return S_OK;
2660 /******************************************************************************
2661 * VarDateFromBool32 [OLEAUT32.96]
2663 HRESULT WINAPI VarDateFromBool32(VARIANT_BOOL boolIn, DATE* pdateOut)
2665 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdateOut );
2667 *pdateOut = (DATE) boolIn;
2669 return S_OK;
2672 /**********************************************************************
2673 * VarDateFromCy32 [OLEAUT32.93]
2674 * Convert currency to date
2676 HRESULT WINAPI VarDateFromCy32(CY cyIn, DATE* pdateOut) {
2677 *pdateOut = (DATE)((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
2679 if (*pdateOut > DATE_MAX || *pdateOut < DATE_MIN) return DISP_E_TYPEMISMATCH;
2680 return S_OK;
2683 /******************************************************************************
2684 * VarBstrFromUI132 [OLEAUT32.108]
2686 HRESULT WINAPI VarBstrFromUI132(BYTE bVal, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2688 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", bVal, lcid, dwFlags, pbstrOut );
2689 sprintf( pBuffer, "%d", bVal );
2691 *pbstrOut = StringDupAtoBstr( pBuffer );
2693 return S_OK;
2696 /******************************************************************************
2697 * VarBstrFromI232 [OLEAUT32.109]
2699 HRESULT WINAPI VarBstrFromI232(short iVal, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2701 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", iVal, lcid, dwFlags, pbstrOut );
2702 sprintf( pBuffer, "%d", iVal );
2703 *pbstrOut = StringDupAtoBstr( pBuffer );
2705 return S_OK;
2708 /******************************************************************************
2709 * VarBstrFromI432 [OLEAUT32.110]
2711 HRESULT WINAPI VarBstrFromI432(LONG lIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2713 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", lIn, lcid, dwFlags, pbstrOut );
2715 sprintf( pBuffer, "%ld", lIn );
2716 *pbstrOut = StringDupAtoBstr( pBuffer );
2718 return S_OK;
2721 /******************************************************************************
2722 * VarBstrFromR432 [OLEAUT32.111]
2724 HRESULT WINAPI VarBstrFromR432(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2726 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", fltIn, lcid, dwFlags, pbstrOut );
2728 sprintf( pBuffer, "%.7g", fltIn );
2729 *pbstrOut = StringDupAtoBstr( pBuffer );
2731 return S_OK;
2734 /******************************************************************************
2735 * VarBstrFromR832 [OLEAUT32.112]
2737 HRESULT WINAPI VarBstrFromR832(double dblIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2739 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", dblIn, lcid, dwFlags, pbstrOut );
2741 sprintf( pBuffer, "%.15g", dblIn );
2742 *pbstrOut = StringDupAtoBstr( pBuffer );
2744 return S_OK;
2747 /******************************************************************************
2748 * VarBstrFromDate32 [OLEAUT32.114]
2750 * The date is implemented using an 8 byte floating-point number.
2751 * Days are represented by whole numbers increments starting with 0.00 has
2752 * being December 30 1899, midnight.
2753 * The hours are expressed as the fractional part of the number.
2754 * December 30 1899 at midnight = 0.00
2755 * January 1 1900 at midnight = 2.00
2756 * January 4 1900 at 6 AM = 5.25
2757 * January 4 1900 at noon = 5.50
2758 * December 29 1899 at midnight = -1.00
2759 * December 18 1899 at midnight = -12.00
2760 * December 18 1899 at 6AM = -12.25
2761 * December 18 1899 at 6PM = -12.75
2762 * December 19 1899 at midnight = -11.00
2763 * The tm structure is as follows:
2764 * struct tm {
2765 * int tm_sec; seconds after the minute - [0,59]
2766 * int tm_min; minutes after the hour - [0,59]
2767 * int tm_hour; hours since midnight - [0,23]
2768 * int tm_mday; day of the month - [1,31]
2769 * int tm_mon; months since January - [0,11]
2770 * int tm_year; years since 1900
2771 * int tm_wday; days since Sunday - [0,6]
2772 * int tm_yday; days since January 1 - [0,365]
2773 * int tm_isdst; daylight savings time flag
2774 * };
2776 HRESULT WINAPI VarBstrFromDate32(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2778 /* If the date is not after the 1900 return an error because
2779 * the tm structure does not allow such dates.
2781 if( dateIn >= 1.0 )
2783 double decimalPart = 0.0;
2784 double wholePart = 0.0;
2785 struct tm TM = {0,0,0,0,0,0,0,0,0};
2787 wholePart = (double) (long) dateIn;
2788 decimalPart = fmod( dateIn, wholePart );
2790 if( !(lcid & VAR_TIMEVALUEONLY) )
2792 int nDay = 0;
2793 int leapYear = 0;
2794 /* find in what year the day in the "wholePart" falls into.
2796 TM.tm_year = (int) ( wholePart / 365.25 );
2797 /* determine if this is a leap year.
2799 if( ( TM.tm_year % 4 ) == 0 )
2800 leapYear = 1;
2801 /* find what day of that year does the "wholePart" corresponds to.
2802 * the day is [1-366]
2804 nDay = (int) ( wholePart - ( TM.tm_year * 365.25 ) );
2805 TM.tm_yday = nDay - 1;
2806 /* find which mount this day corresponds to.
2808 if( nDay <= 31 )
2810 TM.tm_mday = nDay;
2811 TM.tm_mon = 0;
2813 else if( nDay <= ( 59 + leapYear ) )
2815 TM.tm_mday = nDay - 31;
2816 TM.tm_mon = 1;
2818 else if( nDay <= ( 90 + leapYear ) )
2820 TM.tm_mday = nDay - ( 59 + leapYear );
2821 TM.tm_mon = 2;
2823 else if( nDay <= ( 120 + leapYear ) )
2825 TM.tm_mday = nDay - ( 90 + leapYear );
2826 TM.tm_mon = 3;
2828 else if( nDay <= ( 151 + leapYear ) )
2830 TM.tm_mday = nDay - ( 120 + leapYear );
2831 TM.tm_mon = 4;
2833 else if( nDay <= ( 181 + leapYear ) )
2835 TM.tm_mday = nDay - ( 151 + leapYear );
2836 TM.tm_mon = 5;
2838 else if( nDay <= ( 212 + leapYear ) )
2840 TM.tm_mday = nDay - ( 181 + leapYear );
2841 TM.tm_mon = 6;
2843 else if( nDay <= ( 243 + leapYear ) )
2845 TM.tm_mday = nDay - ( 212 + leapYear );
2846 TM.tm_mon = 7;
2848 else if( nDay <= ( 273 + leapYear ) )
2850 TM.tm_mday = nDay - ( 243 + leapYear );
2851 TM.tm_mon = 8;
2853 else if( nDay <= ( 304 + leapYear ) )
2855 TM.tm_mday = nDay - ( 273 + leapYear );
2856 TM.tm_mon = 9;
2858 else if( nDay <= ( 334 + leapYear ) )
2860 TM.tm_mday = nDay - ( 304 + leapYear );
2861 TM.tm_mon = 10;
2863 else if( nDay <= ( 365 + leapYear ) )
2865 TM.tm_mday = nDay - ( 334 + leapYear );
2866 TM.tm_mon = 11;
2869 if( !(lcid & VAR_DATEVALUEONLY) )
2871 /* find the number of seconds in this day.
2872 * fractional part times, hours, minutes, seconds.
2874 TM.tm_hour = (int) ( decimalPart * 24 );
2875 TM.tm_min = (int) ( ( ( decimalPart * 24 ) - TM.tm_hour ) * 60 );
2876 TM.tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( TM.tm_hour * 60 ) - TM.tm_min ) * 60 );
2879 if( lcid & VAR_DATEVALUEONLY )
2880 strftime( pBuffer, BUFFER_MAX, "%x", &TM );
2881 else if( lcid & VAR_TIMEVALUEONLY )
2882 strftime( pBuffer, BUFFER_MAX, "%X", &TM );
2883 else
2884 strftime( pBuffer, 100, "%x %X", &TM );
2886 *pbstrOut = StringDupAtoBstr( pBuffer );
2888 else
2890 FIXME( ole, "( %f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
2891 return E_INVALIDARG;
2894 return S_OK;
2897 /******************************************************************************
2898 * VarBstrFromBool32 [OLEAUT32.116]
2900 HRESULT WINAPI VarBstrFromBool32(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2902 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", boolIn, lcid, dwFlags, pbstrOut );
2904 if( boolIn == VARIANT_FALSE )
2906 sprintf( pBuffer, "False" );
2908 else
2910 sprintf( pBuffer, "True" );
2913 *pbstrOut = StringDupAtoBstr( pBuffer );
2915 return S_OK;
2918 /******************************************************************************
2919 * VarBstrFromI132 [OLEAUT32.229]
2921 HRESULT WINAPI VarBstrFromI132(CHAR cIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2923 TRACE( ole, "( %c, %ld, %ld, %p ), stub\n", cIn, lcid, dwFlags, pbstrOut );
2924 sprintf( pBuffer, "%d", cIn );
2925 *pbstrOut = StringDupAtoBstr( pBuffer );
2927 return S_OK;
2930 /******************************************************************************
2931 * VarBstrFromUI232 [OLEAUT32.230]
2933 HRESULT WINAPI VarBstrFromUI232(USHORT uiIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2935 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", uiIn, lcid, dwFlags, pbstrOut );
2936 sprintf( pBuffer, "%d", uiIn );
2937 *pbstrOut = StringDupAtoBstr( pBuffer );
2939 return S_OK;
2942 /******************************************************************************
2943 * VarBstrFromUI432 [OLEAUT32.231]
2945 HRESULT WINAPI VarBstrFromUI432(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2947 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", ulIn, lcid, dwFlags, pbstrOut );
2948 sprintf( pBuffer, "%ld", ulIn );
2949 *pbstrOut = StringDupAtoBstr( pBuffer );
2951 return S_OK;
2954 /******************************************************************************
2955 * VarBoolFromUI132 [OLEAUT32.118]
2957 HRESULT WINAPI VarBoolFromUI132(BYTE bIn, VARIANT_BOOL* pboolOut)
2959 TRACE( ole, "( %d, %p ), stub\n", bIn, pboolOut );
2961 if( bIn == 0 )
2963 *pboolOut = VARIANT_FALSE;
2965 else
2967 *pboolOut = VARIANT_TRUE;
2970 return S_OK;
2973 /******************************************************************************
2974 * VarBoolFromI232 [OLEAUT32.119]
2976 HRESULT WINAPI VarBoolFromI232(short sIn, VARIANT_BOOL* pboolOut)
2978 TRACE( ole, "( %d, %p ), stub\n", sIn, pboolOut );
2980 if( sIn == 0 )
2982 *pboolOut = VARIANT_FALSE;
2984 else
2986 *pboolOut = VARIANT_TRUE;
2989 return S_OK;
2992 /******************************************************************************
2993 * VarBoolFromI432 [OLEAUT32.120]
2995 HRESULT WINAPI VarBoolFromI432(LONG lIn, VARIANT_BOOL* pboolOut)
2997 TRACE( ole, "( %ld, %p ), stub\n", lIn, pboolOut );
2999 if( lIn == 0 )
3001 *pboolOut = VARIANT_FALSE;
3003 else
3005 *pboolOut = VARIANT_TRUE;
3008 return S_OK;
3011 /******************************************************************************
3012 * VarBoolFromR432 [OLEAUT32.121]
3014 HRESULT WINAPI VarBoolFromR432(FLOAT fltIn, VARIANT_BOOL* pboolOut)
3016 TRACE( ole, "( %f, %p ), stub\n", fltIn, pboolOut );
3018 if( fltIn == 0.0 )
3020 *pboolOut = VARIANT_FALSE;
3022 else
3024 *pboolOut = VARIANT_TRUE;
3027 return S_OK;
3030 /******************************************************************************
3031 * VarBoolFromR832 [OLEAUT32.122]
3033 HRESULT WINAPI VarBoolFromR832(double dblIn, VARIANT_BOOL* pboolOut)
3035 TRACE( ole, "( %f, %p ), stub\n", dblIn, pboolOut );
3037 if( dblIn == 0.0 )
3039 *pboolOut = VARIANT_FALSE;
3041 else
3043 *pboolOut = VARIANT_TRUE;
3046 return S_OK;
3049 /******************************************************************************
3050 * VarBoolFromDate32 [OLEAUT32.123]
3052 HRESULT WINAPI VarBoolFromDate32(DATE dateIn, VARIANT_BOOL* pboolOut)
3054 TRACE( ole, "( %f, %p ), stub\n", dateIn, pboolOut );
3056 if( dateIn == 0.0 )
3058 *pboolOut = VARIANT_FALSE;
3060 else
3062 *pboolOut = VARIANT_TRUE;
3065 return S_OK;
3068 /******************************************************************************
3069 * VarBoolFromStr32 [OLEAUT32.125]
3071 HRESULT WINAPI VarBoolFromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL* pboolOut)
3073 HRESULT ret = S_OK;
3074 char* pNewString = NULL;
3076 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pboolOut );
3078 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3080 if( pNewString == NULL || strlen( pNewString ) == 0 )
3082 ret = DISP_E_TYPEMISMATCH;
3085 if( ret == S_OK )
3087 if( strncasecmp( pNewString, "True", strlen( pNewString ) ) == 0 )
3089 *pboolOut = VARIANT_TRUE;
3091 else if( strncasecmp( pNewString, "False", strlen( pNewString ) ) == 0 )
3093 *pboolOut = VARIANT_FALSE;
3095 else
3097 /* Try converting the string to a floating point number.
3099 double dValue = 0.0;
3100 HRESULT res = VarR8FromStr32( strIn, lcid, dwFlags, &dValue );
3101 if( res != S_OK )
3103 ret = DISP_E_TYPEMISMATCH;
3105 else if( dValue == 0.0 )
3107 *pboolOut = VARIANT_FALSE;
3109 else
3111 *pboolOut = VARIANT_TRUE;
3116 HeapFree( GetProcessHeap(), 0, pNewString );
3118 return ret;
3121 /******************************************************************************
3122 * VarBoolFromI132 [OLEAUT32.233]
3124 HRESULT WINAPI VarBoolFromI132(CHAR cIn, VARIANT_BOOL* pboolOut)
3126 TRACE( ole, "( %c, %p ), stub\n", cIn, pboolOut );
3128 if( cIn == 0 )
3130 *pboolOut = VARIANT_FALSE;
3132 else
3134 *pboolOut = VARIANT_TRUE;
3137 return S_OK;
3140 /******************************************************************************
3141 * VarBoolFromUI232 [OLEAUT32.234]
3143 HRESULT WINAPI VarBoolFromUI232(USHORT uiIn, VARIANT_BOOL* pboolOut)
3145 TRACE( ole, "( %d, %p ), stub\n", uiIn, pboolOut );
3147 if( uiIn == 0 )
3149 *pboolOut = VARIANT_FALSE;
3151 else
3153 *pboolOut = VARIANT_TRUE;
3156 return S_OK;
3159 /******************************************************************************
3160 * VarBoolFromUI432 [OLEAUT32.235]
3162 HRESULT WINAPI VarBoolFromUI432(ULONG ulIn, VARIANT_BOOL* pboolOut)
3164 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pboolOut );
3166 if( ulIn == 0 )
3168 *pboolOut = VARIANT_FALSE;
3170 else
3172 *pboolOut = VARIANT_TRUE;
3175 return S_OK;
3178 /**********************************************************************
3179 * VarBoolFromCy32 [OLEAUT32.124]
3180 * Convert currency to boolean
3182 HRESULT WINAPI VarBoolFromCy32(CY cyIn, VARIANT_BOOL* pboolOut) {
3183 if (cyIn.u.Hi || cyIn.u.Lo) *pboolOut = -1;
3184 else *pboolOut = 0;
3186 return S_OK;
3189 /******************************************************************************
3190 * VarI1FromUI132 [OLEAUT32.244]
3192 HRESULT WINAPI VarI1FromUI132(BYTE bIn, CHAR* pcOut)
3194 TRACE( ole, "( %d, %p ), stub\n", bIn, pcOut );
3196 /* Check range of value.
3198 if( bIn > CHAR_MAX )
3200 return DISP_E_OVERFLOW;
3203 *pcOut = (CHAR) bIn;
3205 return S_OK;
3208 /******************************************************************************
3209 * VarI1FromI232 [OLEAUT32.245]
3211 HRESULT WINAPI VarI1FromI232(short uiIn, CHAR* pcOut)
3213 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3215 if( uiIn > CHAR_MAX )
3217 return DISP_E_OVERFLOW;
3220 *pcOut = (CHAR) uiIn;
3222 return S_OK;
3225 /******************************************************************************
3226 * VarI1FromI432 [OLEAUT32.246]
3228 HRESULT WINAPI VarI1FromI432(LONG lIn, CHAR* pcOut)
3230 TRACE( ole, "( %ld, %p ), stub\n", lIn, pcOut );
3232 if( lIn < CHAR_MIN || lIn > CHAR_MAX )
3234 return DISP_E_OVERFLOW;
3237 *pcOut = (CHAR) lIn;
3239 return S_OK;
3242 /******************************************************************************
3243 * VarI1FromR432 [OLEAUT32.247]
3245 HRESULT WINAPI VarI1FromR432(FLOAT fltIn, CHAR* pcOut)
3247 TRACE( ole, "( %f, %p ), stub\n", fltIn, pcOut );
3249 fltIn = round( fltIn );
3250 if( fltIn < CHAR_MIN || fltIn > CHAR_MAX )
3252 return DISP_E_OVERFLOW;
3255 *pcOut = (CHAR) fltIn;
3257 return S_OK;
3260 /******************************************************************************
3261 * VarI1FromR832 [OLEAUT32.248]
3263 HRESULT WINAPI VarI1FromR832(double dblIn, CHAR* pcOut)
3265 TRACE( ole, "( %f, %p ), stub\n", dblIn, pcOut );
3267 dblIn = round( dblIn );
3268 if( dblIn < CHAR_MIN || dblIn > CHAR_MAX )
3270 return DISP_E_OVERFLOW;
3273 *pcOut = (CHAR) dblIn;
3275 return S_OK;
3278 /******************************************************************************
3279 * VarI1FromDate32 [OLEAUT32.249]
3281 HRESULT WINAPI VarI1FromDate32(DATE dateIn, CHAR* pcOut)
3283 TRACE( ole, "( %f, %p ), stub\n", dateIn, pcOut );
3285 dateIn = round( dateIn );
3286 if( dateIn < CHAR_MIN || dateIn > CHAR_MAX )
3288 return DISP_E_OVERFLOW;
3291 *pcOut = (CHAR) dateIn;
3293 return S_OK;
3296 /******************************************************************************
3297 * VarI1FromStr32 [OLEAUT32.251]
3299 HRESULT WINAPI VarI1FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, CHAR* pcOut)
3301 double dValue = 0.0;
3302 LPSTR pNewString = NULL;
3304 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pcOut );
3306 /* Check if we have a valid argument
3308 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3309 RemoveCharacterFromString( pNewString, "," );
3310 if( IsValidRealString( pNewString ) == FALSE )
3312 return DISP_E_TYPEMISMATCH;
3315 /* Convert the valid string to a floating point number.
3317 dValue = atof( pNewString );
3319 /* We don't need the string anymore so free it.
3321 HeapFree( GetProcessHeap(), 0, pNewString );
3323 /* Check range of value.
3325 dValue = round( dValue );
3326 if( dValue < CHAR_MIN || dValue > CHAR_MAX )
3328 return DISP_E_OVERFLOW;
3331 *pcOut = (CHAR) dValue;
3333 return S_OK;
3336 /******************************************************************************
3337 * VarI1FromBool32 [OLEAUT32.253]
3339 HRESULT WINAPI VarI1FromBool32(VARIANT_BOOL boolIn, CHAR* pcOut)
3341 TRACE( ole, "( %d, %p ), stub\n", boolIn, pcOut );
3343 *pcOut = (CHAR) boolIn;
3345 return S_OK;
3348 /******************************************************************************
3349 * VarI1FromUI232 [OLEAUT32.254]
3351 HRESULT WINAPI VarI1FromUI232(USHORT uiIn, CHAR* pcOut)
3353 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3355 if( uiIn > CHAR_MAX )
3357 return DISP_E_OVERFLOW;
3360 *pcOut = (CHAR) uiIn;
3362 return S_OK;
3365 /******************************************************************************
3366 * VarI1FromUI432 [OLEAUT32.255]
3368 HRESULT WINAPI VarI1FromUI432(ULONG ulIn, CHAR* pcOut)
3370 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pcOut );
3372 if( ulIn > CHAR_MAX )
3374 return DISP_E_OVERFLOW;
3377 *pcOut = (CHAR) ulIn;
3379 return S_OK;
3382 /**********************************************************************
3383 * VarI1FromCy32 [OLEAUT32.250]
3384 * Convert currency to signed char
3386 HRESULT WINAPI VarI1FromCy32(CY cyIn, CHAR* pcOut) {
3387 double t = round((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
3389 if (t > CHAR_MAX || t < CHAR_MIN) return DISP_E_OVERFLOW;
3391 *pcOut = (CHAR)t;
3392 return S_OK;
3395 /******************************************************************************
3396 * VarUI2FromUI132 [OLEAUT32.257]
3398 HRESULT WINAPI VarUI2FromUI132(BYTE bIn, USHORT* puiOut)
3400 TRACE( ole, "( %d, %p ), stub\n", bIn, puiOut );
3402 *puiOut = (USHORT) bIn;
3404 return S_OK;
3407 /******************************************************************************
3408 * VarUI2FromI232 [OLEAUT32.258]
3410 HRESULT WINAPI VarUI2FromI232(short uiIn, USHORT* puiOut)
3412 TRACE( ole, "( %d, %p ), stub\n", uiIn, puiOut );
3414 if( uiIn < UI2_MIN )
3416 return DISP_E_OVERFLOW;
3419 *puiOut = (USHORT) uiIn;
3421 return S_OK;
3424 /******************************************************************************
3425 * VarUI2FromI432 [OLEAUT32.259]
3427 HRESULT WINAPI VarUI2FromI432(LONG lIn, USHORT* puiOut)
3429 TRACE( ole, "( %ld, %p ), stub\n", lIn, puiOut );
3431 if( lIn < UI2_MIN || lIn > UI2_MAX )
3433 return DISP_E_OVERFLOW;
3436 *puiOut = (USHORT) lIn;
3438 return S_OK;
3441 /******************************************************************************
3442 * VarUI2FromR432 [OLEAUT32.260]
3444 HRESULT WINAPI VarUI2FromR432(FLOAT fltIn, USHORT* puiOut)
3446 TRACE( ole, "( %f, %p ), stub\n", fltIn, puiOut );
3448 fltIn = round( fltIn );
3449 if( fltIn < UI2_MIN || fltIn > UI2_MAX )
3451 return DISP_E_OVERFLOW;
3454 *puiOut = (USHORT) fltIn;
3456 return S_OK;
3459 /******************************************************************************
3460 * VarUI2FromR832 [OLEAUT32.261]
3462 HRESULT WINAPI VarUI2FromR832(double dblIn, USHORT* puiOut)
3464 TRACE( ole, "( %f, %p ), stub\n", dblIn, puiOut );
3466 dblIn = round( dblIn );
3467 if( dblIn < UI2_MIN || dblIn > UI2_MAX )
3469 return DISP_E_OVERFLOW;
3472 *puiOut = (USHORT) dblIn;
3474 return S_OK;
3477 /******************************************************************************
3478 * VarUI2FromDate32 [OLEAUT32.262]
3480 HRESULT WINAPI VarUI2FromDate32(DATE dateIn, USHORT* puiOut)
3482 TRACE( ole, "( %f, %p ), stub\n", dateIn, puiOut );
3484 dateIn = round( dateIn );
3485 if( dateIn < UI2_MIN || dateIn > UI2_MAX )
3487 return DISP_E_OVERFLOW;
3490 *puiOut = (USHORT) dateIn;
3492 return S_OK;
3495 /******************************************************************************
3496 * VarUI2FromStr32 [OLEAUT32.264]
3498 HRESULT WINAPI VarUI2FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, USHORT* puiOut)
3500 double dValue = 0.0;
3501 LPSTR pNewString = NULL;
3503 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, puiOut );
3505 /* Check if we have a valid argument
3507 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3508 RemoveCharacterFromString( pNewString, "," );
3509 if( IsValidRealString( pNewString ) == FALSE )
3511 return DISP_E_TYPEMISMATCH;
3514 /* Convert the valid string to a floating point number.
3516 dValue = atof( pNewString );
3518 /* We don't need the string anymore so free it.
3520 HeapFree( GetProcessHeap(), 0, pNewString );
3522 /* Check range of value.
3524 dValue = round( dValue );
3525 if( dValue < UI2_MIN || dValue > UI2_MAX )
3527 return DISP_E_OVERFLOW;
3530 *puiOut = (USHORT) dValue;
3532 return S_OK;
3535 /******************************************************************************
3536 * VarUI2FromBool32 [OLEAUT32.266]
3538 HRESULT WINAPI VarUI2FromBool32(VARIANT_BOOL boolIn, USHORT* puiOut)
3540 TRACE( ole, "( %d, %p ), stub\n", boolIn, puiOut );
3542 *puiOut = (USHORT) boolIn;
3544 return S_OK;
3547 /******************************************************************************
3548 * VarUI2FromI132 [OLEAUT32.267]
3550 HRESULT WINAPI VarUI2FromI132(CHAR cIn, USHORT* puiOut)
3552 TRACE( ole, "( %c, %p ), stub\n", cIn, puiOut );
3554 *puiOut = (USHORT) cIn;
3556 return S_OK;
3559 /******************************************************************************
3560 * VarUI2FromUI432 [OLEAUT32.268]
3562 HRESULT WINAPI VarUI2FromUI432(ULONG ulIn, USHORT* puiOut)
3564 TRACE( ole, "( %ld, %p ), stub\n", ulIn, puiOut );
3566 if( ulIn < UI2_MIN || ulIn > UI2_MAX )
3568 return DISP_E_OVERFLOW;
3571 *puiOut = (USHORT) ulIn;
3573 return S_OK;
3576 /******************************************************************************
3577 * VarUI4FromStr32 [OLEAUT32.277]
3579 HRESULT WINAPI VarUI4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, ULONG* pulOut)
3581 double dValue = 0.0;
3582 LPSTR pNewString = NULL;
3584 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pulOut );
3586 /* Check if we have a valid argument
3588 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3589 RemoveCharacterFromString( pNewString, "," );
3590 if( IsValidRealString( pNewString ) == FALSE )
3592 return DISP_E_TYPEMISMATCH;
3595 /* Convert the valid string to a floating point number.
3597 dValue = atof( pNewString );
3599 /* We don't need the string anymore so free it.
3601 HeapFree( GetProcessHeap(), 0, pNewString );
3603 /* Check range of value.
3605 dValue = round( dValue );
3606 if( dValue < UI4_MIN || dValue > UI4_MAX )
3608 return DISP_E_OVERFLOW;
3611 *pulOut = (ULONG) dValue;
3613 return S_OK;
3616 /**********************************************************************
3617 * VarUI2FromCy32 [OLEAUT32.263]
3618 * Convert currency to unsigned short
3620 HRESULT WINAPI VarUI2FromCy32(CY cyIn, USHORT* pusOut) {
3621 double t = round((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
3623 if (t > UI2_MAX || t < UI2_MIN) return DISP_E_OVERFLOW;
3625 *pusOut = (USHORT)t;
3627 return S_OK;
3630 /******************************************************************************
3631 * VarUI4FromUI132 [OLEAUT32.270]
3633 HRESULT WINAPI VarUI4FromUI132(BYTE bIn, ULONG* pulOut)
3635 TRACE( ole, "( %d, %p ), stub\n", bIn, pulOut );
3637 *pulOut = (USHORT) bIn;
3639 return S_OK;
3642 /******************************************************************************
3643 * VarUI4FromI232 [OLEAUT32.271]
3645 HRESULT WINAPI VarUI4FromI232(short uiIn, ULONG* pulOut)
3647 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
3649 if( uiIn < UI4_MIN )
3651 return DISP_E_OVERFLOW;
3654 *pulOut = (ULONG) uiIn;
3656 return S_OK;
3659 /******************************************************************************
3660 * VarUI4FromI432 [OLEAUT32.272]
3662 HRESULT WINAPI VarUI4FromI432(LONG lIn, ULONG* pulOut)
3664 TRACE( ole, "( %ld, %p ), stub\n", lIn, pulOut );
3666 if( lIn < UI4_MIN )
3668 return DISP_E_OVERFLOW;
3671 *pulOut = (ULONG) lIn;
3673 return S_OK;
3676 /******************************************************************************
3677 * VarUI4FromR432 [OLEAUT32.273]
3679 HRESULT WINAPI VarUI4FromR432(FLOAT fltIn, ULONG* pulOut)
3681 fltIn = round( fltIn );
3682 if( fltIn < UI4_MIN || fltIn > UI4_MAX )
3684 return DISP_E_OVERFLOW;
3687 *pulOut = (ULONG) fltIn;
3689 return S_OK;
3692 /******************************************************************************
3693 * VarUI4FromR832 [OLEAUT32.274]
3695 HRESULT WINAPI VarUI4FromR832(double dblIn, ULONG* pulOut)
3697 TRACE( ole, "( %f, %p ), stub\n", dblIn, pulOut );
3699 dblIn = round( dblIn );
3700 if( dblIn < UI4_MIN || dblIn > UI4_MAX )
3702 return DISP_E_OVERFLOW;
3705 *pulOut = (ULONG) dblIn;
3707 return S_OK;
3710 /******************************************************************************
3711 * VarUI4FromDate32 [OLEAUT32.275]
3713 HRESULT WINAPI VarUI4FromDate32(DATE dateIn, ULONG* pulOut)
3715 TRACE( ole, "( %f, %p ), stub\n", dateIn, pulOut );
3717 dateIn = round( dateIn );
3718 if( dateIn < UI4_MIN || dateIn > UI4_MAX )
3720 return DISP_E_OVERFLOW;
3723 *pulOut = (ULONG) dateIn;
3725 return S_OK;
3728 /******************************************************************************
3729 * VarUI4FromBool32 [OLEAUT32.279]
3731 HRESULT WINAPI VarUI4FromBool32(VARIANT_BOOL boolIn, ULONG* pulOut)
3733 TRACE( ole, "( %d, %p ), stub\n", boolIn, pulOut );
3735 *pulOut = (ULONG) boolIn;
3737 return S_OK;
3740 /******************************************************************************
3741 * VarUI4FromI132 [OLEAUT32.280]
3743 HRESULT WINAPI VarUI4FromI132(CHAR cIn, ULONG* pulOut)
3745 TRACE( ole, "( %c, %p ), stub\n", cIn, pulOut );
3747 *pulOut = (ULONG) cIn;
3749 return S_OK;
3752 /******************************************************************************
3753 * VarUI4FromUI232 [OLEAUT32.281]
3755 HRESULT WINAPI VarUI4FromUI232(USHORT uiIn, ULONG* pulOut)
3757 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
3759 *pulOut = (ULONG) uiIn;
3761 return S_OK;
3764 /**********************************************************************
3765 * VarUI4FromCy32 [OLEAUT32.276]
3766 * Convert currency to unsigned long
3768 HRESULT WINAPI VarUI4FromCy32(CY cyIn, ULONG* pulOut) {
3769 double t = round((((double)cyIn.u.Hi * 4294967296) + (double)cyIn.u.Lo) / 10000);
3771 if (t > UI4_MAX || t < UI4_MIN) return DISP_E_OVERFLOW;
3773 *pulOut = (ULONG)t;
3775 return S_OK;
3778 /**********************************************************************
3779 * VarCyFromUI132 [OLEAUT32.98]
3780 * Convert unsigned char to currency
3782 HRESULT WINAPI VarCyFromUI132(BYTE bIn, CY* pcyOut) {
3783 pcyOut->u.Hi = 0;
3784 pcyOut->u.Lo = ((ULONG)bIn) * 10000;
3786 return S_OK;
3789 /**********************************************************************
3790 * VarCyFromI232 [OLEAUT32.99]
3791 * Convert signed short to currency
3793 HRESULT WINAPI VarCyFromI232(short sIn, CY* pcyOut) {
3794 if (sIn < 0) pcyOut->u.Hi = -1;
3795 else pcyOut->u.Hi = 0;
3796 pcyOut->u.Lo = ((ULONG)sIn) * 10000;
3798 return S_OK;
3801 /**********************************************************************
3802 * VarCyFromI432 [OLEAUT32.100]
3803 * Convert signed long to currency
3805 HRESULT WINAPI VarCyFromI432(LONG lIn, CY* pcyOut) {
3806 double t = (double)lIn * (double)10000;
3807 pcyOut->u.Hi = (LONG)(t / (double)4294967296);
3808 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296);
3809 if (lIn < 0) pcyOut->u.Hi--;
3811 return S_OK;
3814 /**********************************************************************
3815 * VarCyFromR432 [OLEAUT32.101]
3816 * Convert float to currency
3818 HRESULT WINAPI VarCyFromR432(FLOAT fltIn, CY* pcyOut) {
3819 double t = round((double)fltIn * (double)10000);
3820 pcyOut->u.Hi = (LONG)(t / (double)4294967296);
3821 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296);
3822 if (fltIn < 0) pcyOut->u.Hi--;
3824 return S_OK;
3827 /**********************************************************************
3828 * VarCyFromR832 [OLEAUT32.102]
3829 * Convert double to currency
3831 HRESULT WINAPI VarCyFromR832(double dblIn, CY* pcyOut) {
3832 double t = round(dblIn * (double)10000);
3833 pcyOut->u.Hi = (LONG)(t / (double)4294967296);
3834 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296);
3835 if (dblIn < 0) pcyOut->u.Hi--;
3837 return S_OK;
3840 /**********************************************************************
3841 * VarCyFromDate32 [OLEAUT32.103]
3842 * Convert date to currency
3844 HRESULT WINAPI VarCyFromDate32(DATE dateIn, CY* pcyOut) {
3845 double t = round((double)dateIn * (double)10000);
3846 pcyOut->u.Hi = (LONG)(t / (double)4294967296);
3847 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296);
3848 if (dateIn < 0) pcyOut->u.Hi--;
3850 return S_OK;
3853 /**********************************************************************
3854 * VarCyFromBool32 [OLEAUT32.106]
3855 * Convert boolean to currency
3857 HRESULT WINAPI VarCyFromBool32(VARIANT_BOOL boolIn, CY* pcyOut) {
3858 if (boolIn < 0) pcyOut->u.Hi = -1;
3859 else pcyOut->u.Hi = 0;
3860 pcyOut->u.Lo = (ULONG)boolIn * (ULONG)10000;
3862 return S_OK;
3865 /**********************************************************************
3866 * VarCyFromI132 [OLEAUT32.225]
3867 * Convert signed char to currency
3869 HRESULT WINAPI VarCyFromI132(CHAR cIn, CY* pcyOut) {
3870 if (cIn < 0) pcyOut->u.Hi = -1;
3871 else pcyOut->u.Hi = 0;
3872 pcyOut->u.Lo = (ULONG)cIn * (ULONG)10000;
3874 return S_OK;
3877 /**********************************************************************
3878 * VarCyFromUI232 [OLEAUT32.226]
3879 * Convert unsigned short to currency
3881 HRESULT WINAPI VarCyFromUI232(USHORT usIn, CY* pcyOut) {
3882 pcyOut->u.Hi = 0;
3883 pcyOut->u.Lo = (ULONG)usIn * (ULONG)10000;
3885 return S_OK;
3888 /**********************************************************************
3889 * VarCyFromUI432 [OLEAUT32.227]
3890 * Convert unsigned long to currency
3892 HRESULT WINAPI VarCyFromUI432(ULONG ulIn, CY* pcyOut) {
3893 double t = (double)ulIn * (double)10000;
3894 pcyOut->u.Hi = (LONG)(t / (double)4294967296);
3895 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296);
3897 return S_OK;