1// Copyright 2017 Keybase Inc. All rights reserved.
2// Use of this source code is governed by a BSD
3// license that can be found in the LICENSE file.
4
5package libkbfs
6
7import (
8	"math"
9	"unsafe"
10
11	"github.com/pkg/errors"
12	"golang.org/x/sys/windows"
13)
14
15// getDiskLimits gets the disk limits for the logical disk containing
16// the given path.
17func getDiskLimits(path string) (
18	availableBytes, totalBytes, availableFiles, totalFiles uint64, err error) {
19	pathPtr, err := windows.UTF16PtrFromString(path)
20	if err != nil {
21		return 0, 0, 0, 0, errors.WithStack(err)
22	}
23
24	dll := windows.NewLazySystemDLL("kernel32.dll")
25	proc := dll.NewProc("GetDiskFreeSpaceExW")
26	r1, _, err := proc.Call(uintptr(unsafe.Pointer(pathPtr)),
27		uintptr(unsafe.Pointer(&availableBytes)),
28		uintptr(unsafe.Pointer(&totalBytes)), 0)
29	// err is always non-nil, but meaningful only when r1 == 0
30	// (which signifies function failure).
31	if r1 == 0 {
32		return 0, 0, 0, 0, errors.WithStack(err)
33	}
34
35	// TODO: According to http://superuser.com/a/104224 , on
36	// Windows, the available file limit is determined just from
37	// the filesystem type. Detect the filesystem type and use
38	// that to determine and return availableFiles.
39
40	// For now, assume all FSs on Windows are NTFS, or have
41	// similarly large file limits.
42	return availableBytes, totalBytes, math.MaxInt64, math.MaxInt64, nil
43}
44