0

I am trying to determine the current session state using the Win32 API ::WTSQuerySessionInformation function by querying for SessionFlags of the WTSINFOEX_LEVEL1 structure according to the answers to C++: check if computer is locked.

On my machine (Windows 10 1703) SesssionFlags can reach only two (of three documented) values: WTS_SESSIONSTATE_UNLOCK and WTS_SESSIONSTATE_UNKNOWN. The latter seems to mean the same as the expected WTS_SESSIONSTATE_LOCK which I cannot reach, neither through <WinKey>+<L> nor by programmatically locking the session through ::LockWorkStation.

So my questions are:

  1. Does WTS_SESSIONSTATE_LOCK exist?
  2. If yes, then how can I reach that state?
  3. If yes, what is the difference between both states (LOCK and UNKNOWN)?

According to SessionChangeReason Enumeration the .NET Framework distinguishes (correctly?) between just two corresponding states SessionUnlock and SessionUnlock. So the state of a session is triple or binary?

Peter Rawytsch
  • 115
  • 1
  • 9
  • It is not possible to detect that the secure desktop is currently displayed. The .NET Framework avoids that problem by detecting changes in the session state with WTSRegisterSessionNotification – Hans Passant May 09 '18 at 17:15

1 Answers1

1

One would think that WTS_SESSIONSTATE_UNKNOWN means that the state is unknown and you should not interpret it as locked nor unlocked. It seems this member has a sorry history, MSDN says

Windows Server 2008 R2 and Windows 7: Due to a code defect, the usage of the WTS_SESSIONSTATE_LOCK and WTS_SESSIONSTATE_UNLOCK flags is reversed. That is, WTS_SESSIONSTATE_LOCK indicates that the session is unlocked, and WTS_SESSIONSTATE_UNLOCK indicates the session is locked.

Because the member is named SessionFlags and MSDN says "This can be one or more of the following values" one could imagine that more flags could be added over time and you should actually be doing:

isUnlocked = SessionFlags & WTS_SESSIONSTATE_UNLOCK;

(and the logic reversed on Windows 7). I don't think anyone does this so I doubt Microsoft will ever add more flags but you never know.

On my Windows 8 and 10.0.17134 machines it returns WTS_SESSIONSTATE_UNLOCK normally and WTS_SESSIONSTATE_LOCK when I press Win+L so it is possible you are doing something wrong?

I don't know what happens if a Windows 7+ machine tries to ask a Vista machine, maybe you get WTS_SESSIONSTATE_UNKNOWN or maybe the entire call fails because Vista does not support WTSSessionInfoEx.

The accepted answer in the question you linked to tells you to use WTSRegisterSessionNotification and it will provide you with the same values as SessionChangeReason and you don't have to pull to detect changes.

Anders
  • 97,548
  • 12
  • 110
  • 164
  • You're right: I have reviewed my code and I saw that I mixed-up `WTS_SESSIONSTATE_LOCK` with `WM_WTSSESSION_CHANGE`'s `WTS_SESSION_LOCK`. Having fixed the typo, `WTS_SESSION**STATE**_LOCK` discovered itself. In my case `WTSRegisterSessionNotification`is not acceptable since I have to know the initial state (before any session change). – Peter Rawytsch May 11 '18 at 12:36