github.com/robhaswell/grandperspective-scan@v0.1.0/test/go-go1.7.1/src/os/types_windows.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package os 6 7 import ( 8 "sync" 9 "syscall" 10 "time" 11 ) 12 13 // A fileStat is the implementation of FileInfo returned by Stat and Lstat. 14 type fileStat struct { 15 name string 16 sys syscall.Win32FileAttributeData 17 pipe bool 18 19 // used to implement SameFile 20 sync.Mutex 21 path string 22 vol uint32 23 idxhi uint32 24 idxlo uint32 25 } 26 27 func (fs *fileStat) Size() int64 { 28 return int64(fs.sys.FileSizeHigh)<<32 + int64(fs.sys.FileSizeLow) 29 } 30 31 func (fs *fileStat) Mode() (m FileMode) { 32 if fs == &devNullStat { 33 return ModeDevice | ModeCharDevice | 0666 34 } 35 if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { 36 m |= ModeDir | 0111 37 } 38 if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 { 39 m |= 0444 40 } else { 41 m |= 0666 42 } 43 if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 { 44 m |= ModeSymlink 45 } 46 if fs.pipe { 47 m |= ModeNamedPipe 48 } 49 return m 50 } 51 52 func (fs *fileStat) ModTime() time.Time { 53 return time.Unix(0, fs.sys.LastWriteTime.Nanoseconds()) 54 } 55 56 // Sys returns syscall.Win32FileAttributeData for file fs. 57 func (fs *fileStat) Sys() interface{} { return &fs.sys } 58 59 func (fs *fileStat) loadFileId() error { 60 fs.Lock() 61 defer fs.Unlock() 62 if fs.path == "" { 63 // already done 64 return nil 65 } 66 pathp, err := syscall.UTF16PtrFromString(fs.path) 67 if err != nil { 68 return err 69 } 70 h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) 71 if err != nil { 72 return err 73 } 74 defer syscall.CloseHandle(h) 75 var i syscall.ByHandleFileInformation 76 err = syscall.GetFileInformationByHandle(h, &i) 77 if err != nil { 78 return err 79 } 80 fs.path = "" 81 fs.vol = i.VolumeSerialNumber 82 fs.idxhi = i.FileIndexHigh 83 fs.idxlo = i.FileIndexLow 84 return nil 85 } 86 87 // devNullStat is fileStat structure describing DevNull file ("NUL"). 88 var devNullStat = fileStat{ 89 name: DevNull, 90 // hopefully this will work for SameFile 91 vol: 0, 92 idxhi: 0, 93 idxlo: 0, 94 } 95 96 func sameFile(fs1, fs2 *fileStat) bool { 97 e := fs1.loadFileId() 98 if e != nil { 99 return false 100 } 101 e = fs2.loadFileId() 102 if e != nil { 103 return false 104 } 105 return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo 106 } 107 108 // For testing. 109 func atime(fi FileInfo) time.Time { 110 return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds()) 111 }