diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index edb5996c4..ac66d5078 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -1144,8 +1144,9 @@ psutil_proc_cwd(PyObject *self, PyObject *args) { /* * Resume or suspends a process */ -int -psutil_proc_suspend_or_resume(DWORD pid, int suspend) { +// [POSSIBLE BUG]: Thread suspending is bad, 'cause programs can use their own thread suspending as a part of internal logic +// And it's slow: https://github.com/mridgers/clink/issues/420 +int psutil_proc_suspend_or_resume_threads(DWORD pid, int suspend) { // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx HANDLE hThreadSnap = NULL; HANDLE hThread; @@ -1208,6 +1209,48 @@ psutil_proc_suspend_or_resume(DWORD pid, int suspend) { return TRUE; } +// Special XP/2003 stuff +int psutil_proc_suspend_or_resume(DWORD pid, int suspend) +{ + HANDLE hProcess = NULL; + + typedef LONG (NTAPI *NtSuspendProcess)(IN HANDLE ProcessHandle); + typedef LONG (NTAPI *NtResumeProcess)(IN HANDLE ProcessHandle); + NtSuspendProcess pfnNtSuspendProcess = (NtSuspendProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtSuspendProcess"); + NtResumeProcess pfnNtResumeProcess = (NtResumeProcess)GetProcAddress(GetModuleHandle("ntdll"), "NtResumeProcess"); + if (!pfnNtSuspendProcess || !pfnNtResumeProcess) { + PyErr_SetFromWindowsErr(0); + return FALSE; + } + + if (pid == 0) { + AccessDenied(""); + return FALSE; + } + + hProcess = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, pid); + if (hProcess == INVALID_HANDLE_VALUE) { + PyErr_SetFromWindowsErr(0); + return FALSE; + } + + if (suspend == 1) { + if (pfnNtSuspendProcess(hProcess) == (DWORD) - 1) { + PyErr_SetFromWindowsErr(0); + CloseHandle(hProcess); + return FALSE; + } + } else { + if (pfnNtResumeProcess(hProcess) == (DWORD) - 1) { + PyErr_SetFromWindowsErr(0); + CloseHandle(hProcess); + return FALSE; + } + } + + CloseHandle(hProcess); + return TRUE; +} static PyObject * psutil_proc_suspend(PyObject *self, PyObject *args) {