diff options
Diffstat (limited to 'vendor/github.com/mitchellh/go-ps/process_windows.go')
-rw-r--r-- | vendor/github.com/mitchellh/go-ps/process_windows.go | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/vendor/github.com/mitchellh/go-ps/process_windows.go b/vendor/github.com/mitchellh/go-ps/process_windows.go new file mode 100644 index 0000000..f151974 --- /dev/null +++ b/vendor/github.com/mitchellh/go-ps/process_windows.go @@ -0,0 +1,119 @@ +// +build windows + +package ps + +import ( + "fmt" + "syscall" + "unsafe" +) + +// Windows API functions +var ( + modKernel32 = syscall.NewLazyDLL("kernel32.dll") + procCloseHandle = modKernel32.NewProc("CloseHandle") + procCreateToolhelp32Snapshot = modKernel32.NewProc("CreateToolhelp32Snapshot") + procProcess32First = modKernel32.NewProc("Process32FirstW") + procProcess32Next = modKernel32.NewProc("Process32NextW") +) + +// Some constants from the Windows API +const ( + ERROR_NO_MORE_FILES = 0x12 + MAX_PATH = 260 +) + +// PROCESSENTRY32 is the Windows API structure that contains a process's +// information. +type PROCESSENTRY32 struct { + Size uint32 + CntUsage uint32 + ProcessID uint32 + DefaultHeapID uintptr + ModuleID uint32 + CntThreads uint32 + ParentProcessID uint32 + PriorityClassBase int32 + Flags uint32 + ExeFile [MAX_PATH]uint16 +} + +// WindowsProcess is an implementation of Process for Windows. +type WindowsProcess struct { + pid int + ppid int + exe string +} + +func (p *WindowsProcess) Pid() int { + return p.pid +} + +func (p *WindowsProcess) PPid() int { + return p.ppid +} + +func (p *WindowsProcess) Executable() string { + return p.exe +} + +func newWindowsProcess(e *PROCESSENTRY32) *WindowsProcess { + // Find when the string ends for decoding + end := 0 + for { + if e.ExeFile[end] == 0 { + break + } + end++ + } + + return &WindowsProcess{ + pid: int(e.ProcessID), + ppid: int(e.ParentProcessID), + exe: syscall.UTF16ToString(e.ExeFile[:end]), + } +} + +func findProcess(pid int) (Process, error) { + ps, err := processes() + if err != nil { + return nil, err + } + + for _, p := range ps { + if p.Pid() == pid { + return p, nil + } + } + + return nil, nil +} + +func processes() ([]Process, error) { + handle, _, _ := procCreateToolhelp32Snapshot.Call( + 0x00000002, + 0) + if handle < 0 { + return nil, syscall.GetLastError() + } + defer procCloseHandle.Call(handle) + + var entry PROCESSENTRY32 + entry.Size = uint32(unsafe.Sizeof(entry)) + ret, _, _ := procProcess32First.Call(handle, uintptr(unsafe.Pointer(&entry))) + if ret == 0 { + return nil, fmt.Errorf("Error retrieving process info.") + } + + results := make([]Process, 0, 50) + for { + results = append(results, newWindowsProcess(&entry)) + + ret, _, _ := procProcess32Next.Call(handle, uintptr(unsafe.Pointer(&entry))) + if ret == 0 { + break + } + } + + return results, nil +} |