@@ -361,7 +361,7 @@ open class FileManager : NSObject {
361
361
362
362
#if os(Windows)
363
363
result [ . deviceIdentifier] = NSNumber ( value: UInt64 ( s. st_rdev) )
364
- let type = FileAttributeType ( attributes: try windowsFileAttributes ( atPath: path) )
364
+ let type = FileAttributeType ( attributes: try windowsFileAttributes ( atPath: path) , atPath : path )
365
365
#else
366
366
if let pwd = getpwuid ( s. st_uid) , pwd. pointee. pw_name != nil {
367
367
let name = String ( cString: pwd. pointee. pw_name)
@@ -937,18 +937,33 @@ public struct FileAttributeType : RawRepresentable, Equatable, Hashable {
937
937
}
938
938
939
939
#if os(Windows)
940
- internal init ( attributes: WIN32_FILE_ATTRIBUTE_DATA ) {
940
+ internal init ( attributes: WIN32_FILE_ATTRIBUTE_DATA , atPath path : String ) {
941
941
if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) == DWORD ( FILE_ATTRIBUTE_DIRECTORY) {
942
942
self = . typeDirectory
943
943
} else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DEVICE) == DWORD ( FILE_ATTRIBUTE_DEVICE) {
944
944
self = . typeCharacterSpecial
945
945
} else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_REPARSE_POINT) == DWORD ( FILE_ATTRIBUTE_REPARSE_POINT) {
946
- // FIXME(compnerd) this is a lie! It may be a junction or a hard link
947
- self = . typeSymbolicLink
948
- } else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_NORMAL) == DWORD ( FILE_ATTRIBUTE_NORMAL) {
949
- self = . typeRegular
946
+ // A reparse point may or may not actually be a symbolic link, we need to read the reparse tag
947
+ let fileHandle = path. withCString ( encodedAs: UTF16 . self) {
948
+ CreateFileW ( /*lpFileName=*/$0,
949
+ /*dwDesiredAccess=*/DWORD ( 0 ) ,
950
+ /*dwShareMode=*/DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE) ,
951
+ /*lpSecurityAttributes=*/nil ,
952
+ /*dwCreationDisposition=*/DWORD ( OPEN_EXISTING) ,
953
+ /*dwFlagsAndAttributes=*/DWORD ( FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS) ,
954
+ /*hTemplateFile=*/nil )
955
+ }
956
+ var tagInfo = FILE_ATTRIBUTE_TAG_INFO ( )
957
+ guard 0 != GetFileInformationByHandleEx ( fileHandle,
958
+ FileAttributeTagInfo,
959
+ & tagInfo,
960
+ DWORD ( MemoryLayout< FILE_ATTRIBUTE_TAG_INFO> . size) ) else {
961
+ self = . typeUnknown
962
+ return
963
+ }
964
+ self = tagInfo. ReparseTag == IO_REPARSE_TAG_SYMLINK ? . typeSymbolicLink : . typeRegular
950
965
} else {
951
- self = . typeUnknown
966
+ self = . typeRegular
952
967
}
953
968
}
954
969
#else
0 commit comments