diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go index 1e3b9343ee..52ef9bd4f7 100644 --- a/daemon/graphdriver/windows/windows.go +++ b/daemon/graphdriver/windows/windows.go @@ -16,12 +16,11 @@ import ( "strconv" "strings" "sync" - "syscall" "time" - "unsafe" winio "github.com/Microsoft/go-winio" "github.com/Microsoft/go-winio/backuptar" + winiofs "github.com/Microsoft/go-winio/pkg/fs" "github.com/Microsoft/go-winio/vhd" "github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim/osversion" @@ -100,7 +99,7 @@ type Driver struct { func InitFilter(home string, options []string, _ idtools.IdentityMapping) (graphdriver.Driver, error) { logrus.Debugf("WindowsGraphDriver InitFilter at %s", home) - fsType, err := getFileSystemType(string(home[0])) + fsType, err := winiofs.GetFileSystemType(home) if err != nil { return nil, err } @@ -137,37 +136,6 @@ func InitFilter(home string, options []string, _ idtools.IdentityMapping) (graph return d, nil } -// win32FromHresult is a helper function to get the win32 error code from an HRESULT -func win32FromHresult(hr uintptr) uintptr { - if hr&0x1fff0000 == 0x00070000 { - return hr & 0xffff - } - return hr -} - -// getFileSystemType obtains the type of a file system through GetVolumeInformation -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx -func getFileSystemType(drive string) (fsType string, hr error) { - var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGetVolumeInformation = modkernel32.NewProc("GetVolumeInformationW") - buf = make([]uint16, 255) - size = windows.MAX_PATH + 1 - ) - if len(drive) != 1 { - hr = errors.New("getFileSystemType must be called with a drive letter") - return - } - drive += `:\` - n := uintptr(unsafe.Pointer(nil)) - r0, _, _ := syscall.Syscall9(procGetVolumeInformation.Addr(), 8, uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(drive))), n, n, n, n, n, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0) - if int32(r0) < 0 { - hr = syscall.Errno(win32FromHresult(r0)) - } - fsType = windows.UTF16ToString(buf) - return -} - // String returns the string representation of a driver. This should match // the name the graph driver has been registered with. func (d *Driver) String() string { diff --git a/vendor/github.com/Microsoft/go-winio/pkg/fs/fs_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/fs/fs_windows.go new file mode 100644 index 0000000000..53bc797e79 --- /dev/null +++ b/vendor/github.com/Microsoft/go-winio/pkg/fs/fs_windows.go @@ -0,0 +1,31 @@ +package fs + +import ( + "errors" + "path/filepath" + + "golang.org/x/sys/windows" +) + +var ( + // ErrInvalidPath is returned when the location of a file path doesn't begin with a driver letter. + ErrInvalidPath = errors.New("the path provided to GetFileSystemType must start with a drive letter") +) + +// GetFileSystemType obtains the type of a file system through GetVolumeInformation. +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx +func GetFileSystemType(path string) (fsType string, err error) { + drive := filepath.VolumeName(path) + if len(drive) != 2 { + return "", ErrInvalidPath + } + + var ( + buf = make([]uint16, 255) + size = uint32(windows.MAX_PATH + 1) + ) + drive += `\` + err = windows.GetVolumeInformation(windows.StringToUTF16Ptr(drive), nil, 0, nil, nil, nil, &buf[0], size) + fsType = windows.UTF16ToString(buf) + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 0b0ce74db0..427e4b394b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -24,6 +24,7 @@ github.com/Microsoft/go-winio github.com/Microsoft/go-winio/backuptar github.com/Microsoft/go-winio/pkg/etw github.com/Microsoft/go-winio/pkg/etwlogrus +github.com/Microsoft/go-winio/pkg/fs github.com/Microsoft/go-winio/pkg/guid github.com/Microsoft/go-winio/pkg/security github.com/Microsoft/go-winio/vhd