ohmu
·
2026-10-15
1#include "top.h"
2
3#include "common/debug.h"
4#include "common/mallocHelper.h"
5#include "common/windows/unicode.h"
6
7#include <ntstatus.h>
8#include <windows.h>
9#include <winternl.h>
10
11const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes) {
12 FF_AUTO_FREE SYSTEM_PROCESS_INFORMATION* pstart = nullptr;
13
14 // Multiple attempts in case processes change while
15 // we are in the middle of querying them.
16 ULONG size = 0;
17 for (int attempts = 0;; ++attempts) {
18 if (size) {
19 pstart = (SYSTEM_PROCESS_INFORMATION*) realloc(pstart, size);
20 assert(pstart);
21 }
22 NTSTATUS status = NtQuerySystemInformation(SystemProcessInformation, pstart, size, &size);
23 if (NT_SUCCESS(status)) {
24 break;
25 } else if (status == STATUS_INFO_LENGTH_MISMATCH && attempts < 4) {
26 size += sizeof(SYSTEM_PROCESS_INFORMATION) * 5;
27 } else {
28 FF_DEBUG("NtQuerySystemInformation(SystemProcessInformation) failed: %s", ffDebugNtStatus(status));
29 return "NtQuerySystemInformation(SystemProcessInformation) failed";
30 }
31 }
32
33 for (SYSTEM_PROCESS_INFORMATION* info = pstart;; info = (SYSTEM_PROCESS_INFORMATION*) ((uint8_t*) info + info->NextEntryOffset)) {
34 uintptr_t pidValue = (uintptr_t) info->UniqueProcessId;
35 if (pidValue <= UINT32_MAX && (uintptr_t) info->InheritedFromUniqueProcessId > 0) {
36 FFTopProcessSnapshot* item = FF_LIST_ADD(FFTopProcessSnapshot, *snapshots);
37 item->pid = (uint32_t) pidValue;
38 item->startTime = (uint64_t) info->CreateTime.QuadPart;
39 item->cpuTime = ((uint64_t) info->UserTime.QuadPart + (uint64_t) info->KernelTime.QuadPart) / 10000u;
40 item->memBytes = (uint64_t) info->VirtualMemoryCounters.WorkingSetSize;
41 item->bytesRead = (uint64_t) info->IoCounters.ReadTransferCount;
42 item->bytesWritten = (uint64_t) info->IoCounters.WriteTransferCount;
43 item->threads = info->NumberOfThreads;
44 ffStrbufInitNWS(&item->name, info->ImageName.Length / sizeof(wchar_t), info->ImageName.Buffer);
45 }
46 if (info->NextEntryOffset == 0) {
47 break;
48 }
49 }
50 return nullptr;
51}