Skip to content

Commit

Permalink
Handle STATUS_INVALID_PARAMETER 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_PARAMETER`.

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.
  • Loading branch information
klightspeed committed Jan 1, 2025
1 parent d9b2bac commit aadac57
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions psutil/arch/windows/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,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 +335,39 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
sizeof(SYSTEM_PROCESS_ID_INFORMATION),
NULL);
}
else if (status == STATUS_INVALID_PARAMETER) {
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 = 0; // STATUS_SUCCESS
}

if (! NT_SUCCESS(status)) {
FREE(buffer);
Expand Down

0 comments on commit aadac57

Please sign in to comment.