@@ -742,27 +742,35 @@ 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
+ if dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
752
+ // We use the `CreateFileW` here to ensure that the destination
753
+ // of the reparse point exists. The previous check would only
754
+ // ensure that the reparse point exists, not the destination of
755
+ // it.
756
+ let hFile : HANDLE = CreateFileW ( $0, 0 , FILE_SHARE_READ, nil , OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nil )
757
+ if hFile == INVALID_HANDLE_VALUE { return false }
758
+ defer { CloseHandle ( hFile) }
759
+
760
+ if let isDirectory {
761
+ var dwFileAttributes = faAttributes. dwFileAttributes
762
+ if dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
763
+ var info : BY_HANDLE_FILE_INFORMATION = . init( )
764
+ GetFileInformationByHandle ( hFile, & info)
765
+ dwFileAttributes = info. dwFileAttributes
766
+ }
767
+
768
+ isDirectory. pointee = ObjCBool ( dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY)
769
+ }
770
+ }
771
+
772
+ return true
773
+ } ) ?? false
766
774
}
767
775
768
776
0 commit comments