-1

I create a process A which creates a process B. I want to terminate the whole process tree if a certain condition is met, so I follow the instructions provided here: Terminate a process tree (C for Windows)

The sample code works fine, it kills the child and the main process, but I receive an error in ::Process32Next(hSnap, &pe) ERROR_NO_MORE_FILES.

To be more specific, when the pe.th32ParentProcessID == dwPid and child process is terminated, in the next iteration ::Process32Next(hSnap, &pe) returns false with error code 18 (ERROR_NO_MORE_FILES)

Is this correct or I am doing something wrong?

void MyClass::winKillProcess(DWORD dwPid) try {

PROCESSENTRY32 pe;
memset(&pe, 0, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);

HANDLE hSnap = :: CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (::Process32First(hSnap, &pe))
{
    BOOL bContinue = TRUE;

    // kill child processes
    while (bContinue)
    {
        // only kill child processes
        if (pe.th32ParentProcessID == dwPid)
        {
            HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);

            if (hChildProc)
            {
                ::TerminateProcess(hChildProc, 1);
                ::CloseHandle(hChildProc);
            }               
        }

        bContinue = ::Process32Next(hSnap, &pe);
    }

    // kill the main process
    HANDLE hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);

    if (hProc)
    {
        ::TerminateProcess(hProc, 1);
        ::CloseHandle(hProc);
    }  

}
} catch (...) {
error_notify("winKillProcess() threw an unknown exception");
return;
}
Community
  • 1
  • 1
KoKa
  • 797
  • 1
  • 14
  • 31
  • This shouldn't happen, so something is going wrong. Are you using the exact same code snippet as shown in the linked post? I think it's best, also for future reference, if you add the relevant part of your code to your question via an edit. – MicroVirus Aug 13 '14 at 10:49
  • I am using the exact same code snippet as showed in the linked post, this is the reason why I haven't add the relevant part of my code. – KoKa Aug 13 '14 at 11:12
  • 1
    Like it says in [the documentation](http://msdn.microsoft.com/en-us/library/windows/desktop/ms684836(v=vs.85).aspx), this means that there are no more processes to enumerate. Note also that process IDs can be reused, so you may end up terminating the wrong process by mistake (if the parent exits before the child, then the parent's ID gets reused). Also, your code doesn't actually terminate the entire tree because it doesn't catch grandchildren. The correct way to do this is to use a Job Object. – Raymond Chen Aug 13 '14 at 14:28
  • The truth is that the documentation is not that clear. In the same page there is also a comment that says " GetLastError() will return ERROR_SUCCESS when Process32Next finishes enumeration", so I wanted to be sure about the GetLastError() value which I should get once the processes have finished. – KoKa Aug 13 '14 at 14:39

1 Answers1

0

I have tested the enumeration of the Process Snapshot, without the code that kills the processes, and have observed that the final call to Process32Next returns FALSE and (on Windows 7) GetLastError returns ERROR_NO_MORE_FILES. It did enumerate all the processes on my system.

Therefore, though the documentation is unclear, it seems that either ERROR_SUCCESS or ERROR_NO_MORE_FILES indicates the successful completion of the enumeration.

If you are in doubt, count the number of processes found and compare it to task manager's count.

MicroVirus
  • 5,324
  • 2
  • 28
  • 53
  • Thanks for the answer. I will count the number of processes found. One more question regarding the code, if (::Process32First(hSnap, &pe)) fails shouldn't I close the handle to the snapshot? – KoKa Aug 14 '14 at 07:07
  • @KoKa Yes, you should. The handle wasn't opened by `Process32First`, but rather by `CreateToolhelp32Snapshot`. Therefore, if the call to `CreateToolhelp32Snapshot` succeeded you should always close the handle in the end, regardless of what the other functions return. – MicroVirus Aug 14 '14 at 12:05
  • Ok, I will add it to the code. As for the enumeration of the processes I added a counter to the code and number of counter when Process32Next finishes matches processes number on task manager's count. Thank you. – KoKa Aug 14 '14 at 12:12