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.

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 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  

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, 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. 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 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 a guess that the W32PROCESS does not exist as a separate structure before version 4.0. In this version, three members that had been very nearly at the end at the PROCESSINFO move to very near the start. Conspicuous among these 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;
3.51 and higher previously at 0x0108
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 unaccounted 0x0C bytes (x86);
unaccounted 0x28 bytes (x64)
6.2 and higher last W32PROCESS member in 6.2;
last W32PROCESS member in 6.3;
last W32PROCESS member in 10.0

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.

PROCESSINFO Continuation

Again, 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
0xD0 (5.2);
0xE0 (6.0);
0x0100 (6.1);
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
0xD8 (5.2);
0xE8 (6.0);
0x0108 (6.1);
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
0xE0 (5.2);
0xF0 (6.0);
0x0110 (6.1);
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
0xE8 (5.2);
0xF8 (6.0);
0x0118 (6.1);
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
0xF0 (5.2);
0x0100 (6.0);
0x0120 (6.1);
0x0148
CLS *pclsPublicList;
all  
0x40 (5.0 to 5.1);
0x8C (5.2);
0x94 (6.0);
0xA4 (6.1);
0xB0
0xF8 (5.2);
0x0108 (6.0);
0x0128 (6.1);
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
0x0100 (5.2);
0x0110 (6.0);
0x0130 (6.1);
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
0x0108 (5.2);
0x0118 (6.0);
0x0138 (6.1);
0x0160
PROCESSINFO *ppiNextRunning;
5.0 and higher  
0x4C (5.0 to 5.1);
0x98 (5.2);
0xA0 (6.0);
0xB0 (6.1);
0xBC
0x0110 (5.2);
0x0120 (6.0);
0x0140 (6.1);
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
0x0118 (5.2);
0x0128 (6.0);
0x0148 (6.1);
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
0x0120 (5.2);
0x0130 (6.0);
0x0150 (6.1);
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
0x0124 (5.2);
0x0134 (6.0);
0x0154 (6.1);
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
0x0128 (5.2);
0x0138 (6.0);
0x0158 (6.1);
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
0x0228 (5.2);
0x0238 (6.0);
0x0258 (6.1);
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
0x0230 (5.2);
0x0240 (6.0);
0x0260 (6.1);
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
0x0238 (5.2);
0x0248 (6.0);
0x0268 (6.1);
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
0x023C (5.2);
0x024C (6.0);
0x026C (6.1);
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 same debugger extension’s names for the defined bits has 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
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
0x0240 (5.2);
0x0250 (6.0);
0x0270 (6.1);
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
0x0248 (5.2);
0x0258 (6.0);
0x0278 (6.1);
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
0x0250 (5.2);
0x0260 (6.0);
0x0280 (6.1);
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
0x0258 (5.2);
0x0268 (6.0);
0x0288 (6.1);
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
0x0268 (5.2);
0x0278 (6.0);
0x0298 (6.1)'
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
0x0270 (5.2);
0x0280 (6.0);
0x02A0 (6.1);
0x02C8
PVOID pClientBase;
5.0 and higher  
0x0108 (5.0 to 5.1);
0x0154 (5.2);
0x015C (6.0);
0x016C (6.1);
0x0178
0x0278 (5.2);
0x0288 (6.0);
0x02A8 (6.1);
0x02D0
DWORD dwLpkEntryPoints;
5.0 and higher  
0x010C (5.0 to 5.1);
0x0158 (5.2);
0x0160 (6.0);
0x0170 (6.1);
0x017C
0x0280 (5.2);
0x0290 (6.0);
0x02B0 (6.1);
0x02D8
W32JOB *pW32Job;
5.0 and higher  
0x0110 (5.0 to 5.1);
0x015C (5.2);
0x0164 (6.0);
0x0174 (6.1);
0x0180
0x0288 (5.2);
0x0298 (6.0);
0x02B8 (6.1);
0x02E0
DWORD dwImeCompatFlags;
5.0 and higher  
0x0114 (5.0 to 5.1);
0x0160 (5.2);
0x0168 (6.0);
0x0178 (6.1);
0x0184
0x028C (5.2);
0x029C (6.0);
0x02BC (6.1);
0x02E4
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
0x0294 (5.2);
0x02A4 (6.0);
0x02C4 (6.1);
0x02EC
USERSTARTUPINFO usi;
5.0 and higher previously at 0xE0
0x019C (6.1);
0x01A8
0x02E0 (6.1);
0x0308
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
0x02B0 (5.2);
0x02C0 (6.0);
0x02E4 (6.1);
0x030C
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

Offset (x86) Offset (x64) Definition Versions Remarks
0x013C (5.1);
0x0188 (5.2);
0x0190 (6.0);
0x01A4 (6.1);
0x01B0
0x02B8 (5.2);
0x02C8 (6.0);
0x02E8 (6.1);
0x0310
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
0x02D0 (6.0);
0x02F0 (6.1);
0x0318
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
0x02D8 (6.0);
0x02F8 (6.1);
0x0320
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
0x0300 (6.1);
0x0328
unknown VWPL pointer 6.1 and higher not present in 6.1 according to symbol files
0x01B8 (6.1);
0x01C0
0x0308 (6.1);
0x0330
unaccounted 6.1 and higher not present in 6.1 according to symbol files
0x01BC (6.1);
0x01C4
0x0310 (6.1);
0x0338
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 offset 0x01AC. This offset is 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 0x0340 unknown qword 6.2 and higher  
0x01D0 0x0348 unknown dword 6.3 and higher  
0x01D0 (6.2);
0x01D4
0x0348 (6.2);
0x0350
unknown pointer 6.2 and higher  
0x01D8 0x0358 unknown four pointers or handles 10.0 and higher  
0x01D4 (6.2);
0x01D8 (6.3);
0x01E8
0x0350 (6.2);
0x0358 (6.3);
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 0x0380 unknown pointer 10.0 and higher  
0x01F0 0x0388 unknown dword 10.0 and higher  
0x01F4 0x038C unknown CHAR [0x10] 10.0 and higher  
0x0204 0x039C unknown dword 10.0 and higher  
0x0208 0x03A0 unknown dword 10.0 and higher  
0x020C 0x03A4 unknown dword 10.0 and higher  
0x0210 0x03A8 unknown dword 10.0 and higher  
0x0214 0x03AC unknown dword 10.0 and higher  
0x0218 0x03B0 unknown dword 10.0 and higher  
0x021C 0x03B4 unknown dword 10.0 and higher  
0x0220 0x03B8 unknown dword 10.0 and higher  
0x0224 0x03BC unknown dword 10.0 and higher  
0x0228 0x03C0 unknown WCHAR [0x10] 10.0 and higher  
0x0248 0x03E0 unknown dword 10.0 and higher  
0x024C 0x03E4 unknown dword 10.0 and higher last PROCESSINFO member in 10.0

Many of the new members support logging. It’s not impossible that more than the present cursory study will show that some make a nested structure.