Skip EA processing for volumes that do not support EA
This commit is contained in:
parent
a48baf6f3a
commit
56113a8da7
2 changed files with 58 additions and 2 deletions
|
@ -53,6 +53,15 @@ var (
|
||||||
errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
|
errInvalidEaBuffer = errors.New("invalid extended attribute buffer")
|
||||||
errEaNameTooLarge = errors.New("extended attribute name too large")
|
errEaNameTooLarge = errors.New("extended attribute name too large")
|
||||||
errEaValueTooLarge = errors.New("extended attribute value too large")
|
errEaValueTooLarge = errors.New("extended attribute value too large")
|
||||||
|
|
||||||
|
kernel32dll = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
|
procGetVolumeInformationW = kernel32dll.NewProc("GetVolumeInformationW")
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// fileSupportsExtendedAttributes is a bitmask that indicates whether the file system supports extended attributes.
|
||||||
|
fileSupportsExtendedAttributes = 0x00000004
|
||||||
)
|
)
|
||||||
|
|
||||||
// ExtendedAttribute represents a single Windows EA.
|
// ExtendedAttribute represents a single Windows EA.
|
||||||
|
@ -283,3 +292,34 @@ func setFileEA(handle windows.Handle, iosb *ioStatusBlock, buf *uint8, bufLen ui
|
||||||
status = ntStatus(r0)
|
status = ntStatus(r0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathSupportsExtendedAttributes returns true if the path supports extended attributes.
|
||||||
|
func PathSupportsExtendedAttributes(path string) (bool, error) {
|
||||||
|
var (
|
||||||
|
volumeName [syscall.MAX_PATH + 1]uint16
|
||||||
|
fsName [syscall.MAX_PATH + 1]uint16
|
||||||
|
volumeSerial uint32
|
||||||
|
maxComponentLen uint32
|
||||||
|
fileSystemFlags uint32
|
||||||
|
)
|
||||||
|
utf16Path, err := windows.UTF16PtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
ret, _, err := procGetVolumeInformationW.Call(
|
||||||
|
uintptr(unsafe.Pointer(utf16Path)),
|
||||||
|
uintptr(unsafe.Pointer(&volumeName[0])),
|
||||||
|
uintptr(len(volumeName)),
|
||||||
|
uintptr(unsafe.Pointer(&volumeSerial)),
|
||||||
|
uintptr(unsafe.Pointer(&maxComponentLen)),
|
||||||
|
uintptr(unsafe.Pointer(&fileSystemFlags)),
|
||||||
|
uintptr(unsafe.Pointer(&fsName[0])),
|
||||||
|
uintptr(len(fsName)),
|
||||||
|
)
|
||||||
|
if ret == 0 {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
supportsEAs := (fileSystemFlags & fileSupportsExtendedAttributes) != 0
|
||||||
|
return supportsEAs, nil
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ var (
|
||||||
modAdvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
modAdvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
||||||
procEncryptFile = modAdvapi32.NewProc("EncryptFileW")
|
procEncryptFile = modAdvapi32.NewProc("EncryptFileW")
|
||||||
procDecryptFile = modAdvapi32.NewProc("DecryptFileW")
|
procDecryptFile = modAdvapi32.NewProc("DecryptFileW")
|
||||||
|
|
||||||
|
// eaUnsupportedVolumesMap is a map of volumes that do not support extended attributes.
|
||||||
|
eaUnsupportedVolumesMap = map[string]bool{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// mknod is not supported on Windows.
|
// mknod is not supported on Windows.
|
||||||
|
@ -358,7 +361,20 @@ func (node *Node) fillGenericAttributes(path string, fi os.FileInfo, stat *statT
|
||||||
// Also do not allow processing of extended attributes for ADS.
|
// Also do not allow processing of extended attributes for ADS.
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if !strings.HasSuffix(filepath.Clean(path), `\`) {
|
if strings.HasSuffix(filepath.Clean(path), `\`) {
|
||||||
|
// This path is a volume
|
||||||
|
supportsEAs, err := fs.PathSupportsExtendedAttributes(path)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if supportsEAs {
|
||||||
|
delete(eaUnsupportedVolumesMap, filepath.VolumeName(path))
|
||||||
|
} else {
|
||||||
|
// Add the volume to the map of volumes that do not support extended attributes.
|
||||||
|
eaUnsupportedVolumesMap[filepath.VolumeName(path)] = true
|
||||||
|
}
|
||||||
|
return supportsEAs, nil
|
||||||
|
} else {
|
||||||
// Do not process file attributes and created time for windows directories like
|
// Do not process file attributes and created time for windows directories like
|
||||||
// C:, D:
|
// C:, D:
|
||||||
// Filepath.Clean(path) ends with '\' for Windows root drives only.
|
// Filepath.Clean(path) ends with '\' for Windows root drives only.
|
||||||
|
@ -375,8 +391,8 @@ func (node *Node) fillGenericAttributes(path string, fi os.FileInfo, stat *statT
|
||||||
FileAttributes: &stat.FileAttributes,
|
FileAttributes: &stat.FileAttributes,
|
||||||
SecurityDescriptor: sd,
|
SecurityDescriptor: sd,
|
||||||
})
|
})
|
||||||
|
return !eaUnsupportedVolumesMap[filepath.VolumeName(path)], err
|
||||||
}
|
}
|
||||||
return true, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// windowsAttrsToGenericAttributes converts the WindowsAttributes to a generic attributes map using reflection
|
// windowsAttrsToGenericAttributes converts the WindowsAttributes to a generic attributes map using reflection
|
||||||
|
|
Loading…
Reference in a new issue