...

Source file src/github.com/shirou/gopsutil/process/process_windows_386.go

Documentation: github.com/shirou/gopsutil/process

     1  // +build windows
     2  
     3  package process
     4  
     5  import (
     6  	"errors"
     7  	"syscall"
     8  	"unsafe"
     9  
    10  	"github.com/shirou/gopsutil/internal/common"
    11  	"golang.org/x/sys/windows"
    12  )
    13  
    14  type PROCESS_MEMORY_COUNTERS struct {
    15  	CB                         uint32
    16  	PageFaultCount             uint32
    17  	PeakWorkingSetSize         uint32
    18  	WorkingSetSize             uint32
    19  	QuotaPeakPagedPoolUsage    uint32
    20  	QuotaPagedPoolUsage        uint32
    21  	QuotaPeakNonPagedPoolUsage uint32
    22  	QuotaNonPagedPoolUsage     uint32
    23  	PagefileUsage              uint32
    24  	PeakPagefileUsage          uint32
    25  }
    26  
    27  func queryPebAddress(procHandle syscall.Handle, is32BitProcess bool) (uint64, error) {
    28  	if is32BitProcess {
    29  		//we are on a 32-bit process reading an external 32-bit process
    30  		var info processBasicInformation32
    31  
    32  		ret, _, _ := common.ProcNtQueryInformationProcess.Call(
    33  			uintptr(procHandle),
    34  			uintptr(common.ProcessBasicInformation),
    35  			uintptr(unsafe.Pointer(&info)),
    36  			uintptr(unsafe.Sizeof(info)),
    37  			uintptr(0),
    38  		)
    39  		if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS {
    40  			return uint64(info.PebBaseAddress), nil
    41  		} else {
    42  			return 0, windows.NTStatus(ret)
    43  		}
    44  	} else {
    45  		//we are on a 32-bit process reading an external 64-bit process
    46  		if common.ProcNtWow64QueryInformationProcess64.Find() == nil { //avoid panic
    47  			var info processBasicInformation64
    48  
    49  			ret, _, _ := common.ProcNtWow64QueryInformationProcess64.Call(
    50  				uintptr(procHandle),
    51  				uintptr(common.ProcessBasicInformation),
    52  				uintptr(unsafe.Pointer(&info)),
    53  				uintptr(unsafe.Sizeof(info)),
    54  				uintptr(0),
    55  			)
    56  			if status := windows.NTStatus(ret); status == windows.STATUS_SUCCESS {
    57  				return info.PebBaseAddress, nil
    58  			} else {
    59  				return 0, windows.NTStatus(ret)
    60  			}
    61  		} else {
    62  			return 0, errors.New("can't find API to query 64 bit process from 32 bit")
    63  		}
    64  	}
    65  }
    66  
    67  func readProcessMemory(h syscall.Handle, is32BitProcess bool, address uint64, size uint) []byte {
    68  	if is32BitProcess {
    69  		var read uint
    70  
    71  		buffer := make([]byte, size)
    72  
    73  		ret, _, _ := common.ProcNtReadVirtualMemory.Call(
    74  			uintptr(h),
    75  			uintptr(address),
    76  			uintptr(unsafe.Pointer(&buffer[0])),
    77  			uintptr(size),
    78  			uintptr(unsafe.Pointer(&read)),
    79  		)
    80  		if int(ret) >= 0 && read > 0 {
    81  			return buffer[:read]
    82  		}
    83  	} else {
    84  		//reading a 64-bit process from a 32-bit one
    85  		if common.ProcNtWow64ReadVirtualMemory64.Find() == nil { //avoid panic
    86  			var read uint64
    87  
    88  			buffer := make([]byte, size)
    89  
    90  			ret, _, _ := common.ProcNtWow64ReadVirtualMemory64.Call(
    91  				uintptr(h),
    92  				uintptr(address & 0xFFFFFFFF), //the call expects a 64-bit value
    93  				uintptr(address >> 32),
    94  				uintptr(unsafe.Pointer(&buffer[0])),
    95  				uintptr(size), //the call expects a 64-bit value
    96  				uintptr(0),    //but size is 32-bit so pass zero as the high dword
    97  				uintptr(unsafe.Pointer(&read)),
    98  			)
    99  			if int(ret) >= 0 && read > 0 {
   100  				return buffer[:uint(read)]
   101  			}
   102  		}
   103  	}
   104  
   105  	//if we reach here, an error happened
   106  	return nil
   107  }
   108  

View as plain text