@@ -1225,31 +1225,35 @@ public struct FileAttributeType : RawRepresentable, Equatable, Hashable {
1225
1225
1226
1226
#if os(Windows)
1227
1227
internal init ( attributes: WIN32_FILE_ATTRIBUTE_DATA , atPath path: String ) {
1228
- if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) == DWORD ( FILE_ATTRIBUTE_DIRECTORY) {
1229
- self = . typeDirectory
1230
- } else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DEVICE) == DWORD ( FILE_ATTRIBUTE_DEVICE) {
1231
- self = . typeCharacterSpecial
1232
- } else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_REPARSE_POINT) == DWORD ( FILE_ATTRIBUTE_REPARSE_POINT) {
1233
- // A reparse point may or may not actually be a symbolic link, we need to read the reparse tag
1234
- let fileHandle = path. withCString ( encodedAs: UTF16 . self) {
1235
- CreateFileW ( /*lpFileName=*/$0,
1236
- /*dwDesiredAccess=*/DWORD ( 0 ) ,
1237
- /*dwShareMode=*/DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE) ,
1238
- /*lpSecurityAttributes=*/nil ,
1239
- /*dwCreationDisposition=*/DWORD ( OPEN_EXISTING) ,
1240
- /*dwFlagsAndAttributes=*/DWORD ( FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS) ,
1241
- /*hTemplateFile=*/nil )
1242
- }
1243
- defer { CloseHandle ( fileHandle) }
1244
- var tagInfo = FILE_ATTRIBUTE_TAG_INFO ( )
1245
- guard GetFileInformationByHandleEx ( fileHandle, FileAttributeTagInfo, & tagInfo, DWORD ( MemoryLayout< FILE_ATTRIBUTE_TAG_INFO> . size) ) else {
1246
- self = . typeUnknown
1247
- return
1228
+ if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DEVICE) == DWORD ( FILE_ATTRIBUTE_DEVICE) {
1229
+ self = . typeCharacterSpecial
1230
+ } else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_REPARSE_POINT) == DWORD ( FILE_ATTRIBUTE_REPARSE_POINT) {
1231
+ // A reparse point may or may not actually be a symbolic link, we need to read the reparse tag
1232
+ let handle = path. withCString ( encodedAs: UTF16 . self) {
1233
+ CreateFileW ( $0, /*dwDesiredAccess=*/DWORD ( 0 ) , DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE) , /*lpSecurityAttributes=*/nil ,
1234
+ DWORD ( OPEN_EXISTING) , DWORD ( FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS) , /*hTemplateFile=*/nil )
1235
+ }
1236
+ guard handle != INVALID_HANDLE_VALUE else {
1237
+ self = . typeUnknown
1238
+ return
1239
+ }
1240
+ defer { CloseHandle ( handle) }
1241
+ var tagInfo = FILE_ATTRIBUTE_TAG_INFO ( )
1242
+ guard GetFileInformationByHandleEx ( handle, FileAttributeTagInfo, & tagInfo, DWORD ( MemoryLayout< FILE_ATTRIBUTE_TAG_INFO> . size) ) else {
1243
+ self = . typeUnknown
1244
+ return
1245
+ }
1246
+ self = tagInfo. ReparseTag == IO_REPARSE_TAG_SYMLINK ? . typeSymbolicLink : . typeRegular
1247
+ } else if attributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) == DWORD ( FILE_ATTRIBUTE_DIRECTORY) {
1248
+ // Note: Since Windows marks directory symlinks as both
1249
+ // directories and reparse points, having this after the
1250
+ // reparse point check implicitly encodes Windows
1251
+ // directory symlinks as not directories, which matches
1252
+ // POSIX behavior.
1253
+ self = . typeDirectory
1254
+ } else {
1255
+ self = . typeRegular
1248
1256
}
1249
- self = tagInfo. ReparseTag == IO_REPARSE_TAG_SYMLINK ? . typeSymbolicLink : . typeRegular
1250
- } else {
1251
- self = . typeRegular
1252
- }
1253
1257
}
1254
1258
#else
1255
1259
internal init ( statMode: mode_t ) {
0 commit comments