Merge pull request #1848 from secDre4mer/master

Fix issues with GetLastError() usage
master
shirou 6 days ago committed by GitHub
commit 34ac457e15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -71,12 +71,14 @@ func TimesWithContext(_ context.Context, percpu bool) ([]TimesStat, error) {
var lpIdleTime common.FILETIME var lpIdleTime common.FILETIME
var lpKernelTime common.FILETIME var lpKernelTime common.FILETIME
var lpUserTime common.FILETIME var lpUserTime common.FILETIME
r, _, _ := common.ProcGetSystemTimes.Call( // GetSystemTimes returns 0 for error, in which case we check err,
// see https://pkg.go.dev/golang.org/x/sys/windows#LazyProc.Call
r, _, err := common.ProcGetSystemTimes.Call(
uintptr(unsafe.Pointer(&lpIdleTime)), uintptr(unsafe.Pointer(&lpIdleTime)),
uintptr(unsafe.Pointer(&lpKernelTime)), uintptr(unsafe.Pointer(&lpKernelTime)),
uintptr(unsafe.Pointer(&lpUserTime))) uintptr(unsafe.Pointer(&lpUserTime)))
if r == 0 { if r == 0 {
return ret, windows.GetLastError() return nil, err
} }
LOT := float64(0.0000001) LOT := float64(0.0000001)

@ -19,7 +19,6 @@ import (
var ( var (
procGetDiskFreeSpaceExW = common.Modkernel32.NewProc("GetDiskFreeSpaceExW") procGetDiskFreeSpaceExW = common.Modkernel32.NewProc("GetDiskFreeSpaceExW")
procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW") procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW")
procGetDriveType = common.Modkernel32.NewProc("GetDriveTypeW")
procGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW") procGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW")
) )
@ -109,15 +108,14 @@ func PartitionsWithContext(ctx context.Context, _ bool) ([]PartitionStat, error)
if v >= 65 && v <= 90 { if v >= 65 && v <= 90 {
path := string(v) + ":" path := string(v) + ":"
typepath, _ := windows.UTF16PtrFromString(path) typepath, _ := windows.UTF16PtrFromString(path)
typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath))) typeret := windows.GetDriveType(typepath)
if typeret == 0 { switch typeret {
err := windows.GetLastError() case windows.DRIVE_UNKNOWN:
warnings.Add(err)
continue continue
} case windows.DRIVE_REMOVABLE,
// 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 4: DRIVE_REMOTE 5: DRIVE_CDROM windows.DRIVE_FIXED,
windows.DRIVE_REMOTE,
if typeret == 2 || typeret == 3 || typeret == 4 || typeret == 5 { windows.DRIVE_CDROM:
lpVolumeNameBuffer := make([]byte, 256) lpVolumeNameBuffer := make([]byte, 256)
lpVolumeSerialNumber := int64(0) lpVolumeSerialNumber := int64(0)
lpMaximumComponentLength := int64(0) lpMaximumComponentLength := int64(0)
@ -134,7 +132,8 @@ func PartitionsWithContext(ctx context.Context, _ bool) ([]PartitionStat, error)
uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])), uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])),
uintptr(len(lpFileSystemNameBuffer))) uintptr(len(lpFileSystemNameBuffer)))
if driveret == 0 { if driveret == 0 {
if typeret == 2 || typeret == 4 || typeret == 5 { switch typeret {
case windows.DRIVE_REMOVABLE, windows.DRIVE_REMOTE, windows.DRIVE_CDROM:
continue // device is not ready will happen if there is no disk in the drive continue // device is not ready will happen if there is no disk in the drive
} }
warnings.Add(err) warnings.Add(err)
@ -197,9 +196,6 @@ func IOCountersWithContext(_ context.Context, names ...string) (map[string]IOCou
path := string(rune(v)) + ":" path := string(rune(v)) + ":"
typepath, _ := windows.UTF16PtrFromString(path) typepath, _ := windows.UTF16PtrFromString(path)
typeret := windows.GetDriveType(typepath) typeret := windows.GetDriveType(typepath)
if typeret == 0 {
return drivemap, windows.GetLastError()
}
if typeret != windows.DRIVE_FIXED { if typeret != windows.DRIVE_FIXED {
continue continue
} }

@ -5,8 +5,6 @@ package mem
import ( import (
"unsafe" "unsafe"
"golang.org/x/sys/windows"
) )
// ExVirtualMemory represents Windows specific information // ExVirtualMemory represents Windows specific information
@ -28,16 +26,21 @@ func NewExWindows() *ExWindows {
func (e *ExWindows) VirtualMemory() (*ExVirtualMemory, error) { func (e *ExWindows) VirtualMemory() (*ExVirtualMemory, error) {
var memInfo memoryStatusEx var memInfo memoryStatusEx
memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) // If mem == 0 since this is an error according to GlobalMemoryStatusEx documentation
// In that case, use err which is constructed from GetLastError(),
// see https://pkg.go.dev/golang.org/x/sys/windows#LazyProc.Call
mem, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
if mem == 0 { if mem == 0 {
return nil, windows.GetLastError() return nil, err
} }
var perfInfo performanceInformation var perfInfo performanceInformation
perfInfo.cb = uint32(unsafe.Sizeof(perfInfo)) perfInfo.cb = uint32(unsafe.Sizeof(perfInfo))
perf, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb)) // Analogous to above: perf == 0 is an error according to the GetPerformanceInfo documentation,
// use err in that case
perf, _, err := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb))
if perf == 0 { if perf == 0 {
return nil, windows.GetLastError() return nil, err
} }
ret := &ExVirtualMemory{ ret := &ExVirtualMemory{

@ -40,9 +40,11 @@ func VirtualMemory() (*VirtualMemoryStat, error) {
func VirtualMemoryWithContext(_ context.Context) (*VirtualMemoryStat, error) { func VirtualMemoryWithContext(_ context.Context) (*VirtualMemoryStat, error) {
var memInfo memoryStatusEx var memInfo memoryStatusEx
memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) // GlobalMemoryStatusEx returns 0 for error, in which case we check err,
// see https://pkg.go.dev/golang.org/x/sys/windows#LazyProc.Call
mem, _, err := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
if mem == 0 { if mem == 0 {
return nil, windows.GetLastError() return nil, err
} }
ret := &VirtualMemoryStat{ ret := &VirtualMemoryStat{
@ -93,9 +95,11 @@ func SwapMemoryWithContext(_ context.Context) (*SwapMemoryStat, error) {
// Get total memory from performance information // Get total memory from performance information
var perfInfo performanceInformation var perfInfo performanceInformation
perfInfo.cb = uint32(unsafe.Sizeof(perfInfo)) perfInfo.cb = uint32(unsafe.Sizeof(perfInfo))
mem, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb)) // GetPerformanceInfo returns 0 for error, in which case we check err,
// see https://pkg.go.dev/golang.org/x/sys/windows#LazyProc.Call
mem, _, err := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb))
if mem == 0 { if mem == 0 {
return nil, windows.GetLastError() return nil, err
} }
totalPhys := perfInfo.physicalTotal * perfInfo.pageSize totalPhys := perfInfo.physicalTotal * perfInfo.pageSize
totalSys := perfInfo.commitLimit * perfInfo.pageSize totalSys := perfInfo.commitLimit * perfInfo.pageSize
@ -161,9 +165,11 @@ func SwapDevicesWithContext(_ context.Context) ([]*SwapDevice, error) {
// the following system call invokes the supplied callback function once for each page file before returning // the following system call invokes the supplied callback function once for each page file before returning
// see https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumpagefilesw // see https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumpagefilesw
var swapDevices []*SwapDevice var swapDevices []*SwapDevice
result, _, _ := procEnumPageFilesW.Call(windows.NewCallback(pEnumPageFileCallbackW), uintptr(unsafe.Pointer(&swapDevices))) // EnumPageFilesW returns 0 for error, in which case we check err,
// see https://pkg.go.dev/golang.org/x/sys/windows#LazyProc.Call
result, _, err := procEnumPageFilesW.Call(windows.NewCallback(pEnumPageFileCallbackW), uintptr(unsafe.Pointer(&swapDevices)))
if result == 0 { if result == 0 {
return nil, windows.GetLastError() return nil, err
} }
return swapDevices, nil return swapDevices, nil

Loading…
Cancel
Save