@@ -742,27 +742,33 @@ extension FileManager {
742
742
}
743
743
744
744
internal func _fileExists( atPath path: String , isDirectory: UnsafeMutablePointer < ObjCBool > ? ) -> Bool {
745
- var faAttributes : WIN32_FILE_ATTRIBUTE_DATA = WIN32_FILE_ATTRIBUTE_DATA ( )
746
- do { faAttributes = try windowsFileAttributes ( atPath: path) } catch { return false }
747
- if faAttributes. dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
748
- let handle : HANDLE = ( try ? FileManager . default. _fileSystemRepresentation ( withPath: path) {
749
- CreateFileW ( $0, 0 , FILE_SHARE_READ, nil , OPEN_EXISTING,
750
- FILE_FLAG_BACKUP_SEMANTICS, nil )
751
- } ) ?? INVALID_HANDLE_VALUE
752
- if handle == INVALID_HANDLE_VALUE { return false }
753
- defer { CloseHandle ( handle) }
754
-
755
- if let isDirectory = isDirectory {
756
- var info : BY_HANDLE_FILE_INFORMATION = BY_HANDLE_FILE_INFORMATION ( )
757
- GetFileInformationByHandle ( handle, & info)
758
- isDirectory. pointee = ObjCBool ( info. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY)
759
- }
760
- } else {
761
- if let isDirectory = isDirectory {
762
- isDirectory. pointee = ObjCBool ( faAttributes. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY)
763
- }
764
- }
765
- return true
745
+ return ( try ? withNTPathRepresentation ( of: path) {
746
+ var faAttributes : WIN32_FILE_ATTRIBUTE_DATA = . init( )
747
+ guard GetFileAttributesExW ( $0, GetFileExInfoStandard, & faAttributes) else {
748
+ return false
749
+ }
750
+
751
+ var dwFileAttributes = faAttributes. dwFileAttributes
752
+ if dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
753
+ // We use the `CreateFileW` here to ensure that the destination
754
+ // of the reparse point exists. The previous check would only
755
+ // ensure that the reparse point exists, not the destination of
756
+ // it.
757
+ let hFile : HANDLE = CreateFileW ( $0, 0 , FILE_SHARE_READ, nil , OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nil )
758
+ if hFile == INVALID_HANDLE_VALUE { return false }
759
+ defer { CloseHandle ( hFile) }
760
+
761
+ var info : BY_HANDLE_FILE_INFORMATION = . init( )
762
+ GetFileInformationByHandle ( hFile, & info)
763
+ dwFileAttributes = info. dwFileAttributes
764
+ }
765
+
766
+ if let isDirectory {
767
+ isDirectory. pointee = ObjCBool ( dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY)
768
+ }
769
+
770
+ return true
771
+ } ) ?? false
766
772
}
767
773
768
774
0 commit comments