Home > Blockchain >  How to terminate child process in other child process? (win32api)
How to terminate child process in other child process? (win32api)

Time:10-16

I created two child processes called p_1(notepad) and p_2(a clone of parent process) using CreateProcess.

What I want is terminate p_1 in p_2, not in parent process.

First, I created the processes with the following code:

case WM_LBUTTONDOWN:
{
    STARTUPINFO si = { 0, };
    WCHAR notepad[32] = L"C:\\Windows\\notepad.exe";
    WCHAR wndproc[32] = L"WindowProject.exe";

    if (true == CreateProcess(NULL, notepad, NULL, NULL, true, 0, NULL, NULL, &si, &p_1))
    {   
        CreateProcess(NULL, wndproc, NULL, NULL, true, 0, NULL, NULL, &si, &p_2);
    } 
}
    break;

When click the mouse left button, parent process creates two process

And here's the code to terminate p_1 process by right-clicking:

case WM_RBUTTONDOWN:
{
    TerminateProcess(p_1.hProcess, 0);
}
    break;

However, the p_2 process can't terminate p_1, only the parent process can terminate p_1.

I thought it was because p_2 doesn't have a handle of p_1, so I added DuplicateHandle in after CreateProcess (I don't know this is the correct way to use DuplicateHandle):

if (true == CreateProcess(NULL, notepad, NULL, NULL, true, 0, NULL, NULL, &si, &p_1))
    {   
        CreateProcess(NULL, wndproc, NULL, NULL, true, 0, NULL, NULL, &si, &p_2);
        //give handle of p_1 to p_2
        DuplicateHandle(&p_1.hProcess, &p_1.hProcess, &p_2.hProcess, &p_2.hProcess, 0, NULL, DUPLICATE_SAME_ACCESS);
    } 

But the result was the same. So instead of DuplicateHandle I writed p_2.hProcess = OpenProcess(PROCESS_TERMINATE, true, p_1.dwProcessId); , but still the same result.

I wonder how p_2 can terminate p_1. Or which function is correct to use?

(I am a beginner in programming and this is my first time using stackoverflow. Please forgive me even if this is an inexperienced question.)

CodePudding user response:

Using DuplicateHandle(), the parent can start P1 and P2, then duplicate its P1 handle into P2's context, then pass the value of the duplicate handle to P2 via an IPC mechanism of your choosing, such as a pipe, window message, etc. P2 can then store the value into a HANDLE variable and terminate P1 using that handle.

Another option is to have the parent start P1 first, then use SetHandleInformation() to make its P1 handle inheritable, then start P2 with the bInheritHandles parameter set to true (and preferably with the P1 handle specified explicitly via STARTUPINFOEX instead of being inherited implicitly). Then the parent can pass the value of its P1's handle as a command-line parameter when starting P2, and then P2 can parse the parameter into a HANDLE variable that it can use to terminate P1.

Another option is the parent can start P1 first, and then pass P1's PID as a command-line parameter when starting P2, then P2 can parse the parameter into a DWORD variable and OpenProcess() the PID so it can then terminate P1 using the opened handle.

This 3rd approach does have a small risk, though, in that P1 could be terminated through other means after P2 has started and before P2 opens the PID, thus risking the PID being reused for a completely unrelated process. The 1st and 2nd approaches avoid that risk.

  • Related