|
| 1 | +// SPDX-License-Identifier: MIT |
| 2 | +// Copyright (c) 2023 Yousong Zhou |
| 3 | +package sysdep |
| 4 | + |
| 5 | +import ( |
| 6 | + "syscall" |
| 7 | +) |
| 8 | + |
| 9 | +func fiSysGetCtime(sys any) int64 { |
| 10 | + attr, ok := sys.(*syscall.Win32FileAttributeData) |
| 11 | + if !ok { |
| 12 | + return -1 |
| 13 | + } |
| 14 | + nsec := attr.CreationTime.Nanoseconds() |
| 15 | + sec := nsec / (1e9) |
| 16 | + return sec |
| 17 | +} |
| 18 | + |
| 19 | +func fileIdByPath(p string) (uint64, error) { |
| 20 | + pathp, err := syscall.UTF16PtrFromString(p) |
| 21 | + if err != nil { |
| 22 | + return 0, err |
| 23 | + } |
| 24 | + |
| 25 | + // Per https://learn.microsoft.com/en-us/windows/win32/fileio/reparse-points-and-file-operations, |
| 26 | + // “Applications that use the CreateFile function should specify the |
| 27 | + // FILE_FLAG_OPEN_REPARSE_POINT flag when opening the file if it is a reparse |
| 28 | + // point.” |
| 29 | + // |
| 30 | + // And per https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew, |
| 31 | + // “If the file is not a reparse point, then this flag is ignored.” |
| 32 | + // |
| 33 | + // So we set FILE_FLAG_OPEN_REPARSE_POINT unconditionally, since we want |
| 34 | + // information about the reparse point itself. |
| 35 | + // |
| 36 | + // If the file is a symlink, the symlink target should have already been |
| 37 | + // resolved when the fileStat was created, so we don't need to worry about |
| 38 | + // resolving symlink reparse points again here. |
| 39 | + attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS | syscall.FILE_FLAG_OPEN_REPARSE_POINT) |
| 40 | + |
| 41 | + h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0) |
| 42 | + if err != nil { |
| 43 | + return 0, err |
| 44 | + } |
| 45 | + defer syscall.CloseHandle(h) |
| 46 | + var i syscall.ByHandleFileInformation |
| 47 | + err = syscall.GetFileInformationByHandle(h, &i) |
| 48 | + if err != nil { |
| 49 | + return 0, err |
| 50 | + } |
| 51 | + fileIndex := (uint64(i.FileIndexHigh) << 32) | uint64(i.FileIndexLow) |
| 52 | + return fileIndex, nil |
| 53 | +} |
0 commit comments