Why doesn’t GetLastInputInfo() return info for the user I’m impersonating?
The GetLastInputInfo() function returns information about the last input event for the current session, not for any user the calling thread might be impersonating. The function is designed to work at the session level and does not consider impersonation context.
Background
- The Old New Thing is Raymond Chen's long-running Microsoft blog (since 2003) that explains Windows internals, API quirks, and historical design decisions — essential reading for Windows developers.
- GetLastInputInfo() is a Windows API function that returns the tick count since the last user input (keyboard/mouse) on the current desktop session. It's commonly used for idle detection, screensaver triggering, or security timeouts.
- "Impersonation" is a Windows security feature where a thread temporarily assumes another user's security context (e.g., a service acting on behalf of a client). Many APIs respect impersonation and behave as if the impersonated user is running them.
- Chen's point: GetLastInputInfo() explicitly does NOT care about impersonation — it always returns info for the physical user at the console, not the user being impersonated. This is by design; the API's documentation (the "tin") says so. Developers who assume impersonation works here will get confusing results.
GetLastInputInfo() does not return info for an impersonated user because it queries the desktop's input state, not the thread's token. Impersonation changes the security context but not the desktop, so the function still reports the state of the thread's attached desktop, not the impersonated user's session.
The article explains that GetLastInputInfo() returns the last input time for the current desktop's input queue, not for a specific user or thread. Even if impersonating another user, the function still reports the last input on the same interactive desktop session. To track input per user, separate desktop sessions or custom monitoring is needed.