📄 wdm.h
字号:
ULONG UnsignedInteger
);
//
// Large integer shift routines.
//
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlLargeIntegerShiftLeft (
LARGE_INTEGER LargeInteger,
CCHAR ShiftCount
);
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlLargeIntegerShiftRight (
LARGE_INTEGER LargeInteger,
CCHAR ShiftCount
);
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlLargeIntegerArithmeticShift (
LARGE_INTEGER LargeInteger,
CCHAR ShiftCount
);
#else
#pragma warning(disable:4035) // re-enable below
//
// Convert signed integer to large integer.
//
__inline LARGE_INTEGER
NTAPI
RtlConvertLongToLargeInteger (
LONG SignedInteger
)
{
__asm {
mov eax, SignedInteger
cdq ; (edx:eax) = signed LargeInt
}
}
//
// Convert unsigned integer to large integer.
//
__inline LARGE_INTEGER
NTAPI
RtlConvertUlongToLargeInteger (
ULONG UnsignedInteger
)
{
__asm {
sub edx, edx ; zero highpart
mov eax, UnsignedInteger
}
}
//
// Large integer shift routines.
//
__inline LARGE_INTEGER
NTAPI
RtlLargeIntegerShiftLeft (
LARGE_INTEGER LargeInteger,
CCHAR ShiftCount
)
{
__asm {
mov cl, ShiftCount
and cl, 0x3f ; mod 64
cmp cl, 32
jc short sl10
mov edx, LargeInteger.LowPart ; ShiftCount >= 32
xor eax, eax ; lowpart is zero
shl edx, cl ; store highpart
jmp short done
sl10:
mov eax, LargeInteger.LowPart ; ShiftCount < 32
mov edx, LargeInteger.HighPart
shld edx, eax, cl
shl eax, cl
done:
}
}
__inline LARGE_INTEGER
NTAPI
RtlLargeIntegerShiftRight (
LARGE_INTEGER LargeInteger,
CCHAR ShiftCount
)
{
__asm {
mov cl, ShiftCount
and cl, 0x3f ; mod 64
cmp cl, 32
jc short sr10
mov eax, LargeInteger.HighPart ; ShiftCount >= 32
xor edx, edx ; lowpart is zero
shr eax, cl ; store highpart
jmp short done
sr10:
mov eax, LargeInteger.LowPart ; ShiftCount < 32
mov edx, LargeInteger.HighPart
shrd eax, edx, cl
shr edx, cl
done:
}
}
__inline LARGE_INTEGER
NTAPI
RtlLargeIntegerArithmeticShift (
LARGE_INTEGER LargeInteger,
CCHAR ShiftCount
)
{
__asm {
mov cl, ShiftCount
and cl, 3fh ; mod 64
cmp cl, 32
jc short sar10
mov eax, LargeInteger.HighPart
sar eax, cl
bt eax, 31 ; sign bit set?
sbb edx, edx ; duplicate sign bit into highpart
jmp short done
sar10:
mov eax, LargeInteger.LowPart ; (eax) = LargeInteger.LowPart
mov edx, LargeInteger.HighPart ; (edx) = LargeInteger.HighPart
shrd eax, edx, cl
sar edx, cl
done:
}
}
#pragma warning(default:4035)
#endif
//
// Large integer comparison routines.
//
// BOOLEAN
// RtlLargeIntegerGreaterThan (
// LARGE_INTEGER Operand1,
// LARGE_INTEGER Operand2
// );
//
// BOOLEAN
// RtlLargeIntegerGreaterThanOrEqualTo (
// LARGE_INTEGER Operand1,
// LARGE_INTEGER Operand2
// );
//
// BOOLEAN
// RtlLargeIntegerEqualTo (
// LARGE_INTEGER Operand1,
// LARGE_INTEGER Operand2
// );
//
// BOOLEAN
// RtlLargeIntegerNotEqualTo (
// LARGE_INTEGER Operand1,
// LARGE_INTEGER Operand2
// );
//
// BOOLEAN
// RtlLargeIntegerLessThan (
// LARGE_INTEGER Operand1,
// LARGE_INTEGER Operand2
// );
//
// BOOLEAN
// RtlLargeIntegerLessThanOrEqualTo (
// LARGE_INTEGER Operand1,
// LARGE_INTEGER Operand2
// );
//
// BOOLEAN
// RtlLargeIntegerGreaterThanZero (
// LARGE_INTEGER Operand
// );
//
// BOOLEAN
// RtlLargeIntegerGreaterOrEqualToZero (
// LARGE_INTEGER Operand
// );
//
// BOOLEAN
// RtlLargeIntegerEqualToZero (
// LARGE_INTEGER Operand
// );
//
// BOOLEAN
// RtlLargeIntegerNotEqualToZero (
// LARGE_INTEGER Operand
// );
//
// BOOLEAN
// RtlLargeIntegerLessThanZero (
// LARGE_INTEGER Operand
// );
//
// BOOLEAN
// RtlLargeIntegerLessOrEqualToZero (
// LARGE_INTEGER Operand
// );
//
#define RtlLargeIntegerGreaterThan(X,Y) ( \
(((X).HighPart == (Y).HighPart) && ((X).LowPart > (Y).LowPart)) || \
((X).HighPart > (Y).HighPart) \
)
#define RtlLargeIntegerGreaterThanOrEqualTo(X,Y) ( \
(((X).HighPart == (Y).HighPart) && ((X).LowPart >= (Y).LowPart)) || \
((X).HighPart > (Y).HighPart) \
)
#define RtlLargeIntegerEqualTo(X,Y) ( \
!(((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)) \
)
#define RtlLargeIntegerNotEqualTo(X,Y) ( \
(((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)) \
)
#define RtlLargeIntegerLessThan(X,Y) ( \
(((X).HighPart == (Y).HighPart) && ((X).LowPart < (Y).LowPart)) || \
((X).HighPart < (Y).HighPart) \
)
#define RtlLargeIntegerLessThanOrEqualTo(X,Y) ( \
(((X).HighPart == (Y).HighPart) && ((X).LowPart <= (Y).LowPart)) || \
((X).HighPart < (Y).HighPart) \
)
#define RtlLargeIntegerGreaterThanZero(X) ( \
(((X).HighPart == 0) && ((X).LowPart > 0)) || \
((X).HighPart > 0 ) \
)
#define RtlLargeIntegerGreaterOrEqualToZero(X) ( \
(X).HighPart >= 0 \
)
#define RtlLargeIntegerEqualToZero(X) ( \
!((X).LowPart | (X).HighPart) \
)
#define RtlLargeIntegerNotEqualToZero(X) ( \
((X).LowPart | (X).HighPart) \
)
#define RtlLargeIntegerLessThanZero(X) ( \
((X).HighPart < 0) \
)
#define RtlLargeIntegerLessOrEqualToZero(X) ( \
((X).HighPart < 0) || !((X).LowPart | (X).HighPart) \
)
//
// Time conversion routines
//
typedef struct _TIME_FIELDS {
CSHORT Year; // range [1601...]
CSHORT Month; // range [1..12]
CSHORT Day; // range [1..31]
CSHORT Hour; // range [0..23]
CSHORT Minute; // range [0..59]
CSHORT Second; // range [0..59]
CSHORT Milliseconds;// range [0..999]
CSHORT Weekday; // range [0..6] == [Sunday..Saturday]
} TIME_FIELDS;
typedef TIME_FIELDS *PTIME_FIELDS;
NTSYSAPI
VOID
NTAPI
RtlTimeToTimeFields (
PLARGE_INTEGER Time,
PTIME_FIELDS TimeFields
);
//
// A time field record (Weekday ignored) -> 64 bit Time value
//
NTSYSAPI
BOOLEAN
NTAPI
RtlTimeFieldsToTime (
PTIME_FIELDS TimeFields,
PLARGE_INTEGER Time
);
//
// The following macros store and retrieve USHORTS and ULONGS from potentially
// unaligned addresses, avoiding alignment faults. they should probably be
// rewritten in assembler
//
#define SHORT_SIZE (sizeof(USHORT))
#define SHORT_MASK (SHORT_SIZE - 1)
#define LONG_SIZE (sizeof(LONG))
#define LONG_MASK (LONG_SIZE - 1)
#define LOWBYTE_MASK 0x00FF
#define FIRSTBYTE(VALUE) (VALUE & LOWBYTE_MASK)
#define SECONDBYTE(VALUE) ((VALUE >> 8) & LOWBYTE_MASK)
#define THIRDBYTE(VALUE) ((VALUE >> 16) & LOWBYTE_MASK)
#define FOURTHBYTE(VALUE) ((VALUE >> 24) & LOWBYTE_MASK)
//
// if MIPS Big Endian, order of bytes is reversed.
//
#define SHORT_LEAST_SIGNIFICANT_BIT 0
#define SHORT_MOST_SIGNIFICANT_BIT 1
#define LONG_LEAST_SIGNIFICANT_BIT 0
#define LONG_3RD_MOST_SIGNIFICANT_BIT 1
#define LONG_2ND_MOST_SIGNIFICANT_BIT 2
#define LONG_MOST_SIGNIFICANT_BIT 3
//++
//
// VOID
// RtlStoreUshort (
// PUSHORT ADDRESS
// USHORT VALUE
// )
//
// Routine Description:
//
// This macro stores a USHORT value in at a particular address, avoiding
// alignment faults.
//
// Arguments:
//
// ADDRESS - where to store USHORT value
// VALUE - USHORT to store
//
// Return Value:
//
// none.
//
//--
#define RtlStoreUshort(ADDRESS,VALUE) \
if ((ULONG)ADDRESS & SHORT_MASK) { \
((PUCHAR) ADDRESS)[SHORT_LEAST_SIGNIFICANT_BIT] = (UCHAR)(FIRSTBYTE(VALUE)); \
((PUCHAR) ADDRESS)[SHORT_MOST_SIGNIFICANT_BIT ] = (UCHAR)(SECONDBYTE(VALUE)); \
} \
else { \
*((PUSHORT) ADDRESS) = (USHORT) VALUE; \
}
//++
//
// VOID
// RtlStoreUlong (
// PULONG ADDRESS
// ULONG VALUE
// )
//
// Routine Description:
//
// This macro stores a ULONG value in at a particular address, avoiding
// alignment faults.
//
// Arguments:
//
// ADDRESS - where to store ULONG value
// VALUE - ULONG to store
//
// Return Value:
//
// none.
//
// Note:
// Depending on the machine, we might want to call storeushort in the
// unaligned case.
//
//--
#define RtlStoreUlong(ADDRESS,VALUE) \
if ((ULONG)ADDRESS & LONG_MASK) { \
((PUCHAR) ADDRESS)[LONG_LEAST_SIGNIFICANT_BIT ] = (UCHAR)(FIRSTBYTE(VALUE)); \
((PUCHAR) ADDRESS)[LONG_3RD_MOST_SIGNIFICANT_BIT ] = (UCHAR)(SECONDBYTE(VALUE)); \
((PUCHAR) ADDRESS)[LONG_2ND_MOST_SIGNIFICANT_BIT ] = (UCHAR)(THIRDBYTE(VALUE)); \
((PUCHAR) ADDRESS)[LONG_MOST_SIGNIFICANT_BIT ] = (UCHAR)(FOURTHBYTE(VALUE)); \
} \
else { \
*((PULONG) ADDRESS) = (ULONG) VALUE; \
}
//++
//
// VOID
// RtlRetrieveUshort (
// PUSHORT DESTINATION_ADDRESS
// PUSHORT SOURCE_ADDRESS
// )
//
// Routine Description:
//
// This macro retrieves a USHORT value from the SOURCE address, avoiding
// alignment faults. The DESTINATION address is assumed to be aligned.
//
// Arguments:
//
// DESTINATION_ADDRESS - where to store USHORT value
// SOURCE_ADDRESS - where to retrieve USHORT value from
//
// Return Value:
//
// none.
//
//--
#define RtlRetrieveUshort(DEST_ADDRESS,SRC_ADDRESS) \
if ((ULONG)SRC_ADDRESS & SHORT_MASK) { \
((PUCHAR) DEST_ADDRESS)[0] = ((PUCHAR) SRC_ADDRESS)[0]; \
((PUCHAR) DEST_ADDRESS)[1] = ((PUCHAR) SRC_ADDRESS)[1]; \
} \
else { \
*((PUSHORT) DEST_ADDRESS) = *((PUSHORT) SRC_ADDRESS); \
} \
//++
//
// VOID
// RtlRetrieveUlong (
// PULONG DESTINATION_ADDRESS
// PULONG SOURCE_ADDRESS
// )
//
// Routine Description:
//
// This macro retrieves a ULONG value from the SOURCE address, avoiding
// alignment faults. The DESTINATION address is assumed to be aligned.
//
// Arguments:
//
// DESTINATION_ADDRESS - where to store ULONG value
// SOURCE_ADDRESS - where to retrieve ULONG value from
//
// Return Value:
//
// none.
//
// Note:
// Depending on the machine, we might want to call retrieveushort in the
// unaligned case.
//
//--
#define RtlRetrieveUlong(DEST_ADDRESS,SRC_ADDRESS) \
if ((ULONG)SRC_ADDRESS & LONG_MASK) { \
((PUCHAR) DEST_ADDRESS)[0] = ((PUCHAR) SRC_ADDRESS)[0]; \
((PUCHAR) DEST_ADDRESS)[1] = ((PUCHAR) SRC_ADDRESS)[1]; \
((PUCHAR) DEST_ADDRESS)[2] = ((PUCHAR) SRC_ADDRESS)[2]; \
((PUCHAR) DEST_ADDRESS)[3] = ((PUCHAR) SRC_ADDRESS)[3]; \
} \
else { \
*((PULONG) DEST_ADDRESS) = *((PULONG) SRC_ADDRESS); \
}
//
// Define the various device type values. Note that values used by Microsoft
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
// by customers.
//
#define DEVICE_TYPE ULONG
#define FILE_DEVICE_BEEP 0x00000001
#define FILE_DEVICE_CD_ROM 0x00000002
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -