2

I'm trying to check if the process, started from the service, is running.

The problem is, that we migrate our app from Windows XP to Windows 7. One part of this app is the service, which starts some processes. Another part is a dialog app. This dialog app try to recognize if the processes from service are running. The pids of processes are stored in shared memory, so I can get the handle to process using OpenProcess() from WinApi, and that works on the Windows XP. If I try to do it on Windows 7, the function give me error - access denied.

I think, that I know, why is so (new 0 level isolation in Windows7), but I need to find some workaround.

My question is if there is possible to set access permissions on created process and how (please give me some example with explanation)?

I found, that there is a parameter in CreateProcess() and there is a function SetSecurityInfo(), but I use this functions probably in bad way, because does not work.

To check, if the process is running I used

running = (WaitForSingleObject( handle, 0 ) == WAIT_TIMEOUT);

or

BOOL result = GetExitCodeProcess(handle, (LPDWORD) &code);
if(result) {
    if(code == STILL_ACTIVE) {
        running = true;
    }
}

where handle is taken from the OpenProcess() function - OpenProcess( PROCESS_ALL_ACCESS , FALSE, pid ); I've also tried with SYNCHRONIZE, PROCESS_QUERY_INFORMATION and PROCESS_QUERY_LIMITED_INFORMATION. But always access denied..

Every idea will be useful.

michalp
  • 83
  • 5

1 Answers1

1

The problem isn't session 0 isolation (which doesn't affect process objects) but UAC. In Windows XP, the user process probably had administrative privilege and so it could do whatever it liked. In Windows 7 you would have to use "run as admin" to get the same level of privilege.

You shouldn't mess with the process permissions, that's too dangerous. Instead, since you already have an IPC mechanism (shared memory) you can get the service to check that the processes are running and report back to the user process.

One way to trigger the service to perform the check would be to use QueryServiceStatusEx() to query the service status. You can get the service control handler routine to check that the processes are running and report back via the shared memory block.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • You can call [`ControlService`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682108%28v=vs.85%29.aspx) with a user-defined control code that gets handled in the service [`HandlerEx`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683241%28v=vs.85%29.aspx). – Eryk Sun Feb 17 '15 at 23:56
  • @eryksun: true, I didn't think of that. Although it would require changing the permissions on the service. – Harry Johnston Feb 17 '15 at 23:59
  • @HarryJohnston - Do you know, how dangerous can it (changing the process permissions) be? I would like only to can do this operation `PROCESS_QUERY_INFORMATION`. I think `QueryServiceStatusEx()` will not work. My service starts another processes and I need to check the status one of this processes. – michalp Feb 18 '15 at 08:34
  • Oh, I suppose if you added an ACE to allow SYNCHRONIZE and PROCESS_QUERY_LIMITED_INFORMATION it wouldn't really matter. But a bug in the code that changes the permissions could cause serious trouble. Note that QueryServiceStatusEx() causes the service control manager to send a query request to your service. Somewhere in your code you are responding to that request, and you can do whatever you like there - it doesn't *have* to just report on the status of the service process itself, it can make any other checks that are necessary. – Harry Johnston Feb 18 '15 at 19:50