Skip to content

Windows port follow-ups: real argv, single-call enumeration, real state, robustness - #76

Merged
rezdm merged 3 commits into
mainfrom
feature/windows-port-followups
Jul 17, 2026
Merged

Windows port follow-ups: real argv, single-call enumeration, real state, robustness#76
rezdm merged 3 commits into
mainfrom
feature/windows-port-followups

Conversation

@rezdm

@rezdm rezdm commented Jul 17, 2026

Copy link
Copy Markdown
Owner

The Windows follow-ups I flagged when closing #43. Needs runtime validation on a Windows host before merge — W2/W3 use a hand-specified kernel struct layout that CI only compiles, not verifies.

What to validate on Windows

  1. Process list looks correct — memory (working set), CPU%, thread counts, PPID/tree, start times all sane (this is the struct-layout check; if any column is garbage, the SYSTEM_PROCESS_INFORMATION offsets are off and I'll fix them).
  2. State column now shows a mix (not all R); a suspended app (e.g. a minimized Store app) reads T.
  3. Command Line shows real arguments, not just the exe path.
  4. CPU — the per-tick baseline should drop vs the Toolhelp version (fewer handle opens), especially in Release.

All CI jobs green on the branch (incl. Windows compile). Do not merge until the above is confirmed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xodto1bRjCSGEzLuz3JFbV

rezdm and others added 3 commits July 17, 2026 16:49
The Command Line column fell back to the image path. Read the target's
RTL_USER_PROCESS_PARAMETERS.CommandLine (a documented member, reached
via NtQueryInformationProcess + ReadProcessMemory, same as the env read)
and use it for command_line; a best-effort PROCESS_VM_READ handle keeps
a read failure from costing the basic details, and get_all_processes
still falls back to the image path when it comes up empty.

Closes #72

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xodto1bRjCSGEzLuz3JFbV
- get_username_for_pid cached the LookupAccountSid result even when it
  failed (empty string), permanently poisoning that SID's name after one
  transient failure. Only cache a non-empty result.
- get_libraries used a fixed HMODULE[1024] and silently dropped modules
  from a process that loads more. Size the buffer from EnumProcessModulesEx's
  reported need and re-query if it exceeds the initial array.

Closes #75

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xodto1bRjCSGEzLuz3JFbV
get_all_processes took a Toolhelp snapshot and then opened a handle per
process for ~6 more calls (times/memory/IO/path/token/priority) every
tick — the dominant CPU cost of the port. Replace it with a single
NtQuerySystemInformation(SystemProcessInformation) call that returns
every process's name/pid/ppid/threads/times/working-set/IO and per-thread
state in one buffer; no per-process handle for those fields.

- Per-process state is now derived from the threads' KTHREAD_STATE /
  KWAIT_REASON (Running / Suspended / Sleeping) instead of hardcoded 'R'.
- The immutable strings (user, exe path, command line) are fetched once
  per process instance and cached, keyed by pid and validated by
  creation time, so steady state opens no per-process handle at all.
- priority now reflects the base scheduling priority (comparable to the
  Unix priority column) rather than the Win32 priority class.

Uses fully-specified SYSTEM_PROCESS_INFORMATION / SYSTEM_THREAD_INFORMATION
structs (winternl's are reserved-padded); natural x64 alignment matches
the kernel layout. Compile-verified via CI; needs runtime validation.

Closes #73
Closes #74

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xodto1bRjCSGEzLuz3JFbV
@rezdm
rezdm merged commit f21019f into main Jul 17, 2026
20 checks passed
@rezdm
rezdm deleted the feature/windows-port-followups branch July 17, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant