/* Shouldn't happen unless the service failed to start. */\r
if (! k->pid) return; /* XXX: needed? */\r
unsigned long pid = k->pid;\r
+ unsigned long depth = k->depth;\r
\r
TCHAR pid_string[16], code[16];\r
_sntprintf_s(pid_string, _countof(pid_string), _TRUNCATE, _T("%lu"), pid);\r
_sntprintf_s(code, _countof(code), _TRUNCATE, _T("%lu"), k->exitcode);\r
- log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILLING, k->name, pid_string, code, 0);\r
+ if (fn == kill_process) log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILLING, k->name, pid_string, code, 0);\r
\r
/* We will need a process handle in order to call TerminateProcess() later. */\r
HANDLE process_handle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, false, pid);\r
/* Kill this process first, then its descendents. */\r
TCHAR ppid_string[16];\r
_sntprintf_s(ppid_string, _countof(ppid_string), _TRUNCATE, _T("%lu"), ppid);\r
- log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILL_PROCESS_TREE, pid_string, ppid_string, k->name, 0);\r
+ if (fn == kill_process) log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILL_PROCESS_TREE, pid_string, ppid_string, k->name, 0);\r
k->process_handle = process_handle; /* XXX: open directly? */\r
if (! fn(service, k)) {\r
/* Maybe it already died. */\r
}\r
\r
/* This is a child of the doomed process so kill it. */\r
+ k->depth++;\r
if (! check_parent(k, &pe, pid)) {\r
k->pid = pe.th32ProcessID;\r
walk_process_tree(service, fn, k, ppid);\r
if (ret == ERROR_NO_MORE_FILES) break;\r
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_PROCESS_ENUMERATE_FAILED, k->name, error_string(GetLastError()), 0);\r
CloseHandle(snapshot);\r
+ k->depth = depth;\r
return;\r
}\r
\r
}\r
k->pid = pid;\r
}\r
+ k->depth = depth;\r
\r
CloseHandle(snapshot);\r
}\r
void kill_process_tree(kill_t *k, unsigned long ppid) {\r
return walk_process_tree(NULL, kill_process, k, ppid);\r
}\r
+\r
+int print_process(nssm_service_t *service, kill_t *k) {\r
+ TCHAR exe[EXE_LENGTH];\r
+ TCHAR *buffer = 0;\r
+ if (k->depth) {\r
+ buffer = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, (k->depth + 1) * sizeof(TCHAR));\r
+ if (buffer) {\r
+ unsigned long i;\r
+ for (i = 0; i < k->depth; i++) buffer[i] = _T(' ');\r
+ buffer[i] = _T('\0');\r
+ }\r
+ }\r
+\r
+ unsigned long size = _countof(exe);\r
+ if (! imports.QueryFullProcessImageName || ! imports.QueryFullProcessImageName(k->process_handle, 0, exe, &size)) {\r
+ /*\r
+ Fall back to GetModuleFileNameEx(), which won't work for WOW64 processes.\r
+ */\r
+ if (! GetModuleFileNameEx(k->process_handle, NULL, exe, _countof(exe))) {\r
+ long error = GetLastError();\r
+ if (error == ERROR_PARTIAL_COPY) _sntprintf_s(exe, _countof(exe), _TRUNCATE, _T("[WOW64]"));\r
+ else _sntprintf_s(exe, _countof(exe), _TRUNCATE, _T("???"));\r
+ }\r
+ }\r
+\r
+ _tprintf(_T("% 8lu %s%s\n"), k->pid, buffer ? buffer : _T(""), exe);\r
+\r
+ if (buffer) HeapFree(GetProcessHeap(), 0, buffer);\r
+ return 1;\r
+}\r
+\r
+int print_process(kill_t *k) {\r
+ return print_process(NULL, k);\r
+}\r