views:

166

answers:

5

I need to lock the workstation from a windows service written in VB.Net. I am writing the app on Windows 7 but it needs to work under Vista and XP as well.

User32 API LockWorkStation does not work as it requires an interactive desktop and I get return value of 0.

I tried calling %windir%\System32\rundll32.exe user32.dll,LockWorkStation from both a Process and from Shell, but still nothing happens.

Setting the service to interact with the desktop is a no-go as I am running the service under the admin account so it can do some other stuff that requires admin rights - like disabling the network, and you can only select the interact with desktop option if running under Local System Account.

That would be secondary question - how to run another app with admin rights from a service running under Local System Account without bugging the user.

I am writing an app to control my kids computer/internet access (which I plan to open source when done) so I need everything to happen as stealthily as possible.

I have a UI that handles settings and status notifications in the taskbar, but that is easy to kill and thus defeat the locking. I could make another hidden Windows Forms app to handle the locking, but that just seems a rather inelegant solution.

Better ideas anyone?

+1  A: 

Another inelegant solution (but without the drawbacks of signaling your UI application) is to have another service that is installed to interact with the desktop whose job it is to listen for a signal to lock the desktop.

I agree that it's not great to have to run with local system credentials, but if all the service does is lock the desktop, there's a pretty small footprint that needs secured.

Michael Burr
I think this is a great way to go.
overslacked
Interacting with the desktop is history since session 0 isolation.
Hans Passant
I do not know the difficulty in signaling the UI from a service yet, but I want to avoid adding another piece (2 services plus the UI). Also, I heard that interacting with the desktop was deprecated in Vista, but I see it back in 7. (I skipped Vista myself). Not sure if I can trust it to stay around? Thoughts?
Brad Mathews
I had forgotten about the tightening up of the session 0 access to the desktop. It seems that my suggestion is probably too fragile with dependencies on how various versions of Windows let (or prevent) services from interacting with the desktop. I agree that having 2 services would leave something to be desired (assuming it even works). I'd have to do some research to come up with answers (so I'm probably not the best resource).I'd have to do some reaserch to
Michael Burr
+2  A: 

What you're trying to do is actively blocked by Microsoft - if you did get it working, it'd be exploiting a loophole that will surely be closed soon.

What you can do though is the Friar Tuck/Robin Hood solution - have two programs running and monitoring each other. When one is killed, the other detects this and restarts it (or, just logs the current user out as punishment, depending on how severe you want this to be).

overslacked
I don't know if this still works, but I an old Windows app I made for an April Fools Day would start a new copy of itself in response to WM_CLOSE. That way, Windows was happy (no "this program is not responding..." dialog) yet the little monster was still running.
overslacked
Thank you all for your help! I am working on a version of the Robin Hood (the service) /Friar Tuck (the UI) solution. As usual permission issues prevent me from doing it the simple way - capture the service process and attach an Exit event. I will have to use a timer. I can probably do that from the service to watch the UI though.Any advice on the best way to signal the UI to handle the lock?
Brad Mathews
Ok, it looks like I am going to give up on the Robin Hood/Friar Tuck solution for now. Security issues are preventing the UI from starting a service (permission denied when I do a controller.Start()). I will circle back to hardening the application at a later time.
Brad Mathews
@Brad Mathews - my idea was that the two programs would be run as regular programs, not services. I really don't think you can do what you want from a service.
overslacked
@Overslacked, hmm.... That would certainly harden the UI. One would run hidden. And like the service the name would provide some obfuscation. Also, I just learned that you can set a service to ignore stop requests - have yet to try it. That in combination with automatic service recovery options would provide a fairly high, though not insurmountable, wall around the service.
Brad Mathews
A: 

You could try to launch a screensaver from a windows service that automatically locks the workstation.

SoftwareGeek
A: 

Am am not totally satisfied with my answer but Window's security leaves me little alternative. Anything opened bu the service (through Process, Shell whatever) will not have desktop access. I understand the reasons behind the limitations Microsoft has created but still frustrating!

My Service uses IPC to tell my UI to lock the computer. Here is a basic link on doing that:

http://anoriginalidea.wordpress.com/2007/08/09/simple-inter-process-communication-in-vbnet/

See his reference links for additional data.

However, that still does not quite work. Also see this link for how to do it without the Access Is Denied messages:

http://social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/ce968b5b-04fe-46d2-bb75-73e367a8b0c3

Make sure your URIs are correct. The portName property on the server side is the first part of the IPC path in the GetObject method call. The second part maps to the second parameter of the RegisterWellKnownServiceType call on the server side.

And apparently the portName properties need to be DIFFERENT on the sever and client sides.

If you get "Failed to connect to an IPC Port: The system cannot find the file specified." on your client then the server has not started yet so there is nothing to hear you scream.

Brad Mathews
A: 

Just curious... what kind of hack does UltraVNC use to get this to work? It is my understanding that it CAN work on Windows 7 as a service without the use of the video hook drivers. If so, how does its service get access to the local session?

Brad