From b09406accb4736d857a32bf9444cd7edae2ffa79 Mon Sep 17 00:00:00 2001 From: Takuto Ikuta Date: Thu, 10 Oct 2019 18:17:53 +0900 Subject: [PATCH] windows: add GetDiskFreeSpaceEx function ref: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexw Change-Id: If57b0777106a2253e4287818d2c5aee2d6be13d3 Reviewed-on: https://go-review.googlesource.com/c/sys/+/200257 Run-TryBot: Jason A. Donenfeld TryBot-Result: Gobot Gobot Reviewed-by: Jason A. Donenfeld --- windows/syscall_windows.go | 1 + windows/syscall_windows_test.go | 21 +++++++++++++++++++++ windows/zsyscall_windows.go | 13 +++++++++++++ 3 files changed, 35 insertions(+) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 33513e34..df0ffc69 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -290,6 +290,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) = FindNextVolumeMountPointW //sys FindVolumeClose(findVolume Handle) (err error) //sys FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) +//sys GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = GetDiskFreeSpaceExW //sys GetDriveType(rootPathName *uint16) (driveType uint32) = GetDriveTypeW //sys GetLogicalDrives() (drivesBitMask uint32, err error) [failretval==0] //sys GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) [failretval==0] = GetLogicalDriveStringsW diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index a63df60b..7f232164 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -356,3 +356,24 @@ func TestBuildSecurityDescriptor(t *testing.T) { t.Fatalf("SD = %q; want %q", got, want) } } + +func TestGetDiskFreeSpaceEx(t *testing.T) { + cwd, err := windows.UTF16PtrFromString(".") + if err != nil { + t.Fatalf(`failed to call UTF16PtrFromString("."): %v`, err) + } + var freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes uint64 + if err := windows.GetDiskFreeSpaceEx(cwd, &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes); err != nil { + t.Fatalf("failed to call GetDiskFreeSpaceEx: %v", err) + } + + if freeBytesAvailableToCaller == 0 { + t.Errorf("freeBytesAvailableToCaller: got 0; want > 0") + } + if totalNumberOfBytes == 0 { + t.Errorf("totalNumberOfBytes: got 0; want > 0") + } + if totalNumberOfFreeBytes == 0 { + t.Errorf("totalNumberOfFreeBytes: got 0; want > 0") + } +} diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index ace2c19e..74d721e0 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -224,6 +224,7 @@ var ( procFindNextVolumeMountPointW = modkernel32.NewProc("FindNextVolumeMountPointW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") @@ -2503,6 +2504,18 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { return } +func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { + r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + func GetDriveType(rootPathName *uint16) (driveType uint32) { r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) driveType = uint32(r0)