package win32api import ( "bytes" "syscall" "unsafe" ) func (entry PROCESSENTRY32) ExeFile() string { n := bytes.IndexByte(entry.SzExeFile[:], 0) if n < 0 { n = len(entry.SzExeFile) } return string(entry.SzExeFile[:n]) } func (entry MODULEENTRY32W) ModuleName() string { return syscall.UTF16ToString(entry.SzModule[:]) } func (entry MODULEENTRY32W) ExePath() string { return syscall.UTF16ToString(entry.SzExePath[:]) } func (info DebugEventInfo) String() string { return info.CodeName } func EnumerateProcesses() ([]PROCESSENTRY32, error) { snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) if err != nil { return nil, err } defer func() { _ = CloseHandle(snapshot) }() var entry PROCESSENTRY32 entry.DwSize = Ulong(unsafe.Sizeof(entry)) if err := Process32First(snapshot, &entry); err != nil { return nil, err } processes := make([]PROCESSENTRY32, 0, 64) for { processes = append(processes, entry) entry.DwSize = Ulong(unsafe.Sizeof(entry)) err = Process32Next(snapshot, &entry) if err != nil { if errno, ok := err.(syscall.Errno); ok && errno == ERROR_NO_MORE_FILES { break } if err == syscall.EINVAL { break } return nil, err } } return processes, nil } func EnumerateThreads(ownerProcessID DWORD) ([]THREADENTRY32, error) { snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0) if err != nil { return nil, err } defer func() { _ = CloseHandle(snapshot) }() var entry THREADENTRY32 entry.DwSize = DWORD(unsafe.Sizeof(entry)) if err := Thread32First(snapshot, &entry); err != nil { return nil, err } threads := make([]THREADENTRY32, 0, 64) for { if ownerProcessID == 0 || entry.Th32OwnerProcessID == ownerProcessID { threads = append(threads, entry) } entry.DwSize = DWORD(unsafe.Sizeof(entry)) err = Thread32Next(snapshot, &entry) if err != nil { if errno, ok := err.(syscall.Errno); ok && errno == ERROR_NO_MORE_FILES { break } if err == syscall.EINVAL { break } return nil, err } } return threads, nil } func EnumerateModules(processID DWORD) ([]MODULEENTRY32W, error) { snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE|TH32CS_SNAPMODULE32, processID) if err != nil { return nil, err } defer func() { _ = CloseHandle(snapshot) }() var entry MODULEENTRY32W entry.DwSize = DWORD(unsafe.Sizeof(entry)) if err := Module32First(snapshot, &entry); err != nil { return nil, err } modules := make([]MODULEENTRY32W, 0, 32) for { modules = append(modules, entry) entry.DwSize = DWORD(unsafe.Sizeof(entry)) err = Module32Next(snapshot, &entry) if err != nil { if errno, ok := err.(syscall.Errno); ok && errno == ERROR_NO_MORE_FILES { break } if err == syscall.EINVAL { break } return nil, err } } return modules, nil }