github.com/Serizao/go-winio@v0.0.0-20230906082528-f02f7f4ad6e8/pkg/process/process.go (about) 1 //go:build windows 2 // +build windows 3 4 package process 5 6 import ( 7 "unsafe" 8 9 "golang.org/x/sys/windows" 10 ) 11 12 // EnumProcesses returns a slice containing the process IDs of all processes 13 // currently running on the system. 14 func EnumProcesses() ([]uint32, error) { 15 count := 256 16 uint32Size := unsafe.Sizeof(uint32(0)) 17 for { 18 buf := make([]uint32, count) 19 bufferSize := uint32(len(buf) * int(uint32Size)) 20 retBufferSize := uint32(0) 21 if err := enumProcesses(&buf[0], bufferSize, &retBufferSize); err != nil { 22 return nil, err 23 } 24 if retBufferSize == bufferSize { 25 count = count * 2 26 continue 27 } 28 actualCount := retBufferSize / uint32(uint32Size) 29 return buf[:actualCount], nil 30 } 31 } 32 33 // ProcessMemoryCountersEx is the PROCESS_MEMORY_COUNTERS_EX struct from 34 // Windows: 35 // https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-process_memory_counters_ex 36 // 37 //nolint:revive // process.ProcessMemoryCountersEx stutters, too late to change it 38 type ProcessMemoryCountersEx struct { 39 Cb uint32 40 PageFaultCount uint32 41 PeakWorkingSetSize uint 42 WorkingSetSize uint 43 QuotaPeakPagedPoolUsage uint 44 QuotaPagedPoolUsage uint 45 QuotaPeakNonPagedPoolUsage uint 46 QuotaNonPagedPoolUsage uint 47 PagefileUsage uint 48 PeakPagefileUsage uint 49 PrivateUsage uint 50 } 51 52 // GetProcessMemoryInfo returns the memory usage information for the given 53 // process. The process handle must have the PROCESS_QUERY_INFORMATION or 54 // PROCESS_QUERY_LIMITED_INFORMATION, and the PROCESS_VM_READ access rights. 55 func GetProcessMemoryInfo(process windows.Handle) (*ProcessMemoryCountersEx, error) { 56 memCounters := &ProcessMemoryCountersEx{} 57 size := unsafe.Sizeof(*memCounters) 58 if err := getProcessMemoryInfo(process, memCounters, uint32(size)); err != nil { 59 return nil, err 60 } 61 return memCounters, nil 62 } 63 64 // These constants are used with QueryFullProcessImageName's flags. 65 const ( 66 // ImageNameFormatWin32Path indicates to format the name as a Win32 path. 67 ImageNameFormatWin32Path = iota 68 // ImageNameFormatNTPath indicates to format the name as a NT path. 69 ImageNameFormatNTPath 70 ) 71 72 // QueryFullProcessImageName returns the full process image name for the given 73 // process. The process handle must have the PROCESS_QUERY_INFORMATION or 74 // PROCESS_QUERY_LIMITED_INFORMATION access right. The flags can be either 75 // `ImageNameFormatWin32Path` or `ImageNameFormatNTPath`. 76 func QueryFullProcessImageName(process windows.Handle, flags uint32) (string, error) { 77 bufferSize := uint32(256) 78 for { 79 b := make([]uint16, bufferSize) 80 err := queryFullProcessImageName(process, flags, &b[0], &bufferSize) 81 if err == windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno 82 bufferSize = bufferSize * 2 83 continue 84 } 85 if err != nil { 86 return "", err 87 } 88 return windows.UTF16ToString(b[:bufferSize]), nil 89 } 90 }