Skip to content

Commit e938d94

Browse files
authored
Correctly set .fileTypeSymlink on windows (swiftlang#788)
1 parent e9406cb commit e938d94

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

Sources/FoundationEssentials/FileManager/FileManager+Files.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ extension _FileManagerImpl {
555555
func attributesOfItem(atPath path: String) throws -> [FileAttributeKey : Any] {
556556
#if os(Windows)
557557
return try path.withNTPathRepresentation { pwszPath in
558-
let hFile = CreateFileW(pwszPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nil)
558+
let hFile = CreateFileW(pwszPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nil)
559559
if hFile == INVALID_HANDLE_VALUE {
560560
throw CocoaError.errorWithFilePath(path, win32: GetLastError(), reading: true)
561561
}
@@ -567,7 +567,7 @@ extension _FileManagerImpl {
567567
}
568568

569569
let dwFileType = GetFileType(hFile)
570-
let fatType: FileAttributeType = switch (dwFileType) {
570+
var fatType: FileAttributeType = switch (dwFileType) {
571571
case FILE_TYPE_CHAR: FileAttributeType.typeCharacterSpecial
572572
case FILE_TYPE_DISK:
573573
info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY
@@ -578,6 +578,16 @@ extension _FileManagerImpl {
578578
default: FileAttributeType.typeUnknown
579579
}
580580

581+
if info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
582+
// This could by a symlink, check if that's the case and update fatType if necessary
583+
var tagInfo = FILE_ATTRIBUTE_TAG_INFO()
584+
if GetFileInformationByHandleEx(hFile, FileAttributeTagInfo, &tagInfo, DWORD(MemoryLayout<FILE_ATTRIBUTE_TAG_INFO>.size)) {
585+
if tagInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK {
586+
fatType = .typeSymbolicLink
587+
}
588+
}
589+
}
590+
581591
let systemNumber = UInt64(info.dwVolumeSerialNumber)
582592
let systemFileNumber = UInt64(info.nFileIndexHigh << 32) | UInt64(info.nFileIndexLow)
583593
let referenceCount = UInt64(info.nNumberOfLinks)

Tests/FoundationEssentialsTests/FileManager/FileManagerTests.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -890,13 +890,11 @@ final class FileManagerTests : XCTestCase {
890890
XCTAssertEqual(attrs[.type] as? FileAttributeType, FileAttributeType.typeDirectory)
891891
}
892892

893-
#if !os(Windows)
894893
do {
895894
try $0.createSymbolicLink(atPath: "symlink", withDestinationPath: "file")
896895
let attrs = try $0.attributesOfItem(atPath: "symlink")
897896
XCTAssertEqual(attrs[.type] as? FileAttributeType, FileAttributeType.typeSymbolicLink)
898897
}
899-
#endif
900898
}
901899
}
902900
}

0 commit comments

Comments
 (0)