lib/file: check if windows long paths are enabled

This commit is contained in:
Herlon Aguiar 2021-12-07 20:52:28 +01:00
parent c10aa6bed8
commit 3b697538f5
4 changed files with 38 additions and 2 deletions

View File

@ -9,6 +9,8 @@ import (
"path/filepath"
"regexp"
"syscall"
"golang.org/x/sys/windows/registry"
)
// OpenFile is the generalized open call; most users will use Open or Create
@ -28,9 +30,11 @@ func OpenFile(path string, mode int, perm os.FileMode) (*os.File, error) {
if len(path) == 0 {
return nil, syscall.ERROR_FILE_NOT_FOUND
}
// For windows the max path length is 260 characters
// if the LongPathsEnabled is not set
// https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
if len(path) >= 260 {
if !IsLongPathsEnabled() && len(path) >= 260 {
return nil, &os.PathError{Path: path, Op: "open", Err: errors.New("path length higher than 260")}
}
@ -107,3 +111,24 @@ func IsReserved(path string) error {
}
return nil
}
// IsLongPathsEnabled checks if the current have the LongPathsEnabled enabled
func IsLongPathsEnabled() bool {
// Read registry
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\FileSystem`, registry.QUERY_VALUE)
if err != nil {
return false
}
defer k.Close()
s, _, err := k.GetIntegerValue("LongPathsEnabled")
if err != nil {
return false
}
if s == 0x00000001 {
return true
} else {
return false
}
}

View File

@ -10,6 +10,11 @@ import (
)
func TestFileOpenMaxPathLength(t *testing.T) {
// Skip if the long path is enabled
if IsLongPathsEnabled() {
t.Skip()
}
path := `C:\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path`
_, err := OpenFile(path, 0644, 0644)
assert.Error(t, err, "mkdir: Max path length can't exceed 260")

View File

@ -19,8 +19,9 @@ import (
// (https://github.com/golang/go/blob/master/src/os/path.go)
func MkdirAll(path string, perm os.FileMode) error {
// For windows the max path length is 260 characters
// if the LongPathsEnabled is not set
// https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
if len(path) >= 260 {
if !IsLongPathsEnabled() && len(path) >= 260 {
return &os.PathError{Path: path, Op: "open", Err: errors.New("path length higher than 260")}
}

View File

@ -132,6 +132,11 @@ func TestMkdirAllOnUnusedDrive(t *testing.T) {
}
func TestMkdirMaxPathLength(t *testing.T) {
// Skip if the long path is enabled
if IsLongPathsEnabled() {
t.Skip()
}
path := `C:\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path\my\path`
err := MkdirAll(path, 0777)
assert.Error(t, err, "mkdir: Max path length can't exceed 260")