tiago2014
tiago2014

Reputation: 3461

How to get the current number of interactive user sessions in Windows?

I'm writing a Windows service that needs to know whether there are any users currently logged-on in the machine.

So far I've tried Win32_LogonSession (WMI), and LsaEnumerateLogonSessions/LsaGetLogonSessionData (secur32.dll).

Both work, and seem to return the same data, but they are too slow to update when a user log off:

Thus Win32_LogonSession nor LsaEnumerateLogonSessions are good enough. The service needs to know within 5 minutes after the last interactive user leaves.

Not even SysInternals' LogonSessions.exe gives up-to-date answers.
Also, the answer cannot be "monitor logon and logoff events and have a counter variable", because the service can be started at any time.

Upvotes: 4

Views: 3946

Answers (2)

AntonK
AntonK

Reputation: 1310

WTSEnumerateSessionsA + WTSQuerySessionInformationA work better with detecting active/interactive sessions.

Upvotes: 2

tiago2014
tiago2014

Reputation: 3461

I ended up with the following approach: count the number of interactive sessions which have at least one process running.

1) Get the logon session id for each interactive session.

  • LsaEnumerateLogonSessions (secur32.dll)
  • LsaGetLogonSessionData (secur32.dll)
  • sessionData.LogonType = SECURITY_LOGON_TYPE.Interactive or sessionData.LogonType = SECURITY_LOGON_TYPE.RemoteInteractive
  • sessionData.LoginID <- Keep this value in a LUID set.
  • LsaFreeReturnBuffer (secur32.dll)

2) Get the logon session id for each running process.

[First we need to enable the SeDebugPrivilege to the current application.]

  • GetCurrentProcess (kernel32.dll)
  • OpenProcessToken TOKEN_ADJUST_PRIVILEGES (advapi32.dll)
  • LookupPrivilegeValue SE_DEBUG_NAME (advapi32.dll)
  • AdjustTokenPrivileges (advapi32.dll)
  • CloseHandle (kernel32.dll)

[Then retrieve the data we want.]

3) Sets intersection cardinality

interactiveSessionsCount = | { sessionData.LoginID } ∩ { accessTokenStatistics.AuthenticationId } |

Obs: sessionData.LoginID and accessTokenStatistics.AuthenticationId are both of type LUID.

Upvotes: 10

Related Questions