Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenInputDesktop() to determine Secure/Login desktop

Visual C++ 2008

How to establish whether or not the currently interactive user is at either the Locked desktop (Windows-Key L) or the Shutdown Screen (Vista or 7) waiting for programs to close during log-out.

HDESK hd = OpenInputDesktop(0, false, READ_CONTROL);

This works fine for a user app on the Default desktop, but fails with error Code 5 when at the Locked or Shutdown desktops due to, I understand, the user not having permissions to open the secure desktop object.

Calling this from a Service running under the SYSTEM account returns error 1 (invalid function). I believe that the Service is in any case in the wrong session (Session 0) and is unable to determine the interactive desktop for any other session.

I have an app running under the currently interactive user, and also, the system service running, so could do the code from either.

Should I perhaps attempt to enumerate all of the sessions, Window stations and desktops?

Even then how do I determine the currently interactive desktop if I can only make the call to OpenInputDesktop from the SYSTEM service in session 0?

like image 734
Peter350 Avatar asked Oct 26 '25 08:10

Peter350


2 Answers

I think you can try these methods:

  • From a process running in currently interactive user:
    Use WTSRegisterSessionNotification to register for session change notifications. Once registered, interactive process would get logon/logoff notifications. More info can be found here:
    http://msdn.microsoft.com/en-us/library/aa383841.aspx
    http://blogs.msdn.com/b/oldnewthing/archive/2006/01/04/509194.aspx

  • From a service (running in session 0):
    • Use GetProcessWindowStation to get the current station handle of service, and save it for later use.
    • Use WTSGetActiveConsoleSessionId to get session id of current interactive session.
    • Get station name corresponding to current session id using WTSQuerySessionInformation with WTSWinStationName info class.
    • Open this station using OpenWindowStation. Set this station to your service process using SetProcessWindowStation.
    • Now, you can use OpenInputDesktop to check if user has logged-in or not.
    • Close the opened interactive window station by calling CloseWindowStation. Reset the original window station of service by calling SetProcessWindowStation with station handle saved earlier.

PS: Currently, "WinSta0" is the only interactive station in Windows. So, you can skip WTSGetActiveConsoleSessionId and WTSQuerySessionInformation calls.

like image 85
swatkat Avatar answered Oct 29 '25 09:10

swatkat


Beware: MSDN about WTSQuerySessionInformation with WTSWinStationName:

Note: Despite its name, specifying this type does not return the window station name. Rather, it returns the name of the Remote Desktop Services session. Each Remote Desktop Services session is associated with an interactive window station. Currently, since the only supported window station name for an interactive window station is "WinSta0", each session is associated with its own "WinSta0" window station. For more information, see Window Stations.

like image 39
olivier Avatar answered Oct 29 '25 07:10

olivier



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!