func (self *ProcMem) Get(pid int) error { handle, err := syscall.OpenProcess(PROCESS_ALL_ACCESS, false, uint32(pid)) defer syscall.CloseHandle(handle) if err != nil { return fmt.Errorf("OpenProcess fails with %v", err) } var mem PROCESS_MEMORY_COUNTERS_EX mem.CB = uint32(unsafe.Sizeof(mem)) r1, _, e1 := procGetProcessMemoryInfo.Call( uintptr(handle), uintptr(unsafe.Pointer(&mem)), uintptr(mem.CB), ) if r1 == 0 { if e1 != nil { return error(e1) } else { return syscall.EINVAL } } self.Resident = uint64(mem.WorkingSetSize) self.Size = uint64(mem.PrivateUsage) // Size contains only to the Private Bytes // Virtual Bytes are the Working Set plus paged Private Bytes and standby list. return nil }
// findExePath searches for process pid, and returns its executable path. func findExePath(pid int) (string, error) { // Original code suggested different approach (see below). // Maybe it could be useful in the future. // // Find executable path from PID/handle on Windows: // https://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx p, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) if err != nil { return "", err } defer syscall.CloseHandle(p) n := uint32(128) for { buf := make([]uint16, int(n)) err = _QueryFullProcessImageName(p, 0, &buf[0], &n) switch err { case syscall.ERROR_INSUFFICIENT_BUFFER: // try bigger buffer n *= 2 // but stop if it gets too big if n > 10000 { return "", err } case nil: return syscall.UTF16ToString(buf[:n]), nil default: return "", err } } }
func (self *ProcTime) Get(pid int) error { handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) defer syscall.CloseHandle(handle) if err != nil { return fmt.Errorf("OpenProcess fails with %v", err) } var CPU syscall.Rusage if err := syscall.GetProcessTimes(handle, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil { return fmt.Errorf("GetProcessTimes fails with %v", err) } // convert to millis self.StartTime = uint64(FiletimeToDuration(&CPU.CreationTime).Nanoseconds() / 1e6) self.User = uint64(FiletimeToDuration(&CPU.UserTime).Nanoseconds() / 1e6) self.Sys = uint64(FiletimeToDuration(&CPU.KernelTime).Nanoseconds() / 1e6) self.Total = self.User + self.Sys return nil }
func OpenProcess(pid uint32) (*Process, error) { const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE h, err := syscall.OpenProcess(da, false, uint32(pid)) if err != nil { return nil, os.NewSyscallError("OpenProcess", err) } procEntry, err := win32.FindProcessEntry(pid) if err != nil { return nil, err } modEntry, err := win32.FirstModuleEntry(pid) if err != nil { return nil, err } handleCount, err := win32.GetProcessHandleCount(h) if err != nil { return nil, err } return &Process{ Pid: pid, handle: uintptr(h), ParentId: procEntry.ParentProcessID, Name: syscall.UTF16ToString(modEntry.ModuleName[:]), Executable: syscall.UTF16ToString(procEntry.ExeFile[:]), CmdLine: syscall.UTF16ToString(modEntry.ExePath[:]), HandleCount: handleCount, ThreadCount: procEntry.Threads, }, nil }
func initJob() { // Create Job object and assign current process to it. jobObject, err := createJobObject(nil, nil) if err != nil { log.Printf("CreateJobObject failed: %v", err) return } if err = assignProcessToJobObject(jobObject, currentProcess); err != nil { log.Printf("AssignProcessToJobObject failed: %v", err) syscall.Close(jobObject) return } iocp, err := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 1) if err != nil { log.Printf("CreateIoCompletionPort failed: %v", err) syscall.Close(jobObject) return } port := JOBOBJECT_ASSOCIATE_COMPLETION_PORT{ CompletionKey: uintptr(jobObject), CompletionPort: iocp, } err = setInformationJobObject(jobObject, JobObjectAssociateCompletionPortInformation, uintptr(unsafe.Pointer(&port)), uint32(unsafe.Sizeof(port))) if err != nil { log.Printf("SetInformationJobObject failed: %v", err) syscall.Close(jobObject) syscall.Close(iocp) return } // Read Job notifications about new "child" processes and collect them in childProcesses. go func() { var code, key uint32 var o *syscall.Overlapped for { err := syscall.GetQueuedCompletionStatus(iocp, &code, &key, &o, syscall.INFINITE) if err != nil { log.Printf("GetQueuedCompletionStatus failed: %v", err) return } if key != uint32(jobObject) { panic("Invalid GetQueuedCompletionStatus key parameter") } if code == JOB_OBJECT_MSG_NEW_PROCESS { pid := int(uintptr(unsafe.Pointer(o))) if pid == syscall.Getpid() { continue } c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) if err != nil { log.Printf("OpenProcess failed: %v", err) continue } childMu.Lock() childProcesses = append(childProcesses, c) childMu.Unlock() } } }() }
func terminateProcess(pid, exitcode int) error { h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid)) if e != nil { return NewSyscallError("OpenProcess", e) } defer syscall.CloseHandle(h) e = syscall.TerminateProcess(h, uint32(exitcode)) return NewSyscallError("TerminateProcess", e) }
func findProcess(pid int) (p *Process, err error) { const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE h, e := syscall.OpenProcess(da, false, uint32(pid)) if e != nil { return nil, NewSyscallError("OpenProcess", e) } return newProcess(pid, uintptr(h)), nil }
// killProcess terminates a given pid using TerminateProcess. func killProcess(pid uint32) error { handle, err := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false /* inheritHandle */, pid) if err != nil { return err } defer syscall.CloseHandle(handle) log.VV("TerminateProcess(%v) with handle %v", pid, handle) return syscall.TerminateProcess(handle, 1) }
func TestGetProcessMemoryInfo(t *testing.T) { h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(syscall.Getpid())) if err != nil { t.Fatal(err) } counters, err := GetProcessMemoryInfo(h) if err != nil { t.Fatal(err) } t.Logf("GetProcessMemoryInfo: ProcessMemoryCountersEx=%+v", counters) }
func TestGetProcessImageFileName(t *testing.T) { h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(syscall.Getpid())) if err != nil { t.Fatal(err) } filename, err := GetProcessImageFileName(h) if err != nil { t.Fatal(err) } t.Logf("GetProcessImageFileName: %v", filename) }
// _pidAlive tests whether a process is alive or not func _pidAlive(pid int) bool { h, err := syscall.OpenProcess(processDesiredAccess, false, uint32(pid)) if err != nil { return false } var ec uint32 if e := syscall.GetExitCodeProcess(h, &ec); e != nil { return false } return ec == exit_STILL_ACTIVE }
func getMemoryInfo(pid int32) (PROCESS_MEMORY_COUNTERS, error) { var mem PROCESS_MEMORY_COUNTERS c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) if err != nil { return mem, err } defer syscall.CloseHandle(c) if err := getProcessMemoryInfo(c, &mem); err != nil { return mem, err } return mem, err }
func processExists(pid int) bool { h, err := syscall.OpenProcess(processQueryLimitedInformation, false, uint32(pid)) if err != nil { return false } var c uint32 err = syscall.GetExitCodeProcess(h, &c) syscall.Close(h) if err != nil { return c == stillActive } return true }
// getProcName returns the process name associated with the PID. func getProcName(pid int) (string, error) { handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) if err != nil { return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) filename, err := windows.GetProcessImageFileName(handle) if err != nil { return "", errors.Wrapf(err, "GetProcessImageFileName failed for pid=%v", pid) } return filepath.Base(filename), nil }
// getParentPid returns the parent process ID of a process. func getParentPid(pid int) (int, error) { handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) if err != nil { return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) procInfo, err := windows.NtQueryProcessBasicInformation(handle) if err != nil { return 0, errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid) } return int(procInfo.InheritedFromUniqueProcessID), nil }
func getRusage(pid int32) (*syscall.Rusage, error) { var CPU syscall.Rusage c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) if err != nil { return nil, err } defer syscall.CloseHandle(c) if err := syscall.GetProcessTimes(c, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil { return nil, err } return &CPU, nil }
func (s *Spawner) Alive() bool { const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE h, e := syscall.OpenProcess(da, false, uint32(s.SpawnPid)) if e != nil { return false } var ec uint32 e = syscall.GetExitCodeProcess(h, &ec) if e != nil { return false } return ec == STILL_ACTIVE }
func killProcess(pid int) error { const PROCESS_TERMINATE = 0x0001 const da = syscall.STANDARD_RIGHTS_READ | syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE | PROCESS_TERMINATE h, e := syscall.OpenProcess(da, false, uint32(pid)) if e != nil { return os.NewSyscallError("OpenProcess", e) } defer syscall.CloseHandle(h) e = syscall.TerminateProcess(h, 1) if nil != e { return os.NewSyscallError("TerminateProcess", e) } return nil }
func (self *ProcMem) Get(pid int) error { handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid)) if err != nil { return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) counters, err := windows.GetProcessMemoryInfo(handle) if err != nil { return errors.Wrapf(err, "GetProcessMemoryInfo failed for pid=%v", pid) } self.Resident = uint64(counters.WorkingSetSize) self.Size = uint64(counters.PrivateUsage) return nil }
func TestNtQueryProcessBasicInformation(t *testing.T) { h, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(syscall.Getpid())) if err != nil { t.Fatal(err) } info, err := NtQueryProcessBasicInformation(h) if err != nil { t.Fatal(err) } assert.EqualValues(t, os.Getpid(), info.UniqueProcessID) assert.EqualValues(t, os.Getppid(), info.InheritedFromUniqueProcessID) t.Logf("NtQueryProcessBasicInformation: %+v", info) }
// getProcStatus returns the status of a process. func getProcStatus(pid int) (RunState, error) { handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) if err != nil { return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) var exitCode uint32 err = syscall.GetExitCodeProcess(handle, &exitCode) if err != nil { return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v") } if exitCode == 259 { //still active return RunStateRun, nil } return RunStateSleep, nil }
func isRunning(pid int) (bool, error) { procHnd, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, true, uint32(pid)) if err != nil { if scerr, ok := err.(syscall.Errno); ok { if uintptr(scerr) == error_invalid_parameter { return false, nil } } } var code uint32 err = syscall.GetExitCodeProcess(procHnd, &code) if err != nil { return false, err } return code == code_still_active, nil }
func GetProcStatus(pid int) (RunState, error) { handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) defer syscall.CloseHandle(handle) if err != nil { return RunStateUnknown, fmt.Errorf("OpenProcess fails with %v", err) } var ec uint32 e := syscall.GetExitCodeProcess(syscall.Handle(handle), &ec) if e != nil { return RunStateUnknown, os.NewSyscallError("GetExitCodeProcess", e) } if ec == 259 { //still active return RunStateRun, nil } return RunStateSleep, nil }
func GetProcCredName(pid int) (string, error) { var err error handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) if err != nil { return "", fmt.Errorf("OpenProcess fails with %v", err) } defer syscall.CloseHandle(handle) var token syscall.Token // Find process token via win32 err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token) if err != nil { return "", fmt.Errorf("Error opening process token %v", err) } // Find the token user tokenUser, err := token.GetTokenUser() if err != nil { return "", fmt.Errorf("Error getting token user %v", err) } // Close token to prevent handle leaks err = token.Close() if err != nil { return "", fmt.Errorf("Error failed to closed process token") } // look up domain account by sid account, domain, _, err := tokenUser.User.Sid.LookupAccount("localhost") if err != nil { return "", fmt.Errorf("Error looking up sid %v", err) } return fmt.Sprintf("%s\\%s", domain, account), nil }
func getProcCredName(pid int) (string, error) { handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) if err != nil { return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) // Find process token via win32. var token syscall.Token err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token) if err != nil { return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid) } // Find the token user. tokenUser, err := token.GetTokenUser() if err != nil { return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid) } // Close token to prevent handle leaks. err = token.Close() if err != nil { return "", errors.Wrapf(err, "failed while closing process token handle for pid=%v", pid) } // Look up domain account by SID. account, domain, _, err := tokenUser.User.Sid.LookupAccount("") if err != nil { sid, sidErr := tokenUser.User.Sid.String() if sidErr != nil { return "", errors.Wrapf(err, "failed while looking up account name for pid=%v", pid) } return "", errors.Wrapf(err, "failed while looking up account name for SID=%v of pid=%v", sid, pid) } return fmt.Sprintf(`%s\%s`, domain, account), nil }
func (self *ProcTime) Get(pid int) error { handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid)) if err != nil { return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) } defer syscall.CloseHandle(handle) var CPU syscall.Rusage if err := syscall.GetProcessTimes(handle, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil { return errors.Wrapf(err, "GetProcessTimes failed for pid=%v", pid) } // Windows epoch times are expressed as time elapsed since midnight on // January 1, 1601 at Greenwich, England. This converts the Filetime to // unix epoch in milliseconds. self.StartTime = uint64(CPU.CreationTime.Nanoseconds() / 1e6) // Convert to millis. self.User = uint64(windows.FiletimeToDuration(&CPU.UserTime).Nanoseconds() / 1e6) self.Sys = uint64(windows.FiletimeToDuration(&CPU.KernelTime).Nanoseconds() / 1e6) self.Total = self.User + self.Sys return nil }
func GetProcName(pid int) (string, error) { handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) defer syscall.CloseHandle(handle) if err != nil { return "", fmt.Errorf("OpenProcess fails with %v", err) } var nameProc [MAX_PATH]byte ret, _, _ := procGetProcessImageFileName.Call( uintptr(handle), uintptr(unsafe.Pointer(&nameProc)), uintptr(MAX_PATH), ) if ret == 0 { return "", syscall.GetLastError() } return filepath.Base(CarrayToString(nameProc)), nil }
func TestNumCPU(t *testing.T) { if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { // in child process fmt.Fprintf(os.Stderr, "%d", runtime.NumCPU()) os.Exit(0) } switch n := runtime.NumberOfProcessors(); { case n < 1: t.Fatalf("system cannot have %d cpu(s)", n) case n == 1: if runtime.NumCPU() != 1 { t.Fatalf("runtime.NumCPU() returns %d on single cpu system", runtime.NumCPU()) } return } const ( _CREATE_SUSPENDED = 0x00000004 _PROCESS_ALL_ACCESS = syscall.STANDARD_RIGHTS_REQUIRED | syscall.SYNCHRONIZE | 0xfff ) kernel32 := syscall.MustLoadDLL("kernel32.dll") _GetProcessAffinityMask := kernel32.MustFindProc("GetProcessAffinityMask") _SetProcessAffinityMask := kernel32.MustFindProc("SetProcessAffinityMask") cmd := exec.Command(os.Args[0], "-test.run=TestNumCPU") cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1") var buf bytes.Buffer cmd.Stdout = &buf cmd.Stderr = &buf cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: _CREATE_SUSPENDED} err := cmd.Start() if err != nil { t.Fatal(err) } defer func() { err = cmd.Wait() childOutput := string(buf.Bytes()) if err != nil { t.Fatalf("child failed: %v: %v", err, childOutput) } // removeOneCPU should have decreased child cpu count by 1 want := fmt.Sprintf("%d", runtime.NumCPU()-1) if childOutput != want { t.Fatalf("child output: want %q, got %q", want, childOutput) } }() defer func() { err = resumeChildThread(kernel32, cmd.Process.Pid) if err != nil { t.Fatal(err) } }() ph, err := syscall.OpenProcess(_PROCESS_ALL_ACCESS, false, uint32(cmd.Process.Pid)) if err != nil { t.Fatal(err) } defer syscall.CloseHandle(ph) var mask, sysmask uintptr ret, _, err := _GetProcessAffinityMask.Call(uintptr(ph), uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask))) if ret == 0 { t.Fatal(err) } newmask, err := removeOneCPU(mask) if err != nil { t.Fatal(err) } ret, _, err = _SetProcessAffinityMask.Call(uintptr(ph), newmask) if ret == 0 { t.Fatal(err) } ret, _, err = _GetProcessAffinityMask.Call(uintptr(ph), uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask))) if ret == 0 { t.Fatal(err) } if newmask != mask { t.Fatalf("SetProcessAffinityMask didn't set newmask of 0x%x. Current mask is 0x%x.", newmask, mask) } }