30
28
return nil, &PathError{"GetFileInformationByHandle", file.name, e}
33
name: basename(file.name),
34
size: mkSize(d.FileSizeHigh, d.FileSizeLow),
35
modTime: mkModTime(d.LastWriteTime),
36
mode: mkMode(d.FileAttributes),
31
name: basename(file.name),
32
sys: syscall.Win32FileAttributeData{
33
FileAttributes: d.FileAttributes,
34
CreationTime: d.CreationTime,
35
LastAccessTime: d.LastAccessTime,
36
LastWriteTime: d.LastWriteTime,
37
FileSizeHigh: d.FileSizeHigh,
38
FileSizeLow: d.FileSizeLow,
40
vol: d.VolumeSerialNumber,
41
idxhi: d.FileIndexHigh,
42
idxlo: d.FileIndexLow,
45
50
return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
47
52
if name == DevNull {
50
var d syscall.Win32FileAttributeData
51
e := syscall.GetFileAttributesEx(syscall.StringToUTF16Ptr(name), syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&d)))
53
return &devNullStat, nil
55
fs := &fileStat{name: basename(name)}
56
namep, e := syscall.UTF16PtrFromString(name)
58
return nil, &PathError{"Stat", name, e}
60
e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys)))
53
62
return nil, &PathError{"GetFileAttributesEx", name, e}
58
path = cwd + `\` + path
67
fs.path = cwd + `\` + fs.path
62
size: mkSize(d.FileSizeHigh, d.FileSizeLow),
63
modTime: mkModTime(d.LastWriteTime),
64
mode: mkMode(d.FileAttributes),
65
sys: mkSys(path, d.LastAccessTime, d.CreationTime),
69
72
// Lstat returns the FileInfo structure describing the named file.
78
// statDevNull return FileInfo structure describing DevNull file ("NUL").
79
// It creates invented data, since none of windows api will return
81
func statDevNull() (fi FileInfo, err error) {
84
mode: ModeDevice | ModeCharDevice | 0666,
86
// hopefully this will work for SameFile
94
81
// basename removes trailing slashes and the leading
95
82
// directory name and drive letter from path name.
96
83
func basename(name string) string {
175
atime, ctime syscall.Filetime
176
vol, idxhi, idxlo uint32
179
func mkSize(hi, lo uint32) int64 {
180
return int64(hi)<<32 + int64(lo)
183
func mkModTime(mtime syscall.Filetime) time.Time {
184
return time.Unix(0, mtime.Nanoseconds())
187
func mkMode(fa uint32) (m FileMode) {
188
if fa&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
191
if fa&syscall.FILE_ATTRIBUTE_READONLY != 0 {
199
func mkSys(path string, atime, ctime syscall.Filetime) *winSys {
207
func mkSysFromFI(i *syscall.ByHandleFileInformation) *winSys {
209
atime: i.LastAccessTime,
210
ctime: i.CreationTime,
211
vol: i.VolumeSerialNumber,
212
idxhi: i.FileIndexHigh,
213
idxlo: i.FileIndexLow,
217
func (s *winSys) loadFileId() error {
224
h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(s.path), 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
228
defer syscall.CloseHandle(h)
229
var i syscall.ByHandleFileInformation
230
e = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
235
s.vol = i.VolumeSerialNumber
236
s.idxhi = i.FileIndexHigh
237
s.idxlo = i.FileIndexLow
241
func sameFile(sys1, sys2 interface{}) bool {
252
return s1.vol == s2.vol && s1.idxhi == s2.idxhi && s1.idxlo == s2.idxlo
256
func atime(fi FileInfo) time.Time {
257
return time.Unix(0, fi.Sys().(*winSys).atime.Nanoseconds())