mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 07:40:08 +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"
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue
Block a user