summaryrefslogtreecommitdiff
path: root/vendor/github.com/mitchellh/go-ps/process_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mitchellh/go-ps/process_windows.go')
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_windows.go119
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
+}