diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2019-02-17 10:15:33 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-17 10:15:33 -0800 |
commit | 7381d4d15dd7fe108e1bf350c3f76035922c6ed4 (patch) | |
tree | d86643c2c47698ffc3fec20e5f76e73058d3e084 | |
parent | 1c3287754f7b87708c3b81e72d1ab4f7f423e9ea (diff) | |
download | psutil-7381d4d15dd7fe108e1bf350c3f76035922c6ed4.tar.gz |
#1394 / win / exe: use QueryFullProcessImageNameW to get the exe() (#1413)
#1394 / win / exe: use QueryFullProcessImageNameW to get the exe()
-rw-r--r-- | HISTORY.rst | 11 | ||||
-rw-r--r-- | psutil/__init__.py | 2 | ||||
-rw-r--r-- | psutil/_psutil_windows.c | 19 | ||||
-rw-r--r-- | psutil/_pswindows.py | 43 |
4 files changed, 63 insertions, 12 deletions
diff --git a/HISTORY.rst b/HISTORY.rst index ebac8db7..b1eb8ea4 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,16 @@ *Bug tracker at https://github.com/giampaolo/psutil/issues* +5.5.2 +===== + +XXXX-XX-XX + +**Bug fixes** + +- 1394_: [Windows] Process name() and exe() may erronously return "Registry". + QueryFullProcessImageNameW is now used instead of GetProcessImageFileNameW + in order to prevent that. + 5.5.1 ===== diff --git a/psutil/__init__.py b/psutil/__init__.py index 9e7d3d02..241dc5f9 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -215,7 +215,7 @@ __all__ = [ ] __all__.extend(_psplatform.__extra__all__) __author__ = "Giampaolo Rodola'" -__version__ = "5.5.1" +__version__ = "5.5.2" version_info = tuple([int(num) for num in __version__.split('.')]) AF_LINK = _psplatform.AF_LINK POWER_TIME_UNLIMITED = _common.POWER_TIME_UNLIMITED diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index eb35c5f7..b5b5a8f5 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -764,14 +764,30 @@ psutil_proc_exe(PyObject *self, PyObject *args) { long pid; HANDLE hProcess; wchar_t exe[MAX_PATH]; +#if (_WIN32_WINNT >= 0x0600) // >= Vista + PDWORD size = MAX_PATH; +#endif if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; hProcess = psutil_handle_from_pid(pid, PROCESS_QUERY_LIMITED_INFORMATION); if (NULL == hProcess) return NULL; + + // Here we differentiate between XP and Vista+ because + // QueryFullProcessImageNameW is better than GetProcessImageFileNameW + // (avoid using QueryDosDevice on the returned path), see: + // https://github.com/giampaolo/psutil/issues/1394 +#if (_WIN32_WINNT >= 0x0600) // Windows >= Vista + memset(exe, 0, MAX_PATH); + if (QueryFullProcessImageNameW(hProcess, 0, exe, &size) == 0) { + PyErr_SetFromWindowsErr(0); + CloseHandle(hProcess); + return NULL; + } +#else // Windows XP if (GetProcessImageFileNameW(hProcess, exe, MAX_PATH) == 0) { - // https://github.com/giampaolo/psutil/issues/1394 + // see: https://github.com/giampaolo/psutil/issues/1394 if (GetLastError() == 0) PyErr_SetFromWindowsErr(ERROR_ACCESS_DENIED); else @@ -779,6 +795,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) { CloseHandle(hProcess); return NULL; } +#endif CloseHandle(hProcess); return PyUnicode_FromWideChar(exe, wcslen(exe)); } diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index e66febe0..0441b8a1 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -147,6 +147,28 @@ ZombieProcess = None AccessDenied = None TimeoutExpired = None +# More values at: https://stackoverflow.com/a/20804735/376587 +WIN_10 = (10, 0) +WIN_8 = (6, 2) +WIN_7 = (6, 1) +WIN_SERVER_2008 = (6, 0) +WIN_VISTA = (6, 0) +WIN_SERVER_2003 = (5, 2) +WIN_XP = (5, 1) + + +@lru_cache() +def get_winver(): + """Usage: + >>> if get_winver() <= WIN_VISTA: + ... ... + """ + wv = sys.getwindowsversion() + return (wv.major, wv.minor) + + +IS_WIN_XP = get_winver() < WIN_VISTA + # ===================================================================== # --- named tuples @@ -694,16 +716,17 @@ class Process(object): @wrap_exceptions def exe(self): - # Note: os.path.exists(path) may return False even if the file - # is there, see: - # http://stackoverflow.com/questions/3112546/os-path-exists-lies - - # see https://github.com/giampaolo/psutil/issues/414 - # see https://github.com/giampaolo/psutil/issues/528 - if self.pid in (0, 4): - raise AccessDenied(self.pid, self._name) - exe = cext.proc_exe(self.pid) - exe = convert_dos_path(exe) + # Dual implementation, see: + # https://github.com/giampaolo/psutil/pull/1413 + if not IS_WIN_XP: + exe = cext.proc_exe(self.pid) + else: + if self.pid in (0, 4): + # https://github.com/giampaolo/psutil/issues/414 + # https://github.com/giampaolo/psutil/issues/528 + raise AccessDenied(self.pid, self._name) + exe = cext.proc_exe(self.pid) + exe = convert_dos_path(exe) return py2_strencode(exe) @wrap_exceptions |