Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1394 / win / exe: use QueryFullProcessImageNameW to get the exe() #1413

Merged
merged 4 commits into from
Feb 17, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add logic to support windows XP
  • Loading branch information
giampaolo committed Feb 17, 2019
commit e5926872ba69cc5de807ac81afd2ba2ccb1a86a0
21 changes: 19 additions & 2 deletions psutil/_psutil_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,22 +763,39 @@ static PyObject *
psutil_proc_exe(PyObject *self, PyObject *args) {
long pid;
HANDLE hProcess;
PDWORD size = MAX_PATH;
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;
// before this was using GetProcessImageFileNameW see:

// 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) {
// see: https://github.com/giampaolo/psutil/issues/1394
if (GetLastError() == 0) {
PyErr_SetFromWindowsErr(ERROR_ACCESS_DENIED);
else
PyErr_SetFromWindowsErr(0);
CloseHandle(hProcess);
return NULL;
}
#endif
CloseHandle(hProcess);
return PyUnicode_FromWideChar(exe, wcslen(exe));
}
Expand Down
38 changes: 34 additions & 4 deletions psutil/_pswindows.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,28 @@ class Priority(enum.IntEnum):
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
Expand Down Expand Up @@ -694,10 +716,18 @@ def name(self):

@wrap_exceptions
def exe(self):
exe = cext.proc_exe(self.pid)
if not PY3:
exe = py2_strencode(exe)
return 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
def cmdline(self):
Expand Down