@@ -742,27 +742,33 @@ extension FileManager {
742742 }
743743
744744 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
766772 }
767773
768774
0 commit comments