summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2022-10-21 13:23:26 -0700
committerGiampaolo Rodola <g.rodola@gmail.com>2022-10-21 13:23:26 -0700
commit1cd46a0076b52a3d2ccf8e0b077fe0adae38549b (patch)
tree597b7ce2c5d0e2d2bbe19cfc3170d5d5a9146e67
parent8e4099d9f063ceb4ee3da5845562c5b934f83544 (diff)
downloadpsutil-1cd46a0076b52a3d2ccf8e0b077fe0adae38549b.tar.gz
expose disk_swaps() on Windows
-rw-r--r--psutil/arch/windows/disk.c83
-rw-r--r--psutil/arch/windows/ntextapi.h11
2 files changed, 94 insertions, 0 deletions
diff --git a/psutil/arch/windows/disk.c b/psutil/arch/windows/disk.c
index 7c35e812..c3a38082 100644
--- a/psutil/arch/windows/disk.c
+++ b/psutil/arch/windows/disk.c
@@ -360,6 +360,89 @@ error:
/*
+ * Return information about the disk page files as a list.
+ * A page file is basically the same thing as a swap partition.
+ */
+PyObject *
+psutil_disk_swaps(PyObject *self, PyObject *args) {
+ NTSTATUS status;
+ PVOID buffer = NULL;
+ ULONG bufferSize = 0x200;
+ PSYSTEM_PAGEFILE_INFORMATION pInfo;
+ PyObject *py_tuple = NULL;
+ PyObject *py_path = NULL;
+ PyObject *py_retlist = PyList_New(0);
+
+ if (! py_retlist)
+ return NULL;
+
+ // Enumerate page files.
+ buffer = MALLOC_ZERO(bufferSize);
+ while ((status = NtQuerySystemInformation(
+ SystemPageFileInformation,
+ buffer,
+ bufferSize,
+ NULL)) == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ FREE(buffer);
+ bufferSize *= 2;
+ buffer = MALLOC_ZERO(bufferSize);
+ }
+
+ if (! NT_SUCCESS(status)) {
+ psutil_SetFromNTStatusErr(status, "NtQuerySystemInformation");
+ goto error;
+ }
+
+ // Traverse the resulting struct.
+ // A TotalSize of 0 is used to indicate that there are no pagefiles.
+ pInfo = (SYSTEM_PAGEFILE_INFORMATION *)buffer;
+ if (pInfo->TotalSize != 0) {
+ while (TRUE) {
+ // construct python list
+ py_path = PyUnicode_FromWideChar(
+ pInfo->PageFileName.Buffer,
+ wcslen(pInfo->PageFileName.Buffer));
+ if (! py_path)
+ goto error;
+
+ py_tuple = Py_BuildValue(
+ "Okkk",
+ py_path,
+ pInfo->TotalSize * PSUTIL_SYSTEM_INFO.dwPageSize,
+ pInfo->TotalInUse * PSUTIL_SYSTEM_INFO.dwPageSize,
+ pInfo->PeakUsage * PSUTIL_SYSTEM_INFO.dwPageSize
+ );
+ if (!py_tuple)
+ goto error;
+ if (PyList_Append(py_retlist, py_tuple))
+ goto error;
+ Py_CLEAR(py_tuple);
+ Py_CLEAR(py_path);
+
+ // end of list
+ if (pInfo->NextEntryOffset == 0)
+ break;
+ // set pointer to the next pInfo struct
+ pInfo = (SYSTEM_PAGEFILE_INFORMATION *) \
+ ((BYTE *)pInfo + pInfo->NextEntryOffset);
+ }
+ }
+
+ FREE(buffer);
+ return py_retlist;
+
+error:
+ if (buffer != NULL)
+ FREE(buffer);
+ Py_XDECREF(py_tuple);
+ Py_XDECREF(py_path);
+ Py_DECREF(py_retlist);
+ return NULL;
+}
+
+
+/*
Accept a filename's drive in native format like "\Device\HarddiskVolume1\"
and return the corresponding drive letter (e.g. "C:\\").
If no match is found return an empty string.
diff --git a/psutil/arch/windows/ntextapi.h b/psutil/arch/windows/ntextapi.h
index e0662fa0..a07f9831 100644
--- a/psutil/arch/windows/ntextapi.h
+++ b/psutil/arch/windows/ntextapi.h
@@ -41,6 +41,8 @@ typedef LONG NTSTATUS;
#define ProcessWow64Information 26
#undef SystemProcessIdInformation
#define SystemProcessIdInformation 88
+#undef SystemPageFileInformation
+#define SystemPageFileInformation 18
// process suspend() / resume()
typedef enum _KTHREAD_STATE {
@@ -448,6 +450,15 @@ typedef struct _SYSTEM_PROCESS_ID_INFORMATION {
UNICODE_STRING ImageName;
} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION;
+// disk_swaps()
+typedef struct _SYSTEM_PAGEFILE_INFORMATION {
+ ULONG NextEntryOffset;
+ ULONG TotalSize;
+ ULONG TotalInUse;
+ ULONG PeakUsage;
+ UNICODE_STRING PageFileName;
+} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION;
+
// ====================================================================
// PEB structs for cmdline(), cwd(), environ()
// ====================================================================