summaryrefslogtreecommitdiff
path: root/psutil/_psutil_windows.c
diff options
context:
space:
mode:
authorPetrPospisil <Sengir321@gmail.com>2021-10-18 20:47:18 +0200
committerGitHub <noreply@github.com>2021-10-18 20:47:18 +0200
commitadbfeae3525769c7c001000ab8dd816e88b18736 (patch)
treea55c3f2a18cd75c86aca599cad9723a520cf568c /psutil/_psutil_windows.c
parente72438f08ac7aa93b33fddcb11298ece28d0150d (diff)
downloadpsutil-adbfeae3525769c7c001000ab8dd816e88b18736.tar.gz
Fix WOW64 issue: NtQuerySystemInformation does not set ImageName.MaximumLength (#1981)
* fix WOW64 issue when the NtQuerySystemInformation does not set ImageName.MaximumLength when STATUS_INFO_LENGTH_MISMATCH is returned Signed-off-by: Petr Pospíšil <petr.pospisil@safetica.com>
Diffstat (limited to 'psutil/_psutil_windows.c')
-rw-r--r--psutil/_psutil_windows.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index 8abd8a8d..0a6ac726 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -338,8 +338,8 @@ static PyObject *
psutil_proc_exe(PyObject *self, PyObject *args) {
DWORD pid;
NTSTATUS status;
- PVOID buffer;
- ULONG bufferSize = 0x100;
+ PVOID buffer = NULL;
+ ULONG bufferSize = 0x104 * 2; // WIN_MAX_PATH * sizeof(wchar_t)
SYSTEM_PROCESS_ID_INFORMATION processIdInfo;
PyObject *py_exe;
@@ -350,8 +350,11 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
return AccessDenied("automatically set for PID 0");
buffer = MALLOC_ZERO(bufferSize);
- if (! buffer)
- return PyErr_NoMemory();
+ if (! buffer) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
processIdInfo.ProcessId = (HANDLE)(ULONG_PTR)pid;
processIdInfo.ImageName.Length = 0;
processIdInfo.ImageName.MaximumLength = (USHORT)bufferSize;
@@ -363,12 +366,41 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
sizeof(SYSTEM_PROCESS_ID_INFORMATION),
NULL);
- if (status == STATUS_INFO_LENGTH_MISMATCH) {
+ if (status == STATUS_INFO_LENGTH_MISMATCH && processIdInfo.ImageName.MaximumLength <= bufferSize) {
+ // Required length was NOT stored in MaximumLength (WOW64 issue).
+
+ ULONG maxBufferSize = 0x7FFF * 2; // NTFS_MAX_PATH * sizeof(wchar_t)
+
+ do {
+ // Iteratively double the size of the buffer up to maxBufferSize
+ bufferSize *= 2;
+
+ FREE(buffer);
+ buffer = MALLOC_ZERO(bufferSize);
+ if (! buffer) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ processIdInfo.ImageName.MaximumLength = (USHORT)bufferSize;
+ processIdInfo.ImageName.Buffer = buffer;
+
+ status = NtQuerySystemInformation(
+ SystemProcessIdInformation,
+ &processIdInfo,
+ sizeof(SYSTEM_PROCESS_ID_INFORMATION),
+ NULL);
+ } while (status == STATUS_INFO_LENGTH_MISMATCH && bufferSize <= maxBufferSize);
+ }
+ else if (status == STATUS_INFO_LENGTH_MISMATCH) {
// Required length is stored in MaximumLength.
FREE(buffer);
buffer = MALLOC_ZERO(processIdInfo.ImageName.MaximumLength);
- if (! buffer)
- return PyErr_NoMemory();
+ if (! buffer) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
processIdInfo.ImageName.Buffer = buffer;
status = NtQuerySystemInformation(