...

Source file src/github.com/Microsoft/go-winio/pkg/process/process.go

Documentation: github.com/Microsoft/go-winio/pkg/process

     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  }
    91  

View as plain text