From db39d013c275c0cd88d61399860495b3d5c612fe Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Wed, 1 Jan 2025 18:12:14 +1000 Subject: [PATCH] Handle STATUS_INVALID_INFO_CLASS in psutil_proc_exe Wine versions before 9.8 and Proton versions before 9.0-1 did not implement the `SystemProcessIdInformation` system information class in `NtQuerySystemInformation`, returning `STATUS_INVALID_INFO_CLASS`. Ubuntu 24.04.1 LTS currently ships with Wine 9.0, and CrossOver 24.0.5 has not backported the implementation of the `SystemProcessIdInformation` system information class to its bundled Wine 9.0 Handle this error case and fall back to `QueryFullProcessImageNameW` to get the process name. Signed-off-by: Ben Peddell --- psutil/arch/windows/proc.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/psutil/arch/windows/proc.c b/psutil/arch/windows/proc.c index 41fa9dda6..637bd511e 100644 --- a/psutil/arch/windows/proc.c +++ b/psutil/arch/windows/proc.c @@ -13,9 +13,12 @@ // Fixes clash between winsock2.h and windows.h #define WIN32_LEAN_AND_MEAN +// Fixes clash between ntstatus.h and windows.h +#define UMDF_USING_NTSTATUS #include #include +#include #include // memory_info(), memory_maps() #include #include // threads(), PROCESSENTRY32 @@ -261,6 +264,8 @@ psutil_proc_exe(PyObject *self, PyObject *args) { ULONG bufferSize = 0x104 * 2; // WIN_MAX_PATH * sizeof(wchar_t) SYSTEM_PROCESS_ID_INFORMATION processIdInfo; PyObject *py_exe; + HANDLE hProcess; + DWORD size; if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) return NULL; @@ -333,6 +338,39 @@ psutil_proc_exe(PyObject *self, PyObject *args) { sizeof(SYSTEM_PROCESS_ID_INFORMATION), NULL); } + else if (status == STATUS_INVALID_INFO_CLASS) { + FREE(buffer); + hProcess = psutil_handle_from_pid(pid, PROCESS_QUERY_LIMITED_INFORMATION); + + if (NULL == hProcess) + return NULL; + + buffer = MALLOC_ZERO(bufferSize); + if (! buffer) { + PyErr_NoMemory(); + return NULL; + } + + size = bufferSize / 2; + + if (QueryFullProcessImageNameW(hProcess, 0, buffer, &size) == 0) { + FREE(buffer); + // https://github.com/giampaolo/psutil/issues/1662 + if (GetLastError() == 0) + AccessDenied("QueryFullProcessImageNameW (forced EPERM)"); + else + psutil_PyErr_SetFromOSErrnoWithSyscall("QueryFullProcessImageNameW"); + CloseHandle(hProcess); + return NULL; + } + + CloseHandle(hProcess); + + processIdInfo.ImageName.Buffer = buffer; + processIdInfo.ImageName.Length = (USHORT)(size * 2); + + status = STATUS_SUCCESS; + } if (! NT_SUCCESS(status)) { FREE(buffer);