UAC-style elevated prompt - c#

I'm interested in launching a window in a temporary session, like how UAC prompts appear. There's been some interest in this concept from a few people, so I figured I'd ask here. Essentially what we're going for is an elevated window like the UAC "are you sure you want to <...>" prompts, but with an arbitrary window. The end goal is to prevent window event hooks and all sorts of other issues that might occur during password entry.
I've had a quick look at the UAC APIs and a few other places, but there's nothing particularly useful out there. Obviously the UAC prompts get elevated to their own desktop session somehow, so there must be a way to create windows in such a way.

You can create a desktop using CreateDesktop. You can use SwitchDesktop to switch to the new desktop. Then you can call SetThreadDesktop on your main thread and draw your window. To get back get the handle of the default desktop by calling OpenDesktop with "Default" as lpszDesktop and use SwitchDesktop with this handle. You can also run Processes on a certain desktop. In order to do this you have to set lpDesktop member of the STARTUPINFO structure to the name of the desktop the process should be run on. Close the handles to the desktops after using them (CloseDesktop).
You can show your own window on an own desktop in this way.
The secure desktop used by UAC and by the Logon UI is called "Winlogon". In order to access it you need system rights. Luke provided an example in one of his answers.
Brian R. Bondy wrote a blog entry on desktops and window stations which is worth reading.

Related

Running sub application in the normal mode when the base application is in the administrative mode

I have two application which is a main and a sub. both can also be opened separately and the main can also open the sub.Since the main application is in the administrative mode, the sub-application when opened from the main application is also opening in the same mode. Is there any possible way where can I open the sub-application in a normal but I need to have the base application running in the admin mode. The problem is I need to drag and drop files in the sub-application which cant be done when the application is in administrator mode.
Getting rid of Adminsitrative Privileges is surprisingly hard. It is nigh impossible to get rid of them, like starting a non-Elevated Process from a elevated one. It is a a vexing property of Windows.
There are ways but they usually involve unmanaged code (Windows API) and are not that stable.
It is possibly if you have the Application user/System Adminsitrator Specify a specific Windows User that he he maintains explicitly as one without Administrative Privileges. The way most non-elevated Services are started is by a explicit Windows User that is set in the Service Manager.
Most programmers eventualy settle to dodge this Problem entirely via an approach like this:
Have both Process A and B designed to always start non-Elevated (no Manifest or anything demand Elevation)
Modify Process A to detect that it is non-Elevated right now
Let Process A try to start a Elevated copy of itself via Runas with proper Options.
If the user is always Elevated (because the UAC is turned off or soemthing like that), it is out of your hands.
As I learned the hard way, there is also a chance that elevation might fail due to faulty Windows configuration. Again, this is out of your hands.
Of course there is the big question of why this is a Problem to begin with and if that is perhaps a XY Problem. Drag & Drop might have those limits. But do you have to use D&D for this? There are many ways to go about Interprocess Communicaiton. Most of them do not suffer such Limitations. D&D is just one of them.

How to check is UAC is currently blacking out the screen?

I am trying to determine if User Account Control is currently blacking out the screen/asking for permission.
I have an application which uses SlimDX and when UAC takes over the screen it causes the DirectX device to be lost, I can recreate the device once the UAC window has been closed, if I try this before(even in a try{}catch{} and loop the application crashes)
I have looked over at pinvoke and msdn and I can't seem to find anything about this. Does anyone have an ideas?
As a note: I do not want to interact with these prompts in any way, I only want to check if they are open so I can delay the creation of my DirectX device.
Sorry for making a late answer. But I think it may help.
As far as I see, you are not looking for a way to see if UAC is running, but a way to check whether UAC is blocking the screen.
I've confirmed that UAC is using SwitchDesktop to change to another desktop, so you can just use GetInputDesktop to get the 'active' desktop. Then use GetUserObjectInformation to check its name. The 'normal' desktop should be default, while UAC will be running on the WinLogon desktop.
Wish it will help.
If a UAC prompt is currently on screen then C:\Windows\System32\consent.exe will be running. There are ways to be notified with a event when a program starts or stops, you can use them and have your program perform the action to recreate the DirectX device after the consent.exe program terminates.

Measures to prevent from closing a program

Say I have a simple C# monitoring program that is to be installed on some company computers, so I know what the employees are doing. The program is a single .exe file that works in the system tray. How do I prevent employees from closing this program? Is there a way to be notified when a program is closed?
If you don't want users to close your program, run it under a different account. Normal users can't kill processes they don't own, ie that run using different accounts. Of course, this means that you can't run your program as a simple application that displays a taskbar notification. You will have to convert it to a service.
In fact, a service makes a lot more sense than a user application in this scenario. If you want to display feedback or options to the user you can still create an app that creates a taskbar icon and communicates with your service
Set it up as a service and in the options for the service on first, second, and third failure - make it reboot the computer. Have the service login-as an service user with a strong password and prevent the users from running as Administrators. This should solve your problem and probably create a bit of annoyance at the same time.
The short answer: No.
The long answer: Yes...write a rootkit which will either guard or hide your process. Otherwise the users will be able to kill the process f.e. via the Task-Manager or any other means. Same goes for any helper processes which would monitor your application.

How to allow users only interactive with my program?

I'm writing a software for a call-center. It's somewhat like a ATM program: user can only interactive with it, not with underlying Windows. It takes controls when user logs in to Windows, and when user exits, it logs off Windows.
How can I do that in .NET? A demo will be much appreciated.
Thank you.
Replace the Windows Shell.
By that I mean Explorer.exe, by means of editing the Windows Registry. What this does for you is instead of logging on and the system running Explorer.exe which consists of the Start Menu, Taskbar and other similar features you are familiar with, it only runs your program. There is no desktop, no context menu, no taskbar, or start menu. Thus, making your application "The Shell" or the new "Explorer.exe".
However, by doing this the user still has access to Control+Alt+Delete, so they would still be able to access the Windows Task Manager, which mind you can also be disabled via a simple Registry Key Entry.
This is the most pain free, easiest solution because you don't even have to worry about things such as disabling the WindowsKey or other annoyances.
The registry key to this is as follows:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
The name of the value to modify is:
Shell
And you can simply enter the value to be the fully qualified path to your program's executable file. You will only want to do this under HKEY_CURRENT_USER and only for the account that is to run your shell program. So you will need two separate accounts.
Administrator account
This account will just be a normal password protected account that will be used to manage the system
Kiosk account
This account will be the account that is logged on at all times, which runs your custom shell (your application)
Additional Notes
To disable the Task Manager the registry path is as follows:
Software\Microsoft\Windows\CurrentVersion\Policies\System
The name of the value is:
DisableTaskMgr
This is a DWORD value which to enforce the policy must be set to '1'.
What I did was to use DirectX and just use full-screen and exclusive modes, which you can see a small example of here: http://www.directxtutorial.com/tutorial9/b-direct3dbasics/dx9B2.aspx.
This is more work, but it will allow you to do what you want.
Depending on what control you have, there are steps you can do with group policy to limit what people can do on the computer. You can look at how people set up a kiosk application on Windows for some ideas.
What you want to do is run the OS in "kiosk mode".
This entails using the Group Policy Management Console to apply the kiosk mode template - as part of this you register your application as the shell.
As such there is no taskbar, or explorer view to fall back on to. The only way to run the usual shell would be to connect a keyboard to the system - press ctl-alt-delete and run explorer from the taskmanager that pops up.
And you can disable even the standard task manager if users are going to have keyboard access to the console. You will want to implement some kind of launch explorer.exe interface otherwise the system might become a bit difficult to manage :P
You can set your applications window to be always on top and to cover the entire screen. If you exclude buttons that close the window the user must know that ALT+F4 closes the window in order to exit. This has been good enough for me those times I've needed it.

Prevent application launch in C#

Okay I've spent the afternoon researching and haven't had much luck finding the answer to this. I am trying to prevent an application from launching via some sort of dll or background application. It is to be used in monitoring application usage and licenses at my institution. I have found leads here regarding WqlEventQuery and also FileSystemWatcher. Neither of these solutions appear to work for me because:
With WqlEventQuery I was only able to handle an event after the process was created. Using notepad as a test, notepad was visible and accessible to me before my logic closed it. I attempted to Suspend/Resume the thread (I know this is unsafe but I was testing/playing) but this just hung the window until my logic finished.
With FileSystemWatcher I was not able to get any events from launching a .exe, only creating, renaming and deleting files.
The goal here is to not let the application launch at all unless my logic allows it to launch. Is this possible? The next best solution I came up with was forcing some type of modal dialog which does not allow the user to interact with anything, once the dialog is closed the application is killed. My concern here is killing the application nicely and handling applications with high overhead when they load such as Photoshop or something. This would also interfere with a feature I was hoping to have where the user could enter a queue until a license is available. Is this my best route? Any other suggestions?
Thanks
edit: To clarify this is not a virus or anything malicious. It's not about preventing access to a blacklist or allowing access through a whitelist. The idea is to check a database on a case by case basis for certain applications and see if there is a license available for use. If there is, let the app launch, if not display a dialog letting the user know. We also will use this for monitoring and keeping track if we have enough licenses to meet demand, etc. An example of one of these apps is SPSS which have very expensive licenses but a very limited pool of people using it.
Could you use
System.Diagnostics.Process.GetProcessesByName
in a loop to look for the process?
It might work if you don't use too aggressive a polling rate.
You are indeed close, take a look at the WMI Management Events. http://msdn.microsoft.com/en-us/library/ms186151%28VS.80%29.aspx
Sample code from Microsoft: http://msdn.microsoft.com/en-us/library/ms257355(VS.80).aspx
Subscribing to the appropriate event will provide your application with the appropriate information to perform what you described.
Not sure if this is a GOOD solution but you could do something like pass a key into main so that if the key is not present or valid the application shuts down. Then when you open the application in your code, just pass the key in. Someone would then have to know the key in order to start the application.
This is assuming you have access to the application in question's source code, which upon reading your question again, I'm not so sure of.
I assume you don't have source for the application you want to prevent from loading...
Have you considered using a system policy? That would be the best-supported way to prevent a user from launching a program.
You could have a service running that force-kills any app that isn't "whitelisted", but I can't say how well that would work.
I wonder if you are taking the wrong approach. Back in the day there was a Mac app that would prevent access to the desktop and had buttons to launch a set list of applications.
IDEA
What if you had a wrapper for the approved apps then only allow your wrapper to run on the computer?
I would expect there is some way of hooking an application launch, but can't help directly on that front.
You may be able to improve your current approach by detecting the application's window opening and hiding it (move it offscreen) so that the user can't attempt to interact with it while you are trying to shut it down.
However, another approach that may be possible (depending on your circumstances) would be to write an application launcher. This simply is a replacement for the shortcut to the application that checks your licencing conditions, and then does a Process.Start to launch the real .exe at that point. This would work well for any application. (I used a system like this for starting up applications with specialised environment settings and it works beautifully)
You could combine this with your current approach as a fall-back for "clever" users who manage to circumvent your launcher.
If my understanding is right you want to create an application what will prevent the computer user to start any other process except ones for a white-list.
If this is the case, monitor the process list of processes (in a while loop) using System.Diagnostics.Process (the GetProcesses method gives the list of all running ones)
Just kill the process when it starts.
Or if your machines have Windows 7 (Windows 2008??) you can use AppLocker. http://www.microsoft.com/windows/enterprise/products/windows-7/features.aspx#applocker Just let Windows prevent the startup.
You might want to look at this product: http://www.sassafras.com/licensing.html Personally I can't stand it, but that's because it does what you describe. Might save you some coding.
You could actually edit the registry so when you click a psd, your launcher gets called instead of photoshop. Your launcher then checks for licenses and if there is one starts photoshop with the path of the file.
This is a long shot but you may find it helpful.
Perceived Types and Application Registration
http://msdn.microsoft.com/en-us/library/cc144150(VS.85).aspx

Categories