process.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include "nssm.h"
  2. void kill_process_tree(char *service_name, unsigned long pid, unsigned long exitcode, unsigned long ppid) {
  3. log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILLING, service_name, pid, exitcode, 0);
  4. /* Shouldn't happen. */
  5. if (! pid) return;
  6. HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  7. if (! snapshot) {
  8. log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATETOOLHELP32SNAPSHOT_FAILED, service_name, GetLastError(), 0);
  9. return;
  10. }
  11. PROCESSENTRY32 pe;
  12. ZeroMemory(&pe, sizeof(pe));
  13. pe.dwSize = sizeof(pe);
  14. if (! Process32First(snapshot, &pe)) {
  15. log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, service_name, GetLastError(), 0);
  16. return;
  17. }
  18. if (pe.th32ParentProcessID == pid) kill_process_tree(service_name, pe.th32ProcessID, exitcode, ppid);
  19. while (true) {
  20. /* Try to get the next process. */
  21. if (! Process32Next(snapshot, &pe)) {
  22. unsigned long ret = GetLastError();
  23. if (ret == ERROR_NO_MORE_FILES) break;
  24. log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, service_name, GetLastError(), 0);
  25. return;
  26. }
  27. if (pe.th32ParentProcessID == pid) kill_process_tree(service_name, pe.th32ProcessID, exitcode, ppid);
  28. }
  29. HANDLE process_handle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, false, pid);
  30. if (! process_handle) {
  31. log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENPROCESS_FAILED, pid, service_name, GetLastError(), 0);
  32. return;
  33. }
  34. log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILL_PROCESS_TREE, pid, ppid, service_name, 0);
  35. if (! TerminateProcess(process_handle, exitcode)) {
  36. log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_TERMINATEPROCESS_FAILED, pid, service_name, GetLastError(), 0);
  37. return;
  38. }
  39. }