func GetProcessNameMap() map[uint32]string { defer metrics("GetProcessNameMap")(time.Now()) snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) if err != nil { common.Error("Fail to syscall CreateToolhelp32Snapshot: %v", err) return nil } defer syscall.CloseHandle(snapshot) var procEntry syscall.ProcessEntry32 procEntry.Size = uint32(unsafe.Sizeof(procEntry)) if err = syscall.Process32First(snapshot, &procEntry); err != nil { common.Error("Fail to syscall Process32First: %v", err) return nil } processNameMap := make(map[uint32]string) for { processNameMap[procEntry.ProcessID] = parseProcessName(procEntry.ExeFile) if err = syscall.Process32Next(snapshot, &procEntry); err != nil { if err == syscall.ERROR_NO_MORE_FILES { return processNameMap } common.Error("Fail to syscall Process32Next: %v", err) return nil } } }
// re-implementation of private function in https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go#L945 func getProcessEntry(pid int) (pe *syscall.ProcessEntry32, err error) { snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) if err != nil { return nil, err } defer syscall.CloseHandle(syscall.Handle(snapshot)) var processEntry syscall.ProcessEntry32 processEntry.Size = uint32(unsafe.Sizeof(processEntry)) err = syscall.Process32First(snapshot, &processEntry) if err != nil { return nil, err } for { if processEntry.ProcessID == uint32(pid) { pe = &processEntry return } err = syscall.Process32Next(snapshot, &processEntry) if err != nil { return nil, err } } }
func resumeChildThread(kernel32 *syscall.DLL, childpid int) error { _OpenThread := kernel32.MustFindProc("OpenThread") _ResumeThread := kernel32.MustFindProc("ResumeThread") _Thread32First := kernel32.MustFindProc("Thread32First") _Thread32Next := kernel32.MustFindProc("Thread32Next") snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPTHREAD, 0) if err != nil { return err } defer syscall.CloseHandle(snapshot) const _THREAD_SUSPEND_RESUME = 0x0002 type ThreadEntry32 struct { Size uint32 tUsage uint32 ThreadID uint32 OwnerProcessID uint32 BasePri int32 DeltaPri int32 Flags uint32 } var te ThreadEntry32 te.Size = uint32(unsafe.Sizeof(te)) ret, _, err := _Thread32First.Call(uintptr(snapshot), uintptr(unsafe.Pointer(&te))) if ret == 0 { return err } for te.OwnerProcessID != uint32(childpid) { ret, _, err = _Thread32Next.Call(uintptr(snapshot), uintptr(unsafe.Pointer(&te))) if ret == 0 { return err } } h, _, err := _OpenThread.Call(_THREAD_SUSPEND_RESUME, 1, uintptr(te.ThreadID)) if h == 0 { return err } defer syscall.Close(syscall.Handle(h)) ret, _, err = _ResumeThread.Call(h) if ret == 0xffffffff { return err } return nil }
// loadProcessMap returns a map of processes and their children. func loadProcessMap() (map[uint32][]uint32, error) { snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) if err != nil { return nil, err } defer syscall.CloseHandle(snapshot) var proc syscall.ProcessEntry32 proc.Size = uint32(unsafe.Sizeof(proc)) if err := syscall.Process32First(snapshot, &proc); err != nil { return nil, err } parentMap := make(map[uint32][]uint32) for { parentMap[proc.ParentProcessID] = append(parentMap[proc.ParentProcessID], proc.ProcessID) if err := syscall.Process32Next(snapshot, &proc); err != nil { if errNo, ok := err.(syscall.Errno); ok && errNo == syscall.ERROR_NO_MORE_FILES { return parentMap, nil } return nil, err } } }