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