Is it possible to, in Windows, create a sort of anonymous process? For instance, creating a process that shows up in task manager, which has a PID, etc. However, instead of starting it up with an EXE, you just give it an entry point address to a currently running process (sort of like a DLL) and it starts its own thread.
Is something like this possible? If so, how would one go about it?
EDIT: Also, preferably, the child process would die along with the parent process if the parent process returns or is terminated.
Related
I need to execute processes with still being in control of each process.
I want to create a class which stores the threads or pids or what ever is necessary to do so.
I currently have a program which executes one external application with the C function execvp and also loads the environment from a shell script. So my current program is blocking. But I need to be able to keep it freely running and only by time I terminate a currently running or start a new external application.
My current approach would be to create a thread, which uses the execve function. But then the thread would be blocking as far as I can see.
The code which might be in the thread (with variables then):
char *argv[] = { "/bin/bash", "-c", "myApplication", 0 };
execve(argv[0], &argv[0], environment.data());
The applications called are probably not fixed in the code their names will be given by an external setup file, including parameters.
Now my actual question, is there a better way to "manage" external applications like that in c++? Some ready solution (class, library)? And if not how do I terminate the thread if this is the actual way. Using the terminate call is said to be bad practice, that's what I often read.
I hope this is now specific enough for the forum, because I do not know how to get more specific anymore. If you need more hints what I want to create here, feel free to ask in the comments.
Update:
to DBus & others:
Additional information I do not wrote all of the processes I want to start!
So it will be used to start 3rd party applications, which even if I have the code, do not want to change.
You want to fork() before you exec. fork() is a function that creates a new process identical to the original caller of fork() running as a subprocess. The difference is that the parent process gets the child's pid as a return value and the child gets 0. The gist of what you want to do is this:
pid_t pid = fork();
if( pid == 0 )
{
// we're the child process
char *argv[] = { "/bin/bash", "-c", "myApplication", 0 };
int rc = execve(argv[0], &argv[0], environment.data());
// execve only returns if there was an error
// check 'errno' and handle it here
}
else if ( pid < 0 )
{
// pid is less than zero, we didn't successfully fork,
// there is no child process.
throw "error message";
}
// do whatever processing the parent does
More info is here. The kill() function isn't bad practice per se, if you want to quickly and gracefully end the subprocess you can write signal handlers in it, but you should be using something like dbus or zeromq to do proper interprocess communication. You want to tell the program to do something, not just tell it to die (usually what you want it to do if you're killing it).
NEVER USE execv functions in threads because the execve() system call overlays the current process image with a new process image.
The correct pattern if fork-exec or better vfork-exec. Extract from the manpage:
The vfork() system call can be used to create new processes without fully
copying the address space of the old process, which is horrendously inefficient in a paged environment. It is useful when the purpose of fork(2)
would have been to create a new system context for an execve(2). The
vfork() system call differs from fork(2) in that the child borrows the
parent's memory and thread of control until a call to execve(2) or an
exit (either by a call to _exit(2) or abnormally). The parent process is
suspended while the child is using its resources.
Using vfork shortly followed with execve, you avoid the copy of the original process image, and do not erase if with the new process, so the original process has the pid of its child and cat control it, look whether it has ended, send it signals and so on.
How can I detect the name of the application that created my application's process?
For example, if someone wanted, they could call CreateProcess and pass it the suspended flag and inject into my application.
Is there a way to block CreateProcess or to figure out what process created an instance of my application?
I've hooked loadlibrary, createthread and all the other easy stuff but CreateProcess seems like it can bypass that.
I'm doing it for fun and learning, not for real world use. I just haven't seen anything that detects CreateProcess..
Any ideas at all?
You can find the parent process ID using the tool help library:
Call CreateToolhelp32Snapshot.
Call Process32First and Process32Next to enumerate the processes.
At some point you will encounter a PROCESSENTRY32 struct for which th32ProcessID is the process ID of your process.
Read out the th32ParentProcessID member to find the process ID of your parent.
Now that you know the parent process, you can enumerate again to gain information about it.
Be prepared for the parent process to have been terminated before you reach this point.
I'm working on a function which gets me the PID of the parent process for a given PID. The prototype of the function is
DWORD getParentPid( DWORD pid );
To do so, I'm using the CreateToolhelp32Snapshot function (and related functions) to get the PROCESSENTRY32 structure for my given PID pid. I can then use the th32ParentProcessId field of the structure to get the PID of the process which created my given process.
However, since the parent process might have been destroyed already (and it's PID might have been reused by Windows), I'm using the GetProcessTimes function to get the creation times of the supposed parent and the child process and then compare those using CompareFileTime.
If CompareFileTime returns -1, I know that the process with the parent ID was created before my child process, so it's indeed the parent. Otherwise, it's apparently a re-used ID - and the parent PID is invalid (it doesn't reference the original parent anymore).
The issue with this is that it very much relies on a strictly monotonous system clock and the granularity of GetProcessTimes. I did experience cases in which CompareFileTime returned 0 (which means "equal time") even though the process being considered were indeed in a parent-child relationship. I could change my check so that a CompareFileTime result value <= 0 would be considered to indicate a parent, but then I would break the (theoretical) case where a parent created a child process, then the parent was destroyed, and then Windows re-used the PID - all within 100ns (which is the resolution of GetProcessTimes).
I wonder - is there a different, more reliably, mechanism to verify that some process is indeed the parent of another process in C++?
Edit: I need this function in order to determine all child processes (this means including grand-child processes). The CreateToolhelp32Snapshot lets me iterate over all processes but I need to look at the parent PID of each of them to tell whether it's a child of my process at hand.
If the process(es) have been created whilst your app is running, you could just iterate over it repeatedly over time and catch PID re-use.
The sample here:
http://msdn.microsoft.com/en-us/library/ms686701(v=vs.85).aspx
Shows calling CreateToolhelp32Snapshot with a parameter of 0 for the processId and it uses the option TH32CS_SNAPPROCESS which says it captures all processes. Then, once you've got the snapshot, as in the sample you can walk the processes as they existed in the snapshot. The parent id's should be valid within the snapshot because you're looking at the state of all the processes as they existed in the single moment when the snapshot was taken. You don't have to bother with your process start time comparison stuff.
I have a program which needs to invoke a process to perform an operation and wait for it to complete the operation. The problem is that the invoked process clones itself and exits, which causes the wait api to return when the process exits. How can I wait for the cloned process to finish execution and return?
I am using the windows JOB object as mentioned in http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx, But I am not sure if this is the best way.
umm, I'm pretty sure you can can the spawner process id from any process. I'd iterate through all the processes, find the one's who's parent id matches the one of the process you spawned, and wait for it to die.
alternatively (I mean, thats pretty hack) what is the child child process doing? is there some other way you could detect when it has finished doing what it is meant to do?
a hack way to get a process's parent id
http://www.codeguru.com/cpp/w-p/win32/article.php/c1437
takes a handle, and using the method in the code above, returns the parent id.
http://msdn.microsoft.com/en-us/library/ms684280(VS.85).aspx
OpenProcess takes an id, gets a handle to it (if you're lucky)
http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx
GetProcessId takes a handle, gets it's id.
http://msdn.microsoft.com/en-us/library/ms683215(VS.85).aspx
GetExitCodeProcess takes a handle, returns whether the process is done or not.
http://msdn.microsoft.com/en-us/library/ms683189(VS.85).aspx
so appart from using hidden nt calls that it expressly tells you not to, you would basically have to create your process, get it's id, then spam all the process, opening them and checking their parent ids against the id of the process you created, if you didn't find one, then it's done, if you do, spam it with GetExitCodeProcess until its done.
I haven't tested any of this, but it looks like A way to do it. though if it's THE BEST way to do it I might just have to loose all faith in windows...
+1 for using job objects ;)
Assuming the process that you're running isn't spawning the cloned version of itself in such a way that it breaks out of the job...
You should be able to simply monitor the job events and act on JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO (see JOBOBJECT_ASSOCIATE_COMPLETION_PORT and SetInformationJobObject()). Monitoring the job in this way will also give you notifications of the processId's of new processes created within the job and details of when they exit.
If you have control over the source of invoked process, one possible solution would be to make it wait for the process it spawns by cloning itself.
I will jump right in, to be brief and descriptive:
C++, Windows API
I am creating child processes using CreateProcess to run external (command-line) applications. I have built in a time-out, and if the child process has not returned normal execution by that time, I wish to force termination on that child process.
Ideally, I would like for that child process to act the same as if it had called ExitProcess, or as if a Ctrl+C was sent to its console (which calls ExitProcess from the default console control handler).
My solution so far has been the use of TerminateProcess to kill the child forcefully. This does force the child to terminate immediately, but unfortunately if that child spawned any children of its own they are left to run until their "natural" completion.
Is there a way to tell the child process to call ExitProcess, or to force all of the child's children to also terminate when TerminateProcess is called?
These external applications are beyond my control, and as such I can not modify them to provide a custom work-around.
Assume no knowledge of grand-child processes (names/pids/etc) that would allow me to manually call TerminateProcess on grand-child processes individually. Although this could be done by manually enumerating all processes, mapping process relationships, and tracking all processes, I do not consider this a valid solution except as the absolute last resort.
Thank you for your time.
You can use Job objects to kill all the processes as a unit. You create a job object via the CreateJobObject API, and assign a process to it with AssignProcessToJobObject. New processes created by a process in a job object belong to the same job object by default. Calling TerminateJobObject will terminate all associated processes in the job object.