2ab2cf155055d76d294ddff302198ecf6080e136
[platform/upstream/coreclr.git] / src / pal / inc / rt / intsafe.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /******************************************************************
6 *                                                                 *
7 *  intsafe.h -- This module defines helper functions to prevent   *
8 *               integer overflow issues.                          *
9 *                                                                 *
10 *                                                                 *
11 ******************************************************************/
12 #ifndef _INTSAFE_H_INCLUDED_
13 #define _INTSAFE_H_INCLUDED_
14
15 #if _MSC_VER > 1000
16 #pragma once
17 #endif
18
19 #include <specstrings.h>    // for IN, etc.
20
21
22 #if defined(_AMD64_)
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 #define UnsignedMultiply128 _umul128
27 ULONG64
28 UnsignedMultiply128 (
29     IN ULONG64  Multiplier,
30     IN ULONG64  Multiplicand,
31     OUT ULONG64 *HighProduct
32     );
33 #ifdef _MSC_VER
34 #pragma intrinsic(_umul128)
35 #endif // _MSC_VER
36 #ifdef __cplusplus
37 }
38 #endif
39 #endif // _AMD64_
40
41 #ifndef FEATURE_PAL
42
43 #ifdef  _WIN64
44 typedef unsigned __int64    size_t;
45 typedef unsigned __int64    UINT_PTR;
46 typedef unsigned __int64    ULONG_PTR;
47 typedef unsigned __int64    DWORD_PTR;
48 typedef unsigned __int64    SIZE_T;
49 #else
50 typedef __w64 unsigned int  size_t;
51 typedef __w64 unsigned int  UINT_PTR;
52 typedef __w64 unsigned long ULONG_PTR;
53 typedef __w64 unsigned long DWORD_PTR;
54 typedef __w64 unsigned long SIZE_T;
55 #endif
56 typedef          char       CHAR;
57 typedef          int        INT;
58 typedef          long       LONG;
59 typedef unsigned char       UCHAR;
60 typedef unsigned short      USHORT;
61 typedef unsigned short      WORD;
62 typedef unsigned int        UINT;
63 typedef unsigned long       ULONG;
64 typedef unsigned long       DWORD;
65 typedef unsigned __int64    ULONGLONG;
66
67
68 typedef LONG HRESULT;
69
70 #ifndef SUCCEEDED
71 #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
72 #endif
73
74 #ifndef FAILED
75 #define FAILED(hr) (((HRESULT)(hr)) < 0)
76 #endif
77
78 #define S_OK ((HRESULT)0x00000000L)
79
80 #endif // !FEATURE_PAL
81
82 #define INTSAFE_E_ARITHMETIC_OVERFLOW       ((HRESULT)0x80070216L)  // 0x216 = 534 = ERROR_ARITHMETIC_OVERFLOW
83
84 #ifndef LOWORD
85 #define LOWORD(l)       ((WORD)(((DWORD_PTR)(l)) & 0xffff))
86 #endif
87
88 #ifndef HIWORD
89 #define HIWORD(l)       ((WORD)(((DWORD_PTR)(l)) >> 16))
90 #endif
91
92 #define HIDWORD(_qw)    ((ULONG)((_qw) >> 32))
93 #define LODWORD(_qw)    ((ULONG)(_qw))
94
95 #if defined(MIDL_PASS) || defined(RC_INVOKED) || defined(_M_CEE_PURE) \
96     || defined(_68K_) || defined(_MPPC_) || defined(_PPC_)            \
97     || defined(_M_IA64) || defined(_M_AMD64) || defined(__ARM_ARCH)
98
99 #ifndef UInt32x32To64
100 #define UInt32x32To64(a, b) ((unsigned __int64)((ULONG)(a)) * (unsigned __int64)((ULONG)(b)))
101 #endif
102
103 #elif defined(_M_IX86)
104
105 #ifndef UInt32x32To64
106 #define UInt32x32To64(a, b) (unsigned __int64)((unsigned __int64)(ULONG)(a) * (ULONG)(b))
107 #endif
108
109 #else
110
111 #error Must define a target architecture.
112
113 #endif
114
115 #define INT_MAX         2147483647
116 #define LONG_MAX        2147483647L
117 #define USHRT_MAX       0xffff
118 #define UINT_MAX        0xffffffff
119 #define ULONG_MAX       0xffffffffUL
120 #define DWORD_MAX       0xffffffffUL
121
122 //
123 // It is common for -1 to be used as an error value for various types
124 //
125 #define USHORT_ERROR    (0xffff)
126 #define INT_ERROR       (-1)
127 #define LONG_ERROR      (-1L)
128 #define UINT_ERROR      (0xffffffff)
129 #define ULONG_ERROR     (0xffffffffUL)
130 #ifdef _MSC_VER
131 #define ULONGLONG_ERROR (0xffffffffffffffffui64)
132 #define HIDWORD_MASK (0xffffffff00000000ui64)
133 #else // _MSC_VER
134 #define ULONGLONG_ERROR (0xffffffffffffffffULL)
135 #define HIDWORD_MASK (0xffffffff00000000ULL)
136 #endif // _MSC_VER
137 #ifdef _WIN64
138 #define SIZET_ERROR     ULONGLONG_ERROR
139 #else
140 #define SIZET_ERROR     ULONG_ERROR
141 #endif
142
143 //
144 // We make some assumptions about the sizes of various types. Let's be
145 // explicit about those assumptions and check them.
146 //
147 C_ASSERT(sizeof(unsigned short) == 2);
148 C_ASSERT(sizeof(unsigned int) == 4);
149 C_ASSERT(sizeof(ULONG) == 4);
150
151 //
152 // INT -> signed char conversion
153 //
154 __inline
155 HRESULT
156 IntToSignedChar(
157     IN INT iOperand,
158     OUT signed char* pch)
159 {
160     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
161     *pch = 0;
162
163     if ((iOperand >= -128) && (iOperand <= 127))
164     {
165         *pch = (signed char)iOperand;
166         hr = S_OK;
167     }
168
169     return hr;
170 }
171
172 //
173 // INT -> UCHAR conversion
174 //
175 __inline
176 HRESULT
177 IntToUChar(
178     IN INT iOperand,
179     OUT UCHAR* pch)
180 {
181     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
182     *pch = 0;
183
184     if ((iOperand >= 0) && (iOperand <= 255))
185     {
186         *pch = (UCHAR)iOperand;
187         hr = S_OK;
188     }
189
190     return hr;
191 }
192
193 //
194 // LONG -> UCHAR conversion
195 //
196 __inline
197 HRESULT
198 LongToUChar(
199     IN LONG lOperand,
200     OUT UCHAR* pch)
201 {
202     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
203     *pch = 0;
204
205     if ((lOperand >= 0) && (lOperand <= 255))
206     {
207         *pch = (UCHAR)lOperand;
208         hr = S_OK;
209     }
210
211     return hr;
212 }
213
214 //
215 // __inline is not sufficient. __forceinline is necessary.
216 // If the function is not inlined and you link .objs compiled with different compiler switches,
217 // you get one or the other function arbitrarily chosen.
218 //
219 // INT -> CHAR conversion
220 //
221 __forceinline
222 HRESULT
223 IntToChar(
224     IN INT iOperand,
225     OUT CHAR* pch)
226 {
227 #ifdef _CHAR_UNSIGNED
228     return IntToUChar(iOperand, (UCHAR*)pch);
229 #else
230     return IntToSignedChar(iOperand, (signed char*)pch);
231 #endif
232 }
233
234 //
235 // INT -> USHORT conversion
236 //
237 __inline
238 HRESULT
239 IntToUShort(
240     IN INT iOperand,
241     OUT USHORT* pusResult)
242 {
243     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
244     *pusResult = USHORT_ERROR;
245
246     if ((iOperand >= 0) && (iOperand <= USHRT_MAX))
247     {
248         *pusResult = (USHORT)iOperand;
249         hr = S_OK;
250     }
251
252     return hr;
253 }
254
255 //
256 // INT -> UINT conversion
257 //
258 __inline
259 HRESULT
260 IntToUInt(
261     IN INT iOperand,
262     OUT UINT* puResult)
263 {
264     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
265     *puResult = UINT_ERROR;
266
267     if (iOperand >= 0)
268     {
269         *puResult = (UINT)iOperand;
270         hr = S_OK;
271     }
272
273     return hr;
274 }
275
276 //
277 // INT -> ULONG conversion
278 //
279 __inline
280 HRESULT
281 IntToULong(
282     IN INT iOperand,
283     OUT ULONG* pulResult)
284 {
285     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
286     *pulResult = ULONG_ERROR;
287
288     if (iOperand >= 0)
289     {
290         *pulResult = (ULONG)iOperand;
291         hr = S_OK;
292     }
293
294     return hr;
295 }
296
297 //
298 // INT -> ULONGLONG conversion
299 //
300 __inline
301 HRESULT
302 IntToULongLong(
303     IN INT iOperand,
304     OUT ULONGLONG* pullResult)
305 {
306     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
307     *pullResult = ULONG_ERROR;
308
309     if (iOperand >= 0)
310     {
311         *pullResult = (ULONGLONG)iOperand;
312         hr = S_OK;
313     }
314
315     return hr;
316 }
317
318 //
319 // UINT -> signed char conversion
320 //
321 __inline
322 HRESULT
323 UIntToSignedChar(
324     IN UINT uOperand,
325     OUT signed char* pch)
326 {
327     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
328     *pch = 0;
329
330     if (uOperand <= 127)
331     {
332         *pch = (signed char)uOperand;
333         hr = S_OK;
334     }
335
336     return hr;
337 }
338
339 //
340 // UINT -> UCHAR conversion
341 //
342 __inline
343 HRESULT
344 UIntToUChar(
345     IN UINT uOperand,
346     OUT UCHAR* pch)
347 {
348     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
349     *pch = 0;
350
351     if (uOperand <= 255)
352     {
353         *pch = (UCHAR)uOperand;
354         hr = S_OK;
355     }
356
357     return hr;
358 }
359
360 //
361 // UINT -> BYTE conversion
362 //
363 #define UIntToByte   UIntToUChar
364
365 //
366 // __inline is not sufficient. __forceinline is necessary.
367 // If the function is not inlined and you link .objs compiled with different compiler switches,
368 // you get one or the other function arbitrarily chosen.
369 //
370 // UINT -> CHAR conversion
371 //
372 __forceinline
373 HRESULT
374 UIntToChar(
375     IN UINT uOperand,
376     OUT CHAR* pch)
377 {
378 #ifdef _CHAR_UNSIGNED
379     return UIntToUChar(uOperand, (UCHAR*)pch);
380 #else
381     return UIntToSignedChar(uOperand, (signed char*)pch);
382 #endif // _CHAR_UNSIGNED
383 }
384
385 //
386 // UINT -> INT conversion
387 //
388 __inline
389 HRESULT
390 UIntToInt(
391     IN UINT uOperand,
392     OUT INT* piResult)
393 {
394     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
395     *piResult = INT_ERROR;
396
397     if (uOperand <= INT_MAX)
398     {
399         *piResult = (INT)uOperand;
400         hr = S_OK;
401     }
402
403     return hr;
404 }
405
406 //
407 // UINT -> LONG conversion
408 //
409 __inline
410 HRESULT
411 UIntToLong(
412     IN UINT Operand,
413     OUT LONG* Result)
414 {
415     if (Operand <= LONG_MAX)
416     {
417         *Result = (LONG)Operand;
418         return S_OK;
419     }
420     else
421     {
422         *Result = LONG_ERROR;
423         return INTSAFE_E_ARITHMETIC_OVERFLOW;
424     }
425 }
426
427 //
428 // UINT -> ULONG conversion
429 //
430 __inline
431 HRESULT
432 UIntToULong(
433     IN UINT uOperand,
434     OUT ULONG* pulResult)
435 {
436     *pulResult = (ULONG)uOperand;
437     
438     return S_OK;
439 }
440
441 //
442 // ULONG -> UCHAR conversion
443 //
444 __inline
445 HRESULT
446 ULongToSignedChar(
447     IN ULONG ulOperand,
448     OUT signed char* pch)
449 {
450     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
451     *pch = 0;
452
453     if (ulOperand <= 127)
454     {
455         *pch = (signed char)ulOperand;
456         hr = S_OK;
457     }
458
459     return hr;
460 }
461
462 //
463 // ULONG -> UCHAR conversion
464 //
465 __inline
466 HRESULT
467 ULongToUChar(
468     IN ULONG ulOperand,
469     OUT unsigned char* pch)
470 {
471     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
472     *pch = 0;
473
474     if (ulOperand <= 255)
475     {
476         *pch = (unsigned char)ulOperand;
477         hr = S_OK;
478     }
479
480     return hr;
481 }
482
483 //
484 // __inline is not sufficient. __forceinline is necessary.
485 // If the function is not inlined and you link .objs compiled with different compiler switches,
486 // you get one or the other function arbitrarily chosen.
487 //
488 // ULONG -> CHAR conversion
489 //
490 __forceinline
491 HRESULT
492 ULongToChar(
493     IN ULONG ulOperand,
494     OUT CHAR* pch)
495 {
496 #ifdef _CHAR_UNSIGNED
497     return ULongToUChar(ulOperand, (unsigned char*)pch);
498 #else
499     return ULongToSignedChar(ulOperand, (signed char*)pch);
500 #endif // _CHAR_UNSIGNED
501 }
502
503 //
504 // ULONG -> USHORT conversion
505 //
506 __inline
507 HRESULT
508 ULongToUShort(
509     IN ULONG ulOperand,
510     OUT USHORT* pusResult)
511 {
512     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
513     *pusResult = USHORT_ERROR;
514
515     if (ulOperand <= USHRT_MAX)
516     {
517         *pusResult = (USHORT)ulOperand;
518         hr = S_OK;
519     }
520
521     return hr;
522 }
523
524 //
525 // ULONG -> INT conversion
526 //
527 __inline
528 HRESULT
529 ULongToInt(
530     IN ULONG ulOperand,
531     OUT INT* piResult)
532 {
533     if (ulOperand <= INT_MAX)
534     {
535         *piResult = (INT)ulOperand;
536         return S_OK;
537     }
538     else
539     {
540         *piResult = INT_ERROR;
541         return INTSAFE_E_ARITHMETIC_OVERFLOW;
542     }
543 }
544
545 //
546 // ULONG -> UINT conversion
547 //
548 __inline
549 HRESULT
550 ULongToUInt(
551     IN ULONG ulOperand,
552     OUT UINT* puResult)
553 {
554     *puResult = (UINT)ulOperand;
555     
556     return S_OK;
557 }
558
559 //
560 // ULONG -> LONG conversion
561 //
562 __inline
563 HRESULT
564 ULongToLong(
565     IN ULONG Operand,
566     OUT LONG* Result)
567 {
568     if (Operand <= LONG_MAX)
569     {
570         *Result = (LONG)Operand;
571         return S_OK;
572     }
573     else
574     {
575         *Result = LONG_ERROR;
576         return INTSAFE_E_ARITHMETIC_OVERFLOW;
577     }
578 }
579
580 //
581 // ULONGLONG -> INT conversion
582 //
583 __inline
584 HRESULT
585 ULongLongToInt(
586     IN ULONGLONG ullOperand,
587     OUT INT* piResult)
588 {
589     if (ullOperand <= INT_MAX)
590     {
591         *piResult = (INT)ullOperand;
592         return S_OK;
593     }
594     else
595     {
596         *piResult = INT_ERROR;
597         return INTSAFE_E_ARITHMETIC_OVERFLOW;
598     }
599 }
600
601 //
602 // ULONGLONG -> LONG conversion
603 //
604 __inline
605 HRESULT
606 ULongLongToLong(
607     IN ULONGLONG Operand,
608     OUT LONG* Result)
609 {
610     if (Operand <= LONG_MAX)
611     {
612         *Result = (LONG)Operand;
613         return S_OK;
614     }
615     else
616     {
617         *Result = LONG_ERROR;
618         return INTSAFE_E_ARITHMETIC_OVERFLOW;
619     }
620 }
621
622 //
623 // UINT -> USHORT conversion
624 //
625 __inline
626 HRESULT
627 UIntToUShort(
628     IN UINT uOperand,
629     OUT USHORT* pusResult)
630 {
631     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
632     *pusResult = USHORT_ERROR;
633
634     if (uOperand <= USHRT_MAX)
635     {
636         *pusResult = (USHORT)uOperand;
637         hr = S_OK;
638     }
639
640     return hr;
641 }
642
643 //
644 // ULONGLONG -> USHORT conversion
645 //
646 __inline
647 HRESULT
648 ULongLongToUShort(
649     IN ULONGLONG ullOperand,
650     OUT USHORT* pusResult)
651 {
652     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
653     USHORT usResult = USHORT_ERROR;
654
655     if (ullOperand <= USHRT_MAX)
656     {
657         usResult = (USHORT)ullOperand;
658         hr = S_OK;
659     }
660     *pusResult = usResult;
661
662     return hr;
663 }
664
665 //
666 // ULONGLONG -> ULONG conversion
667 //
668 __inline
669 HRESULT
670 ULongLongToULong(
671     IN ULONGLONG ullOperand,
672     OUT ULONG* pulResult)
673 {
674     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
675     *pulResult = ULONG_ERROR;
676     
677     if (ullOperand <= ULONG_MAX)
678     {
679         *pulResult = (ULONG)ullOperand;
680         hr = S_OK;
681     }
682     
683     return hr;
684 }
685
686 //
687 // UINT_PTR -> ULONG conversion
688 // ULONG_PTR -> ULONG conversion
689 //
690 #ifdef _WIN64
691
692 #define UIntPtrToULong  ULongLongToULong
693 #define ULongPtrToULong ULongLongToULong
694
695 #else
696
697 __inline
698 HRESULT
699 UIntPtrToULong(
700     IN UINT_PTR Operand,
701     OUT ULONG* pResult)
702 {
703     *pResult = (ULONG)Operand;
704     return S_OK;
705 }
706
707 __inline
708 HRESULT
709 ULongPtrToULong(
710     IN ULONG_PTR Operand,
711     OUT ULONG* pResult)
712 {
713     *pResult = (ULONG)Operand;
714     return S_OK;
715 }
716
717 #endif
718
719 //
720 // ULONGLONG -> UINT conversion
721 //
722 __inline
723 HRESULT
724 ULongLongToUInt(
725     IN ULONGLONG ullOperand,
726     OUT UINT* puResult)
727 {
728     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
729     *puResult = UINT_ERROR;
730     
731     if (ullOperand <= UINT_MAX)
732     {
733         *puResult = (UINT)ullOperand;
734         hr = S_OK;
735     }
736     
737     return hr;
738 }
739
740 //
741 // UINT_PTR -> UINT conversion
742 // ULONG_PTR -> UINT conversion
743 //
744 #ifdef _WIN64
745
746 #define UIntPtrToUInt  ULongLongToUInt
747 #define ULongPtrToUInt ULongLongToUInt
748
749 #else
750
751 __inline
752 HRESULT
753 UIntPtrToUInt(
754     IN UINT_PTR Operand,
755     OUT UINT* pResult)
756 {
757     *pResult = (UINT)Operand;
758     return S_OK;
759 }
760
761 __inline
762 HRESULT
763 ULongPtrToUInt(
764     IN ULONG_PTR Operand,
765     OUT UINT* pResult)
766 {
767     *pResult = (UINT)Operand;
768     return S_OK;
769 }
770
771 #endif
772
773 //
774 // * -> BYTE conversion (BYTE is always unsigned char)
775 //
776 #define  IntToByte   IntToUChar
777 #define UIntToByte  UIntToUChar
778 #define  LongToByte  LongToUChar
779 #define ULongToByte ULongToUChar
780
781 //
782 // * -> WORD conversion (WORD is always unsigned short)
783 //
784 #define IntToWord               IntToUShort
785 #define LongToWord              LongToUShort
786 #define LongLongToWord          LongLongToUShort
787 #define UIntToWord              UIntToUShort
788 #define ULongToWord             ULongToUShort
789 #define ULongLongToWord         ULongLongToUShort
790 #define UIntPtrToWord           UIntPtrToUShort
791 #define ULongPtrToWord          ULongPtrToUShort
792 #define SizeTToWord             SizeTToUShort
793 #define SIZETToWord             SIZETToUShort
794
795 //
796 // WORD -> * conversion (WORD is always unsigned short)
797 //
798 #define WordToUChar             UShortToUChar
799 #define WordToByte              UShortToByte
800 #define WordToChar              UShortToChar
801 #define WordToSignedChar        UShortToSignedChar
802 #define WordToInt               UShortToInt
803 #define WordToLong              UShortToLong
804 #define WordToLongLong          UShortToLongLong
805 #define WordToIntPtr            UShortToIntPtr
806 #define WordToLongPtr           UShortToLongPtr
807
808 //
809 // * -> DWORD conversion (DWORD is always ULONG)
810 //
811 #define CharToDWord             CharToULong
812 #define SignedCharToDWord       SignedCharToULong
813 #define ShortToDWord            ShortToULong
814 #define IntToDWord              IntToULong
815 #define LongToDWord             LongToULong
816 #define LongLongToDWord         LongLongToULong
817 #define UIntToDWord             UIntToULong
818 #define ULongLongToDWord        ULongLongToULong
819 #define IntPtrToDWord           IntPtrToULong
820 #define LongPtrToDWord          LongPtrToULong
821 #define UIntPtrToDWord          UIntPtrToULong
822 #define ULongPtrToDWord         ULongPtrToULong
823 #define SizeTToDWord            SizeTToULong
824 #define SIZETToDWord            SIZETToULong
825
826 //
827 // DWORD -> * conversion (DWORD is always ULONG)
828 //
829 #define DWordToChar             ULongToChar
830 #define DWordToUChar            ULongToUChar
831 #define DWordToByte             ULongToByte
832 #define DWordToSignedChar       ULongToSignedChar
833 #define DWordToUShort           ULongToUShort
834 #define DWordToUInt             ULongToUInt
835 #define DWordToInt              ULongToInt
836 #define DWordToLong             ULongToLong
837 #define DWordToLongLong         ULongToLongLong
838 #define DWordToIntPtr           ULongToIntPtr
839 #define DWordToLongPtr          ULongToLongPtr
840
841
842 //
843 // * -> UINT_PTR conversion (UINT_PTR is UINT on Win32, ULONGLONG on Win64)
844 //
845 #ifdef _WIN64
846 #define CharToUIntPtr           CharToULongLong
847 #define SignedCharToUIntPtr     SignedCharToULongLong
848 #define ShortToUIntPtr          ShortToULongLong
849 #define IntToUIntPtr            IntToULongLong
850 #define LongToUIntPtr           LongToULongLong
851 #define LongLongToUIntPtr       LongLongToULongLong
852 #define IntPtrToUIntPtr         IntPtrToULongLong
853 #define LongPtrToUIntPtr        LongPtrToULongLong
854 #else
855 #define CharToUIntPtr           CharToUInt
856 #define SignedCharToUIntPtr     SignedCharToUInt
857 #define ShortToUIntPtr          ShortToUInt
858
859 __inline
860 HRESULT
861 IntToUIntPtr(
862     IN INT iOperand,
863     OUT UINT_PTR* puResult)
864 {
865         return IntToUInt(iOperand, (UINT*)puResult);
866 }
867
868 #define LongToUIntPtr           LongToUInt
869 #define LongLongToUIntPtr       LongLongToUInt
870
871 #define IntPtrToUIntPtr         IntPtrToUInt
872 #define LongPtrToUIntPtr        LongPtrToUInt
873 #endif
874
875 __inline
876 HRESULT
877 ULongLongToUIntPtr(
878     IN ULONGLONG ullOperand,
879     OUT UINT_PTR* puResult)
880 {
881 #ifdef _WIN64
882         *puResult = ullOperand;
883         return S_OK;
884 #else
885         return ULongLongToUInt(ullOperand, (UINT*)puResult);
886 #endif
887 }
888
889
890 //
891 // UINT_PTR -> * conversion (UINT_PTR is UINT on Win32, ULONGLONG on Win64)
892 //
893 #ifdef _WIN64
894 #define UIntPtrToUShort         ULongLongToUShort
895 #define UIntPtrToInt            ULongLongToInt
896 #define UIntPtrToLong           ULongLongToLong
897 #define UIntPtrToLongLong       ULongLongToLongLong
898 #define UIntPtrToIntPtr         ULongLongToIntPtr
899 #define UIntPtrToLongPtr        ULongLongToLongPtr
900 #else
901
902 __inline
903 HRESULT
904 UIntPtrToUShort(
905     IN UINT_PTR uOperand,
906     OUT USHORT* pusResult)
907 {
908         return UIntToUShort((UINT)uOperand, pusResult);
909 }
910
911 __inline
912 HRESULT
913 UIntPtrToInt(
914     IN UINT_PTR uOperand,
915     OUT INT* piResult)
916 {
917         return UIntToInt((UINT)uOperand, piResult);
918 }
919
920 __inline
921 HRESULT
922 UIntPtrToLong(
923     IN UINT_PTR Operand,
924     OUT LONG* Result)
925 {
926         return UIntToLong((UINT)Operand, Result);
927 }
928
929 #define UIntPtrToLongLong       UIntToLongLong
930 #define UIntPtrToIntPtr         UIntToIntPtr
931 #define UIntPtrToLongPtr        UIntToLongPtr
932 #endif
933
934
935 //
936 // * -> ULONG_PTR conversion (ULONG_PTR is ULONG on Win32, ULONGLONG on Win64)
937 //
938 #ifdef _WIN64
939 #define CharToULongPtr          CharToULongLong
940 #define SignedCharToULongPtr    SignedCharToULongLong
941 #define ShortToULongPtr         ShortToULongLong
942 #define IntToULongPtr           IntToULongLong
943 #define LongToULongPtr          LongToULongLong
944 #define LongLongToULongPtr      LongLongToULongLong
945 #define IntPtrToULongPtr        IntPtrToULongLong
946 #define LongPtrToULongPtr       LongPtrToULongLong
947 #else
948 #define CharToULongPtr          CharToULong
949 #define SignedCharToULongPtr    SignedCharToULong
950 #define ShortToULongPtr         ShortToULong
951
952 __inline
953 HRESULT
954 IntToULongPtr(
955     IN INT iOperand,
956     OUT ULONG_PTR* pulResult)
957 {
958         return IntToULong(iOperand, (ULONG*)pulResult);
959 }
960
961 #define LongToULongPtr          LongToULong
962 #define LongLongToULongPtr      LongLongToULong
963
964 #define IntPtrToULongPtr        IntPtrToULong
965 #define LongPtrToULongPtr       LongPtrToULong
966 #endif
967
968 __inline
969 HRESULT
970 ULongLongToULongPtr(
971     IN ULONGLONG ullOperand,
972     OUT ULONG_PTR* pulResult)
973 {
974 #ifdef _WIN64
975         *pulResult = ullOperand;
976         return S_OK;
977 #else
978         return ULongLongToULong(ullOperand, (ULONG*)pulResult);
979 #endif
980 }
981
982
983 //
984 // ULONG_PTR -> * conversion (ULONG_PTR is ULONG on Win32, ULONGLONG on Win64)
985 //
986 #ifdef _WIN64
987 #define ULongPtrToUShort        ULongLongToUShort
988 #define ULongPtrToInt           ULongLongToInt
989 #define ULongPtrToLong          ULongLongToLong
990 #define ULongPtrToLongLong      ULongLongToLongLong
991 #define ULongPtrToIntPtr        ULongLongToIntPtr
992 #define ULongPtrToLongPtr       ULongLongToLongPtr
993 #else
994
995 __inline
996 HRESULT
997 ULongPtrToUShort(
998     IN ULONG_PTR ulOperand,
999     OUT USHORT* pusResult)
1000 {
1001         return ULongToUShort((ULONG)ulOperand, pusResult);
1002 }
1003
1004 __inline
1005 HRESULT
1006 ULongPtrToInt(
1007     IN ULONG_PTR ulOperand,
1008     OUT INT* piResult)
1009 {
1010         return ULongToInt((ULONG)ulOperand, piResult);
1011 }
1012
1013 __inline
1014 HRESULT
1015 ULongPtrToLong(
1016     IN ULONG_PTR Operand,
1017     OUT LONG* Result)
1018 {
1019         return ULongToLong((ULONG)Operand, Result);
1020 }
1021
1022 #define ULongPtrToLongLong      ULongToLongLong
1023 #define ULongPtrToIntPtr        ULongToIntPtr
1024 #define ULongPtrToLongPtr       ULongToLongPtr
1025 #endif
1026
1027 //
1028 // * -> size_t conversion (size_t is always UINT_PTR)
1029 //
1030 #define CharToSizeT             CharToUIntPtr
1031 #define SignedCharToSizeT       SignedCharToUIntPtr
1032 #define ShortToSizeT            ShortToUIntPtr
1033 #define IntToSizeT              IntToUIntPtr
1034 #define LongToSizeT             LongToUIntPtr
1035 #define LongLongToSizeT         LongLongToUIntPtr
1036 #define ULongLongToSizeT        ULongLongToUIntPtr
1037 #define IntPtrToSizeT           IntPtrToUIntPtr
1038 #define LongPtrToSizeT          LongPtrToUIntPtr
1039
1040 //
1041 // size_t -> * conversion (size_t is always UINT_PTR)
1042 //
1043 #define SizeTToUShort           UIntPtrToUShort
1044 #define SizeTToUInt             UIntPtrToUInt
1045 #define SizeTToULong            UIntPtrToULong
1046 #define SizeTToInt              UIntPtrToInt
1047 #define SizeTToLong             UIntPtrToLong
1048 #define SizeTToLongLong         UIntPtrToLongLong
1049 #define SizeTToIntPtr           UIntPtrToIntPtr
1050 #define SizeTToLongPtr          UIntPtrToLongPtr
1051
1052 //
1053 // * -> SIZE_T conversion (SIZE_T is always ULONG_PTR)
1054 //
1055 #define CharToSIZET             CharToULongPtr
1056 #define SignedCharToSIZET       SignedCharToULongPtr
1057 #define ShortToSIZET            ShortToULongPtr
1058 #define IntToSIZET              IntToULongPtr
1059 #define LongToSIZET             LongToULongPtr
1060 #define LongLongToSIZET         LongLongToULongPtr
1061 #define IntPtrToSIZET           IntPtrToULongPtr
1062 #define LongPtrToSIZET          LongPtrToULongPtr
1063 #define ULongLongToSIZET        ULongLongToULongPtr
1064
1065 //
1066 // SIZE_T -> * conversion (SIZE_T is always ULONG_PTR)
1067 //
1068 #define SIZETToUShort           ULongPtrToUShort
1069 #define SIZETToUInt             ULongPtrToUInt
1070 #define SIZETToULong            ULongPtrToULong
1071 #define SIZETToUIntPtr          ULongPtrToUIntPtr
1072 #define SIZETToULongPtr         ULongPtrToULongPtr
1073 #define SIZETToInt              ULongPtrToInt
1074 #define SIZETToLong             ULongPtrToLong
1075 #define SIZETToLongLong         ULongPtrToLongLong
1076 #define SIZETToIntPtr           ULongPtrToIntPtr
1077 #define SIZETToLongPtr          ULongPtrToLongPtr
1078
1079 //
1080 // * -> DWORD_PTR conversion (DWORD_PTR is always ULONG_PTR)
1081 //
1082 #define CharToDWordPtr             CharToULongPtr
1083 #define SignedCharToDWordPtr       SignedCharToULongPtr
1084 #define ShortToDWordPtr            ShortToULongPtr
1085 #define IntToDWordPtr              IntToULongPtr
1086 #define LongToDWordPtr             LongToULongPtr
1087 #define LongLongToDWordPtr         LongLongToULongPtr
1088 #define ULongLongToDWordPtr        ULongLongToULongPtr
1089 #define IntPtrToDWordPtr           IntPtrToULongPtr
1090 #define LongPtrToDWordPtr          LongPtrToULongPtr
1091
1092 //
1093 // DWORD_PTR -> * conversion (DWORD_PTR is always ULONG_PTR)
1094 //
1095 #define DWordPtrToUShort           ULongPtrToUShort
1096 #define DWordPtrToUInt             ULongPtrToUInt
1097 #define DWordPtrToULong            ULongPtrToULong
1098 #define DWordPtrToDWord            ULongPtrToDWord
1099 #define DWordPtrToInt              ULongPtrToInt
1100 #define DWordPtrToLong             ULongPtrToLong
1101 #define DWordPtrToLongLong         ULongPtrToLongLong
1102 #define DWordPtrToIntPtr           ULongPtrToIntPtr
1103 #define DWordPtrToLongPtr          ULongPtrToLongPtr
1104
1105 //
1106 // USHORT addition
1107 //
1108 __inline
1109 HRESULT
1110 UShortAdd(
1111     IN USHORT usAugend,
1112     IN USHORT usAddend,
1113     OUT USHORT* pusResult)
1114 {
1115     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1116     *pusResult = USHORT_ERROR;
1117
1118     if (((USHORT)(usAugend + usAddend)) >= usAugend)
1119     {
1120         *pusResult = (usAugend + usAddend);
1121         hr = S_OK;
1122     }
1123     
1124     return hr;
1125 }
1126
1127 //
1128 // WORD addtition
1129 //
1130 #define WordAdd     UShortAdd
1131
1132 //
1133 // UINT addition
1134 //
1135 __inline
1136 HRESULT
1137 UIntAdd(
1138     IN UINT uAugend,
1139     IN UINT uAddend,
1140     OUT UINT* puResult)
1141 {
1142     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1143     *puResult = UINT_ERROR;
1144
1145     if ((uAugend + uAddend) >= uAugend)
1146     {
1147         *puResult = (uAugend + uAddend);
1148         hr = S_OK;
1149     }
1150     
1151     return hr;
1152 }
1153
1154 //
1155 // UINT_PTR addition
1156 //
1157 #define UIntPtrAdd              SizeTAdd
1158
1159 //
1160 // ULONG addition
1161 //
1162 __inline
1163 HRESULT
1164 ULongAdd(
1165     IN ULONG ulAugend,
1166     IN ULONG ulAddend,
1167     OUT ULONG* pulResult)
1168 {
1169     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1170     *pulResult = ULONG_ERROR;
1171
1172     if ((ulAugend + ulAddend) >= ulAugend)
1173     {
1174         *pulResult = (ulAugend + ulAddend);
1175         hr = S_OK;
1176     }
1177     
1178     return hr;
1179 }
1180
1181 //
1182 // ULONG_PTR addition
1183 //
1184 #ifdef _WIN64
1185 #define ULongPtrAdd     ULongLongAdd
1186 #else
1187 __inline
1188 HRESULT
1189 ULongPtrAdd(
1190     IN ULONG_PTR ulAugend,
1191     IN ULONG_PTR ulAddend,
1192     OUT ULONG_PTR* pulResult)
1193 {
1194         return ULongAdd((ULONG)ulAugend, (ULONG)ulAddend, (ULONG*)pulResult);
1195 }
1196 #endif // _WIN64
1197
1198 //
1199 // DWORD addition
1200 //
1201 #define DWordAdd        ULongAdd
1202
1203 //
1204 // DWORD_PTR addition
1205 //
1206 #define DWordPtrAdd             ULongPtrAdd
1207
1208 //
1209 // size_t addition
1210 //
1211 __inline
1212 HRESULT
1213 SizeTAdd(
1214     IN size_t Augend,
1215     IN size_t Addend,
1216     OUT size_t* pResult)
1217 {
1218     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1219     *pResult = SIZET_ERROR;
1220
1221     if ((Augend + Addend) >= Augend)
1222     {
1223         *pResult = (Augend + Addend);
1224         hr = S_OK;
1225     }
1226     
1227     return hr;
1228 }
1229
1230 //
1231 // SIZE_T addition
1232 //
1233 #define SIZETAdd        ULongPtrAdd
1234
1235 //
1236 // ULONGLONG addition
1237 //
1238 __inline
1239 HRESULT
1240 ULongLongAdd(
1241     IN ULONGLONG ullAugend,
1242     IN ULONGLONG ullAddend,
1243     OUT ULONGLONG* pullResult)
1244 {
1245     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1246     *pullResult = ULONGLONG_ERROR;
1247
1248     if ((ullAugend + ullAddend) >= ullAugend)
1249     {
1250         *pullResult = (ullAugend + ullAddend);
1251         hr = S_OK;
1252     }
1253     
1254     return hr;
1255 }
1256
1257 //
1258 // USHORT subtraction
1259 //
1260 __inline
1261 HRESULT
1262 UShortSub(
1263     IN USHORT usMinuend,
1264     IN USHORT usSubtrahend,
1265     OUT USHORT* pusResult)
1266 {
1267     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1268     *pusResult = USHORT_ERROR;
1269
1270     if (usMinuend >= usSubtrahend)
1271     {
1272         *pusResult = (usMinuend - usSubtrahend);
1273         hr = S_OK;
1274     }
1275     
1276     return hr;
1277 }
1278
1279 //
1280 // WORD subtraction
1281 //
1282 #define WordSub     UShortSub
1283
1284
1285 //
1286 // UINT subtraction
1287 //
1288 __inline
1289 HRESULT
1290 UIntSub(
1291     IN UINT uMinuend,
1292     IN UINT uSubtrahend,
1293     OUT UINT* puResult)
1294 {
1295     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1296     *puResult = UINT_ERROR;
1297
1298     if (uMinuend >= uSubtrahend)
1299     {
1300         *puResult = (uMinuend - uSubtrahend);
1301         hr = S_OK;
1302     }
1303     
1304     return hr;
1305 }
1306
1307 //
1308 // UINT_PTR subtraction
1309 //
1310 #define UIntPtrSub      SizeTSub
1311
1312 //
1313 // ULONG subtraction
1314 //
1315 __inline
1316 HRESULT
1317 ULongSub(
1318     IN ULONG ulMinuend,
1319     IN ULONG ulSubtrahend,
1320     OUT ULONG* pulResult)
1321 {
1322     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1323     *pulResult = ULONG_ERROR;
1324
1325     if (ulMinuend >= ulSubtrahend)
1326     {
1327         *pulResult = (ulMinuend - ulSubtrahend);
1328         hr = S_OK;
1329     }
1330     
1331     return hr;
1332 }
1333
1334 //
1335 // ULONG_PTR subtraction
1336 //
1337 #ifdef _WIN64
1338 #define ULongPtrSub ULongLongSub
1339 #else
1340 __inline
1341 HRESULT
1342 ULongPtrSub(
1343     IN ULONG_PTR ulMinuend,
1344     IN ULONG_PTR ulSubtrahend,
1345     OUT ULONG_PTR* pulResult)
1346 {
1347         return ULongSub((ULONG)ulMinuend, (ULONG)ulSubtrahend, (ULONG*)pulResult);
1348 }
1349 #endif // _WIN64
1350
1351
1352 //
1353 // DWORD subtraction
1354 //
1355 #define DWordSub        ULongSub
1356
1357 //
1358 // DWORD_PTR subtraction
1359 //
1360 #define DWordPtrSub             ULongPtrSub
1361
1362 //
1363 // size_t subtraction
1364 //
1365 __inline
1366 HRESULT
1367 SizeTSub(
1368     IN size_t Minuend,
1369     IN size_t Subtrahend,
1370     OUT size_t* pResult)
1371 {
1372     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1373     *pResult = SIZET_ERROR;
1374
1375     if (Minuend >= Subtrahend)
1376     {
1377         *pResult = (Minuend - Subtrahend);
1378         hr = S_OK;
1379     }
1380     
1381     return hr;
1382 }
1383
1384 //
1385 // SIZE_T subtraction
1386 //
1387 #define SIZETSub        ULongPtrSub
1388
1389 //
1390 // ULONGLONG subtraction
1391 //
1392 __inline
1393 HRESULT
1394 ULongLongSub(
1395     IN ULONGLONG ullMinuend,
1396     IN ULONGLONG ullSubtrahend,
1397     OUT ULONGLONG* pullResult)
1398 {
1399     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1400     *pullResult = ULONGLONG_ERROR;
1401
1402     if (ullMinuend >= ullSubtrahend)
1403     {
1404         *pullResult = (ullMinuend - ullSubtrahend);
1405         hr = S_OK;
1406     }
1407     
1408     return hr;
1409 }
1410
1411 //
1412 // USHORT multiplication
1413 //
1414 __inline
1415 HRESULT
1416 UShortMult(
1417     IN USHORT usMultiplicand,
1418     IN USHORT usMultiplier,
1419     OUT USHORT* pusResult)
1420 {
1421     ULONG ulResult = ((ULONG)usMultiplicand) * (ULONG)usMultiplier;
1422     
1423     return ULongToUShort(ulResult, pusResult);
1424 }
1425
1426 //
1427 // WORD multiplication
1428 //
1429 #define WordMult      UShortMult
1430
1431 //
1432 // UINT multiplication
1433 //
1434 __inline
1435 HRESULT
1436 UIntMult(
1437     IN UINT uMultiplicand,
1438     IN UINT uMultiplier,
1439     OUT UINT* puResult)
1440 {
1441     ULONGLONG ull64Result = UInt32x32To64(uMultiplicand, uMultiplier);
1442
1443     return ULongLongToUInt(ull64Result, puResult);
1444 }
1445
1446 //
1447 // UINT_PTR multiplication
1448 //
1449 #ifdef _WIN64
1450 #define UIntPtrMult     ULongLongMult
1451 #else
1452 __inline
1453 HRESULT
1454 UIntPtrMult(
1455     IN UINT_PTR ulMultiplicand,
1456     IN UINT_PTR ulMultiplier,
1457     OUT UINT_PTR* pulResult)
1458 {
1459         return UIntMult((UINT)ulMultiplicand, (UINT)ulMultiplier, (UINT*)pulResult);
1460 }
1461 #endif // _WIN64
1462
1463 //
1464 // ULONG multiplication
1465 //
1466 __inline
1467 HRESULT
1468 ULongMult(
1469     IN ULONG ulMultiplicand,
1470     IN ULONG ulMultiplier,
1471     OUT ULONG* pulResult)
1472 {
1473     ULONGLONG ull64Result = UInt32x32To64(ulMultiplicand, ulMultiplier);
1474     
1475     return ULongLongToULong(ull64Result, pulResult);
1476 }
1477
1478 //
1479 // ULONG_PTR multiplication
1480 //
1481 #ifdef _WIN64
1482 #define ULongPtrMult    ULongLongMult
1483 #else
1484 __inline
1485 HRESULT
1486 ULongPtrMult(
1487     IN ULONG_PTR ulMultiplicand,
1488     IN ULONG_PTR ulMultiplier,
1489     OUT ULONG_PTR* pulResult)
1490 {
1491         return ULongMult((ULONG)ulMultiplicand, (ULONG)ulMultiplier, (ULONG*)pulResult);
1492 }
1493 #endif // _WIN64
1494
1495
1496 //
1497 // DWORD multiplication
1498 //
1499 #define DWordMult       ULongMult
1500
1501 //
1502 // DWORD_PTR multiplication
1503 //
1504 #define DWordPtrMult    ULongPtrMult
1505
1506 //
1507 // size_t multiplication
1508 //
1509 #define SizeTMult               UIntPtrMult
1510
1511 //
1512 // SIZE_T multiplication
1513 //
1514 #define SIZETMult               ULongPtrMult
1515
1516 //
1517 // ULONGLONG multiplication
1518 //
1519 __inline
1520 HRESULT
1521 ULongLongMult(
1522     IN ULONGLONG ullMultiplicand,
1523     IN ULONGLONG ullMultiplier,
1524     OUT ULONGLONG* pullResult)
1525 {
1526     HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
1527 #ifdef _AMD64_
1528     ULONGLONG u64ResultHigh;
1529     ULONGLONG u64ResultLow;
1530     
1531     *pullResult = ULONGLONG_ERROR;
1532     
1533     u64ResultLow = UnsignedMultiply128(ullMultiplicand, ullMultiplier, &u64ResultHigh);
1534     if (u64ResultHigh == 0)
1535     {
1536         *pullResult = u64ResultLow;
1537         hr = S_OK;
1538     }
1539 #else
1540     // 64x64 into 128 is like 32.32 x 32.32.
1541     //
1542     // a.b * c.d = a*(c.d) + .b*(c.d) = a*c + a*.d + .b*c + .b*.d
1543     // back in non-decimal notation where A=a*2^32 and C=c*2^32:  
1544     // A*C + A*d + b*C + b*d
1545     // So there are four components to add together.
1546     //   result = (a*c*2^64) + (a*d*2^32) + (b*c*2^32) + (b*d)
1547     //
1548     // a * c must be 0 or there would be bits in the high 64-bits
1549     // a * d must be less than 2^32 or there would be bits in the high 64-bits
1550     // b * c must be less than 2^32 or there would be bits in the high 64-bits
1551     // then there must be no overflow of the resulting values summed up.
1552     
1553     ULONG dw_a;
1554     ULONG dw_b;
1555     ULONG dw_c;
1556     ULONG dw_d;
1557     ULONGLONG ad = 0;
1558     ULONGLONG bc = 0;
1559     ULONGLONG bd = 0;
1560     ULONGLONG ullResult = 0;
1561     
1562     *pullResult = ULONGLONG_ERROR;
1563
1564     dw_a = (ULONG)(ullMultiplicand >> 32);
1565     dw_c = (ULONG)(ullMultiplier >> 32);
1566
1567     // common case -- if high dwords are both zero, no chance for overflow
1568     if ((dw_a == 0) && (dw_c == 0))
1569     {
1570         dw_b = (DWORD)ullMultiplicand;
1571         dw_d = (DWORD)ullMultiplier;
1572
1573         *pullResult = (((ULONGLONG)dw_b) * (ULONGLONG)dw_d);
1574         hr = S_OK;
1575     }
1576     else
1577     {
1578         // a * c must be 0 or there would be bits set in the high 64-bits
1579         if ((dw_a == 0) ||
1580             (dw_c == 0))
1581         {
1582             dw_d = (DWORD)ullMultiplier;
1583
1584             // a * d must be less than 2^32 or there would be bits set in the high 64-bits
1585             ad = (((ULONGLONG)dw_a) * (ULONGLONG)dw_d);
1586             if ((ad & HIDWORD_MASK) == 0)
1587             {
1588                 dw_b = (DWORD)ullMultiplicand;
1589
1590                 // b * c must be less than 2^32 or there would be bits set in the high 64-bits
1591                 bc = (((ULONGLONG)dw_b) * (ULONGLONG)dw_c);
1592                 if ((bc & HIDWORD_MASK) == 0)
1593                 {
1594                     // now sum them all up checking for overflow.
1595                     // shifting is safe because we already checked for overflow above
1596                     if (SUCCEEDED(ULongLongAdd(bc << 32, ad << 32, &ullResult)))                        
1597                     {
1598                         // b * d
1599                         bd = (((ULONGLONG)dw_b) * (ULONGLONG)dw_d);
1600                     
1601                         if (SUCCEEDED(ULongLongAdd(ullResult, bd, &ullResult)))
1602                         {
1603                             *pullResult = ullResult;
1604                             hr = S_OK;
1605                         }
1606                     }
1607                 }
1608             }
1609         }
1610     }
1611 #endif // _AMD64_  
1612     
1613     return hr;
1614 }
1615
1616 #endif // _INTSAFE_H_INCLUDED_