Search code examples
winapiwindows-7windows-xpwindows-vistaterminal-services

Windows session APIs not loading in time on Windows XP and ways to bypass it


I'm writing a service application that needs to enumerate all current user sessions, and obtain their session IDs, and later see what processes are running for what session. I'm using the WTSEnumerateSessions() API, as well as WTSQuerySessionInformation() to obtain a session specific information. Unfortunately those WTS APIs are very unreliable.

On a Windows XP machine with Fast User Switching turned off, or on an XP machine joined to a domain, those APIs are not immediately available. They may fail with the RPC_S_INVALID_BINDING, or 1702, error code for as long as several minutes after the Windows XP boots up and my service starts.

I could not find any official documentation explaining how to handle such limitation. The one available via a search engine is to wait for the terminal services service to load up, which is of course possible, but becomes a MAJOR pain in the a** to implement.

So, if someone could answer the following I'd appreciate it:

  1. Are there any alternative APIs to work with session specific data, that are more reliable that those WTS ones? I mostly need to see current sessions on the machine, get a user name and session status. Also enumerate processes with session IDs for each process. (I know that this is possible, since GINA or a log-in screen, can do all that way before the terminal services load up.)
  2. Is there a 100% guaratee that WTS-class APIs (such as WTSEnumerateSessions(), WTSQuerySessionInformation() and WTSEnumerateProcesses()) will load up before my service starts up on any version of Windows Vista/Windows 7 machine?

Please note bofore and any stipulations that a VERY important.


Solution

  • Another API which could be helpful for you are LsaEnumerateLogonSessions and LsaGetLogonSessionData SECURITY_LOGON_SESSION_DATA having Session field. See the code example and this one. To get information about the session of the process you can use GetTokenInformation with TokenSessionId as parameter. To enumerate processes you can use NtQuerySystemInformation (see my old answer).