Author: tkreuzer
Date: Tue Jun 19 13:05:23 2012
New Revision: 56750
URL: 
http://svn.reactos.org/svn/reactos?rev=56750&view=rev
Log:
[PSDK]
intsafe.h:
- Fix type redefinitions when ntdef.h is included
- Implement (Rtl)LongLongSub and (Rtl)UlongLongMult
- Add some more definitions
- misc fixes
Modified:
    trunk/reactos/include/psdk/intsafe.h
Modified: trunk/reactos/include/psdk/intsafe.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/intsafe.h?rev…
==============================================================================
--- trunk/reactos/include/psdk/intsafe.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/intsafe.h [iso-8859-1] Tue Jun 19 13:05:23 2012
@@ -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;
+#endif
 #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
-#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
-#endif
+#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 @@
 /* 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 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(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 @@
 #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 @@
     if (Input <= _TypeTo ## _MAX) \
     { \
         *pOutput = (_TypeTo)Input; \
-        return S_OK; \
+        return INTSAFE_SUCCESS; \
     } \
     else \
     { \
@@ -289,6 +313,8 @@
 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 @@
     if ((Input >= 0) && (Input <= _TypeTo ## _MAX)) \
     { \
         *pOutput = (_TypeTo)Input; \
-        return S_OK; \
+        return INTSAFE_SUCCESS; \
     } \
     else \
     { \
@@ -375,7 +401,7 @@
     if ((Input >= _TypeTo ## _MIN) && (Input <= _TypeTo ## _MAX)) \
     { \
         *pOutput = (_TypeTo)Input; \
-        return S_OK; \
+        return INTSAFE_SUCCESS; \
     } \
     else \
     { \
@@ -400,76 +426,47 @@
 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
-#define DEFINE_SAFE_ADD(_Name, _Type) \
-_Must_inspect_result_ \
-__forceinline \
-INTSAFE_RESULT \
-INTSAFE_NAME(_Name)( \
-    _In_ _Type Augend, \
-    _In_ _Type Addend, \
-    _Out_ _Deref_out_range_(==, Augend + Addend) _Type *pOutput) \
-{ \
-    if ((Augend + Addend) >= Augend) \
-    { \
-        *pOutput = Augend + Addend; \
-        return INTSAFE_SUCCESS; \
-    } \
-    else \
-    { \
-        *pOutput = _Type ## _ERROR; \
-        return INTSAFE_E_ARITHMETIC_OVERFLOW; \
-    } \
-}
-
-DEFINE_SAFE_ADD(UInt8Add, UINT8)
-DEFINE_SAFE_ADD(UShortAdd, USHORT)
-DEFINE_SAFE_ADD(UIntAdd, UINT)
-DEFINE_SAFE_ADD(UlongAdd, ULONG)
-DEFINE_SAFE_ADD(UIntPtrAdd, UINT_PTR)
-DEFINE_SAFE_ADD(ULongPtrAdd, ULONG_PTR)
-DEFINE_SAFE_ADD(DWordPtrAdd, DWORD_PTR)
-DEFINE_SAFE_ADD(SizeTAdd, size_t)
-DEFINE_SAFE_ADD(SIZETAdd, SIZE_T)
-DEFINE_SAFE_ADD(ULongLongAdd, ULONGLONG)
-
-
-#define DEFINE_SAFE_SUB(_Name, _Type) \
-_Must_inspect_result_ \
-__forceinline \
-INTSAFE_RESULT \
-INTSAFE_NAME(_Name)( \
-    _In_ _Type Minuend, \
-    _In_ _Type Subtrahend, \
-    _Out_ _Deref_out_range_(==, Minuend - Subtrahend) _Type* pOutput) \
-{ \
-    if (Minuend >= Subtrahend) \
-    { \
-        *pOutput = Minuend - Subtrahend; \
-        return INTSAFE_SUCCESS; \
-    } \
-    else \
-    { \
-        *pOutput = _Type ## _ERROR; \
-        return INTSAFE_E_ARITHMETIC_OVERFLOW; \
-    } \
-}
-
-DEFINE_SAFE_SUB(UInt8Sub, UINT8)
-DEFINE_SAFE_SUB(UShortSub, USHORT)
-DEFINE_SAFE_SUB(UIntSub, UINT)
-DEFINE_SAFE_SUB(UIntPtrSub, UINT_PTR)
-DEFINE_SAFE_SUB(ULongSub, ULONG)
-DEFINE_SAFE_SUB(ULongPtrSub, ULONG_PTR)
-DEFINE_SAFE_SUB(DWordPtrSub, DWORD_PTR)
-DEFINE_SAFE_SUB(SizeTSub, size_t)
-DEFINE_SAFE_SUB(SIZETSub, SIZE_T)
-DEFINE_SAFE_SUB(ULongLongSub, ULONGLONG)
-
+
+#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
@@ -483,6 +480,241 @@
 #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 \
+INTSAFE_RESULT \
+INTSAFE_NAME(_Name)( \
+    _In_ _Type Augend, \
+    _In_ _Type Addend, \
+    _Out_ _Deref_out_range_(==, Augend + Addend) _Type *pOutput) \
+{ \
+    if ((Augend + Addend) >= Augend) \
+    { \
+        *pOutput = Augend + Addend; \
+        return INTSAFE_SUCCESS; \
+    } \
+    else \
+    { \
+        *pOutput = _Type ## _ERROR; \
+        return INTSAFE_E_ARITHMETIC_OVERFLOW; \
+    } \
+}
+
+DEFINE_SAFE_ADD(UInt8Add, UINT8)
+DEFINE_SAFE_ADD(UShortAdd, USHORT)
+DEFINE_SAFE_ADD(UIntAdd, UINT)
+DEFINE_SAFE_ADD(UlongAdd, ULONG)
+DEFINE_SAFE_ADD(UIntPtrAdd, UINT_PTR)
+DEFINE_SAFE_ADD(ULongPtrAdd, ULONG_PTR)
+DEFINE_SAFE_ADD(DWordPtrAdd, DWORD_PTR)
+DEFINE_SAFE_ADD(SizeTAdd, size_t)
+DEFINE_SAFE_ADD(SIZETAdd, SIZE_T)
+DEFINE_SAFE_ADD(ULongLongAdd, ULONGLONG)
+
+
+#define DEFINE_SAFE_SUB(_Name, _Type) \
+_Must_inspect_result_ \
+__forceinline \
+INTSAFE_RESULT \
+INTSAFE_NAME(_Name)( \
+    _In_ _Type Minuend, \
+    _In_ _Type Subtrahend, \
+    _Out_ _Deref_out_range_(==, Minuend - Subtrahend) _Type* pOutput) \
+{ \
+    if (Minuend >= Subtrahend) \
+    { \
+        *pOutput = Minuend - Subtrahend; \
+        return INTSAFE_SUCCESS; \
+    } \
+    else \
+    { \
+        *pOutput = _Type ## _ERROR; \
+        return INTSAFE_E_ARITHMETIC_OVERFLOW; \
+    } \
+}
+
+DEFINE_SAFE_SUB(UInt8Sub, UINT8)
+DEFINE_SAFE_SUB(UShortSub, USHORT)
+DEFINE_SAFE_SUB(UIntSub, UINT)
+DEFINE_SAFE_SUB(UIntPtrSub, UINT_PTR)
+DEFINE_SAFE_SUB(ULongSub, ULONG)
+DEFINE_SAFE_SUB(ULongPtrSub, ULONG_PTR)
+DEFINE_SAFE_SUB(DWordPtrSub, DWORD_PTR)
+DEFINE_SAFE_SUB(SizeTSub, size_t)
+DEFINE_SAFE_SUB(SIZETSub, SIZE_T)
+DEFINE_SAFE_SUB(ULongLongSub, ULONGLONG)
+
+
+_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 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_