mirror of
https://github.com/rclone/rclone.git
synced 2025-02-16 23:22:57 +08:00
lib/file: check if windows long paths are enabled
This commit is contained in:
parent
c10aa6bed8
commit
3b697538f5
|
@ -9,6 +9,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OpenFile is the generalized open call; most users will use Open or Create
|
// 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 {
|
if len(path) == 0 {
|
||||||
return nil, syscall.ERROR_FILE_NOT_FOUND
|
return nil, syscall.ERROR_FILE_NOT_FOUND
|
||||||
}
|
}
|
||||||
|
|
||||||
// For windows the max path length is 260 characters
|
// 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
|
// 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")}
|
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
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFileOpenMaxPathLength(t *testing.T) {
|
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`
|
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)
|
_, err := OpenFile(path, 0644, 0644)
|
||||||
assert.Error(t, err, "mkdir: Max path length can't exceed 260")
|
assert.Error(t, err, "mkdir: Max path length can't exceed 260")
|
||||||
|
|
|
@ -19,8 +19,9 @@ import (
|
||||||
// (https://github.com/golang/go/blob/master/src/os/path.go)
|
// (https://github.com/golang/go/blob/master/src/os/path.go)
|
||||||
func MkdirAll(path string, perm os.FileMode) error {
|
func MkdirAll(path string, perm os.FileMode) error {
|
||||||
// For windows the max path length is 260 characters
|
// 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
|
// 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")}
|
return &os.PathError{Path: path, Op: "open", Err: errors.New("path length higher than 260")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,11 @@ func TestMkdirAllOnUnusedDrive(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMkdirMaxPathLength(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`
|
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)
|
err := MkdirAll(path, 0777)
|
||||||
assert.Error(t, err, "mkdir: Max path length can't exceed 260")
|
assert.Error(t, err, "mkdir: Max path length can't exceed 260")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user