internal/procscan: Toolhelp32 PID enumerator
Build / test (push) Failing after 28s
Build / build-windows (push) Has been skipped

Filters by exe basename, case-insensitive. DiffPIDs reports add/remove
sets so the engine can decide whether to rebuild the WinDivert filter.
Pure syscalls, no third-party dependencies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-01 19:51:16 +03:00
parent a45c1c0ab7
commit 837208d9ed
2 changed files with 120 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
//go:build windows
package procscan
import (
"strings"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// Snapshot returns a map of PID → exe basename for every running
// process whose exe name (case-insensitively) matches one of the
// names in `targets`. Pass an empty/nil targets to capture all
// processes (useful for debugging).
func Snapshot(targets []string) (map[uint32]string, error) {
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
if err != nil {
return nil, err
}
defer windows.CloseHandle(snap)
var entry windows.ProcessEntry32
entry.Size = uint32(unsafe.Sizeof(entry))
if err := windows.Process32First(snap, &entry); err != nil {
return nil, err
}
wantAll := len(targets) == 0
wantSet := make(map[string]struct{}, len(targets))
for _, n := range targets {
wantSet[strings.ToLower(n)] = struct{}{}
}
out := map[uint32]string{}
for {
exeName := syscall.UTF16ToString(entry.ExeFile[:])
if wantAll {
out[entry.ProcessID] = exeName
} else if _, ok := wantSet[strings.ToLower(exeName)]; ok {
out[entry.ProcessID] = exeName
}
err := windows.Process32Next(snap, &entry)
if err != nil {
if err == syscall.ERROR_NO_MORE_FILES {
break
}
return nil, err
}
}
return out, nil
}
// DiffPIDs reports which PIDs are added (in cur but not prev) and
// removed (in prev but not cur). Used by the engine's procscan ticker
// to decide whether to rebuild the WinDivert filter.
func DiffPIDs(prev, cur map[uint32]string) (added, removed []uint32) {
for pid := range cur {
if _, ok := prev[pid]; !ok {
added = append(added, pid)
}
}
for pid := range prev {
if _, ok := cur[pid]; !ok {
removed = append(removed, pid)
}
}
return
}