I think many of you have got experience with multiple Terminal Server Sessions in windows XP, also called Fast User Switching (FUS). Let’s get inside this cool feature.

How does FUS work? Each session has its own winlogon.exe. It draws the same interface which looks like the screenshot below:

multiple-users-logged-on

1) When the current session is empty (no user is logged in), and you clicking on a user name, the system just logs you on to the current session. This case is very clear.

user-new

user-new-loggin-in

user-new-logged-on

2) If you click on an already logged in user, you are connected to the target user session using the WinStationConnect API. It’s prototype is

The current session is just disconnected (if it contains logged on user) or even eliminated (if it doesn’t contain a logged on user and if its not session number 0, which is never disposed).

new-session-old-user

user-new-logged-on

3) But what happens when you click on a user other than yourself and you are already logged into the current session? Visually it looks almost the same – but look, there is a quick blank switch (you may not notice this as it disappears very quickly). This is a session disconnect and re-connect:

user-new

blank-screen

user-new-loggin-in

user-new-logged-on

So what is happening? After verifying your credentials, msgina.dll starts a Credential Server, and disconnects the current session from the console. Because the console session is an auto-reconnected session (if you disconnect it, you’ll get a new session attached to the console (Terminal Server has even a “hardcode” in termsrv.dll to reconnect console session faster, if the current gina is msgina.dll)), a new session will be created and attached to the console. Msgina.dll perfoms some checks on startup: if it’s attached to the console session, and the Credential Server is running, it will read the credentials, and perform the login as if the credentials were typed manually.

But how we can use this programmatically? Msgina.dll has an undocumented, exported, function named ShellStartCredentialServer. It’s exported from msgina.dll by ordinal #23.

It’s full prototype is

The function doesn’t validate anything; it just packs the data, writes it to a pipe and disconnects the console session. However, if the credentials are invalid, you will not get FUS working, so it is a good idea to validate them before sending. The domain parameter is ignored (it seems that FUS was initially designed to work with domain users as well, however this support was apparently dropped on some stage). If you pass valid credentials data, but the user is already logged on, you will just switch to this session. So you can use this function whenever you need to switch the console. You can even call this function from an RDP session but it will still affect the console session only.

This function will fail if the Welcome screen is disabled; in that case you’ll just get your session disconnected and locked. The caller is required to have SE_TCB_NAME privilege (“Act as part of the operating system”) enabled. Actually, this is not enough since the default security of the registry hive HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Credentials allows read and write access to system only.

In the next part I’ll show you how to create your own implementation of the Credential Server.