Geoff Chappell, Software Analyst
The CsrCallServerFromServer function calls a server DLL from within the CSRSS.EXE process. The intended caller is NTDLL.DLL, specifically for its CsrClientCallServer function. When software in the CSRSS process asks NTDLL for anything that would ordinarily require calling the server, NTDLL realises that because it is already in the server process the call can be made through CsrCallServerFromServer instead of as a Local Procedure Call (LPC) through a port.
NTSTATUS CsrCallServerFromServer ( CSR_API_MSG *Input, CSR_API_MSG *Output);
The required Input and Output arguments point respectively to structures that provide the input and output. The same address can be given for both input and output. Indeed, this is the only way that NTDLL is known to call this function.
The function returns STATUS_SUCCESS if successful, else a negative error code.
The CsrCallServerFromServer function is exported by name from CSRSRV.DLL in all known Windows versions.
The CsrCallServerFromServer function is not documented.
The function is a router to an API routine in a server DLL. The selection is detemined from the ApiNumber in the Input. The high word is the 0-based index of the server DLL. The low word selects from this server DLL’s API routines. CSRSRV knows each server DLL’s index from the corresponding ServerDLL argument on the CSRSS command line. As each server DLL initialised, it describes its API routines by setting members of a CSR_SERVER_DLL. The ApiDispatchTable is an array of pointers to the routines. The numbering for the low word of the ApiNumber begins with ApiNumberBase and (putting aside a coding error in versions before 5.0) continues up to but not including MaxApiNumber. The server DLL may (but in version 3.10 is assumed to) also provide an ApiServerValidTable, which is an array of booleans which tell whether the corresponding routine is valid for calling through CsrCallServerFromServer. The default is that all routines are valid.
If the high word does not select a loaded server DLL or if the low word does not select a valid API routine for the selected server DLL, the CsrCallServerFromServer function fails: STATUS_ILLEGAL_FUNCTION becomes both the function’s return value and the ReturnValue in the Output.
Ordinarily, the function calls the indicated API routine for the selected server DLL. The function returns STATUS_SUCCESS to indicate that the call was at least attempted. This is true even if an exception occurs, though in this case the function sets STATUS_ACCESS_VIOLATION as the ReturnValue in the Output.
The server DLL’s API routine has the prototype
typedef ULONG (*PCSR_API_ROUTINE) (CSR_API_MSG *, CSR_REPLY_STATUS *);
The server DLL receives only the Input, not the Output. It also gets the address of a CSR_REPLY_STATUS but nothing is either set at the address before calling or interpreted after. Whatever ULONG the server DLL returns becomes the ReturnValue in the Output.
Versions before 5.0 treat the ApiDispatchTable and ApiServerValidTable as each having MaxApiNumber elements.