mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-08-28 04:46:50 -04:00
Some new upcoming changes require us to use Go 1.23. However, if we switch to Go 1.23 some new linter errors are showing up. This commit fixes most of the errors and adds an exclusion for integer overflow errors. Signed-off-by: Amit <ambarve@microsoft.com>
90 lines
2.8 KiB
Go
90 lines
2.8 KiB
Go
//go:build windows
|
|
|
|
package process
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
// EnumProcesses returns a slice containing the process IDs of all processes
|
|
// currently running on the system.
|
|
func EnumProcesses() ([]uint32, error) {
|
|
count := 256
|
|
uint32Size := unsafe.Sizeof(uint32(0))
|
|
for {
|
|
buf := make([]uint32, count)
|
|
bufferSize := uint32(len(buf) * int(uint32Size))
|
|
retBufferSize := uint32(0)
|
|
if err := enumProcesses(&buf[0], bufferSize, &retBufferSize); err != nil {
|
|
return nil, err
|
|
}
|
|
if retBufferSize == bufferSize {
|
|
count = count * 2
|
|
continue
|
|
}
|
|
actualCount := retBufferSize / uint32(uint32Size)
|
|
return buf[:actualCount], nil
|
|
}
|
|
}
|
|
|
|
// ProcessMemoryCountersEx is the PROCESS_MEMORY_COUNTERS_EX struct from
|
|
// Windows:
|
|
// https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-process_memory_counters_ex
|
|
//
|
|
//nolint:revive // process.ProcessMemoryCountersEx stutters, too late to change it
|
|
type ProcessMemoryCountersEx struct {
|
|
Cb uint32
|
|
PageFaultCount uint32
|
|
PeakWorkingSetSize uint
|
|
WorkingSetSize uint
|
|
QuotaPeakPagedPoolUsage uint
|
|
QuotaPagedPoolUsage uint
|
|
QuotaPeakNonPagedPoolUsage uint
|
|
QuotaNonPagedPoolUsage uint
|
|
PagefileUsage uint
|
|
PeakPagefileUsage uint
|
|
PrivateUsage uint
|
|
}
|
|
|
|
// GetProcessMemoryInfo returns the memory usage information for the given
|
|
// process. The process handle must have the PROCESS_QUERY_INFORMATION or
|
|
// PROCESS_QUERY_LIMITED_INFORMATION, and the PROCESS_VM_READ access rights.
|
|
func GetProcessMemoryInfo(process windows.Handle) (*ProcessMemoryCountersEx, error) {
|
|
memCounters := &ProcessMemoryCountersEx{}
|
|
size := unsafe.Sizeof(*memCounters)
|
|
if err := getProcessMemoryInfo(process, memCounters, uint32(size)); err != nil {
|
|
return nil, err
|
|
}
|
|
return memCounters, nil
|
|
}
|
|
|
|
// These constants are used with QueryFullProcessImageName's flags.
|
|
const (
|
|
// ImageNameFormatWin32Path indicates to format the name as a Win32 path.
|
|
ImageNameFormatWin32Path = iota
|
|
// ImageNameFormatNTPath indicates to format the name as a NT path.
|
|
ImageNameFormatNTPath
|
|
)
|
|
|
|
// QueryFullProcessImageName returns the full process image name for the given
|
|
// process. The process handle must have the PROCESS_QUERY_INFORMATION or
|
|
// PROCESS_QUERY_LIMITED_INFORMATION access right. The flags can be either
|
|
// `ImageNameFormatWin32Path` or `ImageNameFormatNTPath`.
|
|
func QueryFullProcessImageName(process windows.Handle, flags uint32) (string, error) {
|
|
bufferSize := uint32(256)
|
|
for {
|
|
b := make([]uint16, bufferSize)
|
|
err := queryFullProcessImageName(process, flags, &b[0], &bufferSize)
|
|
if err == windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
|
|
bufferSize = bufferSize * 2
|
|
continue
|
|
}
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return windows.UTF16ToString(b[:bufferSize]), nil
|
|
}
|
|
}
|