DuplicateTokenEx for changing windows sessions - c++

I have a service which runs as system (in session 0) that is capable of spawning processes on the desktop (in user's sessions). I'm following the exact method described here: http://www.developerfusion.com/community/blog-entry/8389765/creating-a-process-in-another-user-session/
This code has been working for years, but I recently found out that the windows file I/O on the child programs is acting MUCH worse for the spawned process than if ran manually by a regular user.
The penalty can be seen by launching notepad (from the daemon running in session 0), and trying to open a file through the windows dialog. It takes more than 10 seconds just for the "open" file browser to come up. I used process monitor and saw that the File and registry access had almost 1,000,000 events. When doing the same process on a notepad launched manually, there are ~6,000 events.
I'm assuming I am missing some flag in the token impersonation, but I haven’t been able to find anything online. I ruled out my CreateProcessAsUser code by running it from session 1 vs session 0, and the session 1 code ran the same as the manual launch. Any ideas would be appreciated.
Extra information: This problem may be very specific because I have a roaming profile on the network instead of on the local machine.

Related

How to know when the Winlogon desktop is ready for inputs?

I successfully used SendSAS in a service (Local System Account). I call the API four seconds after the service starts. It seems that whatever the boot process duration, Windows manage to cache (sort of) the call: the same code finally shows me a logon screen a few seconds after the power on, on a fast laptop (Win10), and also shows me the logon screen after a very much longer delay on a slow Server (2012R2) running virtualized (wmware).
I am also able to use CreateProcessAsUser (with an updated token) to inject a tiny executable in the Session 1, Station WinSta0, Desktop Winlogon. The process then uses SendInput to "auto-logon" the session (yes, this is an awful think to do do, I am aware of that).
My problem: if the tiny process starts "too early", nothing happens. If the service waits, say, 2 minutes, all is OK.
What API should I use (in the service or in the started process) to find out when the WinLogon desktop is ready to accept keyboard inputs?
I tried WTSGetActiveConsoleSessionId (in the service) and OpenInputDesktop (in the process) hopping that failure would indicate the need to wait, but with no avail.
When your process starts in session 1, attached to the WinSta0\Winlogon desktop, you can periodically test the Control Type of the currently IUIAutomationElement focused element.
The APIs to use are : IUIAutomation::GetFocusedElement and then IUIAutomationElement::GetCurrentPropertyValue for the UIA_ControlTypePropertyId property. When you successfully get a focused element of type UIA_EditControlTypeId, the Windows logon screen is ready to accept inputs.
Don't forget to add a Sleep call between each try.
Tested OK with Windows Server 2008R2 and 2012R2, and with Windows 10.

Invoking the application as system user(Windows)

We have a native GUI application which runs on a windows machine, and recently we have found out that the application terminates unexpectedly. After days I have found that this is happening because the application is run by explorer.exe and it gets killed unexpectedly, random somehow, so it causes termination of all child processes including our application.
Is there a way to invoke/call our app as system process (not with explorer.exe)?
Also assume that application/user has administrator access too.
Thanks in advance.
Killing explorer does not in general kill other processes. This is very easy to verify yourself by killing explorer from the task manager. Notice that other processes stay alive when you kill explorer. Something else is killing your process.
If killing explorer leads to your process dying, then the obvious explanation is that something in your process is leading to its death. In other words the problem is most likely in your code, and you need to work out what that problem is.
Also note that explorer isn't really a special "system process" as such. It's just a normal process that that runs under the logged on user's token.
You may need to give some hand of a OS services, then run the service as admin(run as system boot), then start he application from the service ,this will ensures you the app will started as admin and without the explorer.exe(as child)

Service blocks windows startup

We have automatically started service which in some cases spends a lot of the time loading necessary data, let's say 10 minutes. During this time it works as expected (processing some huge data files required to start). I report the progess by C++ SetServiceStatus function, it is working fine.
This service is not dependent on anything and has only one dependency which is again our own service. It is started after those 10 minutes, it needs the first "server" service to be fully running to accept the requests.
I thought that windows would start all other automatic services (in less then 10 minutes as usually) and then start working normally but system is completely blocked during startup (i can't login to computer or ping the computer) until this one specific service is started (reports SERVICE_RUNNING by SetServiceStatus). When out service completely starts, the other missing system services (required for network, remote desktop, whatever, it's quite random) are also started. Is this normal behaviour? Why are non-depending processes (as remote desktop, network connections, etc.) waiting for this process? Am I missing something?
I tried to add some dependencies to postpone the startup of my service but I ended up with many dependencies and behaviour still somehow random (as order of services is random). Sometimes I was able to login but for example Start button started working only after those 10 minutes when my service was started. I am not sure what is "the last service" to depend on and what services to include to my depend-list and on some computers this services can be disabled and it can bring new problems... so I don't like this solution very much.
Another option was Delayed start option for our service. This should start service when all other automatic services are running. Well, this works fine, windows boots, computer running and responding, our service is started, but the performance is very bad, many times slower than usually, it seems that delayed started services have much lower priority or something like that.
My only current solution is to report to system that my service is running (by SetServiceStatus function), but to continue loading (this works, I tested it). But then we have problem with our dependent service as it needs to be started when the first one is really ready. It can be solved but I still wonder how is this possible and if there is something I could use to keep the current state of automatic started service which reports "started" when it is really fully started and prepared to work. Thanks for any ideas.
Set SERVICE_RUNNING as soon as possible, and then continue processing in background. Make your other service resilient to the first service being in a running state, but not yet ready to service.
The longer the service is in the starting state the more problems we get from different windows versions.

Windows Service with GUI monitor?

I have a C++ Win32 application that was written as a Windows GUI project, and now I'm trying to figure out to make it into a Service / GUI hybrid. I understand that a Windows Service cannot / should not have a user interface. But allow me to explain what I have so far and what I'm shooting for.
WHAT I HAVE NOW is a windows application. When it is run it places an icon in the system tray that you can double-click on to open up the GUI. The purpose of this application is to process files located in a specified directory on a nightly schedule. The GUI consists of the following:
A button to start an unscheduled scan/process manually.
A button to open a dialog for modifying settings.
A List Box for displaying status messages sent from the processing thread.
A custom drawn window for displaying image data (the file processing includes the creation and saving of images).
A status bar - while a process is not running, it shows a countdown to the next scheduled scan. During a scan it also provides some status feedback, including a progress bar.
WHAT I'M SHOOTING FOR is a service that will run on boot-up and not require a user to login. This would consist of the scheduled file processing. However, when a user logs in I would still like the tray icon to be loaded and allow them to open up a GUI as I described above to monitor the current state of the service, change settings, start a scan manually, and monitor the progress of a scan.
I'm sure that I have seen applications like this - that function as a service even when I'm not logged in, but still give me a user interface to work with once I do log in.
I'm thinking that instead of having a single multi-threaded application that sends messages to the GUI thread from the processing thread, I need two applications - a Service to perform the processing and a GUI application to provide visual feedback from the Service and also send messages to the Service (for example, to start a scan manually). But I am new to Windows Services and have no idea how this is done.
It is also possible that I'm completely off base and a Service is not what I'm looking for at all.
Any help / ideas / suggestions would be greatly appreciated! Thank you.
You can't do this as a service.
You'll need to make your Windows Service as a normal service application. This will startup on system startup, and run the entire time the system is up.
You'd then make a completely separate GUI application, which "talks" to the service. This can be set to run when a user logs in, in the user's account.
In order to make them "talk" to each other, you'll need to use some form of IPC. Since these run on the same system (but in different accounts, typically), named pipes or sockets both work quite well.
There is a simple way of doing it.
You can’t have the service access any user’s session (session 1,2,3..) since services are isolated and can access session 0 only. This is a change from 2011.
You should write a win32 program to be launched by your service per each user who logs in using https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx
The service can continue performing any task that isn’t user specific.

WNetAddConnection2 in Windows 7 with Impersonation and no Error Code

I'm doing some crazy impersonation stuff to get around UAC dialogs in Windows 7 so the user does not have to interact with the UI (I have the admin creds of course).
I have a process running as the Administrator and elevated past UAC. The issue that I'm facing is that when I make a call to WNetAddConnection2, within this process, I am not getting a new mapped net drive. The function returns ERROR_SUCCESS but no net drive is visible. We have another method of adding network drives using 'subst' but this, again, returns successful does does not add a net drive. I have tried to use the default user (which is the Administrator because of process's security context) and I have tried using specific user credentials. I can map the drive just fine through Explorer.
Of course the same functionality works fine in XP/2003. I haven't got around to testing on Vista because of issues with impersonation that are limiting my ability to spin up the process. Are there unique Windows 7 limits on this function? MSDN does not glean any that I can find.
Any help would be greatly appreciated!
The issue was that the process was running as Administrator. Impersonation will not work because WNetAddConnection2 evaluates on processes user. You must start a separate process to accomplish this.