how to know whether user is completely logged in or not? - c++

Is there a way to know whether user is completely logged in or not into system? I mean, i wanted to know whether initial login process, other initialization processes are done or not. Once those are done, i want to launch my application. So, in my service(installed before sys shutdown) i want to keep on checking whether everything is done or not, based on the result i want launch my app.

I'm not sure what you mean about "completeley logged into the system". The user can be logged in, or not; I don't get how he could be uncompletely logged.
If you want to launch an application when the session is opened, there are several ways of doing this:
Adding a shortcut in the "Startup" folder, in the "Start" menu
Adding a "Run" key in the registry (either in HKLM or HKCU depending on what your application does)
Your application can then detect if the session is about to close, listening to some specific Windows events, if it needs to.
If your application is a service, it can depend on other services and will wait for them to be started before starting itself.
If you just want to detect when the opened session is "ready to use", I'm afraid there is no good way to do this. The user could have some custom softwares launched on startup and there is no generic way to detect when these softwares were started.

Related

Alternative to disabling UAC

I am looking for a method to use as an alternative to disabling UAC to keep application persistence throughout the lifetime of the system.
My application runs every time the system starts up, and it requires elevated privileges, so when UAC is enabled it asks the user whether or not to run my application, every time the system is rebooted. This is very tedious and can become annoying if it happens every time. If UAC is disabled this warning no longer appears but of course that is very harmful to the user as it could lead to threats on their computer.
My question is; In C++ how can I programmatically allow file/application persistence throughout any event on the users' PC just for my application without getting the UAC warnings each time!
I am looking for ANY possible method, an exploit, a bypass method, anything, I'm really desperate at the moment as I've been stuck with this program for several days now and I'm just 99.9% done my project. I really need to get this through. THANK YOU SO MUCH FOR ANY ADVICE you may offer me!
The first step is to determine whether your program really needs admin privilege at all. Sometimes a program only runs with admin privilege, but for trivial reasons: a log file is being generated in the wrong place, for example, or a file that should be being opened for read-only access is being opened for full access. If that's the case you can fix the problem and avoid any further structural changes.
Secondly, ask whether your program needs admin privilege all the time, or only when the user performs certain actions. In the latter case, you should probably only elevate when it becomes necessary to do so; as well as meaning that the user does not need to approve the program launch on every reboot, it also helps protect the user from making an administrative change without intending to. This is particularly relevant if UAC is configured to require a password each time.
Thirdly, ask whether your program really needs a user interface. If not, then it should be a system service.
If your program really does need admin privilege all the time, and really does need a user interface, then you need to separate it into two parts, one containing the user interface and one containing the functionality that requires elevated privilege.
The user interface part should be a program that runs whenever a user logs in, just as your program does now. The elevated privilege part should be a system service.
The primary logic might belong in either part, or might also need to be split into two; it depends entirely on the context. (The system service does need to contain enough logic to ensure that the the privileged operations it is performing are safe and appropriate. It can't simply do anything the user interface part tells it to.)
These two parts can interact using whatever form of inter-process communication and/or synchronization is most convenient. You do need to be aware that they will be in different Remote Desktop sessions; for example, if you create an event object for synchronization the name must start with the Global\ prefix.
You will need to consider that more than one user may be logged in at the same time, either via Switch User or because the machine is a Remote Desktop server. This may mean that the service component needs to support multiple simultaneous clients, which affects your choice and implementation of IPC. Alternatively, the user interface component needs to detect that another instance is already running, and wait until that instance goes away before attempting to connect.
You will also need to consider how the program should react when the logged-in user does not have administrative privilege. At the moment such a user can't run your program at all, probably making the prompts even more annoying than they are to an admin user! If it is OK for the program to work as normal for a non-admin user then you don't need to do anything special. If the program should not work for a non-admin user, or if some of the functionality should be restricted, then (a) the GUI component needs to behave accordingly, by, e.g., exiting silently; and (b) the service component needs to check the context in which the GUI component is running. It is not enough for the GUI component to do the check, because the user can trick it if he or she wishes to; the service component must check too.
The easiest way to do that is probably to use GetTokenInformation with the TokenElevationType option; if the token type is TokenElevationTypeLimited or TokenElevationTypeFull, the user has administrator privilege. If the token type is TokenElevationTypeDefault, there is no split token; either the user is not an administrator, is the local Administrator account, or UAC is turned off; in this case, use CheckTokenMembership to check whether the user is in the Administrators group or not.
In some cases, it might also be sensible for certain tasks to require UAC approval, even if other tasks do not. Such tasks need not involve the service component; the GUI component can elevate itself, with the user's consent, to perform them.

How to tell that the logon screen is currently displayed?

I am writing a service application that will run with local system credentials. I will need to know from my service if the Windows logon screen is displayed at any particular time. Is there any way to do this?
PS. The screens that can be brought up by locking the workstation:
Or by trying to switch the user:
Or after a Ctrl+Alt+Del:
PS. I need this to run on Windows XP and up.
EDIT: The only viable solution that I came up with so far is to see if LogonUI.exe process is running. The issue with this approach is how to distinguish between the actual system logon process and any other process that has that image name?
As described in the comments you are trying to detect whether or not a process in an interactive desktop session should show a message box. There being no point doing so if the interactive session is not active.
In which case I believe that your proposed solution is the wrong one. Instead you should register for session change notifications by calling WTSRegisterSessionNotification. When you do this you'll get sent WM_WTSSESSION_CHANGE messages that allow you to keep track of the current state.
Note that you do this in your desktop app rather than the service. The service still sends its messages to the desktop app. But the desktop app now knows whether or not it is worth showing them.
Update
Remy suggests a better way in the comments:
And if a separate app is being used, there is no reason to detect session changes at all, that app can simply check if its currently assigned workstation/desktop is the currently interactive workstation/desktop instead, comparing GetThreadDesktop() to OpenInputDesktop(), for instance.
All such screens are presented on a separate desktop. You may try to enumerate the user's desktops and compare it with the current (I am not sure the service in session 0 - Vista and up - can do that; if not, spawn a helper process in the user session). This however may give a false positive if an UAC desktop is up. Another corner case is a userless situation (right after boot before any user looged on).
There are several states in the windows.
Logged-Off State
When Winlogon is in the logged-off state, users are prompted to identify themselves and provide authentication information. If a user provides correct user account information and no restrictions prevent it, the user is logged on and a shell program (such as Windows Explorer) is executed in the application desktop. Winlogon changes to the logged-on state.
Logged-On State
When Winlogon is in the logged-on state, users can interact with the shell, activate additional applications, and do their work. From the logged-on state, users can either stop all work and log off, or lock their workstations (leaving all work in place). If the user decides to log off, Winlogon will terminate all processes associated with that logon session and the workstation will be available for another user. If, instead, the user decides to lock the workstation, Winlogon changes to the workstation-locked state.
Workstation-Locked State
When Winlogon is in the workstation-locked state, a secure desktop is displayed until the user unlocks the workstation by providing the same identification and authentication information as the user who originally logged on, or until an administrator forces a logoff. If the workstation is unlocked, the application desktop is displayed, and work can resume.
reference: https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa380547(v=vs.85).aspx
p.s. registering a secure attention sequence (SAS, CTRL+ALT+Delete) is included in Workstation-Locked state
Similarly, there are several desktop types on windows.
Winlogon desktop
Application desktop(=Default desktop)
Screensaver desktop
Secure desktop
I recommend you read this:
https://msdn.microsoft.com/ko-kr/library/windows/desktop/aa375994(v=vs.85).aspx
I don't know my answers are what you want... but I hope it helps in some ways.

Windows Service for launching and restarting a user process (with GUI)

I need a certain process to be constantly running in every user’s computer. If that .exe is killed, I must be able to restart it and send an alert.
I immediately thought of building a Windows Service as the ideal solution, but I am facing a problem:
The process started by that service needs to be able to interact with the user, e.g. be able to show him a GUI.
my application also sets a keyboard hook in order to monitor the user's typing rhythms, and when I start the .exe from a service, that information is not accessible.
From the service I am able to launch the process "as the user" (using the LogonUser and CreateProcessAsUser functions), but still can’t see the GUI.
Is this possible? If not, what can I use to achieve the desired functionality?
tia
By default the GUI .exe will be run in the service session, which is separate from the interactive session of the user. You need to look into techniques for building an interactive service.

Windows 7 UAC elevation

I have a single thread that I'd like to run as an administrator in my application. The rest of the application I can happily run as the default user level (asInvoker). Is this possible? I notice there is an "ImpersonateLoggedOnUser" function. Can I somehow use this to log the administrator on and then get the thread to impersonate that person?
It seems as though this ought to be something pretty trivial to do ... but there doesn't appear to be any obvious way to do it. Can anyone help me out?
Edit: So if I have to fire off a seperate process is there any way I can CreateProcess a new process and have it launch from a specific entry point. I can, of course use command line processing to do it, but i'd really rather I could stop the user from entering the command line and starting an unclosable process!
No, elevation is per process, not thread.
If the rest of the application has to run non-elevated, you could run yourself elevated with some parameter (myapp.exe /uac "ipcparamhere") and use some sort of Inter-process communication to communicate back to the "main instance" of your app. (If the elevated process only performs a simple operation, you could probably check for success by using the exit code of the process)
This is not possible. You'll need to gain admin privileges by including a manifest in the app. Google "requireAdministrator" to find the manifest you'll need. Your user will probably quickly tire of doing this over and over again, your best bet is to spin-off the task that requires these privileges into a separate process. A service for example.
You can launch a separate exe and have a manifest on it saying it requires administrator. Then be sure to launch it with shell execute, which uses manifests, and you're all set. As a thoughtful touch, put a UAC shield on the button that kicks off that thread. (Send it a BCM_SETSHIELD message if you're doing this all by hand.)
You can decided whether you want a visible window or not on the separate process. Meanwhile the user can still drag and drop into the main app.

App started by logged off XP user can seen on desktop of a different user

This is a coding question. Please read it before you flag it as belonging on ServerFault as the last one I wrote got thrown over there in less than 5 minutes.
I'm testing my win32/c++ application on XP which has the latest service packs. It contains two administrative user accounts both without passwords. I log in as User1 and start my app. The app runs, its main window appears and all is well with the world. I then log User1 off without first closing my app. Yes, I used "log off" not "switch user"
I then log in as User2 and my application is still running. I see it on the User 2 desktop, and I can even interact with it. It appears to be functioning normally. And task manager shows it running as User1.
Any ideas which might be going on here? Other applications (like notepad) don't exhibit this issue, yet mine does. Seems to me I'm doing something wrong in my code, but it really is a rather standard win32/c++ app. Perhaps I'm not processing some shutdown message properly? I'm sorry I can't give more specifics right now. I'm really hoping for some clue to spark further research.
Check windows task manager's for 2 things:
"Session ID" column
"User Name" column
If either of these columns do not show up then select them from View -> Select columns.
Check which username and session your application that is staying open with is on. Then go and start notepad.exe and compare to the session ID and User Name that it is started with.
When you do a logoff it will close the applications running under your Session ID and username.
I'm guessing that your application is running in it's own session ID and/or username.
When you login with the other user it checks to see if it can re-use a session that is already started for the new username. So that is why you will see it running again when you login with the second user.
Are you sure your application isn't running as a service? A service with "Interact with Desktop" could look like this.
UPDATE:
It must be somehow related to a service. A normal application, running in a session will be forced to close by Windows before the logoff is complete. Even if you don't handle the end session messages, Windows will tell the user about the nonresponding process and/or just kill it.
Do you need to be listening for a shutdown or logoff events?
Check out this answer for a similar question.
That answer refers to listening for WM_QUERYENDSESSION.
See WM_QUERYENDSESSION Message