Search code examples
c++windowswinapiservicewinlogon

How to know when the Winlogon desktop is ready for inputs?


I successfully used SendSAS in a service (Local System Account). I call the API four seconds after the service starts. It seems that whatever the boot process duration, Windows manage to cache (sort of) the call: the same code finally shows me a logon screen a few seconds after the power on, on a fast laptop (Win10), and also shows me the logon screen after a very much longer delay on a slow Server (2012R2) running virtualized (wmware).

I am also able to use CreateProcessAsUser (with an updated token) to inject a tiny executable in the Session 1, Station WinSta0, Desktop Winlogon. The process then uses SendInput to "auto-logon" the session (yes, this is an awful think to do do, I am aware of that).

My problem: if the tiny process starts "too early", nothing happens. If the service waits, say, 2 minutes, all is OK.

What API should I use (in the service or in the started process) to find out when the WinLogon desktop is ready to accept keyboard inputs?

I tried WTSGetActiveConsoleSessionId (in the service) and OpenInputDesktop (in the process) hopping that failure would indicate the need to wait, but with no avail.


Solution

  • When your process starts in session 1, attached to the WinSta0\Winlogon desktop, you can periodically test the Control Type of the currently IUIAutomationElement focused element.

    The APIs to use are : IUIAutomation::GetFocusedElement and then IUIAutomationElement::GetCurrentPropertyValue for the UIA_ControlTypePropertyId property. When you successfully get a focused element of type UIA_EditControlTypeId, the Windows logon screen is ready to accept inputs.

    Don't forget to add a Sleep call between each try.

    Tested OK with Windows Server 2008R2 and 2012R2, and with Windows 10.