Geoff Chappell, Software Analyst
SKETCH OF HOW RESEARCH MIGHT CONTINUE AND RESULTS BE PRESENTED
The KTHREAD structure is the Kernel Core’s portion of the ETHREAD structure. The latter is the thread object as exposed through the Object Manager. The KTHREAD is the core of it.
The KTHREAD structure is plainly internal to the kernel and its layout changes greatly between Windows versions and even between builds. That said, the structure’s variability seems to have settled. Changes have mostly been by expansion:
Version | Size (x86) | Size (x64) |
---|---|---|
6.2 | 0x01E8 | 0x0348 |
6.3 | 0x0338 | 0x05D0 |
10.0 | 0x0348 | 0x05D8 |
These sizes, and the offsets, types and names in the tables that follow, are from Microsoft’s symbol files for the kernel.
It is well known that the KTHREAD begins with a DISPATCHER_HEADER in which the Type is 6, i.e., ThreadObject in the KOBJECTS enumeration.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks | History |
---|---|---|---|---|---|
0x00 | 0x00 |
DISPATCHER_HEADER Header; |
6.2 and higher | previously at 0x00 | |
0x10 | 0x18 |
PVOID SListFaultAddress; |
6.2 and higher | previously at 0x01F0 and 0x0318 | |
0x18 | 0x20 |
ULONGLONG QuantumTarget; |
6.2 and higher | previously at 0x20 (both) | |
0x20 | 0x28 |
PVOID InitialStack; |
6.2 and higher | previously at 0x28 (both) | |
0x24 | 0x30 |
PVOID volatile StackLimit; |
6.2 and higher | previously at 0x2C and 0x30 | |
0x28 | 0x38 |
PVOID StackBase; |
6.2 and higher | previously at 0x0190 and 0x0278 | |
0x2C | 0x40 |
KSPIN_LOCK ThreadLock; |
6.2 and higher | previously at 0x34 and 0x40 | |
0x30 | 0x48 |
ULONGLONG volatile CycleTime; |
6.2 and higher | previously at 0x10 and 0x18 | |
0x38 |
ULONG volatile HighCycleTime; |
6.2 and higher | x86 only | previously at 0x18 | |
0x3C |
PVOID ServiceTable; |
6.2 and higher | x86 only | previously at 0xBC | |
0x40 | 0x50 |
ULONG CurrentRunTime; |
6.2 and higher | ||
0x44 | 0x54 |
ULONG ExpectedRunTime; |
6.2 and higher | ||
0x48 | 0x58 |
PVOID KernelStack; |
6.2 and higher | previously at 0x30 and x038 | |
0x4C | 0x60 |
XSAVE_FORMAT *StateSaveArea; |
6.2 and higher | ||
0x50 | 0x68 |
KSCHEDULING_GROUP *SchedulingGroup; |
6.2 and higher | ||
0x54 | 0x70 |
KWAIT_STATUS_REGISTER WaitRegister; |
6.2 and higher | previously at 0x38 and 0x48 | |
0x55 | 0x71 |
BOOLEAN volatile Running; |
6.2 and higher | previously at 0x39 and 0x49 | |
0x56 | 0x72 |
BOOLEAN Alerted [2]; |
6.2 and higher | previously at 0x3A and 0x4A | |
0x58 | 0x74 |
union { struct { /* bit fields, follow link */ }; LONG MiscFlags; }; |
6.2 and higher | previously at 0x3C and 0x4C | |
0x5C | 0x78 |
union { struct { /* bit fields, follow link */ }; LONG volatile ThreadFlags; }; |
6.2 and higher | previously at 0xB8 and 0x0100 | |
0x60 | 0x7C |
ULONG Spare0; |
6.2 to 6.3 | ||
UCHAR volatile Tag; |
10.0 and higher | ||||
0x61 | 0x7D |
UCHAR SystemHeteroCpuPolicy; |
10.0 and higher | ||
0x62 | 0x7E |
union { UCHAR UserHeteroCpuPolicy : 7; UCHAR ExplicitSystemHeteroCpuPolicy : 1; }; |
10.0 and higher | ||
0x63 | 0x7F |
UCHAR Spare0; |
10.0 and higher | ||
0x64 | 0x80 |
ULONG SystemCallNumber; |
6.2 and higher | previously at 0x013C and 0x01F8 | |
0x84 |
ULONG Spare1; |
6.2 and higher | |||
0x68 | 0x88 |
PVOID FirstArgument; |
6.2 and higher | previously at 0x012C and 0x01E0 | |
0x6C | 0x90 |
KTRAP_FRAME *TrapFrame; |
6.2 and higher | previously at 0x0128 and 0x01D8 | |
0x70 | 0x98 |
union { KAPC_STATE ApcState; /* overlay, see below */ }; |
6.2 and higher | previously at 0x40 and 0x50 |
Overlaying the ApcState is first some padding to get past the defined members of the KAPC_STATE to the space that’s left for alignment:
struct { UCHAR ApcStateFill [KAPC_STATE_ACTUAL_LENGTH]; /* 5 bytes, see below */ };
With this construction, the 64-bit builds squeeze five bytes into the end of the 0x30-byte ApcState. In 32-bit builds, only the first fits the 0x18-byte ApcState: the remaining four just follow as if they had been declared outside the union. Disregard the construction, and the members that are packed with the ApcState are:
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x87 | 0xC3 |
CHAR Priority; |
6.2 and higher | previously at 0x57 and 0x7B |
0x88 | 0xC4 |
ULONG UserIdealProcessor; |
6.2 and higher | previously at 0x0164 and 0x022C |
The structures used for larger members of the KTHREAD tend to have more spare space in the 64-bit builds, whose wider pointers have a wider alignment requirement. There follow a few members that aren’t treated to the packing game in the 32-bit builds. The 64-bit builds pack them with the WaitBlock member (see below).
Offset (x86) | Offset (x64) | Definition | Versions | Remarks | History |
---|---|---|---|---|---|
0x8C |
ULONG ContextSwitches; |
6.2 and higher | for x64, see below | previously at 0x64 | |
0x90 |
UCHAR volatile State; |
6.2 and higher | for x64, see below | previously at 0x68 | |
0x91 |
CHAR NpxState; |
6.2 to 6.3 | for x64, see below; next as LONGLONG at 0x0340 |
previously as UCHAR at 0x69 | |
CHAR Spare12; |
10.0 and higher | ||||
0x92 |
KIRQL WaitIrql; |
6.2 and higher | for x64, see below | previously at 0x6A | |
0x93 |
KPROCESSOR_MODE WaitMode; |
6.2 and higher | for x64, see below | previously at 0x6B | |
0x94 | 0xC8 |
LONG_PTR WaitStatus; |
6.2 and higher | previously at 0x6C and 0x90 | |
0x98 | 0xD0 |
KWAIT_BLOCK *WaitBlockList; |
6.2 and higher | previously at 0x70 and 0x98 | |
0x9C | 0xD8 |
union { LIST_ENTRY WaitListEntry; SINGLE_LIST_ENTRY SwapListEntry; }; |
6.2 and higher | previously at 0x74 and 0xA0 | |
0xA4 | 0xE8 |
KQUEUE *Queue; |
6.2 and higher | previously at 0x7C and 0xB0 | |
0xA8 | 0xF0 |
PVOID Teb; |
6.2 and higher | previously at 0x88 and 0xB8 | |
0xB0 | 0xF8 |
ULONGLONG RelativeTimerBias; |
6.2 and higher | ||
0xB8 | 0x0100 |
KTIMER Timer; |
6.2 and higher | previously as union at 0x90 and 0xC0 | |
0xE0 | 0x0140 |
union { KWAIT_BLOCK WaitBlock4; /* overlay, see below */ }; |
6.2 and higher | previously without union at 0xC0 (x86); previously as changed union at 0x0108 (x64) |
Overlaying the long-standing WaitBlock are a succession of structures that pad to spare or resuable members:
#ifdef _AMD64_ // SpareLong exists only for x64 struct { UCHAR WaitBlockFill4 [FIELD_OFFSET (KWAIT_BLOCK, SpareLong)]; /* reclaimed 4 bytes, see below */ }; struct { UCHAR WaitBlockFill5 [FIELD_OFFSET (KWAIT_BLOCK, SpareLong) + sizeof (KWAIT_BLOCK)]; /* reclaimed 4 bytes, see below */ }; struct { UCHAR WaitBlockFill6 [FIELD_OFFSET (KWAIT_BLOCK, SpareLong) + 2 * sizeof (KWAIT_BLOCK)]; /* reclaimed 4 bytes, see below */ }; struct { UCHAR WaitBlockFill7 [FIELD_OFFSET (KWAIT_BLOCK, SpareLong) + 3 * sizeof (KWAIT_BLOCK)]; /* reclaimed 4 bytes, see below */ }; #endif struct { UCHAR WaitBlockFill8 [FIELD_OFFSET (KWAIT_BLOCK, SparePtr)]; /* reclaimed 4 or 8 bytes, see below */ }; struct { UCHAR WaitBlockFill9 [FIELD_OFFSET (KWAIT_BLOCK, SparePtr) + sizeof (KWAIT_BLOCK)]; /* reclaimed 4 or 8 bytes, see below */ }; struct { UCHAR WaitBlockFill10 [FIELD_OFFSET (KWAIT_BLOCK, SparePtr) + 2 * sizeof (KWAIT_BLOCK)]; /* reclaimed 4 or 8 bytes, see below */ }; struct { UCHAR WaitBlockFill11 [FIELD_OFFSET (KWAIT_BLOCK, Object) + 3 * sizeof (KWAIT_BLOCK)]; /* reclaimed 8 or 16 bytes, see below */ ;
The KWAIT_BLOCK structure changed for version 6.2. The x86 builds had an explicitly spare byte and the x64 builds had both this an explicitly spare long. In version 6.2 and higher, both have an explicitly spare pointer and the x64 builds still have the spare long too. With the KTHREAD having four of these structures, packing members into these spares is certainly worthwhile, even if it’s beyond messy. Moroever, for the particular use that the KTHREAD makes of the last KWAIT_BLOCK in the array, the Object member is known to be irrelevant and is therefore also available for reuse.
Disregard all this scaffolding and here are the members that get squeezed in with the WaitBlock array:
Offset (x86) | Offset (x64) | Definition | Versions | Remarks | History |
---|---|---|---|---|---|
0x0154 |
ULONG ContextSwitches; |
6.2 and higher | for x86, see above | previously at 0x0134 | |
0xF4 | 0x0168 |
KTHREAD_COUNTERS *ThreadCounters; |
6.2 and higher | previously at 0x01F4 and 0x0350 | |
0x0184 |
UCHAR volatile State; |
6.2 and higher | for x86, see above | previously at 0x0164 | |
0x0185 |
CHAR NpxState; |
6.2 to 6.3 | for x86, see above; next as LONGLONG at 0x0250 |
previously as UCHAR at 0x0165 | |
CHAR Spare13; |
10.0 and higher | ||||
0x0186 |
KIRQL WaitIrql; |
6.2 and higher | for x86, see above | previously at 0x0166 | |
0x0187 |
KPROCESSOR_MODE WaitMode; |
6.2 and higher | for x86, see above | previously at 0x0167 | |
0x010C | 0x0198 |
XSTATE_SAVE *XStateSave; |
6.2 and higher | previously at 0x01F8 and 0x0358 | |
0x01B4 |
ULONG WaitTime; |
6.2 and higher | for x86, see below | previously at 0x0194 | |
0x0124 | 0x01C8 |
PVOID volatile Win32Thread; |
6.2 and higher | previously at 0x018C and 0x0270 | |
0x01E4 |
union { struct { SHORT KernelApcDisable; SHORT SpecialApcDisable; }; ULONG CombinedApcDisable; }; |
6.2 and higher | for x86, see below | previously at 0x01C4 | |
0x0138 |
ULONG WaitTime; |
6.2 and higher | for x64, see above | previously at 0x7C | |
0x01F0 |
UMS_CONTROL_BLOCK *Ucb; |
6.2 and higher | x64 only | previously at 0x01B8 | |
0x01F8 |
KUMS_CONTEXT_HEADER *Uch; |
6.2 and higher | x64 only |
Note that WaitTime is listed twice above. Because it is packed with the spare object in 32-bit builds but the spare long in 64-bit builds, it is ordered differently with respect to Win32Thread. The union of members that count the depth of requests to disable APC delivery is another example that isn’t packed into spare space in the x86 builds:
Offset (x86) | Offset (x64) | Definition | Versions | Remarks | History |
---|---|---|---|---|---|
0x013C |
union { struct { SHORT KernelApcDisable; SHORT SpecialApcDisable; }; ULONG CombinedApcDisable; }; |
6.2 and higher | for x64, see above | previously at 0x84 | |
0x0200 |
PVOID TebMappedLowVa; |
6.2 and higher | x64 only | previously at 0x01B0 | |
0x0140 | 0x0208 |
LIST_ENTRY QueueListEntry; |
6.2 and higher | previously at 0x0120 and 0x01C8 | |
0x0148 | 0x0218 |
ULONG volatile NextProcessor; |
6.2 only | previously at 0x58 and 0x7C | |
union { ULONG volatile NextProcessor; struct { ULONG NextProcessorNumber : 31; ULONG SharedReadyQueue : 1; }; }; |
6.3 and higher | ||||
0x014C | 0x021C |
ULONG volatile DeferredProcessor; |
6.2 only | previously at 0x5C and 0x80 | |
LONG QueuePriority; |
6.3 and higher | ||||
0x0150 | 0x0220 |
KPROCESS *Process; |
6.2 and higher | previously at 0x0150 and 0x0210 | |
0x0154 | 0x0228 |
union { GROUP_AFFINITY volatile UserAffinity; /* overlay, see below */ }; |
6.2 and higher | previously without union at 0x0144 and 0x0200 |
Version 6.1, with its support for potentially many more processors, changed UserAffinity and Affinity from KAFFINITY to GROUP_AFFINITY. The latter has six bytes explicitly labelled as Reserved. Version 6.1 doesn’t pack anything into them, but version 6.2 goes all the way. Overlaying UserAffinity is:
struct { UCHAR UserAffinityFill [FIELD_OFFSET (GROUP_AFFINITY, Reserved)]; /* reclaimed 6 bytes, see below */ };
Reclaimed from UserAffinity:
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x015A | 0x0232 |
KPROCESSOR_MODE PreviousMode; |
6.2 and higher | previously at 0x013A and 0x01F6 |
0x015B | 0x0233 |
CHAR BasePriority; |
6.2 and higher | previously at 0x0135 and 0x01F1 |
0x015C | 0x0234 |
union { CHAR PriorityDecrement; struct { UCHAR ForegroundBoost : 4; UCHAR UnusualBoost : 4; }; }; |
6.2 and higher | previously at 0x0136 and 0x01F2 |
0x015D | 0x0235 |
BOOLEAN Preempted; |
6.2 and higher | previously at 0x0137 and 0x01F3 |
0x015E | 0x0236 |
UCHAR AdjustReason; |
6.2 and higher | previously at 0x0138 and 0x01F4 |
0x015F | 0x0237 |
CHAR AdjustIncrement; |
6.2 and higher | previously at 0x0139 and 0x01F5 |
Insertion of the AffinityVersion for Windows 10 produces the first change of offset for any KTHREAD member since Windows 8.
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x0160 | 0x0238 |
ULONG AffinityVersion; |
10.0 and higher | |
0x0160 (6.2 to 6.3); 0x0164 |
0x0238 (6.2 to 6.3); 0x0240 |
union { GROUP_AFFINITY volatile Affinity; /* overlay, see below */ }; |
6.2 and higher | previously at 0x0154 and 0x0218 |
Overlaying Affinity:
struct { UCHAR AffinityFill [FIELD_OFFSET (GROUP_AFFINITY, Reserved)]; /* reclaimed 6 bytes, see below */ };
Reclaimed from Affinity:
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x0166 (6.2 to 6.3); 0x016A |
0x0242 (6.2 to 6.3); 0x024A |
UCHAR ApcStateIndex; |
6.2 and higher | previously at 0x0134 and 0x01F0 |
0x0167 (6.2 to 6.3); 0x016B |
0x0243 (6.2 to 6.3); 0x024B |
UCHAR WaitBlockCount; |
6.2 and higher | |
0x0168 (6.2 to 6.3); 0x016C |
0x0244 (6.2 to 6.3); 0x024C |
ULONG IdealProcessor; |
6.2 and higher | previously at 0x0160 and 0x0228 |
The KTHREAD keeps two KAPC_STATE structures, the second to support the KeStackAttachProcess function. From as far back as version 3.51, the KTHREAD has initialised its ApcStatePointer array with the addresses of these two structures and then left them there, unchanging, with the (8-bit) ApcStateIndex to select which pointer to use. This always was an extravagance for an implementation that’s supposedly so concerned about space that it fits small members into otherwise unused space in larger members. Windows 10 does away with it.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks | History |
---|---|---|---|---|---|
0x016C (6.2 to 6.3) | 0x0248 (6.2 to 6.3) |
KAPC_STATE *ApcStatePointer [2]; |
6.2 to 6.3 | previously at 0x0168 and 0x0230 | |
0x0170 |
ULONG Spare15 [1]; |
10.0 and higher | |||
0x0250 |
LONGLONG NpxState; |
10.0 and higher | previously as CHAR at 0x0185 |
See that Windows 10 inserts members with the effect, if not the intention, of restoring continuity of offsets for the second KAPC_STATE structure and beyond.
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x0174 | 0x0258 |
union { KAPC_STATE SavedApcState; /* overlay, see below */ }; |
6.2 and higher | previously at 0x0170 and 0x0240 |
Overlaying the SavedApcState:
struct { UCHAR SavedApcStateFill [KAPC_STATE_ACTUAL_LENGTH]; /* reclaimed, see below */ };
Reclaimed from the SavedApcState:
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x018B | 0x0283 |
UCHAR WaitReason; |
6.2 and higher | previously at 0x0187 and 0x026B |
0x018C | 0x0284 |
CHAR SuspendCount; |
6.2 and higher | previously at 0x0188 and 0x026C |
0x018D | 0x0285 |
CHAR Saturation; |
6.2 and higher | previously at 0x013B and 0x01F7 |
0x018E | 0x0286 |
USHORT SListFaultCount; |
6.2 and higher | previously as ULONG at 0x01DC and 0x02D4 |
What had been the SuspendApc (previously at offsets 0x0194 and 0x0280) is renamed to SchedulerApc.
Offset (x86) | Offset (x64) | Definition | Versions |
---|---|---|---|
0x0190 | 0x0288 |
union { KAPC SchedulerApc; /* overlay, see below */ }; |
6.2 and higher |
Overlaying the SchedulerApc:
struct { UCHAR SchedulerApcFill0 [KAPC_OFFSET_TO_SPARE_BYTE0]; /* reclaimed byte, see below */ }; struct { UCHAR SchedulerApcFill1 [KAPC_OFFSET_TO_SPARE_BYTE1]; /* reclaimed byte, see below */ }; struct { UCHAR SchedulerApcFill2 [KAPC_OFFSET_TO_SPARE_LONG]; /* reclaimed four bytes, see below */ }; struct { UCHAR SchedulerApcFill3 [KAPC_OFFSET_TO_SYSTEMARGUMENT1]; /* reclaimed 4 or 8 bytes, see below */ }; struct { UCHAR SchedulerApcFill4 [KAPC_OFFSET_TO_SYSTEMARGUMENT2]; /* reclaimed 4 or 8 bytes, see below */ }; struct { UCHAR SchedulerApcFill5 [KAPC_ACTUAL_LENGTH]; /* reclaimed 1 or 5 bytes, see below) */ };
Whatever its name, its sprinkling of other members in spare space barely changes:
Offset (x86) | Offset (x64) | Definition | Versions | History |
---|---|---|---|---|
0x0191 | 0x0289 |
UCHAR ResourceIndex; |
6.2 and higher | previously at 0x0195 and 0x0281 |
0x0193 | 0x028B |
UCHAR QuantumReset; |
6.2 and higher | previously at 0x0197 and 0x0283 |
0x0194 | 0x028C |
ULONG KernelTime; |
6.2 and higher | previously at 0x0198 and 0x0284 |
0x01B4 | 0x02C8 |
PVOID WaitPrcb; |
6.2 and higher | previously at 0x01B8 and 0x02C0 |
0x01B8 | 0x02D0 |
PVOID LegoData; |
6.2 and higher | previously at 0x01BC and 0x02C8 |
0x01BF | 0x02DB |
UCHAR CallbackNestingLevel; |
6.2 and higher | |
0x01C0 | 0x02DC |
ULONG UserTime; |
6.2 and higher | previously at 0x01C4 and 0x02DC |
That’s the end of the contrivances over packing members into space that’s left unused in other members.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks | History |
---|---|---|---|---|---|
0x01C4 | 0x02E0 |
KEVENT SuspendEvent; |
6.2 and higher | ||
0x01D4 | 0x02F8 |
LIST_ENTRY ThreadListEntry; |
6.2 and higher | previously at 0x01E0 and 0x02F8 | |
0x01DC | 0x0308 |
LIST_ENTRY MutantListHead; |
6.2 and higher | last member in 6.2 (x86) | previously at 0x01E8 and 0x0308 |
0x01E4 | 0x0318 |
UCHAR AbEntrySummary; |
10.0 and higher | ||
0x01E5 | 0x0319 |
UCHAR AbWaitEntryCount; |
10.0 and higher | previously at 0x032B and 0x058B | |
0x01E6 | 0x031A |
USHORT Spare20; |
10.0 and higher | ||
0x031C |
ULONG SecureThreadCookie; |
10.0 and higher | |||
0x01E4 (6.3) | 0x0318 (6.3) |
SINGLE_LIST_ENTRY LockEntriesFreeList; |
6.3 only | ||
0x01E8 | 0x0320 |
KLOCK_ENTRY LockEntries [6]; |
6.3 and higher | ||
0x0308 | 0x0560 |
SINGLE_LIST_ENTRY PropagateBoostsEntry; |
6.3 and higher | ||
0x030C | 0x0568 |
SINGLE_LIST_ENTRY IoSelfBoostsEntry; |
6.3 and higher | ||
0x0310 | 0x0570 |
UCHAR PriorityFloorCounts [0x10]; |
6.3 and higher | ||
0x0320 | 0x0580 |
ULONG PriorityFloorSummary; |
6.3 and higher | ||
0x0324 | 0x0584 |
LONG volatile AbCompletedIoBoostCount; |
6.3 and higher | ||
0x0328 | 0x0588 |
SHORT volatile AbReferenceCount; |
6.3 only | ||
SHORT volatile KeReferenceCount; |
10.0 and higher | ||||
0x032A | 0x058A |
UCHAR AbFreeEntryCount; |
6.3 only | ||
UCHAR AbOrphanedEntrySummary; |
10.0 and higher | ||||
0x032B | 0x058B |
UCHAR AbWaitEntryCount; |
6.3 only | next at 0x01E5 and 0x0319 | |
UCHAR AbOwnedEntryCount; |
10.0 and higher | ||||
0x032C | 0x058C |
ULONG ForegroundLossTime; |
6.3 and higher | ||
0x0330 | 0x0590 |
union { LIST_ENTRY GlobalForegroundListEntry; struct { SINGLE_LIST_ENTRY ForegroundDpcStackListEntry; ULONG InGlobalForegroundList; }; }; |
6.3 and higher | last member in 6.3 (x86) | |
0x0318 (6.2); 0x05A0 |
LONGLONG ReadOperationCount; |
6.2 and higher | x64 only | previously at 0x0320 | |
0x0320 (6.2); 0x05A8 |
LONGLONG WriteOperationCount; |
6.2 and higher | x64 only | previously at 0x0328 | |
0x0328 (6.2); 0x05B0 |
LONGLONG OtherOperationCount; |
6.2 and higher | x64 only | previously at 0x0330 | |
0x0330 (6.2); 0x05B8 |
LONGLONG ReadTransferCount; |
6.2 and higher | x64 only | previously at 0x0338 | |
0x0338 (6.2); 0x05C0 |
LONGLONG WriteTransferCount; |
6.2 and higher | x64 only | previously at 0x0340 | |
0x0340 (6.2); 0x05C8 |
LONGLONG OtherTransferCount; |
6.2 and higher | x64 only; last member in 6.2 (x64); last member in 6.3 (x64) |
previously at 0x0348 | |
0x0338 |
KSCB *QueuedScb; |
10.0 and higher | last member in 10.0 (x64) | ||
0x0340 |
LONGLONG NpxState; |
10.0 and higher | for x64, see above; previously as CHAR at 0x91; last member in 10.0 (x86) |