shirou_gopsutil/disk_windows.go

114 lines
3.3 KiB
Go
Raw Normal View History

2014-04-18 20:28:00 +08:00
// +build windows
2014-04-22 08:44:22 +08:00
package gopsutil
2014-04-18 20:28:00 +08:00
2014-04-19 23:03:47 +08:00
import (
2014-04-20 00:53:34 +08:00
"bytes"
2014-04-29 13:59:22 +08:00
"errors"
2014-04-19 23:03:47 +08:00
"syscall"
"unsafe"
)
var (
2014-04-20 00:53:34 +08:00
procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
procGetDriveType = modkernel32.NewProc("GetDriveTypeW")
provGetVolumeInformation = modkernel32.NewProc("GetVolumeInformationW")
2014-04-20 00:53:34 +08:00
)
var (
FILE_FILE_COMPRESSION = int64(16) // 0x00000010
FILE_READ_ONLY_VOLUME = int64(524288) // 0x00080000
2014-04-19 23:03:47 +08:00
)
2014-04-18 20:28:00 +08:00
2014-04-30 14:32:05 +08:00
func DiskUsage(path string) (DiskUsageStat, error) {
ret := DiskUsageStat{}
2014-04-18 20:28:00 +08:00
2014-04-19 23:03:47 +08:00
ret.Path = path
lpFreeBytesAvailable := int64(0)
lpTotalNumberOfBytes := int64(0)
lpTotalNumberOfFreeBytes := int64(0)
2014-04-20 00:53:34 +08:00
diskret, _, err := procGetDiskFreeSpaceExW.Call(
2014-04-19 23:03:47 +08:00
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
if diskret == 0 {
2014-04-20 00:53:34 +08:00
return ret, err
2014-04-19 23:03:47 +08:00
}
ret.Total = uint64(lpTotalNumberOfBytes)
// ret.Free = uint64(lpFreeBytesAvailable) // python psutil does not use this
ret.Free = uint64(lpTotalNumberOfFreeBytes)
ret.Used = ret.Total - ret.Free
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
2014-04-18 20:28:00 +08:00
return ret, nil
}
2014-04-20 00:53:34 +08:00
2014-04-30 14:32:05 +08:00
func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
2014-04-30 15:16:07 +08:00
var ret []DiskPartitionStat
2014-04-20 00:53:34 +08:00
lpBuffer := make([]byte, 254)
diskret, _, err := procGetLogicalDriveStringsW.Call(
uintptr(len(lpBuffer)),
uintptr(unsafe.Pointer(&lpBuffer[0])))
if diskret == 0 {
return ret, err
}
for _, v := range lpBuffer {
if v >= 65 && v <= 90 {
path := string(v) + ":"
if path == "A:" || path == "B:" { // skip floppy drives
continue
}
typepath, _ := syscall.UTF16PtrFromString(path)
typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath)))
if typeret == 0 {
return ret, syscall.GetLastError()
}
// 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 5: DRIVE_CDROM
if typeret == 2 || typeret == 3 || typeret == 5 {
lpVolumeNameBuffer := make([]byte, 256)
lpVolumeSerialNumber := int64(0)
lpMaximumComponentLength := int64(0)
lpFileSystemFlags := int64(0)
lpFileSystemNameBuffer := make([]byte, 256)
volpath, _ := syscall.UTF16PtrFromString(string(v) + ":/")
driveret, _, err := provGetVolumeInformation.Call(
uintptr(unsafe.Pointer(volpath)),
uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])),
uintptr(len(lpVolumeNameBuffer)),
uintptr(unsafe.Pointer(&lpVolumeSerialNumber)),
uintptr(unsafe.Pointer(&lpMaximumComponentLength)),
uintptr(unsafe.Pointer(&lpFileSystemFlags)),
uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])),
uintptr(len(lpFileSystemNameBuffer)))
if driveret == 0 {
return ret, err
}
opts := "rw"
if lpFileSystemFlags&FILE_READ_ONLY_VOLUME != 0 {
opts = "ro"
}
if lpFileSystemFlags&FILE_FILE_COMPRESSION != 0 {
opts += ".compress"
}
2014-04-30 14:32:05 +08:00
d := DiskPartitionStat{
2014-04-20 00:53:34 +08:00
Mountpoint: path,
Device: path,
Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)),
Opts: opts,
}
ret = append(ret, d)
}
}
}
return ret, nil
}
2014-04-29 13:59:22 +08:00
2014-04-30 14:32:05 +08:00
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
ret := make(map[string]DiskIOCountersStat, 0)
return ret, errors.New("not implemented yet")
2014-04-29 13:59:22 +08:00
}