PROCESSINFO

The PROCESSINFO (formally tagPROCESSINFO) is the most of what WIN32K.SYS keeps about a process. A portion at its start is reproduced as a W32PROCESS (formally _W32PROCESS), apparently as an unnamed member. It is not clear what governs the separation.

Documentation Status

Under either name, the PROCESSINFO is not documented. Structural details from type information in symbol files are known to have been disclosed in public only for WIN32K.SYS from Windows 7—not before and not since. Or so I wrote in 2017, having not yet caught up with Windows 10 updates. Symbol files for 1607 and higher have type information for the W32PROCESS. Thus does a little more “official” detail dribble out.

For some early WIndows versions, Microsoft’s names for some, and even all, members of both structures are known with varying confidence from the output of one or another debugger command as implemented in the USEREXTS.DLL or USERKDX.DLL debugger extensions which Microsoft published with one or another Device Driver Kit (DDK). Nobody would sensibly count this as documentation. It does show, however, that Microsoft understood for a while that knowledge of the PROCESSINFO may help programmers in the depths of debugging what they’re doing with Windows!

Layout

Not only is the PROCESSINFO highly variable between versions, and not only is there the complication of what part of it is the W32PROCESS, but in the one version for which type information is publicly available it’s immediately plain that the PROCESSINFO as described therein is not the full story. The memory block it is created in is larger than is declared for the structure and the additional space is accessed as if for members of a larger structure. It could be that the PROCESSINFO is itself a reduction, but close inspection shows something more interesting: the PROCESSINFO as described by type information in the symbol file for WIN32K in Windows 7 is not the PROCESSINFO that the matching WIN32K executable actually uses. Even the following table just of changing sizes is therefore not just more than usually complex but more than usually uncertain.

Version W32PROCESS PROCESSINFO Remarks
Size (x86) Size (x64) SIze (x86) Size (x64)
3.10     0xE4    
3.51     0x0120    
4.0 0x30   0x012C    
5.0 0x2C   0x013C    
5.1 0x2C   0x0144    
5.2 0x78 0xD0 0x018C 0x02C0  
6.0 0x80 0xE0 0x01A8 0x02E8  
6.1 0x90 0x0100 0x01C8 0x0320 symbol files have 0x01B0 and 0x0300 for PROCESSINFO size
6.2 0x9C 0x0128 0x01D8 0x0358  
6.3 0x9C 0x0128 0x01DC 0x0360  
10.0 0x9C 0x0128 0x0250 0x03E8  
1511 0x9C 0x0128 0x0248 0x03D8  
1607 0xA0 0x0120 0x0250 0x03D8  
1703 0xA0 0x0120 0x0268 0x03F8  
1709 0xA8 0x0128 0x0280 0x0410  
1803 0xA8 0x0128 0x028C 0x0420  

In version 4.0, memory for the PROCESSINFO is allocated by the kernel, the required size having been communicated by WIN32K as an argument to the undocumented (and highly variable) PsEstablishWin32Callouts function. Version 5.0 redistributed the work, such that the PROCESSINFO is instead created by WIN32K. Either way, the size of the PROCESSINFO is easily seen in code—indeed, in Windows 10, with WIN32K split into three, it’s immediately visible in data, exported as W32ProcessSize—but how much of the PROCESSINFO is the W32PROCESS can only be guessed.

W32PROCESS

Even for the first part of the PROCESSINFO, Microsoft’s names and types are known with the certainty of type information from public symbol files only for version 6.1 and now for some releases of version 10.0. For versions 4.0 and 5.0, offsets and Microsoft’s names, but not types, are known with good confidence from the output of the debugger’s !dso command as supported by the USEREXTS.DLL debugger extensions for these versions. For almost all Windows versions, everything that’s presented here of the layout is necessarily the result of deduction, inference and outright guesswork from inspection of executables.

Strictly speaking, it’s also a guess that the W32PROCESS does not exist as a separate structure before version 4.0. In this version—before which the PROCESSINFO was a user-mode creation of WINSRV.DLL—three members that had been very nearly at the end at the PROCESSINFO move to very near the start, which is here taken as a reorganisation that defined the W32PROCESS. Conspicuous among these moved members is the dword of flags. Compare with similar flags in the THREADINFO which didn’t move to the W32THREAD.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 0x00
EPROCESS *Process;
4.0 and higher  
0x04 0x08
ULONG RefCount;
5.0 and higher  
0x04 (4.0);
0x08
0x0C
ULONG W32PF_Flags;
4.0 and higher previously at 0xF4
0x08 (4.0);
0x0C
0x10
KEVENT *InputIdleEvent;
4.0 and higher  
0x0C (4.0);
0x10
0x18
ULONG StartCursorHideTime;
4.0 and higher previously at 0xFC
0x10 (4.0);
0x14
0x20
W32PROCESS *NextStart;
4.0 and higher previously at 0x0108 as ppiCalcNext
0x14 (4.0);
0x18
0x28
PVOID pDCAttrList;
4.0 and higher  
0x18 (4.0);
0x1C
0x30
PVOID pBrushAttrList;
4.0 and higher  
0x1C (4.0);
0x20
0x38
ULONG W32Pid;
4.0 and higher  
0x20 (4.0)  
<unknown-type> pidHandleTrack;
4.0 only last W32PROCESS member in 4.0
0x24 0x3C
LONG GDIHandleCount;
5.0 and higher  
0x28 0x40
ULONG GDIHandleCountPeak;
6.1 and higher  
0x28 (5.0 to 6.0);
0x2C
0x40 (5.2 to 6.0);
0x44
LONG UserHandleCount;
5.0 and higher last W32PROCESS member in 5.0;
last W32PROCESS member in 5.1
0x2C (5.2 to 6.0) 0x44 (5.2 to 6.0) unaccounted four bytes 5.2 to 6.0  
0x30 0x48
ULONG UserHandleCountPeak;
6.1 and higher  
0x34 0x50
EX_PUSH_LOCK GDIPushLock;
6.1 and higher  
0x30 (5.2 to 6.0);
0x38
0x48 (5.2 to 6.0);
0x58
RTL_AVL_TABLE GDIEngUserMemAllocTable;
5.2 and higher  
0x68 (5.2 to 6.0);
0x70
0xB0 (5.2 to 6.0);
0xC0
LIST_ENTRY GDIDcAttrFreeList;
5.2 and higher  
0x70 (5.2 to 6.0);
0x78
0xC0 (5.2 to 6.0);
0xD0
LIST_ENTRY GDIBrushAttrFreeList;
5.2 and higher last W32PROCESS member in 5.2
0x80 0xE0
LIST_ENTRY GDIW32PIDLockedBitmaps;
6.1 and higher  
0x78 (6.0);
0x88
0xD0 (6.0);
0xF0
PVOID hSecureGdiSharedHandleTable;
6.0 and higher  
0x7C (6.0);
0x8C
0xD8 (6.0);
0xF8
PVOID DxProcess;
6.0 and higher last W32PROCESS member in 6.0;
last W32PROCESS member in 6.1
0x90 0x0100
PVOID DCompositionProcess;
6.2 and higher  
0x94 0x0108
ULONG UMPDSandboxingEnabled;
6.2 and higher  
0x98 0x0110
PVOID pWakeReference;
6.2 and higher last W32PROCESS member in 6.2 (x86);
last W32PROCESS member in 6.3 (x86);
last W32PROCESS member in 10.0 to 1511 (x86)
  0x0118 (6.2 to 1511) unknown 64-bit count of references 6.2 to 1511  
  00x0120 (6.2 to 1511) unknown 64-bit count of dereferences 6.2 to 1511 last W32PROCESS member in 6.2 (x64);
last W32PROCESS member in 6.3 (x64);
last W32PROCESS member in 10.0 to 1511 (x64)
0x9C 0x0118
ULONG defaultDpiContext;
1607 and higher last W32PROCESS member in 1607 and 1703
0xA0 0x011C
USHORT Dpi;
1709 and higher  
0xA4 0x0120
BOOL bChangedGdiGammaRamp;
1709 and higher last W32PROCESS member in 1709
0xA8 0x0124
UINT GdiInitializeCalloutExecuted : 1;
1803 and higher last W32PROCESS member in 1803

The InputIdleEvent is, of course, what the documented API function WaitForInputIdle waits on. As a kernel-mode structure, the PROCESSINFO can have pointers directly to such things as event objects—and ideally would, since access through handles for kernel-mode use alone is wholly avoidable overhead. In the early history, however, the InputIdleEvent is necessarily a HANDLE. See below, as hEventInputIdle, the different name being suggested by the output of the Windows NT 3.51 debugger’s !dpi command. Version 3.51 introduced some logic with special meaning for INVALID_HANDLE_VALUE as distinct from NULL, which is retained even after the change to a pointer and is remarkable for persisting even to Windows 10.

The W32Pid in version 4.0 is just the low 16 bits of the usual process ID. Later versions save a ULONG but explicitly clear the lowest two bits.

Version 4.0 does track a GDIHandleCount at offset 0x24 but apparently in some structure (0x10 bytes at offset 0x20) that I have little interest in investigating. There is only so much trouble I can care to take for the pre-history!

PROCESSINFO Continuation

For the PROCESSINFO beyond the W32PROCESS, Microsoft’s names and types are known with the certainty of type information from public symbol files only for version 6.1. For versions 4.0 and 5.0, offsets and Microsoft’s names are known with good confidence from the output of the debugger’s !dso command as supported by the USERKDX debugger extensions for these versions. For version 3.51, the output of the !dpi command as supported by the USEREXTS debugger extension suggests names that very likely are Microsoft’s.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 (3.10 to 3.51);
0x30 (4.0)
 
PROCESSINFO *ppiNext;
3.10 to 4.0 next at 0x44
0x04 (3.10 to 3.51)  
DWORD idProcessClient;
3.10 to 3.51  
0x08 (3.10 to 3.51)  
DWORD idSequence;
3.10 to 3.51  
0x0C (3.10 to 3.51)  
HANDLE hEventInputIdle;
3.10 to 3.51  
0x2C (5.0 to 5.1);
0x78 (5.2);
0x80 (6.0);
0x90 (6.1);
0x9C (6.2 to 1511);
0xA0 (1607 to 1703);
0xA8 (1709);
0xAC
0xD0 (5.2);
0xE0 (6.0);
0x0100 (6.1);
0x0128 (6.2 to 1511);
0x0120 (1607 to 1703);
0x0128
THREADINFO *ptiList;
5.0 and higher previously at 0x0108
0x10 (3.10 to 3.51);
0x34 (4.0);
0x30 (5.0 to 5.1);
0x7C (5.2);
0x84 (6.0);
0x94 (6.1);
0xA0 (6.2 to 1511);
0xA4 (1607 to 1703);
0xAC (1709);
0xB0
0xD8 (5.2);
0xE8 (6.0);
0x0108 (6.1);
0x0130 (6.2 to 1511);
0x0128 (1607 to 1703);
0x0130
THREADINFO *ptiMainThread;
all  
0x14 (3.10 to 3.51);
0x38 (4.0)
 
UINT cThreads;
3.10 to 4.0 next at 0x4C
0x18 (3.10 to 3.51);
0x3C (4.0);
0x34 (5.0 to 5.1);
0x80 (5.2);
0x88 (6.0);
0x98 (6.1);
0xA4 (6.2 to 1511);
0xA8 (1607 to 1703);
0xB0 (1709);
0xB4
0xE0 (5.2);
0xF0 (6.0);
0x0110 (6.1);
0x0138 (6.2 to 1511);
0x0130 (1607 to 1703);
0x0138
DESKTOP *spdeskStartup;
3.10 to 3.51  
DESKTOP *rpdeskStartup;
4.0 and higher  
0x1C (3.51);
0x40 (4.0)
 
HDESK hdeskStartup;
3.51 to 4.0 next at 0x50
0x1C (3.10);
0x20 (3.51);
0x44 (4.0);
0x38 (5.0 to 5.1);
0x84 (5.2);
0x8C (6.0);
0x9C (6.1);
0xA8 (6.2 to 1511);
0xAC (1607 to 1703);
0xB4 (1709);
0xB8
0xE8 (5.2);
0xF8 (6.0);
0x0118 (6.1);
0x0140 (6.2 to 1511);
0x0138 (1607 to 1703);
0x0140
CLS *pclsPrivateList;
all  
0x20 (3.10);
0x24 (3.51);
0x48 (4.0);
0x3C (5.0 to 5.1);
0x88 (5.2);
0x90 (6.0);
0xA0 (6.1);
0xAC (6.2 to 1511);
0xB0 (1607 to 1703);
0xB8 (1709);
0xBC
0xF0 (5.2);
0x0100 (6.0);
0x0120 (6.1);
0x0148 (6.2 to 1511);
0x0140 (1607 to 1703);
0x0148
CLS *pclsPublicList;
all  
0x40 (5.0 to 5.1);
0x8C (5.2);
0x94 (6.0);
0xA4 (6.1);
0xB0 (6.2 to 1511);
0xB4 (1607 to 1703);
0xBC (1709);
0xC0
0xF8 (5.2);
0x0108 (6.0);
0x0128 (6.1);
0x0150 (6.2 to 1511);
0x0148 (1607 to 1703);
0x0150
WOWPROCESSINFO *pwpi;
5.0 and higher previously at 0x0104
0x44 (5.0 to 5.1);
0x90 (5.2);
0x98 (6.0);
0xA8 (6.1);
0xB4 (6.2 to 1511);
0xB8 (1607 to 1703);
0xC0 (1709);
0xC4
0x0100 (5.2);
0x0110 (6.0);
0x0130 (6.1);
0x0158 (6.2 to 1511);
0x0150 (1607 to 1703);
0x0158
PROCESSINFO *ppiNext;
5.0 and higher previously at 0x30
0x48 (5.0 to 5.1);
0x94 (5.2);
0x9C (6.0);
0xAC (6.1);
0xB8 (6.2 to 1511);
0xBC (1607 to 1703);
0xC4 (1709);
0xC8
0x0108 (5.2);
0x0118 (6.0);
0x0138 (6.1);
0x0160 (6.2 to 1511);
0x0158 (1607 to1703);
0x0160 
PROCESSINFO *ppiNextRunning;
5.0 and higher  
0x4C (5.0 to 5.1);
0x98 (5.2);
0xA0 (6.0);
0xB0 (6.1);
0xBC (6.2 to 1511);
0xC0 (1607 to 1703);
0xC8 (1709);
0xCC
0x0110 (5.2);
0x0120 (6.0);
0x0140 (6.1);
0x0168 (6.2 to 1511);
0x0160 (1607 to 1703);
0x0168
UINT cThreads;
5.0 and higher previously at 0x38
0x50 (5.0 to 5.1);
0x9C (5.2);
0xA4 (6.0);
0xB4 (6.1);
0xC0 (6.2 to 1511);
0xC4 (1607 to 1703);
0xCC (1709);
0xD0
0x0118 (5.2);
0x0128 (6.0);
0x0148 (6.1);
0x0170 (6.2 to 1511);
0x0168 (1607 to 1703);
0x0170
HDESK hdeskStartup;
5.0 and higher previously at 0x40
0x4C (4.0);
0x54 (5.0 to 5.1);
0xA0 (5.2);
0xA8 (6.0);
0xB8 (6.1);
0xC4 (6.2 to 1511);
0xC8 (1607 to 1703);
0xD0 (1709);
0xD4
0x0120 (5.2);
0x0130 (6.0);
0x0150 (6.1);
0x0178 (6.2 to 1511);
0x0170 (1607 to 1703);
0x0178
UINT cSysExpunge;
4.0 and higher  
0x50 (4.0);
0x58 (5.0 to 5.1);
0xA4 (5.2);
0xAC (6.0);
0xBC (6.1);
0xC8 (6.2 to 1511);
0xCC (1607 to 1703);
0xD4 (1709);
0xD8
0x0124 (5.2);
0x0134 (6.0);
0x0154 (6.1);
0x017C (6.2 to 1511);
0x0174 (1607 to 1703);
0x017C
DWORD dwhmodLibLoadedMask;
4.0 and higher  
0x24 (3.10);
0x28 (3.51);
0x54 (4.0);
0x5C (5.0 to 5.1);
0xA8 (5.2);
0xB0 (6.0);
0xC0 (6.1);
0xCC (6.2 to 1511);
0xD0 (1607 to 1703);
0xD8 (1709);
0xDC
0x0128 (5.2);
0x0138 (6.0);
0x0158 (6.1);
0x0180 (6.2 to 1511);
0x0178 (1607 to 1703);
0x0180
PVOID ahmodLibLoaded [0x20];
all    
0xA8 3.51)   unknown array of two 0x10-byte structures (3.51) 3.51 only  
0xA4 (3.10);
0xC8 (3.51)
 
INT cObjects;
3.10 to 3.51  
0xA8 (3.10)   unknown pointer 3.10 only  
0xAC (3.10);
0xCC (3.51)
 
<unknown-type> pOpenObjectTable;
3.10 to 3.51  
0xB0 (3.10);
0xD0 (3.51);
0xD4 (4.0);
0xDC (5.0 to 5.1);
0x0128 (5.2);
0x0130 (6.0);
0x0140 (6.1);
0x014C (6.2 to 1511);
0x0150 (1607 to 1703);
0x0158 (1709);
0x015C
0x0228 (5.2);
0x0238 (6.0);
0x0258 (6.1);
0x0280 (6.2 to 1511);
0x0278 (1607 to 1703);
0x0280
WINDOWSTATION *spwinsta;
3.10 to 3.51  
WINDOWSTATION *rpwinsta;
4.0 and higher  
0xD4 (3.51);
0xD8 (4.0);
0xE0 (5.0 to 5.1);
0x012C (5.2);
0x0134 (6.0);
0x0144 (6.1);
0x0150 (6.2 to 1511);
0x0154 (1607 to 1703);
0x015C (1709);
0x0160
0x0230 (5.2);
0x0240 (6.0);
0x0260 (6.1);
0x0288 (6.2 to 1511);
0x0280 (1607 to 1703);
0x0288
HWINSTA hwinsta;
3.51 and higher  
0xDC (4.0);
0xE4 (5.0 to 5.1);
0x0130 (5.2);
0x0138 (6.0);
0x0148 (6.1);
0x0154 (6.2 to 1511);
0x0158 (1607 to 1703);
0x0160 (1709);
0x0164
0x0238 (5.2);
0x0248 (6.0);
0x0268 (6.1);
0x0290 (6.2 to 1511);
0x0288 (1607 to 1703);
0x0290
ACCESS_MASK amwinsta;
4.0 and higher  
0xB4 (3.10);
0xD8 (3.51);
0xE0 (4.0)
 
USERSTARTUPINFO usi;
3.10 to 4.0 next at 0x011C
0xD0 (3.10);
0xF4 (3.51)
 
DWORD PIF_flags;
3.10 to 3.51 next at 0x04
0xD4 (3.10);
0xF8 (3.51);
0xFC (4.0)
 
DWORD dwCompatFlags;
3.10 to 4.0  
0xD8 (3.10);
0xFC (3.51)
 
ULONG timeStartCursorOverride;
3.10 to 3.51 next at 0x0C
0xDC (3.10);
0x0100 (3.51 to 4.0);
0xE8 (5.0 to 5.1);
0x0134 (5.2);
0x013C (6.0);
0x014C (6.1);
0x0158 (6.2 to 1511);
0x015C (1607 to 1703);
0x0164 (1709);
0x0168
0x023C (5.2);
0x024C (6.0);
0x026C (6.1);
0x0294 (6.2 to 1511);
0x028C (1607 to 1703);
0x0294
DWORD dwHotkey;
all
0xE0 (3.10);
0x0104 (3.51)
 
<unknown-type> pCsrProcess;
3.10 to 3.51 last PROCESSINFO member in 3.10

The name PIF_flags is hypothesised by analogy with TIF_flags in the THREADINFO. The USEREXTS debugger extension for Windows NT 3.51 has just “flags” but this seems more likely to be intended for easier presentation rather than for faithfully reproducing the member’s name. Note in particular that the names that this same debugger extension gives for the defined bits each begin with PIF.

The name dwCompatFlags is confirrmed by the USERKDX debugger extension for Windows NT 4.0. The dword is a copy of the dwCompatFlags that are also computed for the THREADINFO and CLIENTINFO. Keeping them in the PROCESSINFO too seems to have been dropped after version 4.0.

Appended for Windows NT 3.51

Offset (x86) Definition Versions Remarks
0x0108 (3.51)
W32PROCESS *ppiCalcNext;
3.51 only next at 0x10 as NextStart
0x010C (3.51);
0x0104 (4.0)
WOWPROCESSINFO *pwpi;
3.51 to 4.0 next at 0x40
0x0110 (3.51);
0x0108 (4.0)
THREADINFO *ptiList;
3.51 to 4.0 next at 0x2C
0x0114 (3.51);
0x010C (4.0)
<unknown-type> pcurList;
3.51 to 4.0  
0x0118 (3.51);
0x0110 (4.0)
LUID luidSession;
3.51 to 4.0 last PROCESSINFO member in 3.51;
next at 0x0114

Appended for Windows NT 4.0

Offset (x86) Offset (x64) Definition Versions Remarks
0xEC (5.0 to 5.1);
0x0138 (5.2);
0x0140 (6.0);
0x0150 (6.1);
0x015C (6.2 to 1511);
0x0160 (1607 to 1703);
0x0168 (1709);
0x016C
0x0240 (5.2);
0x0250 (6.0);
0x0270 (6.1);
0x0298 (6.2 to 1511);
0x0290 (1607 to 1703);
0x0298
HMONITOR hMonitor;
5.0 and higher  
0x0118 (4.0);
0xF0 (5.0 to 5.1);
0x013C (5.2);
0x0144 (6.0);
0x0154 (6.1);
0x0160 (6.2 to 1511);
0x0164 (1607 to 1703);
0x016C (1709);
0x0170
0x0248 (5.2);
0x0258 (6.0);
0x0278 (6.1);
0x02A0 (6.2 to 1511);
0x0298 (1607 to 1703);
0x02A0
DESKTOPVIEW *pdvList;
4.0 and higher  
0x11C (4.0);
0xF4 (5.0 to 5.1);
0x0140 (5.2);
0x0148 (6.0);
0x0158 (6.1);
0x0164 (6.2 to 1511);
0x0168 (1607 to 1703);
0x0170 (1709);
0x0174
0x0250 (5.2);
0x0260 (6.0);
0x0280 (6.1);
0x02A8 (6.2 to 1511);
0x02A0 (1607 to 1703);
0x02A8
UINT iClipSerialNumber;
4.0 and higher  
0x0120 (4.0);
0xF8 (5.0 to 5.1);
0x0144 (5.2);
0x014C (6.0);
0x015C (6.1);
0x0168 (6.2 to 1511);
0x016C (1607 to 1703);
0x0174 (1709);
0x0178
0x0258 (5.2);
0x0268 (6.0);
0x0288 (6.1);
0x02B0 (6.2 to 1511);
0x02A8 (1607 to 1703);
0x02B0
RTL_BITMAP bmDesktopHookFlags;
4.0 only  
RTL_BITMAP bmHandleFlags;
5.0 and higher  
0x0128 (4.0);
0x0100 (5.0 to 5.1);
0x014C (5.2);
0x0154 (6.0);
0x0164 (6.1);
0x0170
0x0174
0x017C
0x0180
0x0268 (5.2);
0x0278 (6.0);
0x0298 (6.1);
0x02C0
0x02B8
0x02C0
CURSOR *pCursorCache;
4.0 and higher last PROCESSINFO member in 4.0

That the PROCESSINFO as early as version 4.0 has an RTL_BITMAP where the Windows 7 symbol files locate bmHandleFlags is certain, but it is not clear that handle flags existed before version 5.0, at least not with the generality of later versions. The version 4.0 WIN32K operates on this bitmap not through such routines as SetHandleFlag but SetDesktopHookFlag. The USERKDX debugger extensions for WIndows NT 4.0 and Windows 2000 confirm that the difference also showed in the bitmap’s name.

Appended for Windows 2000

Offset (x86) Offset (x64) Definition Versions Remarks
0x0104 (5.0 to 5.1);
0x0150 (5.2);
0x0158 (6.0);
0x0168 (6.1);
0x0174 (6.2 to 1511);
0x0178 (1607 to 1703);
0x0180 (1709);
0x0184
0x0270 (5.2);
0x0280 (6.0);
0x02A0 (6.1);
0x02C8 (6.2 to 1511);
0x02C0 (1607 to 1703);
0x02C8
PVOID pClientBase;
5.0 and higher  
0x0188 0x02D0 unknown pointer 1803 and higher  
0x0108 (5.0 to 5.1);
0x0154 (5.2);
0x015C (6.0);
0x016C (6.1);
0x0178 (6.2 to 1511);
0x017C (1607 to 1703);
0x0184 (1709);
0x018C
0x0278 (5.2);
0x0288 (6.0);
0x02A8 (6.1);
0x02D0 (6.2 to 1511);
0x02C8 (1607 to 1703);
0x02D0 (1709);
0x02D8
DWORD dwLpkEntryPoints;
5.0 and higher  
0x010C (5.0 to 5.1);
0x0158 (5.2);
0x0160 (6.0);
0x0170 (6.1);
0x017C (6.2 to 1511);
0x0180 (1607 to 1703);
0x0188 (1709);
0x0190
0x0280 (5.2);
0x0290 (6.0);
0x02B0 (6.1);
0x02D8 (6.2 to 1511);
0x02D0 (1607 to 1703);
0x02D8 (1709);
0x02E0
W32JOB *pW32Job;
5.0 and higher  
0x0110 (5.0 to 5.1);
0x015C (5.2);
0x0164 (6.0);
0x0174 (6.1);
0x0180 (6.2 to 1511);
0x0184 (1607 to 1703);
0x018C (1709);
0x0194
0x0288 (5.2);
0x0298 (6.0);
0x02B8 (6.1);
0x02E0 (6.2 to 1511);
0x02D8 (1607 to 1703);
0x02E0 (1709);
0x02E8
DWORD dwImeCompatFlags;
5.0 and higher  
0x0114 (5.0 to 5.1);
0x0160 (5.2);
0x0168 (6.0);
0x0178 (6.1);
0x0184 (6.2 to 1511);
0x0188 (1607 to 1703);
0x0190 (1709);
0x0198
0x028C (5.2);
0x029C (6.0);
0x02BC (6.1);
0x02E4 (6.2 to 1511);
0x02DC (1607 to 1703);
0x02E4 (1709);
0x02EC
LUID luidSession;
5.0 and higher previously at 0x0110
0x011C (5.0 to 5.1);
0x0168 (5.2);
0x0170 (6.0);
0x0180 (6.1);
0x018C (6.2 to 1511);
0x0190 (1607 to 1703);
0x0198 (1709);
0x01A0
0x0294 (5.2);
0x02A4 (6.0);
0x02C4 (6.1);
0x02EC (6.2 to 1511);
0x02E4 (1607 to 1703);
0x02EC (1709);
0x02F4
USERSTARTUPINFO usi;
5.0 and higher previously at 0xE0
0x01BC 0x0310 unknown word 1803 and higher  
0x019C (6.1);
0x01A8 (6.2 to 1511);
0x01AC (1607 to 1703);
0x01B4 (1709);
0x01C0
0x02E0 (6.1);
0x0308 (6.2 to 1511);
0x0300 (1607 to 1703);
0x0308 (1709);
0x0314
union {
    ULONG Flags;
    struct {
        /* bit fields, follow link */
    };
};
6.1 and higher  
0x0138 (5.0 to 5.1);
0x0184 (5.2);
0x018C (6.0);
0x01A0 (6.1);
0x01AC (6.2 to 1511);
0x01B0 (1607 to 1703);
0x01B8 (1709);
0x01C4
0x02B0 (5.2);
0x02C0 (6.0);
0x02E4 (6.1);
0x030C (6.2 to 1511);
0x0304 (1607 to 1703);
0x030C (1709);
0x0318
ULONG dwLayout;
5.0 and higher last PROCESSINFO member in 5.0

The USERKDX debugger extension from the DDK for Windows 2000 does not list dwLayout among the PROCESSINFO members and would have it that the structure is 0x0138 bytes, not 0x013C. It is here thought that the DDK somehow retained a debugger extension for a pre-release build, but it may be that the inspected WIN32K executable is not truly from the original release.

Appended for Windows XP and Windows Server 2003

Offset (x86) Offset (x64) Definition Versions Remarks
0x013C (5.1);
0x0188 (5.2);
0x0190 (6.0);
0x01A4 (6.1);
0x01B0 (6.2 to 1511);
0x01B4 (1607 to 1703);
0x01BC (1709);
0x01C8
0x02B8 (5.2);
0x02C8 (6.0);
0x02E8 (6.1);
0x0310 (6.2 to 1511);
0x0308 (1607 to 1703);
0x0310 (1709);
0x0320
PROCESS_HID_TABLE *pHidTable;
5.1 and higher last PROCESSINFO member in 5.2
0x0140 (5.1)   unknown dword of bit flags 5.1 only last PROCESSINFO member in 5.1

The four bytes at offset 0x0140 in version 5.1 are bit flags. The bit masked by 0x00000001 is set to disable ghosting. Version 5.2 moved it to the bit masked by 0x08000000 in the W32PF_Flags.

Appended for Windows Vista

Offset (x86) Offset (x64) Definition Versions Remarks
0x0194 (6.0);
0x01A8 (6.1);
0x01B4 (6.2 to 1511);
0x01B8 (1607 to 1703);
0x01C0 (1709);
0x01CC
0x02D0 (6.0);
0x02F0 (6.1);
0x0318 (6.2 to 1511);
0x0310 (1607 to 1703);
0x0318 (1709);
0x0328
DWORD dwRegisteredClasses;
6.0 and higher  
0x0198 (6.0);
0x01AC (6.1)
0x02D4 (6.0);
0x02F4 (6.1)
unknown dword 6.0 to 6.1 not present in 6.1 according to symbol files
0x019C (6.0);
0x01B0 (6.1); 
0x01B8 (6.2 to 1511);
0x01BC (1607 to 1703);
0x01C4 (1709);
0x01D0
0x02D8 (6.0);
0x02F8 (6.1);
0x0320 (6.2 to 1511);
0x0318 (1607 to 1703);
0x0320 (1709);
0x0330
unknown pointer 6.0 and higher not present in 6.1 according to symbol files
0x01A0 (6.0) 0x02E0 (6.0) unaccounted 6.0 only last PROCESSINFO member in 6.0

Appended for Windows 7

Offset (x86) Offset (x64) Definition Versions Remarks
0x01B4 (6.1);
0x01BC (6.2 to 1511);
0x01C0 (1607 to 1703);
0x01C8 (1709);
0x01D4
0x0300 (6.1);
0x0328 (6.2 to 1511);
0x0320 (1607 to 1703);
0x0328 (1709);
0x0338
unknown VWPL pointer 6.1 and higher not present in 6.1 according to symbol files
0x01B8 (6.1);
0x01C0 (6.2 to 1511);
0x01C4 (1607 to 1703);
0x01CC (1709);
0x01D8
0x0308 (6.1);
0x0330 (6.2 to 1511);
0x0328 (1607 to 1703);
0x0330 (1709);
0x0340
unaccounted 6.1 and higher not present in 6.1 according to symbol files
0x01BC (6.1);
0x01C4 (6.2 to 1511);
0x01C8 (1607 to 1703);
0x01D0 (1709);
0x01DC
0x0310 (6.1);
0x0338 (6.2 to 1511);
0x0330 (1607 to 1703);
0x0338 (1709);
0x0348
VWPL *pvwplWndGCList;
6.1 and higher 0x01AC and 0x02F8 in 6.1 according to symbol files
0x01C0 (6.1) 0x0318 (6.1) unknown word 6.1 only not present in 6.1 according to symbol files
0x01C4 (6.1) 0x031C (6.1) unknown dword 6.1 only not present in 6.1 according to symbol files;
last PROCESSINFO member in 6.1

Type information in the WIN32K symbol files from version 6.1—which, remember, is all that Microsoft has disclosed in public—has the PROCESSINFO ending with pvwplWndGCList at offsets 0x01AC and 0x02F8. These offsets are simply not plausible for this member. For instance, where a routine that the symbol files name as GetWindowGCList calls another named VWPLGetData, it very plainly takes the pointer from offset 0x01BC. As if this were not trouble enough, there is evidently a second such pointer. For instance, a routine named GetWindowMessageFilter also calls VWPLGetData but taking the pointer from offset 0x01B4.

The unknown word is bit flags. The unknown dword that follows it is perhaps named ProcessCheckSum. It is set by an internal routine that the symbol files—yes, the ones that omit the member from the structure—name as WndLimit_GetProcessCheckSum.. It receives the checksum from the process’s Portable Executable (PE) header. Both seem to have existed only for Windows 7.

Appended for Windows 8

Microsoft’s names for members that have been added to the PROCESSINFO since Windows 7 may never be known.

Offset (x86) Offset (x64) Definition Versions Remarks
0x01C8 (6.2 to 1511);
0x01CC (1607 to 1703);
0x01D4 (1709);
0x01E0
0x0340 (6.2 to 1511);
0x0338 (1607 to 1703);
0x0340 (1709);
0x0350
unknown 8 bytes 6.2 and higher  
0x01D0 (6.3 to 1511);
0x01D4 (1607 to 1703);
0x01DC (1709);
0x01E8
0x0348 (6.3 to 1511);
0x0340 (1607 to 1703);
0x0348 (1709);
0x0358
unknown dword 6.3 and higher  
0x01D0 (6.2);
0x01D4 (6.3 to 1511);
0x01D8 (1607 to 1703);
0x01E0 (1709);
0x01EC
0x0348 (6.2);
0x0350 (6.3 to 1511);
0x0348 (1607 to 1703);
0x0350 (1709);
0x0360
unknown pointer 6.2 and higher  
0x01D8 (10.0 to 1511);
0x01DC (1607 to 1703);
0x01E4 (1709);
0x01F0
0x0358 (10.0 to 1511);
0x0350 (1607 to 1703);
0x0358 (1709);
0x0368
unknown four pointers or handles 10.0 only  
unknown two pointers or handles 1511 and higher  
0x01D4 (6.2);
0x01D8 (6.3);
0x01E8 (10.0);
0x01E0 (1511);
0x01E4 (1607 to 1703);
0x01EC (1709);
0x01F8
0x0350 (6.2);
0x0358 (6.3);
0x0378 (10.0);
0x0368 (1511);
0x0360 (1607 to 1703);
0x0368 (1709);
0x0378
unknown dword 6.2 and higher last PROCESSINFO member in 6.2;
last PROCESSINFO member in 6.3

Appended for Windows 10

Offset (x86) Offset (x64) Definition Versions Remarks
0x01EC (10.0);
0x01E4 (1511);
0x01E8 (1607 to 1703);
0x01F0 (1709);
0x01FC
0x0380 (10.0);
0x0370 (1511);
0x0368 (1607 to 1703);
0x0370 (1709);
0x0380
unknown pointer 10.0 and higher  
0x01F0 (10.0);
0x01E8 (1511);
0x01EC (1607 to 1703);
0x01F4 (1709);
0x0200
0x0388 (10.0);
0x0378 (1511);
0x0370 (1607 to 1703);
0x0378 (1709);
0x0388
unknown dword for NumberOfActivations 10.0 and higher  
0x01F4 (10.0);
0x01EC (1511);
0x01F0 (1607 to 1703);
0x01F8 (1709);
0x0204
0x038C (10.0);
0x037C (1511);
0x0374 (1607 to 1703);
0x037C (1709);
0x038C
unknown CHAR [0x10] for ProcessImageName 10.0 and higher  
0x0204 (10.0);
0x01FC (1511);
0x0200 (1607 to 1703);
0x0208 (1709);
0x0214
0x039C (10.0);
0x038C (1511);
0x0384 (1607 to 1703);
0x038C (1709);
0x039C
unknown dword for ProcessId 10.0 and higher  
0x0208 (10.0);
0x0200 (1511);
0x0204 (1607 to 1703);
0x020C (1709);
0x0218
0x03A0 (10.0);
0x0390 (1511);
0x0388 (1607 to 1703);
0x0390 (1709);
0x03A0
unknown RECT for Monitor.Left, etc 10.0 and higher  
0x0218 (10.0);
0x0210 (1511);
0x0214 (1607 to 1703);
0x021C (1709);
0x0228
0x03B0 (10.0);
0x03A0 (1511);
0x0398 (1607 to 1703);
0x03A0 (1709);
0x03B0
unknown dword for DisplayDPI 10.0 and higher  
0x021C (10.0);
0x0214 (1511);
0x0218 (1607 to 1703);
0x0220 (1709);
0x022C
0x03B4 (10.0);
0x03A4 (1511);
0x039C (1607 to 1703);
0x03A4 (1709);
0x03B4
unknown dword for InitialDisplayDPI 10.0 and higher  
0x0220 (10.0);
0x0218 (1511);
0x021C (1607 to 1703);
0x0224 (1709);
0x0230
0x03B8 (10.0);
0x03A8 (1511);
0x03A0 (1607 to 1703);
0x03A8 (1709);
0x03B8
unknown dword for PrevDisplayDPI 10.0 and higher  
0x0224 (10.0);
0x021C (1511);
0x0220 (1607 to 1703);
0x0228 (1709);
0x0234
0x03BC (10.0);
0x03AC (1511);
0x03A4 (1607 to 1703);
0x03AC (1709);
0x03BC
unknown dword of bit flags:
0x00000001 for MonitorHasChanged;
0x00000002 for DPIHasChangedWhenMonitorChanged;
0x00000004 for DPIHasChangedWhenMonitorNotChanged
10.0 and higher  
0x0228 (10.0);
0x0220 (1511);
0x0224 (1607 to 1703);
0x022C (1709);
0x0238
0x03C0 (10.0);
0x03B0 (1511);
0x03A8 (1607 to 1703);
0x03B0 (1709);
0x03C0
unknown WCHAR [0x10] 10.0 and higher  
0x0248 (10.0);
0x0240 (1511);
0x0244 (1607 to 1703);
0x024C (1709);
0x0258
0x03E0 (10.0);
0x03D0 (1511);
0x03C8 (1607 to 1703);
0x03D0 (1709);
0x03E0
UINT cVisWindows;
10.0 and higher  
0x024C (10.0);
0x0244 (1511);
0x0248 (1607 to 1703);
0x0250 (1709);
0x025C
0x03E4 (10.0);
0x03D4 (1511);
0x03CC (1607 to 1703);
0x03D4 (1709);
0x03E4
unknown dword 10.0 and higher last PROCESSINFO member in 10.0;
last PROCESSINFO member in 1511
0x024C (1607 to 1703);
0x0254 (1709);
0x0260
0x03D0 (1607 to 1703);
0x03D8 (1709);
0x03E8
unknown byte 1607 and higher  
0x024D (1607 to 1703);
0x0255 (1709);
0x0261
0x03D1 (1607 to 1703);
0x03D9 (1709);
0x03E9
unknown byte 1607 and higher  
0x024E (1607 to 1703);
0x0256 (1709);
0x0262
0x03D2 (1607 to 1703);
0x03DA (1709);
0x03EA
unknown byte 1607 and higher last PROCESSINFO member in 1607
0x0250 (1703);
0x0258 (1709);
0x0264
0x03D4 (1703);
0x03DC (1709);
0x03EC
unknown dword 1703 and higher  
0x0254 (1703);
0x025C (1709);
0x0268
0x03D8 (1703);
0x03E0 (1709);
0x03F0
unknown dword 1703 and higher  
0x0258 (1703);
0x0260 (1709);
0x026C
0x03DC (1703);
0x03E4 (1709);
0x03F4
unknown dword 1703 and higher  
0x025C (1703);
0x0264 (1709);
0x0270
0x03E0 (1703);
0x03E8 (1709);
0x03F8
unknown dword 1703 and higher  
0x0260 (1703);
0x0268 (1709);
0x0274
0x03E8 (1703);
0x03F0 (1709);
0x0400
unknown LIST_ENTRY 1703 and higher last PROCESSINFO member in 1703
0x0270 (1709);
0x027C
0x0400 (1709);
0x0410
unknown dword 1709 and higher  
0x0274 (1709);
0x0280
0x0404 (1709);
0x0414
unknown dword 1709 and higher  
0x0278 (1709);
0x0284
0x0408 (1709);
0x0418
unknown dword 1709 and higher  
0x027C (1709);
0x0288
0x040C (1709);
0x041C
unknown dword 1709 and higher last PROCESSINFO member in 1709;
last PROCESSINFO member in 1803

Many consecutive members that are new for Windows 10 support the trace logging event named AppUsageAndDisplayInfoOnExit. It is not known whether they are defined as a nested structure. Names given in italics are those of the parameters for the trace-logging event, except that in 1511 and higher what’s shown as the ProcessImageName is instead hard-coded as ATTRI_DEPRECATED.

The name cVisWindows is proposed with some confidence since it acts as a per-process counter in tandem with the very much older per-thread counter for which Microsoft’s name in version 6.1 is known with the certainty of type information from symbol files.