Executing a Fast User Switch programmatically – part 1

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:


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.




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



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:





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.

Leave a Reply

  1. Hi

    very good internal stuff. That’s fantastic. I’m curious about more articles.

  2. Pingback: Executing a Fast User Switch programmatically - part 2 | RemkoWeijnen.nl

  3. Hey Remko, are you aware of the awesome Super Fast User Switcher powertoy Microsoft had for XP but which they pulled later? Is such a thing possible for Vista/Windows 7?

  4. Have you ever found a way to get this working if there’s no welcome screen? I do need to log in domain users, and it behaves just as you described it would if there’s no welcome screen.

  5. Thanks a lot for your post.

    For sate “1) When the current session is empty” that you said “This case is very clear.” how we can use this programmatically? What is the API or chain APIs that I can login interactively when there is no any login session. For example after system restart and before any login (I want to use API in my Windows Service to login into Win XP)

  6. Hello Naser,

    You can use this program to login interactively if there is no any login session as well. You can also just use ShellStartCredentialServer and disconnect the console.

  7. Thank you for extremely valuable info. But how can I do the same on Vista and later systems?