golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/internal/robustio/robustio_windows.go (about) 1 // Copyright 2019 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 robustio 6 7 import ( 8 "errors" 9 "syscall" 10 "time" 11 ) 12 13 const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND 14 15 // isEphemeralError returns true if err may be resolved by waiting. 16 func isEphemeralError(err error) bool { 17 var errno syscall.Errno 18 if errors.As(err, &errno) { 19 switch errno { 20 case syscall.ERROR_ACCESS_DENIED, 21 syscall.ERROR_FILE_NOT_FOUND, 22 ERROR_SHARING_VIOLATION: 23 return true 24 } 25 } 26 return false 27 } 28 29 // Note: it may be convenient to have this helper return fs.FileInfo, but 30 // implementing this is actually quite involved on Windows. Since we only 31 // currently use mtime, keep it simple. 32 func getFileID(filename string) (FileID, time.Time, error) { 33 filename16, err := syscall.UTF16PtrFromString(filename) 34 if err != nil { 35 return FileID{}, time.Time{}, err 36 } 37 h, err := syscall.CreateFile(filename16, 0, 0, nil, syscall.OPEN_EXISTING, uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS), 0) 38 if err != nil { 39 return FileID{}, time.Time{}, err 40 } 41 defer syscall.CloseHandle(h) 42 var i syscall.ByHandleFileInformation 43 if err := syscall.GetFileInformationByHandle(h, &i); err != nil { 44 return FileID{}, time.Time{}, err 45 } 46 mtime := time.Unix(0, i.LastWriteTime.Nanoseconds()) 47 return FileID{ 48 device: uint64(i.VolumeSerialNumber), 49 inode: uint64(i.FileIndexHigh)<<32 | uint64(i.FileIndexLow), 50 }, mtime, nil 51 }