From 9aa978ce9071a47f075f40708c8705e775f5489a Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Mon, 9 Nov 2020 18:14:22 -0500 Subject: [PATCH 1/4] Add filesystem type support on Windows --- sigar_windows.go | 11 +- sys/windows/syscall_windows.go | 19 ++ sys/windows/zsyscall_windows.go | 365 +++++++++++++------------------- 3 files changed, 170 insertions(+), 225 deletions(-) diff --git a/sigar_windows.go b/sigar_windows.go index d1204b80e..7a89e0fdb 100644 --- a/sigar_windows.go +++ b/sigar_windows.go @@ -136,11 +136,16 @@ func (self *FileSystemList) Get() error { if err != nil { return errors.Wrapf(err, "GetDriveType failed") } + volumeType, err := windows.GetVolumeInfo(drive) + if err != nil { + return errors.Wrapf(err, "GetVolumeInfo failed") + } self.List = append(self.List, FileSystem{ - DirName: drive, - DevName: drive, - TypeName: dt.String(), + DirName: drive, + DevName: drive, + TypeName: dt.String(), + SysTypeName: volumeType, }) } return nil diff --git a/sys/windows/syscall_windows.go b/sys/windows/syscall_windows.go index 371eb256b..83b703944 100644 --- a/sys/windows/syscall_windows.go +++ b/sys/windows/syscall_windows.go @@ -2,6 +2,7 @@ package windows import ( "fmt" + "strings" "syscall" "time" "unsafe" @@ -335,6 +336,23 @@ func GetDriveType(rootPathName string) (DriveType, error) { return dt, nil } +// GetVolumeInfo returns volume informatiom at the given root path. +// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw +func GetVolumeInfo(rootPathName string) (string, error) { + rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName) + if err != nil { + return "", errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName) + } + + buffer := make([]uint16, MAX_PATH) + success, err := _GetVolumeInformation(rootPathNamePtr, nil, 0, nil, nil, nil, &buffer[0], MAX_PATH) + if !success { + return "", errors.Wrap(err, "GetVolumeInformationW failed") + } + + return strings.ToLower(syscall.UTF16ToString(buffer)), nil +} + // EnumProcesses retrieves the process identifier for each process object in the // system. This function can return a max of 65536 PIDs. If there are more // processes than that then this will not return them all. @@ -587,6 +605,7 @@ func GetTickCount64() (uptime uint64, err error) { //sys _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) = psapi.GetProcessImageFileNameW //sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes //sys _GetDriveType(rootPathName *uint16) (dt DriveType, err error) = kernel32.GetDriveTypeW +//sys _GetVolumeInformation(rootPathName *uint16, volumeName *uint16, volumeNameSize uint32, volumeSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemName *uint16, fileSystemNameSize uint32) (success bool, err error) [true] = kernel32.GetVolumeInformationW //sys _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses //sys _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW //sys _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32FirstW diff --git a/sys/windows/zsyscall_windows.go b/sys/windows/zsyscall_windows.go index 75f19c0ea..63db70e92 100644 --- a/sys/windows/zsyscall_windows.go +++ b/sys/windows/zsyscall_windows.go @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -37,342 +38,262 @@ func errnoErr(e syscall.Errno) error { } var ( + modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - modpsapi = windows.NewLazySystemDLL("psapi.dll") modntdll = windows.NewLazySystemDLL("ntdll.dll") - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") + modpsapi = windows.NewLazySystemDLL("psapi.dll") - procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") - procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") - procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") - procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW") - procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") - procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") - procEnumProcesses = modpsapi.NewProc("EnumProcesses") - procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") - procProcess32FirstW = modkernel32.NewProc("Process32FirstW") - procProcess32NextW = modkernel32.NewProc("Process32NextW") - procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") - procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") - procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") + procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") + procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") + procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") + procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") + procGetTickCount64 = modkernel32.NewProc("GetTickCount64") + procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW") procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") - procGetTickCount64 = modkernel32.NewProc("GetTickCount64") + procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") + procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") + procEnumProcesses = modpsapi.NewProc("EnumProcesses") + procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW") + procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") ) -func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) { - r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { + var _p0 uint32 + if releaseAll { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) + success = r0 != 0 + if true { + err = errnoErr(e1) } return } -func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) - length = uint32(r0) - if length == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(systemName) + if err != nil { + return } - return + return __LookupPrivilegeName(_p0, luid, buffer, size) } -func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb)) +func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size)) - length = uint32(r0) - if length == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(systemName) + if err != nil { + return } - return + var _p1 *uint16 + _p1, err = syscall.UTF16PtrFromString(name) + if err != nil { + return + } + return __LookupPrivilegeValue(_p0, _p1, luid) } -func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) { - r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) +func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) { + r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) { - r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) - dt = DriveType(r0) - if dt == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0) + handle = syscall.Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0) + handle = syscall.Handle(r0) + if handle == 0 { + err = errnoErr(e1) } return } -func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { - r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) +func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) +func _FindVolumeClose(handle syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) +func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { + r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0) - handle = syscall.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) { + r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + dt = DriveType(r0) + if dt == 0 { + err = errnoErr(e1) } return } -func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { - r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) - ntstatus = uint32(r0) - if ntstatus == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + length = uint32(r0) + if length == 0 { + err = errnoErr(e1) } return } -func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { - r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0) - ntstatus = uint32(r0) - if ntstatus == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) { + r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) + if r1 == 0 { + err = errnoErr(e1) } return } -func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return +func _GetTickCount64() (uptime uint64, err error) { + r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) + uptime = uint64(r0) + if uptime == 0 { + err = errnoErr(e1) } - return __LookupPrivilegeName(_p0, luid, buffer, size) + return } -func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetVolumeInformation(rootPathName *uint16, volumeName *uint16, volumeNameSize uint32, volumeSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemName *uint16, fileSystemNameSize uint32) (success bool, err error) { + r0, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemName)), uintptr(fileSystemNameSize), 0) + success = r0 != 0 + if true { + err = errnoErr(e1) } return } -func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) { +func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) { var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - var _p1 *uint16 - _p1, err = syscall.UTF16PtrFromString(name) + _p0, err = syscall.UTF16PtrFromString(volumeName) if err != nil { return } - return __LookupPrivilegeValue(_p0, _p1, luid) + return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length) } -func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) +func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { - var _p0 uint32 - if releaseAll { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) - success = r0 != 0 - if true { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) { + r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0) - handle = syscall.Handle(r0) - if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size)) +func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { + r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _FindVolumeClose(handle syscall.Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0) +func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(volumeName) - if err != nil { - return +func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { + r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0) + ntstatus = uint32(r0) + if ntstatus == 0 { + err = errnoErr(e1) } - return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length) + return } -func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { + r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) + ntstatus = uint32(r0) + if ntstatus == 0 { + err = errnoErr(e1) } return } -func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0) +func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func _GetTickCount64() (uptime uint64, err error) { - r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) - uptime = uint64(r0) - if uptime == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size)) + length = uint32(r0) + if length == 0 { + err = errnoErr(e1) + } + return +} + +func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb)) + if r1 == 0 { + err = errnoErr(e1) } return } From d88e8d5713fa0fceccadc1f772a384471041206a Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Mon, 9 Nov 2020 18:17:10 -0500 Subject: [PATCH 2/4] Add Changelog entry --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84b5a3af8..8335e18d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add AIX support. #133 - Add `Cached` data to Memory #145 +- Add `SysTypeName` support on Windows #146 ### Fixed @@ -184,4 +185,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [0.4.0]: https://github.com/elastic/gosigar/releases/tag/v0.4.0 [0.3.0]: https://github.com/elastic/gosigar/releases/tag/v0.3.0 [0.2.0]: https://github.com/elastic/gosigar/releases/tag/v0.2.0 -[0.1.0]: https://github.com/elastic/gosigar/releases/tag/v0.1.0 \ No newline at end of file +[0.1.0]: https://github.com/elastic/gosigar/releases/tag/v0.1.0 From 4d4d2cc22fe7212a42aaf8416eff24143722679d Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Mon, 9 Nov 2020 18:22:04 -0500 Subject: [PATCH 3/4] Add smoke test --- sys/windows/syscall_windows_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/windows/syscall_windows_test.go b/sys/windows/syscall_windows_test.go index 61eff2860..91f0f74cb 100644 --- a/sys/windows/syscall_windows_test.go +++ b/sys/windows/syscall_windows_test.go @@ -114,6 +114,21 @@ func TestGetDiskFreeSpaceEx(t *testing.T) { } } +func TestGetVolumeInfo(t *testing.T) { + drives, err := GetLogicalDriveStrings() + if err != nil { + t.Fatal(err) + } + + for _, drive := range drives { + volumeType, err := GetVolumeInfo(drive) + if err != nil { + t.Fatal(err) + } + t.Logf("GetVolumeInfo: %v - %v", drive, volumeType) + } +} + func TestGetWindowsVersion(t *testing.T) { ver := GetWindowsVersion() assert.True(t, ver.Major >= 5) From c03570f334158d0daf162e9f300507c9d3ad4cf1 Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Mon, 9 Nov 2020 22:12:56 -0500 Subject: [PATCH 4/4] Rename method for retrieving fs type info --- sigar_windows.go | 6 +++--- sys/windows/syscall_windows.go | 6 +++--- sys/windows/syscall_windows_test.go | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sigar_windows.go b/sigar_windows.go index 7a89e0fdb..827b4ec3d 100644 --- a/sigar_windows.go +++ b/sigar_windows.go @@ -136,16 +136,16 @@ func (self *FileSystemList) Get() error { if err != nil { return errors.Wrapf(err, "GetDriveType failed") } - volumeType, err := windows.GetVolumeInfo(drive) + fsType, err := windows.GetFilesystemType(drive) if err != nil { - return errors.Wrapf(err, "GetVolumeInfo failed") + return errors.Wrapf(err, "GetFilesystemType failed") } self.List = append(self.List, FileSystem{ DirName: drive, DevName: drive, TypeName: dt.String(), - SysTypeName: volumeType, + SysTypeName: fsType, }) } return nil diff --git a/sys/windows/syscall_windows.go b/sys/windows/syscall_windows.go index 83b703944..d6d01dee2 100644 --- a/sys/windows/syscall_windows.go +++ b/sys/windows/syscall_windows.go @@ -336,15 +336,15 @@ func GetDriveType(rootPathName string) (DriveType, error) { return dt, nil } -// GetVolumeInfo returns volume informatiom at the given root path. +// GetFilesystemType returns file system type information at the given root path. // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw -func GetVolumeInfo(rootPathName string) (string, error) { +func GetFilesystemType(rootPathName string) (string, error) { rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName) if err != nil { return "", errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName) } - buffer := make([]uint16, MAX_PATH) + buffer := make([]uint16, MAX_PATH+1) success, err := _GetVolumeInformation(rootPathNamePtr, nil, 0, nil, nil, nil, &buffer[0], MAX_PATH) if !success { return "", errors.Wrap(err, "GetVolumeInformationW failed") diff --git a/sys/windows/syscall_windows_test.go b/sys/windows/syscall_windows_test.go index 91f0f74cb..bde47a82c 100644 --- a/sys/windows/syscall_windows_test.go +++ b/sys/windows/syscall_windows_test.go @@ -114,18 +114,18 @@ func TestGetDiskFreeSpaceEx(t *testing.T) { } } -func TestGetVolumeInfo(t *testing.T) { +func TestGetFilesystemType(t *testing.T) { drives, err := GetLogicalDriveStrings() if err != nil { t.Fatal(err) } for _, drive := range drives { - volumeType, err := GetVolumeInfo(drive) + volumeType, err := GetFilesystemType(drive) if err != nil { t.Fatal(err) } - t.Logf("GetVolumeInfo: %v - %v", drive, volumeType) + t.Logf("GetFilesystemType: %v - %v", drive, volumeType) } }