Skip to content

Commit

Permalink
Handle STATUS_INVALID_INFO_CLASS in psutil_proc_exe
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
klightspeed committed Jan 1, 2025
1 parent d9b2bac commit db39d01
Showing 1 changed file with 38 additions and 0 deletions.
38 changes: 38 additions & 0 deletions psutil/arch/windows/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Python.h>
#include <windows.h>
#include <ntstatus.h>
#include <Psapi.h> // memory_info(), memory_maps()
#include <signal.h>
#include <tlhelp32.h> // threads(), PROCESSENTRY32
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit db39d01

Please sign in to comment.