summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2019-02-17 10:15:33 -0800
committerGitHub <noreply@github.com>2019-02-17 10:15:33 -0800
commit7381d4d15dd7fe108e1bf350c3f76035922c6ed4 (patch)
treed86643c2c47698ffc3fec20e5f76e73058d3e084
parent1c3287754f7b87708c3b81e72d1ab4f7f423e9ea (diff)
downloadpsutil-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.rst11
-rw-r--r--psutil/__init__.py2
-rw-r--r--psutil/_psutil_windows.c19
-rw-r--r--psutil/_pswindows.py43
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