CSR_API_MSG

The CSR_API_MSG structure is a container for input and output (mostly but not only) to the API routines of server DLLs in the CSRSS.EXE process. The ordinary means—indeed, in version 4.0 and higher, the only means—of communication is a Local Procedure Call (LPC) through a port. Parameters for the call are marshalled into messages. The CSR_API_MSG is what the server receives. It has a system-defined PORT_MESSAGE header and some allowance for message data whose interpretation is up to the API routine.

Documentation Status

The CSR_API_MSG 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_API_MSG is in public symbol files for CSRSS.EXE in Windows Vista only. 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 debugger extension from the DDK for Windows 2000.

Variability

Being exchanged between multiple components, albeit all written by Microsoft, the CSR_API_MSG is better not to change much. Indeed, the only change in the whole history is a recurring increase in how large may be that part whose interpretation is specific to each API routine. The following changes of size therefore suggest more variability than there arguably is:

Version Size (x86) Size (x64)
3.10 to 4.0 0xA0  
5.0 0xA8  
5.1 to 5.2 0xC8 0x0178
6.0 to 10.0 0xE0 0x01B0

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 versions 3.51 and 6.0. 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
0x00 0x00
PORT_MESSAGE h;
all
0x18 0x28
union {
    CSR_API_CONNECTINFO ConnectionRequest;
    struct {
        /*  individual members, see below  */
    };
};
all

The kernel’s support for ports requires that the message for connecting through a port is a system-defined PORT_MESSAGE followed immediately by port-specific data whose interpretation is up to the server. Before version 6.0, when CSRSRV changed from using NtCreatePort to NtAlpcCreatePort, the size to expect for this connection information is told to the kernel when the port is created. The ConnectionRequest is this data for connecting through the API port. The unnamed structure in union with the ConnectionRequest is similarly for interpretation by the server but for distributing to API routines that get called through the port once connected:

Offset (x86) Offset (x64) Definition Versions
0x18 0x28
CSR_CAPTURE_HEADER *CaptureBuffer;
all
0x1C 0x30
ULONG ApiNumber;
all
0x20 0x34
ULONG ReturnValue;
all
0x24 0x38
ULONG Reserved;
all
0x28 0x40
union {
    /*  changing members, see below  */
} u;
all

The ApiNumber must be meaningful on input. Its high word is the 0-based index of the server DLL. The low word selects from this server DLL’s API routines (which can be numbered from a base other than zero).

The union u has zero or more bytes of data whose interpretation is specific to the selected API routine:

Offset (x86) Offset (x64) Definition Versions
0x28 0x40
CSR_NULLAPICALL_MSG NullApiCall;
3.10 to 4.0
0x28 0x40
CSR_CLIENTCONNECT_MSG ClientConnect;
all
0x28 0x40
CSR_THREADCONNECT_MSG ThreadConnect;
3.10 to 5.1
0x28 0x40
CSR_PROFILE_CONTROL_MSG ProfileControl;
3.10 to 5.1
0x28 0x40
CSR_IDENTIFY_ALERTABLE_MSG IndentifyAlertable;
3.10 to 5.1
0x28 0x40
CSR_SETPRIORITY_CLASS_MSG PriorityClass;
3.10 to 5.1
0x28 0x40
ULONG ApiMessageData [0x1E];
3.10 to 4.0 
ULONG ApiMessageData [0x20];
5.0 only
ULONG_PTR ApiMessageData [0x27];
5.1 to 5.2
ULONG_PTR ApiMessageData [0x2E];
6.0 and higher

The six special cases of this API message data are for the API routines in CSRSRV itself. They are arranged in increasing order of ApiNumber, starting with zero. CSRSRV trivially fails the messages for ThreadConnect and ProfileControl in version 4.0 and higher, and for ProfileControl and IndentifyAlertable in version 5.2 and higher. In contrast, version 5.0 removes all support for NullApiCall (and renumbers the API routines). By the way, the spelling of IndentifyAlertable is Microsoft’s.

The CSR_API_MSG in the x86 builds of versions 5.1 to 5.2 has enough space for the ApiMessageData to have 0x28 elements. It is here thought that the last of these is unlabelled padding created by the structure’s 8-byte alignment (picked up from the PORT_MESSAGE), with the merit of matching the x64 implementation which has space for only 0x27.