3

I'd like to run an application on the logon screen of Windows 7 from a service.

I've been doing long researches on this and trying out different ways already, but unfortunately wasn't fully successful so far. I managed to run the application on the lock screen of a currently logged on user - which at first looked to me as it was what I basically tried to achieve. However, I then realized that there are different logon screens for every user and a general one (user independent).

My guess is that this user independent logon screen (that comes up directly after booting when multiple accounts are available or when clicking "switch user" on the lock screen) runs in session 0, while user 1 runs in session 1, user 2 in session 2 and so on. The problem is that if I run an application in session 0 (with "winsta0\winlogon") it's not visible; running in session 1 works fine but doesn't help much as a user has to be already logged in for that.

So how to run an application on the user independent logon/welcome screen? What are the correct parameters and functions for this purpose? Does anybody have a working example for demonstration? (Delphi is preferred but actually any other language will do as well!)

CodeX
  • 717
  • 7
  • 23
  • Are you tried using [Credential Providers](http://msdn.microsoft.com/en-us/magazine/cc163489.aspx) and the [ICredentialProviderCredential](http://msdn.microsoft.com/en-us/library/windows/desktop/bb776029%28v=vs.85%29.aspx) and [ICredentialProvider](http://msdn.microsoft.com/en-us/library/windows/desktop/bb776042%28v=vs.85%29.aspx) interfaces? – RRUZ May 27 '12 at 01:31

1 Answers1

1

The only supported way to do this is to implement a credential provider, as per RRUZ's comment.

If you don't mind breaking the rules, a service running as local system should be able to launch a subprocess in the session of your choice. Use OpenProcessToken to get a handle to your security token, duplicate it with DuplicateTokenEx, use SetTokenInformation to change the token session identifier, then call CreateProcessAsUser to launch the subprocess. (Initially, it would be simplest to use a separate executable, but once you've ironed out the bugs you could roll the service and the subprocess into a single executable, for example by using a command-line argument or an environment variable to distinguish the two cases.)

The WTSGetActiveConsoleSessionId function will tell you which session is currently connected to the physical console.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • The problem is that WTSGetActiveConsoleSessionId only seems to work with a user logged on. I simply can't manage to access the 'switch user' screen as this one doesn't belong to any user. I'm able to place something on the 'lock' screen but not on the 'switch user' screen. Also: What do you mean by "breaking the rules"? – CodeX May 29 '12 at 11:26
  • I believe on a freshly rebooted system the logon screen will be running in session 1. At any rate, you can check: run tasklist remotely against your target system and look for the session containing the winlogon process. So you could try launching a process in this session, as a proof of concept. Once you've got that sorted you can worry about how to figure out which session to use in the general case. Of course the process will have to connect itself to the right desktop and/or window station; this should be very similar to what you've already done to display content on the lock desktop. – Harry Johnston May 30 '12 at 22:24
  • By "breaking the rules" I mean just that. You're not supposed to display content on the logon screen except by implementing a credential provider. It is almost certainly possible to do so, but there's no guarantee that the same code will continue to work in future versions of the OS. Even installing a future hotfix might make it stop working, though that's less likely. – Harry Johnston May 30 '12 at 22:26