@@ -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)
0 commit comments