views:

380

answers:

1

I maintain a variety of managed userlabs on a university campus. These machines all currently run Windows XP and we have a windows service that is used to "lock" a machine by blocking any keyboard or mouse input. The locking happens during our scripted OS installation so that users aren't able to accidentally halt or break the process. It is also used to prevent users from logging into machines until they are checked out at the front desk of a given lab. Ctrl+Alt+Del is blocked via a keyboard filter driver and the rest of the keys and mouse are currently blocked using the BlockInput() function from user32.dll.

In XP, the service runs as Local System and the checkbox for "Allow service to interact with desktop" must be enabled from the BlockInput() call to succeed. Under Vista, this no longer works I'm guessing because of the Session 0 isolation changes. The call succeeds, but input is not actually blocked.

The keyboard filter driver still works just fine and we can use that to block the whole keyboard instead of just Ctrl+Alt+Del. But I'm at a loss as to how we're going to block the mouse now. I'm not even entirely sure the Session 0 isolation is to blame.

Can anyone recommend a fix or a workaround to allow us to block mouse input from a service in Vista and beyond? I've looked for alternative win32 API's without luck. Assuming Session 0 isolation is to blame, is there a legitimate way to call the function from Session 1 or would that sort of defeat the purpose of the isolation? Will I have to rely on an elevated companion exe that runs on user login and communicates with the service?

A: 

From a service, you can use WTSEnumerateSessions to get all logged on user sessions, WTSQueryUserToken to get the logged on user's token, and then use CreateProcessAsUser with that token to get code running on the user's desktop. This has the disadvantage that the code will run as the logged on user. Since all input is disabled, this is probably safe enough and is at least as safe as the existing XP solution.]

EDIT: BlockInput requires a high mandatory integrity level. You could try adding this group to the token, but then you have code with higher privileges running on the desktop and potentially open to attacks.

An alternative might be to use your service just to disable all HID class devices on the machine.

Michael
I haven't had a chance to actually test this yet. The problem might end up being that the console user is not a privileged account and the BlockInput call will fail.
Ryan
BlockInput should still work, I don't believe it requires privileges.
Michael
I wrote a simple console app to test the call as a limited user in Vista and it didn't work. I forget whether the call failed outright or succeeded and just didn't work. Running the app elevated worked fine.
Ryan
hmm, non-console might work - there might be some goofiness since the consle windows are a bit special.I will take a stab at this a bit later today.
Michael
Yeah, requires high mandatory integrity owner. Expanded answer to cover this.
Michael
Even though I haven't tested it yet. I'm guessing you're probably right and I've marked this as the accepted answer.
Ryan