mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-03-12 07:01:03 -04:00
A number of PRs have come through which modified the vendor folder without recording the proper information. This resets everything back to the recorded version.
120 lines
2.4 KiB
Go
120 lines
2.4 KiB
Go
// +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
|
|
}
|