28#ifndef _INTSAFE_H_INCLUDED_
29#define _INTSAFE_H_INCLUDED_
34#ifdef _NTINTSAFE_H_INCLUDED_
38#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
39#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
40#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095)
41#define INTSAFE_RESULT NTSTATUS
42#define INTSAFE_SUCCESS STATUS_SUCCESS
43#define INTSAFE_E_ARITHMETIC_OVERFLOW STATUS_INTEGER_OVERFLOW
44#define INTSAFE_NAME(name) Rtl##name
46#ifndef _HRESULT_DEFINED
50#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
51#define FAILED(hr) (((HRESULT)(hr)) < 0)
52#define S_OK ((HRESULT)0L)
54#define INTSAFE_RESULT HRESULT
55#define INTSAFE_SUCCESS S_OK
56#define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L)
57#define INTSAFE_NAME(name) name
61#if defined(_MSC_VER) && !defined(__midl) && (defined(_M_IX86) || defined(_M_ARM))
71# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
73# define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1])
120#define INT8_MIN ((signed char)(-127 - 1))
121#define SHORT_MIN (-32768)
122#define INT16_MIN ((short)(-32767 - 1))
123#define INT_MIN (-2147483647 - 1)
124#define INT32_MIN (-2147483647 - 1)
125#define LONG_MIN (-2147483647L - 1)
126#define LONGLONG_MIN (-9223372036854775807LL - 1)
127#define LONG64_MIN (-9223372036854775807LL - 1)
128#define INT64_MIN (-9223372036854775807LL - 1)
129#define INT128_MIN (-170141183460469231731687303715884105727i128 - 1)
131#define INT_PTR_MIN (-9223372036854775807LL - 1)
132#define LONG_PTR_MIN (-9223372036854775807LL - 1)
133#define PTRDIFF_T_MIN (-9223372036854775807LL - 1)
134#define SSIZE_T_MIN (-9223372036854775807LL - 1)
136#define INT_PTR_MIN (-2147483647 - 1)
137#define LONG_PTR_MIN (-2147483647L - 1)
138#define PTRDIFF_T_MIN (-2147483647 - 1)
139#define SSIZE_T_MIN (-2147483647L - 1)
142#define INT8_MAX ((signed char)127)
143#define UINT8_MAX ((unsigned char)0xffU)
144#define BYTE_MAX ((unsigned char)0xff)
145#define SHORT_MAX ((short)32767)
146#define INT16_MAX ((short)32767)
147#define USHORT_MAX ((unsigned short)0xffff)
148#define UINT16_MAX ((unsigned short)0xffff)
149#define WORD_MAX ((unsigned short)0xffff)
150#define INT_MAX 2147483647
151#define INT32_MAX 2147483647
152#define UINT_MAX 0xffffffff
153#define UINT32_MAX 0xffffffffU
154#define LONG_MAX 2147483647L
155#define ULONG_MAX 0xffffffffUL
156#define DWORD_MAX 0xffffffffUL
157#define LONGLONG_MAX 9223372036854775807LL
158#define LONG64_MAX 9223372036854775807LL
159#define INT64_MAX 9223372036854775807LL
160#define ULONGLONG_MAX 0xffffffffffffffffULL
161#define DWORDLONG_MAX 0xffffffffffffffffULL
162#define ULONG64_MAX 0xffffffffffffffffULL
163#define DWORD64_MAX 0xffffffffffffffffULL
164#define UINT64_MAX 0xffffffffffffffffULL
165#define INT128_MAX 170141183460469231731687303715884105727i128
166#define UINT128_MAX 0xffffffffffffffffffffffffffffffffui128
169#define INT_PTR_MAX 9223372036854775807LL
170#define UINT_PTR_MAX 0xffffffffffffffffULL
171#define LONG_PTR_MAX 9223372036854775807LL
172#define ULONG_PTR_MAX 0xffffffffffffffffULL
173#define DWORD_PTR_MAX 0xffffffffffffffffULL
174#define PTRDIFF_T_MAX 9223372036854775807LL
175#define SIZE_T_MAX 0xffffffffffffffffULL
176#define SSIZE_T_MAX 9223372036854775807LL
177#define _SIZE_T_MAX 0xffffffffffffffffULL
179#define INT_PTR_MAX 2147483647
180#define UINT_PTR_MAX 0xffffffff
181#define LONG_PTR_MAX 2147483647L
182#define ULONG_PTR_MAX 0xffffffffUL
183#define DWORD_PTR_MAX 0xffffffffUL
184#define PTRDIFF_T_MAX 2147483647
185#define SIZE_T_MAX 0xffffffff
186#define SSIZE_T_MAX 2147483647L
187#define _SIZE_T_MAX 0xffffffffUL
191#define INT8_ERROR ((signed char)(-1))
192#define UINT8_ERROR ((unsigned char)0xff)
193#define BYTE_ERROR ((unsigned char)0xff)
194#define SHORT_ERROR ((short)(-1))
195#define INT16_ERROR ((short)(-1))
196#define USHORT_ERROR ((unsigned short)0xffff)
197#define UINT16_ERROR ((unsigned short)0xffff)
198#define WORD_ERROR ((unsigned short)0xffff)
199#define INT_ERROR (-1)
200#define INT32_ERROR (-1)
201#define UINT_ERROR 0xffffffffU
202#define UINT32_ERROR 0xffffffffU
203#define LONG_ERROR (-1L)
204#define ULONG_ERROR 0xffffffffUL
205#define DWORD_ERROR 0xffffffffUL
206#define LONGLONG_ERROR (-1LL)
207#define LONG64_ERROR (-1LL)
208#define INT64_ERROR (-1LL)
209#define ULONGLONG_ERROR 0xffffffffffffffffULL
210#define DWORDLONG_ERROR 0xffffffffffffffffULL
211#define ULONG64_ERROR 0xffffffffffffffffULL
212#define UINT64_ERROR 0xffffffffffffffffULL
214#define INT_PTR_ERROR (-1LL)
215#define UINT_PTR_ERROR 0xffffffffffffffffULL
216#define LONG_PTR_ERROR (-1LL)
217#define ULONG_PTR_ERROR 0xffffffffffffffffULL
218#define DWORD_PTR_ERROR 0xffffffffffffffffULL
219#define PTRDIFF_T_ERROR (-1LL)
220#define SIZE_T_ERROR 0xffffffffffffffffULL
221#define SSIZE_T_ERROR (-1LL)
222#define _SIZE_T_ERROR 0xffffffffffffffffULL
224#define INT_PTR_ERROR (-1)
225#define UINT_PTR_ERROR 0xffffffffU
226#define LONG_PTR_ERROR (-1L)
227#define ULONG_PTR_ERROR 0xffffffffUL
228#define DWORD_PTR_ERROR 0xffffffffUL
229#define PTRDIFF_T_ERROR (-1)
230#define SIZE_T_ERROR 0xffffffffU
231#define SSIZE_T_ERROR (-1L)
232#define _SIZE_T_ERROR 0xffffffffUL
236#define _INTSAFE_CHAR CHAR
237#define _INTSAFE_CHAR_ERROR ((signed char)(-1))
239 #define _INTSAFE_CHAR_MIN ((unsigned char)0)
240 #define _INTSAFE_CHAR_MAX ((unsigned char)0xff)
242 #define _INTSAFE_CHAR_MIN ((signed char)(-128))
243 #define _INTSAFE_CHAR_MAX ((signed char)127)
246#define size_t_ERROR SIZE_T_ERROR
247#define UCHAR_ERROR '\0'
248#define CHAR_ERROR '\0'
252#define UInt32x32To64(a,b) ((unsigned __int64)(unsigned int)(a)*(unsigned __int64)(unsigned int)(b))
256#define DEFINE_SAFE_CONVERT_UTOX(_Name, _TypeFrom, _TypeTo) \
257_Must_inspect_result_ \
260INTSAFE_NAME(_Name)( \
261 _In_ _TypeFrom Input, \
262 _Out_ _Deref_out_range_(==, Input) _TypeTo *pOutput) \
264 if ((sizeof(_TypeFrom) < sizeof(_TypeTo)) || (Input <= _TypeTo ## _MAX)) \
266 *pOutput = (_TypeTo)Input; \
267 return INTSAFE_SUCCESS; \
271 *pOutput = _TypeTo ## _ERROR; \
272 return INTSAFE_E_ARITHMETIC_OVERFLOW; \
319#define DEFINE_SAFE_CONVERT_STOU(_Name, _TypeFrom, _TypeTo) \
320_Must_inspect_result_ \
323INTSAFE_NAME(_Name)( \
324 _In_ _TypeFrom Input, \
325 _Out_ _Deref_out_range_(==, Input) _TypeTo *pOutput) \
327 if ((Input >= 0) && \
328 ((sizeof(_TypeFrom) <= sizeof(_TypeTo)) || (Input <= (_TypeFrom)_TypeTo ## _MAX))) \
330 *pOutput = (_TypeTo)Input; \
331 return INTSAFE_SUCCESS; \
335 *pOutput = _TypeTo ## _ERROR; \
336 return INTSAFE_E_ARITHMETIC_OVERFLOW; \
396#define DEFINE_SAFE_CONVERT_STOS(_Name, _TypeFrom, _TypeTo) \
397_Must_inspect_result_ \
400INTSAFE_NAME(_Name)( \
401 _In_ _TypeFrom Input, \
402 _Out_ _Deref_out_range_(==, Input) _TypeTo *pOutput) \
404 if ((Input >= _TypeTo ## _MIN) && (Input <= _TypeTo ## _MAX)) \
406 *pOutput = (_TypeTo)Input; \
407 return INTSAFE_SUCCESS; \
411 *pOutput = _TypeTo ## _ERROR; \
412 return INTSAFE_E_ARITHMETIC_OVERFLOW; \
440#ifdef _NTINTSAFE_H_INCLUDED_
442#define RtlInt8ToByte RtlInt8ToUInt8
443#define RtlInt8ToUInt16 RtlInt8ToUShort
444#define RtlInt8ToWord RtlInt8ToUShort
445#define RtlInt8ToUInt32 RtlInt8ToUInt
446#define RtlInt8ToDWord RtlInt8ToULong
447#define RtlInt8ToDWordPtr RtlInt8ToULongPtr
448#define RtlInt8ToDWordLong RtlInt8ToULongLong
449#define RtlInt8ToULong64 RtlInt8ToULongLong
450#define RtlInt8ToDWord64 RtlInt8ToULongLong
451#define RtlInt8ToUInt64 RtlInt8ToULongLong
452#define RtlInt8ToSizeT RtlInt8ToUIntPtr
453#define RtlInt8ToSIZET RtlInt8ToULongPtr
454#define RtlIntToSizeT RtlIntToUIntPtr
455#define RtlIntToSIZET RtlIntToULongPtr
456#define RtlULongToSSIZET RtlULongToLongPtr
457#define RtlULongToByte RtlULongToUInt8
458#define RtlULongLongToInt64 RtlULongLongToLongLong
459#define RtlULongLongToLong64 RtlULongLongToLongLong
460#define RtlULongLongToPtrdiffT RtlULongLongToIntPtr
461#define RtlULongLongToSizeT RtlULongLongToUIntPtr
462#define RtlULongLongToSSIZET RtlULongLongToLongPtr
463#define RtlULongLongToSIZET RtlULongLongToULongPtr
464#define RtlSIZETToULong RtlULongPtrToULong
465#define RtlSSIZETToULongLong RtlLongPtrToULongLong
466#define RtlSSIZETToULong RtlLongPtrToULong
467#define RtlLongLongToSizeT RtlLongLongToUIntPtr
468#define RtlLongLongToSSIZET RtlLongLongToLongPtr
469#define RtlLongLongToSIZET RtlLongLongToULongPtr
471#define RtlIntToUIntPtr RtlIntToULongLong
472#define RtlULongLongToIntPtr RtlULongLongToLongLong
474#define RtlIntToUIntPtr RtlIntToUInt
475#define RtlULongLongToIntPtr RtlULongLongToInt
476#define RtlULongLongToUIntPtr RtlULongLongToUInt
477#define RtlULongLongToULongPtr RtlULongLongToULong
482#define Int8ToByte Int8ToUInt8
483#define Int8ToUInt16 Int8ToUShort
484#define Int8ToWord Int8ToUShort
485#define Int8ToUInt32 Int8ToUInt
486#define Int8ToDWord Int8ToULong
487#define Int8ToDWordPtr Int8ToULongPtr
488#define Int8ToDWordLong Int8ToULongLong
489#define Int8ToULong64 Int8ToULongLong
490#define Int8ToDWord64 Int8ToULongLong
491#define Int8ToUInt64 Int8ToULongLong
492#define Int8ToSizeT Int8ToUIntPtr
493#define Int8ToSIZET Int8ToULongPtr
494#define IntToSizeT IntToUIntPtr
495#define IntToSIZET IntToULongPtr
496#define ULongToSSIZET ULongToLongPtr
497#define ULongToByte ULongToUInt8
498#define ULongLongToInt64 ULongLongToLongLong
499#define ULongLongToLong64 ULongLongToLongLong
500#define ULongLongToPtrdiffT ULongLongToIntPtr
501#define ULongLongToSizeT ULongLongToUIntPtr
502#define ULongLongToSSIZET ULongLongToLongPtr
503#define ULongLongToSIZET ULongLongToULongPtr
504#define SIZETToULong ULongPtrToULong
505#define SSIZETToULongLong LongPtrToULongLong
506#define SSIZETToULong LongPtrToULong
507#define LongLongToSizeT LongLongToUIntPtr
508#define LongLongToSSIZET LongLongToLongPtr
509#define LongLongToSIZET LongLongToULongPtr
511#define IntToUIntPtr IntToULongLong
512#define ULongLongToIntPtr ULongLongToLongLong
514#define IntToUIntPtr IntToUInt
515#define ULongLongToIntPtr ULongLongToInt
516#define ULongLongToUIntPtr ULongLongToUInt
517#define ULongLongToULongPtr ULongLongToULong
523#define DEFINE_SAFE_ADD(_Name, _Type) \
524_Must_inspect_result_ \
527INTSAFE_NAME(_Name)( \
530 _Out_ _Deref_out_range_(==, Augend + Addend) _Type *pOutput) \
532 if ((_Type)(Augend + Addend) >= Augend) \
534 *pOutput = Augend + Addend; \
535 return INTSAFE_SUCCESS; \
539 *pOutput = _Type ## _ERROR; \
540 return INTSAFE_E_ARITHMETIC_OVERFLOW; \
556#define DEFINE_SAFE_SUB(_Name, _Type) \
557_Must_inspect_result_ \
560INTSAFE_NAME(_Name)( \
561 _In_ _Type Minuend, \
562 _In_ _Type Subtrahend, \
563 _Out_ _Deref_out_range_(==, Minuend - Subtrahend) _Type* pOutput) \
565 if (Minuend >= Subtrahend) \
567 *pOutput = Minuend - Subtrahend; \
568 return INTSAFE_SUCCESS; \
572 *pOutput = _Type ## _ERROR; \
573 return INTSAFE_E_ARITHMETIC_OVERFLOW; \
588#ifdef ENABLE_INTSAFE_SIGNED_FUNCTIONS
603 if ( ((Augend ^
Addend) >= 0) && ((Augend ^
Result) < 0) )
616#define DEFINE_SAFE_ADD_S(_Name, _Type1, _Type2, _Convert) \
617C_ASSERT(sizeof(_Type2) > sizeof(_Type1)); \
618_Must_inspect_result_ \
621INTSAFE_NAME(_Name)( \
622 _In_ _Type1 Augend, \
623 _In_ _Type1 Addend, \
624 _Out_ _Deref_out_range_(==, Augend + Addend) _Type1* pOutput) \
626 return INTSAFE_NAME(_Convert)(((_Type2)Augend) + ((_Type2)Addend), pOutput); \
629DEFINE_SAFE_ADD_S(Int8Add,
INT8,
SHORT, ShortToInt8)
630DEFINE_SAFE_ADD_S(ShortAdd,
SHORT,
INT, IntToShort)
631DEFINE_SAFE_ADD_S(IntAdd,
INT,
LONGLONG, LongLongToInt)
632DEFINE_SAFE_ADD_S(LongAdd,
LONG,
LONGLONG, LongLongToLong)
652 if ( ((Minuend ^ Subtrahend) < 0) && ((Minuend ^
Result) < 0) )
665#define DEFINE_SAFE_SUB_S(_Name, _Type1, _Type2, _Convert) \
666C_ASSERT(sizeof(_Type2) > sizeof(_Type1)); \
667_Must_inspect_result_ \
670INTSAFE_NAME(_Name)( \
671 _In_ _Type1 Minuend, \
672 _In_ _Type1 Subtrahend, \
673 _Out_ _Deref_out_range_(==, Minuend - Subtrahend) _Type1* pOutput) \
675 return INTSAFE_NAME(_Convert)(((_Type2)Minuend) - ((_Type2)Subtrahend), pOutput); \
678DEFINE_SAFE_SUB_S(LongSub,
LONG,
LONGLONG, LongLongToLong)
712 ULONG M1Low = Multiplicand & 0xffffffff;
713 ULONG M2Low = Multiplier & 0xffffffff;
714 ULONG M1Hi = Multiplicand >> 32;
715 ULONG M2Hi = Multiplier >> 32;
742#define DEFINE_SAFE_MULT_U32(_Name, _Type, _Convert) \
743_Must_inspect_result_ \
746INTSAFE_NAME(_Name)( \
747 _In_ _Type Multiplicand, \
748 _In_ _Type Multiplier, \
749 _Out_ _Deref_out_range_(==, Multiplicand * Multiplier) _Type* pOutput) \
751 ULONGLONG Result = UInt32x32To64(Multiplicand, Multiplier); \
752 return INTSAFE_NAME(_Convert)(Result, pOutput); \
761#define DEFINE_SAFE_MULT_U16(_Name, _Type, _Convert) \
762_Must_inspect_result_ \
765INTSAFE_NAME(_Name)( \
766 _In_ _Type Multiplicand, \
767 _In_ _Type Multiplier, \
768 _Out_ _Deref_out_range_(==, Multiplicand * Multiplier) _Type* pOutput) \
770 ULONG Result = ((ULONG)Multiplicand) * ((ULONG)Multiplier); \
771 return INTSAFE_NAME(_Convert)(Result, pOutput); \
777#ifdef _NTINTSAFE_H_INCLUDED_
779#define RtlUInt16Add RtlUShortAdd
780#define RtlWordAdd RtlUShortAdd
781#define RtlUInt32Add RtlUIntAdd
782#define RtlDWordAdd RtlULongAdd
783#define RtlDWordLongAdd RtlULongLongAdd
784#define RtlULong64Add RtlULongLongAdd
785#define RtlDWord64Add RtlULongLongAdd
786#define RtlUInt64Add RtlULongLongAdd
787#define RtlUInt16Sub RtlUShortSub
788#define RtlWordSub RtlUShortSub
789#define RtlUInt32Sub RtlUIntSub
790#define RtlDWordSub RtlULongSub
791#define RtlDWordLongSub RtlULongLongSub
792#define RtlULong64Sub RtlULongLongSub
793#define RtlDWord64Sub RtlULongLongSub
794#define RtlUInt64Sub RtlULongLongSub
795#define RtlUInt16Mult RtlUShortMult
796#define RtlWordMult RtlUShortMult
798#define RtlIntPtrAdd RtlLongLongAdd
799#define RtlLongPtrAdd RtlLongLongAdd
800#define RtlIntPtrSub RtlLongLongSub
801#define RtlLongPtrSub RtlLongLongSub
802#define RtlSizeTMult RtlULongLongMult
803#define RtlSIZETMult RtlULongLongMult
809#define UInt16Add UShortAdd
810#define WordAdd UShortAdd
811#define UInt32Add UIntAdd
812#define DWordAdd ULongAdd
813#define DWordLongAdd ULongLongAdd
814#define ULong64Add ULongLongAdd
815#define DWord64Add ULongLongAdd
816#define UInt64Add ULongLongAdd
817#define UInt16Sub UShortSub
818#define WordSub UShortSub
819#define UInt32Sub UIntSub
820#define DWordSub ULongSub
821#define DWordLongSub ULongLongSub
822#define ULong64Sub ULongLongSub
823#define DWord64Sub ULongLongSub
824#define UInt64Sub ULongLongSub
825#define UInt16Mult UShortMult
826#define WordMult UShortMult
828#define IntPtrAdd LongLongAdd
829#define LongPtrAdd LongLongAdd
830#define IntPtrSub LongLongSub
831#define LongPtrSub LongLongSub
832#define SizeTMult ULongLongMult
833#define SIZETMult ULongLongMult
837#undef _INTSAFE_CHAR_MIN
838#undef _INTSAFE_CHAR_MAX
839#undef _INTSAFE_CHAR_ERROR
unsigned long long ULONG64
#define DEFINE_SAFE_MULT_U32(_Name, _Type, _Convert)
#define ULongLongToULongPtr
#define DEFINE_SAFE_CONVERT_STOU(_Name, _TypeFrom, _TypeTo)
#define UInt32x32To64(a, b)
#define DEFINE_SAFE_CONVERT_STOS(_Name, _TypeFrom, _TypeTo)
#define DEFINE_SAFE_MULT_U16(_Name, _Type, _Convert)
_W64 unsigned int UINT_PTR
unsigned long long UINT64
#define INTSAFE_E_ARITHMETIC_OVERFLOW
_W64 unsigned long DWORD_PTR
unsigned long long DWORDLONG
#define DEFINE_SAFE_CONVERT_UTOX(_Name, _TypeFrom, _TypeTo)
_Must_inspect_result_ __forceinline INTSAFE_RESULT INTSAFE_NAME() ULongLongMult(_In_ ULONGLONG Multiplicand, _In_ ULONGLONG Multiplier, _Out_ _Deref_out_range_(==, Multiplicand *Multiplier) ULONGLONG *pOutput)
#define INTSAFE_NAME(name)
#define DEFINE_SAFE_SUB(_Name, _Type)
#define DEFINE_SAFE_ADD(_Name, _Type)
unsigned long long ULONGLONG
_W64 unsigned long ULONG_PTR
_W64 unsigned long SIZE_T
unsigned long long DWORD64
#define _Deref_out_range_(lb, ub)
#define _Return_type_success_(expr)
#define _Must_inspect_result_
unsigned __int3264 UINT_PTR
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO