#include <ifssupp.h>
#endif
+//
+// A system call ID is formatted as such:
+// .________________________________________________________________.
+// | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+// |--------------|-------------------------------------------------|
+// | TABLE NUMBER | TABLE OFFSET |
+// \----------------------------------------------------------------/
+//
+// The table number is then used as an index into the service descriptor table.
+#define TABLE_NUMBER_BITS 1
+#define TABLE_OFFSET_BITS 12
+
+//
+// There are 2 tables (kernel and shadow, used by Win32K)
+//
+#define NUMBER_SERVICE_TABLES 2
+#define NTOS_SERVICE_INDEX 0
+#define WIN32K_SERVICE_INDEX 1
+
+//
+// NB. From assembly code, the table number must be computed as an offset into
+// the service descriptor table.
+//
+// Each entry into the table is 16 bytes long on 32-bit architectures, and
+// 32 bytes long on 64-bit architectures.
+//
+// Thus, Table Number 1 is offset 16 (0x10) on x86, and offset 32 (0x20) on
+// x64.
+//
+#ifdef _WIN64
+#define BITS_PER_ENTRY 5 // (1 << 5) = 32 bytes
+#else
+#define BITS_PER_ENTRY 4 // (1 << 4) = 16 bytes
+#endif
+
+//
+// We want the table number, but leave some extra bits to we can have the offset
+// into the descriptor table.
+//
+#define SERVICE_TABLE_SHIFT (12 - BITS_PER_ENTRY)
+
+//
+// Now the table number (as an offset) is corrupted with part of the table offset
+// This mask will remove the extra unwanted bits, and give us the offset into the
+// descriptor table proper.
+//
+#define SERVICE_TABLE_MASK (((1 << TABLE_NUMBER_BITS) - 1) << BITS_PER_ENTRY)
+
+//
+// To get the table offset (ie: the service call number), just keep the 12 bits
+//
+#define SERVICE_NUMBER_MASK ((1 << TABLE_OFFSET_BITS) - 1)
+
+//
+// We'll often need to check if this is a graphics call. This is done by comparing
+// the table number offset with the known Win32K table number offset.
+// This is usually index 1, so table number offset 0x10 (x86) or 0x20 (x64)
+//
+#define SERVICE_TABLE_TEST (WIN32K_SERVICE_INDEX << BITS_PER_ENTRY)
+
//
// Context Record Flags
//
//
typedef VOID
(NTAPI *PKNORMAL_ROUTINE)(
- IN PVOID NormalContext,
- IN PVOID SystemArgument1,
- IN PVOID SystemArgument2
+ _In_ PVOID NormalContext,
+ _In_ PVOID SystemArgument1,
+ _In_ PVOID SystemArgument2
);
//
//
typedef VOID
(NTAPI *PTIMER_APC_ROUTINE)(
- IN PVOID TimerContext,
- IN ULONG TimerLowValue,
- IN LONG TimerHighValue
+ _In_ PVOID TimerContext,
+ _In_ ULONG TimerLowValue,
+ _In_ LONG TimerHighValue
);
//
PVOID StartContext
);
+#ifndef _NTSYSTEM_
+typedef VOID
+(NTAPI *PKNORMAL_ROUTINE)(
+ IN PVOID NormalContext OPTIONAL,
+ IN PVOID SystemArgument1 OPTIONAL,
+ IN PVOID SystemArgument2 OPTIONAL);
+
+typedef VOID
+(NTAPI *PKRUNDOWN_ROUTINE)(
+ IN struct _KAPC *Apc);
+
+typedef VOID
+(NTAPI *PKKERNEL_ROUTINE)(
+ IN struct _KAPC *Apc,
+ IN OUT PKNORMAL_ROUTINE *NormalRoutine OPTIONAL,
+ IN OUT PVOID *NormalContext OPTIONAL,
+ IN OUT PVOID *SystemArgument1 OPTIONAL,
+ IN OUT PVOID *SystemArgument2 OPTIONAL);
+#endif
+
//
// APC Environment Types
//
InsertApcEnvironment
} KAPC_ENVIRONMENT;
+typedef struct _KTIMER_TABLE_ENTRY
+{
+#if (NTDDI_VERSION >= NTDDI_LONGHORN) || defined(_M_ARM) || defined(_M_AMD64)
+ KSPIN_LOCK Lock;
+#endif
+ LIST_ENTRY Entry;
+ ULARGE_INTEGER Time;
+} KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;
+
+typedef struct _KTIMER_TABLE
+{
+ PKTIMER TimerExpiry[64];
+ KTIMER_TABLE_ENTRY TimerEntries[256];
+} KTIMER_TABLE, *PKTIMER_TABLE;
+
+typedef struct _KDPC_LIST
+{
+ SINGLE_LIST_ENTRY ListHead;
+ SINGLE_LIST_ENTRY* LastEntry;
+} KDPC_LIST, *PKDPC_LIST;
+
+typedef struct _SYNCH_COUNTERS
+{
+ ULONG SpinLockAcquireCount;
+ ULONG SpinLockContentionCount;
+ ULONG SpinLockSpinCount;
+ ULONG IpiSendRequestBroadcastCount;
+ ULONG IpiSendRequestRoutineCount;
+ ULONG IpiSendSoftwareInterruptCount;
+ ULONG ExInitializeResourceCount;
+ ULONG ExReInitializeResourceCount;
+ ULONG ExDeleteResourceCount;
+ ULONG ExecutiveResourceAcquiresCount;
+ ULONG ExecutiveResourceContentionsCount;
+ ULONG ExecutiveResourceReleaseExclusiveCount;
+ ULONG ExecutiveResourceReleaseSharedCount;
+ ULONG ExecutiveResourceConvertsCount;
+ ULONG ExAcqResExclusiveAttempts;
+ ULONG ExAcqResExclusiveAcquiresExclusive;
+ ULONG ExAcqResExclusiveAcquiresExclusiveRecursive;
+ ULONG ExAcqResExclusiveWaits;
+ ULONG ExAcqResExclusiveNotAcquires;
+ ULONG ExAcqResSharedAttempts;
+ ULONG ExAcqResSharedAcquiresExclusive;
+ ULONG ExAcqResSharedAcquiresShared;
+ ULONG ExAcqResSharedAcquiresSharedRecursive;
+ ULONG ExAcqResSharedWaits;
+ ULONG ExAcqResSharedNotAcquires;
+ ULONG ExAcqResSharedStarveExclusiveAttempts;
+ ULONG ExAcqResSharedStarveExclusiveAcquiresExclusive;
+ ULONG ExAcqResSharedStarveExclusiveAcquiresShared;
+ ULONG ExAcqResSharedStarveExclusiveAcquiresSharedRecursive;
+ ULONG ExAcqResSharedStarveExclusiveWaits;
+ ULONG ExAcqResSharedStarveExclusiveNotAcquires;
+ ULONG ExAcqResSharedWaitForExclusiveAttempts;
+ ULONG ExAcqResSharedWaitForExclusiveAcquiresExclusive;
+ ULONG ExAcqResSharedWaitForExclusiveAcquiresShared;
+ ULONG ExAcqResSharedWaitForExclusiveAcquiresSharedRecursive;
+ ULONG ExAcqResSharedWaitForExclusiveWaits;
+ ULONG ExAcqResSharedWaitForExclusiveNotAcquires;
+ ULONG ExSetResOwnerPointerExclusive;
+ ULONG ExSetResOwnerPointerSharedNew;
+ ULONG ExSetResOwnerPointerSharedOld;
+ ULONG ExTryToAcqExclusiveAttempts;
+ ULONG ExTryToAcqExclusiveAcquires;
+ ULONG ExBoostExclusiveOwner;
+ ULONG ExBoostSharedOwners;
+ ULONG ExEtwSynchTrackingNotificationsCount;
+ ULONG ExEtwSynchTrackingNotificationsAccountedCount;
+} SYNCH_COUNTERS, *PSYNCH_COUNTERS;
+
//
// PRCB DPC Data
//
typedef struct _KDPC_DATA
{
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ KDPC_LIST DpcList;
+#else
LIST_ENTRY DpcListHead;
+#endif
ULONG_PTR DpcLock;
-#ifdef _M_AMD64
+#if defined(_M_AMD64) || defined(_M_ARM)
volatile LONG DpcQueueDepth;
#else
volatile ULONG DpcQueueDepth;
#endif
ULONG DpcCount;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN) || defined(_M_ARM)
+ PKDPC ActiveDpc;
+#endif
} KDPC_DATA, *PKDPC_DATA;
//
UCHAR Spare:2;
} KEXECUTE_OPTIONS, *PKEXECUTE_OPTIONS;
+#if (NTDDI_VERSION >= NTDDI_WIN7)
+typedef union _KWAIT_STATUS_REGISTER
+{
+ UCHAR Flags;
+ struct
+ {
+ UCHAR State:2;
+ UCHAR Affinity:1;
+ UCHAR Priority:1;
+ UCHAR Apc:1;
+ UCHAR UserApc:1;
+ UCHAR Alert:1;
+ UCHAR Unused:1;
+ };
+} KWAIT_STATUS_REGISTER, *PKWAIT_STATUS_REGISTER;
+
+typedef struct _COUNTER_READING
+{
+ enum _HARDWARE_COUNTER_TYPE Type;
+ ULONG Index;
+ ULONG64 Start;
+ ULONG64 Total;
+}COUNTER_READING, *PCOUNTER_READING;
+
+typedef struct _KTHREAD_COUNTERS
+{
+ ULONG64 WaitReasonBitMap;
+ struct _THREAD_PERFORMANCE_DATA* UserData;
+ ULONG Flags;
+ ULONG ContextSwitches;
+ ULONG64 CycleTimeBias;
+ ULONG64 HardwareCounters;
+ COUNTER_READING HwCounter[16];
+}KTHREAD_COUNTERS, *PKTHREAD_COUNTERS;
+#endif
+
//
// Kernel Thread (KTHREAD)
//
UCHAR ApcStateFill[FIELD_OFFSET(KAPC_STATE, UserApcPending) + 1];
#if (NTDDI_VERSION >= NTDDI_LONGHORN) // [
SCHAR Priority;
+#if (NTDDI_VERSION >= NTDDI_WIN7) // [
+ /* On x86, the following members "fall out" of the union */
+ volatile ULONG NextProcessor;
+ volatile ULONG DeferredProcessor;
#else // ][
- UCHAR ApcQueueable;
+ /* On x86, the following members "fall out" of the union */
+ volatile USHORT NextProcessor;
+ volatile USHORT DeferredProcessor;
#endif // ]
+#else // ][
+ UCHAR ApcQueueable;
/* On x86, the following members "fall out" of the union */
volatile UCHAR NextProcessor;
-#if (NTDDI_VERSION < NTDDI_WIN7) // [
volatile UCHAR DeferredProcessor;
-#endif // ]
-#if (NTDDI_VERSION < NTDDI_LONGHORN) // [
UCHAR AdjustReason;
SCHAR AdjustIncrement;
#endif // ]
BOOLEAN WaitNext;
#endif // ]
UCHAR WaitReason;
+#if (NTDDI_VERSION < NTDDI_LONGHORN)
SCHAR Priority;
BOOLEAN EnableStackSwap;
+#endif // ]
volatile UCHAR SwapBusy;
BOOLEAN Alerted[MaximumMode];
#endif // ]
#if !defined(_WIN64) // [
};
};
+#endif // ]
#endif // ]
union
{
struct
{
- LONG AutoAlignment:1;
- LONG DisableBoost:1;
+ ULONG AutoAlignment:1;
+ ULONG DisableBoost:1;
#if (NTDDI_VERSION >= NTDDI_LONGHORN) // [
ULONG EtwStackTraceApc1Inserted:1;
ULONG EtwStackTraceApc2Inserted:1;
};
LONG ThreadFlags;
};
-#if defined(_WIN64) // [
+#if defined(_WIN64) && (NTDDI_VERSION < NTDDI_WIN7) // [
};
};
#endif // ]
+#if (NTDDI_VERSION >= NTDDI_WIN7) // [
+#if defined(_WIN64) // [
+ ULONG Spare0;
+#else // ][
+ PVOID ServiceTable;
+#endif // ]
#endif // ]
union
{
UCHAR WaitBlockFill6[2 * sizeof(KWAIT_BLOCK) + FIELD_OFFSET(KWAIT_BLOCK, SpareLong)];
ULONG WaitTime;
};
+#if (NTDDI_VERSION >= NTDDI_WIN7) // [
+ struct
+ {
+ UCHAR WaitBlockFill7[168];
+ PVOID TebMappedLowVa;
+ struct _UMS_CONTROL_BLOCK* Ucb;
+ };
+#endif // ]
struct
{
+#if (NTDDI_VERSION >= NTDDI_WIN7) // [
+ UCHAR WaitBlockFill8[188];
+#else // ][
UCHAR WaitBlockFill7[3 * sizeof(KWAIT_BLOCK) + FIELD_OFFSET(KWAIT_BLOCK, SpareLong)];
+#endif // ]
union
{
struct
union // 2 elements, 0x8 bytes (sizeof)
{
PVOID CallbackStack;
- ULONG64 CallbackDepth;
+ ULONG_PTR CallbackDepth;
};
#else // ][
PVOID CallbackStack;
BOOLEAN Preempted;
UCHAR AdjustReason;
CHAR AdjustIncrement;
- UINT8 Spare01;
+#if (NTDDI_VERSION >= NTDDI_WIN7)
+ UCHAR PreviousMode;
+#else
+ UCHAR Spare01;
+#endif
#endif // ]
CHAR Saturation;
#if (NTDDI_VERSION >= NTDDI_LONGHORN) // [
ULONG SystemCallNumber;
#if (NTDDI_VERSION >= NTDDI_WIN7) // [
- ULONG2 FreezeCount;
+ ULONG FreezeCount;
#else // ][
- ULONG Spare2;
+ ULONG Spare02;
#endif // ]
#endif // ]
- KAFFINITY UserAffinity;
- struct _KPROCESS *Process;
#if (NTDDI_VERSION >= NTDDI_WIN7) // [
+ GROUP_AFFINITY UserAffinity;
+ struct _KPROCESS *Process;
GROUP_AFFINITY Affinity;
ULONG IdealProcessor;
ULONG UserIdealProcessor;
#else // ][
+ KAFFINITY UserAffinity;
+ struct _KPROCESS *Process;
KAFFINITY Affinity;
#endif // ]
PKAPC_STATE ApcStatePointer[2];
#endif // ]
#if (NTDDI_VERSION >= NTDDI_WIN7) // [
#elif (NTDDI_VERSION >= NTDDI_LONGHORN) // ][
- UCHAR Spare3;
+ UCHAR Spare03;
#else // ][
UCHAR CalloutActive;
#endif // ]
PKTHREAD_COUNTERS ThreadCounters;
PXSTATE_SAVE XStateSave;
#elif (NTDDI_VERSION >= NTDDI_LONGHORN) // ][
- PVOID MdlForLockedteb;
+ PVOID MdlForLockedTeb;
#endif // ]
} KTHREAD;
};
ULONG StackCount;
LIST_ENTRY ProcessListEntry;
-#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+#if (NTDDI_VERSION >= NTDDI_LONGHORN) // [
ULONGLONG CycleTime;
-#endif
+#endif // ]
} KPROCESS;
#define ASSERT_PROCESS(object) \