From ec8833ecc1d77cb8faa0d1b4b120f7efb713d67e Mon Sep 17 00:00:00 2001 From: qmuntal Date: Fri, 23 Feb 2024 15:04:22 +0100 Subject: [PATCH] os: factor out newFileStatFromWin32FileAttributeData The stat function is quite long on Windows. Simplify it a bit by factoring out the creation of a fileStat from a Win32FileAttributeData. This also makes it more consistent with the creation of fileStats from other sources, which all have their own dedicated functions. Change-Id: I0443f96d892b70ce7f3b5e92c5049e4e4a240c6c Reviewed-on: https://go-review.googlesource.com/c/go/+/566435 Reviewed-by: Carlos Amedee Reviewed-by: Alex Brainman Reviewed-by: Bryan Mills LUCI-TryBot-Result: Go LUCI --- src/os/stat_windows.go | 26 +++++++++----------------- src/os/types_windows.go | 13 +++++++++++++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go index 7d0b6abfa4..fd948ab0e3 100644 --- a/src/os/stat_windows.go +++ b/src/os/stat_windows.go @@ -33,6 +33,15 @@ func stat(funcname, name string, followSurrogates bool) (FileInfo, error) { // See https://golang.org/issues/19922#issuecomment-300031421 for details. var fa syscall.Win32FileAttributeData err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa))) + if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 { + // Not a surrogate for another named entity, because it isn't any kind of reparse point. + // The information we got from GetFileAttributesEx is good enough for now. + fs := newFileStatFromWin32FileAttributeData(&fa) + if err := fs.saveInfoFromPath(name); err != nil { + return nil, err + } + return fs, nil + } // GetFileAttributesEx fails with ERROR_SHARING_VIOLATION error for // files like c:\pagefile.sys. Use FindFirstFile for such files. @@ -53,23 +62,6 @@ func stat(funcname, name string, followSurrogates bool) (FileInfo, error) { } } - if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 { - // Not a surrogate for another named entity, because it isn't any kind of reparse point. - // The information we got from GetFileAttributesEx is good enough for now. - fs := &fileStat{ - FileAttributes: fa.FileAttributes, - CreationTime: fa.CreationTime, - LastAccessTime: fa.LastAccessTime, - LastWriteTime: fa.LastWriteTime, - FileSizeHigh: fa.FileSizeHigh, - FileSizeLow: fa.FileSizeLow, - } - if err := fs.saveInfoFromPath(name); err != nil { - return nil, err - } - return fs, nil - } - // Use CreateFile to determine whether the file is a name surrogate and, if so, // save information about the link target. // Set FILE_FLAG_BACKUP_SEMANTICS so that CreateFile will create the handle diff --git a/src/os/types_windows.go b/src/os/types_windows.go index a23dee7064..5d4a669f71 100644 --- a/src/os/types_windows.go +++ b/src/os/types_windows.go @@ -76,6 +76,19 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f }, nil } +// newFileStatFromWin32FileAttributeData copies all required information +// from syscall.Win32FileAttributeData d into the newly created fileStat. +func newFileStatFromWin32FileAttributeData(d *syscall.Win32FileAttributeData) *fileStat { + return &fileStat{ + FileAttributes: d.FileAttributes, + CreationTime: d.CreationTime, + LastAccessTime: d.LastAccessTime, + LastWriteTime: d.LastWriteTime, + FileSizeHigh: d.FileSizeHigh, + FileSizeLow: d.FileSizeLow, + } +} + // newFileStatFromFileIDBothDirInfo copies all required information // from windows.FILE_ID_BOTH_DIR_INFO d into the newly created fileStat. func newFileStatFromFileIDBothDirInfo(d *windows.FILE_ID_BOTH_DIR_INFO) *fileStat { -- 2.48.1