mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[PSDK]
intsafe.h: - Fix type redefinitions when ntdef.h is included - Implement (Rtl)LongLongSub and (Rtl)UlongLongMult - Add some more definitions - misc fixes svn path=/trunk/; revision=56750
This commit is contained in:
parent
9d043b385a
commit
75ac603cd4
1 changed files with 270 additions and 30 deletions
|
@ -36,22 +36,23 @@
|
|||
|
||||
/* Handle ntintsafe here too */
|
||||
#ifdef _NTINTSAFE_H_INCLUDED_
|
||||
#ifndef NT_SUCCESS /* Guard agains redefinition from ntstatus.h */
|
||||
#ifndef _NTDEF_ /* Guard agains redefinition from ntstatus.h */
|
||||
typedef _Return_type_success_(return >= 0) long NTSTATUS;
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||
#endif
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
|
||||
#define STATUS_INTEGER_OVERFLOW ((NTSTATUS)0xC0000095)
|
||||
#define INTSAFE_RESULT NTSTATUS
|
||||
#define INTSAFE_SUCCESS STATUS_SUCCESS
|
||||
#define INTSAFE_E_ARITHMETIC_OVERFLOW STATUS_INTEGER_OVERFLOW
|
||||
#define INTSAFE_NAME(name) Rtl##name
|
||||
#else // _NTINTSAFE_H_INCLUDED_
|
||||
#ifndef SUCCEEDED /* Guard agains redefinition from winerror.h */
|
||||
#ifndef _HRESULT_DEFINED
|
||||
typedef _Return_type_success_(return >= 0) long HRESULT;
|
||||
#endif
|
||||
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
|
||||
#define FAILED(hr) (((HRESULT)(hr)) < 0)
|
||||
#define S_OK ((HRESULT)0L)
|
||||
#endif
|
||||
#define INTSAFE_RESULT HRESULT
|
||||
#define INTSAFE_SUCCESS S_OK
|
||||
#define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L)
|
||||
|
@ -77,17 +78,18 @@ typedef _Return_type_success_(return >= 0) long HRESULT;
|
|||
|
||||
/* Typedefs */
|
||||
#ifndef _WINNT_
|
||||
#ifndef _NTDEF_
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR, UINT8;
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UCHAR, UINT8, BYTE;
|
||||
typedef short SHORT;
|
||||
typedef signed short INT16;
|
||||
typedef unsigned short USHORT, UINT16, WORD;
|
||||
typedef unsigned short USHORT, UINT16;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT32;
|
||||
typedef signed int INT32;
|
||||
typedef unsigned int UINT, UINT32;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG, DWORD;
|
||||
typedef unsigned long ULONG;
|
||||
typedef long long LONGLONG, LONG64;
|
||||
typedef signed long long INT64;
|
||||
typedef unsigned long long ULONGLONG, DWORDLONG, ULONG64, DWORD64, UINT64;
|
||||
|
@ -100,6 +102,11 @@ typedef _W64 unsigned int UINT_PTR, size_t;
|
|||
typedef _W64 long LONG_PTR, SSIZE_T;
|
||||
typedef _W64 unsigned long ULONG_PTR, DWORD_PTR, SIZE_T;
|
||||
#endif // _WIN64
|
||||
#endif
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned long DWORD;
|
||||
#endif // _WINNT_
|
||||
|
||||
/* Just to be sure! */
|
||||
|
@ -110,16 +117,27 @@ C_ASSERT(sizeof(LONG) == 4);
|
|||
C_ASSERT(sizeof(ULONG) == 4);
|
||||
C_ASSERT(sizeof(UINT_PTR) == sizeof(ULONG_PTR));
|
||||
|
||||
/* Undefine these to avoid conflicts with limits.h */
|
||||
#undef CHAR_MIN
|
||||
#undef CHAR_MAX
|
||||
#undef INT_MIN
|
||||
#undef INT_MAX
|
||||
#undef LONG_MIN
|
||||
#undef LONG_MAX
|
||||
#undef UCHAR_MAX
|
||||
#undef UINT_MAX
|
||||
#undef ULONG_MAX
|
||||
|
||||
/* Integer range margins (use (x-1) to prevent warnings) */
|
||||
#define INT8_MIN (-128)
|
||||
#define SHORT_MIN (-32768)
|
||||
#define INT16_MIN (-32768)
|
||||
#define INT8_MIN (-127 - 1)
|
||||
#define SHORT_MIN (-32767 - 1)
|
||||
#define INT16_MIN (-32767 - 1)
|
||||
#define INT_MIN (-2147483647 - 1)
|
||||
#define INT32_MIN (-2147483647 - 1)
|
||||
#define LONG_MIN (-2147483647L - 1)
|
||||
#define LONGLONG_MIN (-9223372036854775808LL)
|
||||
#define LONG64_MIN (-9223372036854775808LL)
|
||||
#define INT64_MIN (-9223372036854775808LL)
|
||||
#define LONGLONG_MIN (-9223372036854775807LL - 1)
|
||||
#define LONG64_MIN (-9223372036854775807LL - 1)
|
||||
#define INT64_MIN (-9223372036854775807LL - 1)
|
||||
//#define INT128_MIN (-170141183460469231731687303715884105728)
|
||||
#ifdef _WIN64
|
||||
#define INT_PTR_MIN INT64_MIN
|
||||
|
@ -242,6 +260,12 @@ C_ASSERT(sizeof(UINT_PTR) == sizeof(ULONG_PTR));
|
|||
#define CHAR_ERROR '\0'
|
||||
|
||||
|
||||
/* 32 bit x 32 bit to 64 bit unsigned multiplication */
|
||||
#ifndef UInt32x32To64
|
||||
#define UInt32x32To64(a,b) ((DWORDLONG)(a)*(DWORDLONG)(b))
|
||||
#endif
|
||||
|
||||
|
||||
#define DEFINE_SAFE_CONVERT_UTOX(_Name, _TypeFrom, _TypeTo) \
|
||||
_Must_inspect_result_ \
|
||||
__forceinline \
|
||||
|
@ -253,7 +277,7 @@ INTSAFE_NAME(_Name)( \
|
|||
if (Input <= _TypeTo ## _MAX) \
|
||||
{ \
|
||||
*pOutput = (_TypeTo)Input; \
|
||||
return S_OK; \
|
||||
return INTSAFE_SUCCESS; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
|
@ -289,6 +313,8 @@ DEFINE_SAFE_CONVERT_UTOX(UIntPtrToInt, UINT_PTR, INT)
|
|||
DEFINE_SAFE_CONVERT_UTOX(UIntPtrToLong, UINT_PTR, LONG)
|
||||
DEFINE_SAFE_CONVERT_UTOX(UIntPtrToIntPtr, UINT_PTR, INT_PTR)
|
||||
DEFINE_SAFE_CONVERT_UTOX(UIntPtrToLongPtr, UINT_PTR, LONG_PTR)
|
||||
DEFINE_SAFE_CONVERT_UTOX(ULongLongToUInt, ULONGLONG, UINT)
|
||||
DEFINE_SAFE_CONVERT_UTOX(ULongLongToULong, ULONGLONG, ULONG)
|
||||
|
||||
|
||||
#define DEFINE_SAFE_CONVERT_ITOU(_Name, _TypeFrom, _TypeTo) \
|
||||
|
@ -302,7 +328,7 @@ INTSAFE_NAME(_Name)( \
|
|||
if ((Input >= 0) && (Input <= _TypeTo ## _MAX)) \
|
||||
{ \
|
||||
*pOutput = (_TypeTo)Input; \
|
||||
return S_OK; \
|
||||
return INTSAFE_SUCCESS; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
|
@ -375,7 +401,7 @@ INTSAFE_NAME(_Name)( \
|
|||
if ((Input >= _TypeTo ## _MIN) && (Input <= _TypeTo ## _MAX)) \
|
||||
{ \
|
||||
*pOutput = (_TypeTo)Input; \
|
||||
return S_OK; \
|
||||
return INTSAFE_SUCCESS; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
|
@ -400,11 +426,80 @@ DEFINE_SAFE_CONVERT_ITOI(LongPtrToShort, LONG_PTR, SHORT)
|
|||
DEFINE_SAFE_CONVERT_ITOI(LongPtrToInt, LONG_PTR, INT)
|
||||
DEFINE_SAFE_CONVERT_ITOI(LongPtrToLong, LONG_PTR, LONG)
|
||||
DEFINE_SAFE_CONVERT_ITOI(LongPtrToIntPtr, LONG_PTR, INT_PTR)
|
||||
DEFINE_SAFE_CONVERT_ITOI(LongLongToLong, LONGLONG, LONG)
|
||||
DEFINE_SAFE_CONVERT_ITOI(LongLongToIntPtr, LONGLONG, INT_PTR)
|
||||
DEFINE_SAFE_CONVERT_ITOI(LongLongToLongPtr, LONGLONG, LONG_PTR)
|
||||
#ifndef _CHAR_UNSIGNED
|
||||
DEFINE_SAFE_CONVERT_ITOI(ShortToChar, SHORT, CHAR)
|
||||
DEFINE_SAFE_CONVERT_ITOI(LongPtrToChar, LONG_PTR, CHAR)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _NTINTSAFE_H_INCLUDED_
|
||||
|
||||
#define RtlInt8ToByte RtlInt8ToUInt8
|
||||
#define RtlInt8ToUInt16 RtlInt8ToUShort
|
||||
#define RtlInt8ToWord RtlInt8ToUShort
|
||||
#define RtlInt8ToUInt32 RtlInt8ToUInt
|
||||
#define RtlInt8ToDWord RtlInt8ToULong
|
||||
#define RtlInt8ToDWordPtr RtlInt8ToULongPtr
|
||||
#define RtlInt8ToDWordLong RtlInt8ToULongLong
|
||||
#define RtlInt8ToULong64 RtlInt8ToULongLong
|
||||
#define RtlInt8ToDWord64 RtlInt8ToULongLong
|
||||
#define RtlInt8ToUInt64 RtlInt8ToULongLong
|
||||
#define RtlInt8ToSizeT RtlInt8ToUIntPtr
|
||||
#define RtlInt8ToSIZET RtlInt8ToULongPtr
|
||||
#define RtlIntToSizeT RtlIntToUIntPtr
|
||||
#define RtlULongLongToInt64 RtlULongLongToLongLong
|
||||
#define RtlULongLongToLong64 RtlULongLongToLongLong
|
||||
#define RtlULongLongToPtrdiffT RtlULongLongToIntPtr
|
||||
#define RtlULongLongToSizeT RtlULongLongToUIntPtr
|
||||
#define RtlULongLongToSSIZET RtlULongLongToLongPtr
|
||||
#define RtlULongLongToSIZET RtlULongLongToULongPtr
|
||||
#ifdef _WIN64
|
||||
#define RtlIntToUIntPtr RtlIntToULongLong
|
||||
#define RtlULongLongToIntPtr RtlULongLongToLongLong
|
||||
#else
|
||||
#define RtlIntToUIntPtr RtlIntToUInt
|
||||
#define RtlULongLongToIntPtr RtlULongLongToInt
|
||||
#define RtlULongLongToUIntPtr RtlULongLongToUInt
|
||||
#define RtlULongLongToULongPtr RtlULongLongToULong
|
||||
#endif
|
||||
|
||||
#else // _NTINTSAFE_H_INCLUDED_
|
||||
|
||||
#define Int8ToByte Int8ToUInt8
|
||||
#define Int8ToUInt16 Int8ToUShort
|
||||
#define Int8ToWord Int8ToUShort
|
||||
#define Int8ToUInt32 Int8ToUInt
|
||||
#define Int8ToDWord Int8ToULong
|
||||
#define Int8ToDWordPtr Int8ToULongPtr
|
||||
#define Int8ToDWordLong Int8ToULongLong
|
||||
#define Int8ToULong64 Int8ToULongLong
|
||||
#define Int8ToDWord64 Int8ToULongLong
|
||||
#define Int8ToUInt64 Int8ToULongLong
|
||||
#define Int8ToSizeT Int8ToUIntPtr
|
||||
#define Int8ToSIZET Int8ToULongPtr
|
||||
#define IntToSizeT IntToUIntPtr
|
||||
#define ULongLongToInt64 ULongLongToLongLong
|
||||
#define ULongLongToLong64 ULongLongToLongLong
|
||||
#define ULongLongToPtrdiffT ULongLongToIntPtr
|
||||
#define ULongLongToSizeT ULongLongToUIntPtr
|
||||
#define ULongLongToSSIZET ULongLongToLongPtr
|
||||
#define ULongLongToSIZET ULongLongToULongPtr
|
||||
#ifdef _WIN64
|
||||
#define IntToUIntPtr IntToULongLong
|
||||
#define ULongLongToIntPtr ULongLongToLongLong
|
||||
#else
|
||||
#define IntToUIntPtr IntToUInt
|
||||
#define ULongLongToIntPtr ULongLongToInt
|
||||
#define ULongLongToUIntPtr ULongLongToUInt
|
||||
#define ULongLongToULongPtr ULongLongToULong
|
||||
#endif
|
||||
|
||||
#endif // _NTINTSAFE_H_INCLUDED_
|
||||
|
||||
|
||||
#define DEFINE_SAFE_ADD(_Name, _Type) \
|
||||
_Must_inspect_result_ \
|
||||
__forceinline \
|
||||
|
@ -471,18 +566,155 @@ DEFINE_SAFE_SUB(SIZETSub, SIZE_T)
|
|||
DEFINE_SAFE_SUB(ULongLongSub, ULONGLONG)
|
||||
|
||||
|
||||
#define Int8ToByte Int8ToUInt8
|
||||
#define Int8ToUInt16 Int8ToUShort
|
||||
#define Int8ToWord Int8ToUShort
|
||||
#define Int8ToUInt32 Int8ToUInt
|
||||
#define Int8ToDWord Int8ToULong
|
||||
#define Int8ToDWordPtr Int8ToULongPtr
|
||||
#define Int8ToDWordLong Int8ToULongLong
|
||||
#define Int8ToULong64 Int8ToULongLong
|
||||
#define Int8ToDWord64 Int8ToULongLong
|
||||
#define Int8ToUInt64 Int8ToULongLong
|
||||
#define Int8ToSizeT Int8ToUIntPtr
|
||||
#define Int8ToSIZET Int8ToULongPtr
|
||||
_Must_inspect_result_
|
||||
__forceinline
|
||||
INTSAFE_RESULT
|
||||
INTSAFE_NAME(LongLongSub)(
|
||||
_In_ LONGLONG Minuend,
|
||||
_In_ LONGLONG Subtrahend,
|
||||
_Out_ _Deref_out_range_(==, Minuend - Subtrahend) LONGLONG* pResult)
|
||||
{
|
||||
LONGLONG Result = Minuend - Subtrahend;
|
||||
|
||||
/* The only way the result can overflow, is when the sign of the minuend
|
||||
and the subtrahend differ. In that case the result is expected to
|
||||
have the same sign as the minuend, otherwise it overflowed.
|
||||
Sign equality is checked with a binary xor operation. */
|
||||
if ( ((Minuend ^ Subtrahend) < 0) && ((Minuend ^ Result) < 0) )
|
||||
{
|
||||
*pResult = LONGLONG_ERROR;
|
||||
return INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pResult = Result;
|
||||
return INTSAFE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define DEFINE_SAFE_SUB_S(_Name, _Type1, _Type2, _Convert) \
|
||||
_Must_inspect_result_ \
|
||||
__forceinline \
|
||||
INTSAFE_RESULT \
|
||||
INTSAFE_NAME(_Name)( \
|
||||
_In_ _Type1 Minuend, \
|
||||
_In_ _Type1 Subtrahend, \
|
||||
_Out_ _Deref_out_range_(==, Minuend - Subtrahend) _Type1* pOutput) \
|
||||
{ \
|
||||
return INTSAFE_NAME(_Convert)(((_Type2)Minuend) - ((_Type2)Subtrahend), pOutput); \
|
||||
}
|
||||
|
||||
DEFINE_SAFE_SUB_S(LongSub, LONG, LONGLONG, LongLongToLong)
|
||||
#ifndef _WIN64
|
||||
DEFINE_SAFE_SUB_S(IntPtrSub, INT_PTR, LONGLONG, LongLongToIntPtr)
|
||||
DEFINE_SAFE_SUB_S(LongPtrSub, LONG_PTR, LONGLONG, LongLongToLongPtr)
|
||||
#endif
|
||||
|
||||
|
||||
_Must_inspect_result_
|
||||
__forceinline
|
||||
INTSAFE_RESULT
|
||||
INTSAFE_NAME(ULongLongMult)(
|
||||
_In_ ULONGLONG Multiplicand,
|
||||
_In_ ULONGLONG Multiplier,
|
||||
_Out_ _Deref_out_range_(==, Multiplicand * Multiplier) ULONGLONG* pOutput)
|
||||
{
|
||||
/* We can split the 64 bit numbers in low and high parts:
|
||||
M1 = M1Low + M1Hi * 0x100000000
|
||||
M2 = M2Low + M2Hi * 0x100000000
|
||||
|
||||
Then the multiplication looks like this:
|
||||
M1 * M2 = (M1Low + M1Hi * 0x100000000) + (M2Low + M2Hi * 0x100000000)
|
||||
= M1Low * M2Low
|
||||
+ M1Low * M2Hi * 0x100000000
|
||||
+ M2Low * M1Hi * 0x100000000
|
||||
+ M1Hi * M2Hi * 0x100000000 * 0x100000000
|
||||
|
||||
We get an overflow when
|
||||
a) M1Hi * M2Hi != 0, so when M1Hi or M2Hi are not 0
|
||||
b) The product of the nonzero high part and the other low part
|
||||
is larger than 32 bits.
|
||||
c) The addition of the product from b) shifted left by 32 and
|
||||
M1Low * M2Low is larger than 64 bits
|
||||
*/
|
||||
ULONG M1Low = Multiplicand & 0xffffffff;
|
||||
ULONG M2Low = Multiplier & 0xffffffff;
|
||||
ULONG M1Hi = Multiplicand >> 32;
|
||||
ULONG M2Hi = Multiplier >> 32;
|
||||
ULONGLONG Temp;
|
||||
|
||||
if (M1Hi == 0)
|
||||
{
|
||||
Temp = UInt32x32To64(M1Low, M2Hi);
|
||||
}
|
||||
else if (M2Hi == 0)
|
||||
{
|
||||
Temp = UInt32x32To64(M1Hi, M2Low);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pOutput = LONGLONG_ERROR;
|
||||
return INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
if (Temp > ULONG_MAX)
|
||||
{
|
||||
*pOutput = LONGLONG_ERROR;
|
||||
return INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return INTSAFE_NAME(ULongLongAdd)(Temp << 32, UInt32x32To64(M1Low, M2Low), pOutput);
|
||||
}
|
||||
|
||||
|
||||
#define DEFINE_SAFE_MULT_U32(_Name, _Type, _Convert) \
|
||||
__checkReturn \
|
||||
__forceinline \
|
||||
INTSAFE_RESULT \
|
||||
INTSAFE_NAME(_Name)( \
|
||||
_In_ _Type Multiplicand, \
|
||||
_In_ _Type Multiplier, \
|
||||
_Out_ _Deref_out_range_(==, Multiplicand * Multiplier) _Type* pOutput) \
|
||||
{ \
|
||||
ULONGLONG Result = UInt32x32To64(Multiplicand, Multiplier); \
|
||||
return INTSAFE_NAME(_Convert)(Result, pOutput); \
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
DEFINE_SAFE_MULT_U32(SizeTMult, size_t, ULongLongToSizeT)
|
||||
DEFINE_SAFE_MULT_U32(SIZETMult, SIZE_T, ULongLongToSIZET)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _NTINTSAFE_H_INCLUDED_
|
||||
|
||||
#define RtlUInt16Add RtlUShortAdd
|
||||
#define RtlWordAdd RtlUShortAdd
|
||||
#define RtlUInt32Add RtlUIntAdd
|
||||
#define RtlDWordAdd RtlULongAdd
|
||||
#define RtlDWordLongAdd RtlULongLongAdd
|
||||
#define RtlULong64Add RtlULongLongAdd
|
||||
#define RtlDWord64Add RtlULongLongAdd
|
||||
#define RtlUInt64Add RtlULongLongAdd
|
||||
#define RtlUInt16Sub RtlUShortSub
|
||||
#define RtlWordSub RtlUShortSub
|
||||
#define RtlUInt32Sub RtlUIntSub
|
||||
#define RtlDWordSub RtlULongSub
|
||||
#define RtlDWordLongSub RtlULongLongSub
|
||||
#define RtlULong64Sub RtlULongLongSub
|
||||
#define RtlDWord64Sub RtlULongLongSub
|
||||
#define RtlUInt64Sub RtlULongLongSub
|
||||
#ifdef _WIN64
|
||||
#define RtlIntPtrSub RtlLongLongSub
|
||||
#define RtlLongPtrSub RtlLongLongSub
|
||||
#define RtlSizeTMult RtlULongLongMult
|
||||
#define RtlSIZETMult RtlULongLongMult
|
||||
#else
|
||||
#endif
|
||||
|
||||
#else // _NTINTSAFE_H_INCLUDED_
|
||||
|
||||
#define UInt16Add UShortAdd
|
||||
#define WordAdd UShortAdd
|
||||
#define UInt32Add UIntAdd
|
||||
|
@ -499,6 +731,14 @@ DEFINE_SAFE_SUB(ULongLongSub, ULONGLONG)
|
|||
#define ULong64Sub ULongLongSub
|
||||
#define DWord64Sub ULongLongSub
|
||||
#define UInt64Sub ULongLongSub
|
||||
#ifdef _WIN64
|
||||
#define IntPtrSub LongLongSub
|
||||
#define LongPtrSub LongLongSub
|
||||
#define SizeTMult ULongLongMult
|
||||
#define SIZETMult ULongLongMult
|
||||
#else
|
||||
#endif
|
||||
|
||||
#endif // _NTINTSAFE_H_INCLUDED_
|
||||
|
||||
#endif // !_INTSAFE_H_INCLUDED_
|
||||
|
|
Loading…
Reference in a new issue