CSR_THREAD

The CSR_THREAD structure is what CSRSRV.DLL and the various server DLLs in the CSRSS.EXE server process use for representing a client thread.

Documentation Status

The CSR_THREAD structure is not documented. Neither is Microsoft known to have disclosed a C-language definition in any header from any publicly available kit for any sort of software development.

Type information for the CSR_THREAD is in public symbol files for CSRSS.EXE starting with Windows Vista. Earlier type information is known in a statically linked library, named GDISRVL.LIB, which Microsoft published with the Device Driver Kit (DDK) for Windows NT 3.51.

Members, but not types, are also listed by the !dso command as implemented in the USEREXTS and USERKDX debugger extensions from the DDK for Windows 2000.

Variability

Considering how little of anything to do with CSRSS is documented, the CSR_THREAD is surprisingly stable. Members are rearranged in the early versions and then a substantial withdrawal of thread-level functionality from CSRSS in and after version 4.0 saw the CSR_THREAD shrink, but the only change since has been one member’s removal. The following changes of size are known:

Version Size (x86) Size (x64)
3.10 0xA0  
3.51 0x70  
4.0 0x48  
5.0 to 6.0 0x38 0x60
6.1 to 10.0 0x38 0x58

Layout

These sizes and the names and types in the table that follows are from type information in public symbol files (or such as would ordinarily be in public symbol files) for version 3.51 as an isolated case and for version 6.0 and higher. What’s known of Microsoft’s names and types for other versions is something of a guess, being inferred from what use CSRSRV is seen to make of the structure. Where use of a member corresponds closely with that of a version for which Microsoft’s symbols are available, it seems reasonable to suppose continuity. Some use, however, has no correspondence, the code having changed too much. Even where the use hasn’t changed, tracking it down exhaustively would be difficult, if not impossible, even with source code.

Offset (x86) Offset (x64) Definition Versions Remarks
0x00 (3.10)   unaccounted four bytes 3.10 only  
0x00 0x00
LARGE_INTEGER CreateTime;
3.51 and higher previously at 0x30
0x04 (3.10);
0x08
0x08
LIST_ENTRY Link;
all  
0x10 0x18
LIST_ENTRY HashLinks;
3.51 and higher previously at 0x28
0x18 0x28
CLIENT_ID ClientId;
3.51 and higher previously at 0x14
0x0C (3.10);
0x20
0x38
CSR_PROCESS *Process;
3.10 and higher  
0x10 (3.10);
0x24 (3.51 to 6.0)
0x40 (before 6.1)
CSR_WAIT_BLOCK *WaitBlock;
3.10 to 6.0  
0x14 (3.10)  
CLIENT_ID ClientId;
3.10 only next at 0x18
0x1C (3.10);
0x28 (3.51 to 6.0);
0x24
0x48 (before 6.1);
0x40
HANDLE ThreadHandle;
3.10 to 6.1  
0x20 (3.10);
0x2C (3.51 to 6.0);
0x28
0x50 (before 6.1);
0x48
ULONG Flags;
all  
0x24 (3.10);
0x30 (3.51 to 6.0);
0x2C
0x54 (before 6.1);
0x4C
ULONG ReferenceCount;
all  
0x28 (3.10)  
LIST_ENTRY HashLinks;
3.10 only next at 0x10
0x30 (3.10)  
LARGE_INTEGER CreateTime;
3.10 only next at 0x00
0x38 (3.10);
0x34
 
NTSTATUS ShutDownStatus;
3.51  
0x3C (3.10)   unaccounted four bytes 3.10 only  
0x40 (3.10);
0x38
 
PVOID ServerId;
3.51  
0x3C  
PVOID ServerThread;
3.51  
0x44 (3.10)   unaccounted eight bytes 3.10 only  
0x4C (3.10)  
ULONG ImpersonateCount;
3.10 only next at 0x60
0x50 (3.10)   unaccounted 0x24 bytes 3.10 only  
0x74 (3.10)  
BOOLEAN ThreadConnected;
3.10 only next at 0x64
0x78 (3.10);
0x40 (3.51)
 
HANDLE ClientEventPairHandle;
3.10 to 3.51  
0x7C (3.10);
0x44 (3.51)
 
HANDLE ClientSectionHandle;
3.10 to 3.51  
0x80 (3.10);
0x48 (3.51)
 
CHAR *ClientSharedMemoryBase;
3.10 to 3.51  
0x84 (3.10);
0x4C (3.51)
 
HANDLE ServerEventPairHandle;
3.10 to 3.51  
0x88 (3.10);
0x50 (3.51)
 
HANDLE ServerSectionHandle;
3.10 to 3.51  
0x8C (3.10);
0x54 (3.51)
 
HANDLE ServerThreadHandle;
3.10 to 3.51  
0x90 (3.10);
0x58 (3.51)
 
CHAR *ServerSharedMemoryBase;
3.10 to 3.51  
0x94 (3.10);
0x5C (3.51)
 
ULONG SharedMemorySize;
3.10 to 3.51  
0x60 (3.51);
0x34 (4.0 to 6.0);
0x30
0x58 (before 6.1);
0x50
ULONG ImpersonateCount;
3.51 to 6.1 previously at 0x4C
0x64 (3.51)  
BOOLEAN ThreadConnected;
3.51 only previously at 0x74
0x65 (3.51)  
BOOLEAN Dying;
3.51 only  
0x38 (4.0)   unaccounted eight bytes 4.0 only  
0x9C (3.10);
0x68 (3.51);
0x40 (4.0)
 
PVOID ServerDllPerThreadData [1];
3.10 to 4.0  

No use is known of the Dying member even in the version for which type information shows it as defined.

Up to and including version 4.0, the CSR_THREAD is built in a memory block that continues with:

A server DLL requests per-thread space for all future processes by setting the wanted amount into the PerThreadDataLength member of the CSR_SERVER_DLL during initialisation. Each server DLL’s allowance is aligned up to 4 bytes in version 3.10 but 8 bytes in later versions. Each ServerDllPerThreadData element points to the allowance for the corresponding server DLL (or is NULL if the server DLL has no per-thread space).