提交 4f591291 编写于 作者: W WAKAYAMA Shirou

implements Disk_partition on windows

上级 8204d224
......@@ -10,6 +10,13 @@ type Disk_usage struct {
UsedPercent float64 `json:"usedPercent"`
}
type Disk_partition struct {
Device string `json:"device"`
Mountpoint string `json:"mountpoint"`
Fstype string `json:"fstype"`
Opts string `json:"opts"`
}
type Disk_IO_Counters struct {
ReadCount uint64 `json:"readCount"`
WriteCount uint64 `json:"writeCount"`
......
......@@ -21,3 +21,14 @@ func TestDisk_usage(t *testing.T) {
d, _ := json.Marshal(v)
fmt.Printf("%s\n", d)
}
func TestDisk_partitions(t *testing.T) {
disk := NewDisk()
v, err := disk.Disk_partitions()
if err != nil {
t.Errorf("error %v", err)
}
d, _ := json.Marshal(v)
fmt.Printf("%s\n", d)
}
......@@ -3,13 +3,21 @@
package main
import (
"bytes"
"syscall"
"unsafe"
)
var (
procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
//GetLogicalDriveStrings, _ = syscall.GetProcAddress(modkernel32, "GetLogicalDriveStringsW")
procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
procGetDriveType = modkernel32.NewProc("GetDriveTypeW")
provGetVolumeInformation = modKernel32.NewProc("GetVolumeInformationW")
)
var (
FILE_FILE_COMPRESSION = int64(16) // 0x00000010
FILE_READ_ONLY_VOLUME = int64(524288) // 0x00080000
)
func (d Disk) Disk_usage(path string) (Disk_usage, error) {
......@@ -19,13 +27,13 @@ func (d Disk) Disk_usage(path string) (Disk_usage, error) {
lpFreeBytesAvailable := int64(0)
lpTotalNumberOfBytes := int64(0)
lpTotalNumberOfFreeBytes := int64(0)
diskret, _, _ := procGetDiskFreeSpaceExW.Call(
diskret, _, err := procGetDiskFreeSpaceExW.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
if diskret == 0 {
return ret, syscall.GetLastError()
return ret, err
}
ret.Total = uint64(lpTotalNumberOfBytes)
// ret.Free = uint64(lpFreeBytesAvailable) // python psutil does not use this
......@@ -35,3 +43,65 @@ func (d Disk) Disk_usage(path string) (Disk_usage, error) {
return ret, nil
}
func (d Disk) Disk_partitions() ([]Disk_partition, error) {
ret := make([]Disk_partition, 0)
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"
}
d := Disk_partition{
Mountpoint: path,
Device: path,
Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)),
Opts: opts,
}
ret = append(ret, d)
}
}
}
return ret, nil
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册