@@ -582,83 +582,77 @@ extension FileManager {
582582 return
583583 }
584584
585- let faAttributes : WIN32_FILE_ATTRIBUTE_DATA
586- do {
587- faAttributes = try windowsFileAttributes ( atPath: path)
588- } catch {
589- // removeItem on POSIX throws fileNoSuchFile rather than
590- // fileReadNoSuchFile that windowsFileAttributes will
591- // throw if it doesn't find the file.
592- if ( error as NSError ) . code == CocoaError . fileReadNoSuchFile. rawValue {
593- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
594- } else {
595- throw error
596- }
597- }
598-
599- if faAttributes. dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
600- if try ! FileManager. default. _fileSystemRepresentation ( withPath: path, {
601- SetFileAttributesW ( $0, faAttributes. dwFileAttributes & ~ FILE_ATTRIBUTE_READONLY)
602- } ) {
603- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
604- }
605- }
585+ try URL ( fileURLWithPath: path) . withUnsafeFileSystemRepresentation {
586+ " \\ \\ ? \\ \( String ( cString: $0!) ) " . withCString ( encodedAs: UTF16 . self) {
587+ var faAttributes : WIN32_FILE_ATTRIBUTE_DATA = . init( )
588+ if !GetFileAttributesExW( $0, GetFileExInfoStandard, & faAttributes) {
589+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
590+ }
606591
607- if faAttributes. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0 {
608- if try ! FileManager . default . _fileSystemRepresentation ( withPath : path , DeleteFileW ) {
609- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading : false , paths : [ path ] )
610- }
611- return
612- }
592+ guard faAttributes. dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY else {
593+ if faAttributes . dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
594+ if !SetFileAttributesW ( $0 , faAttributes . dwFileAttributes & ~ FILE_ATTRIBUTE_READONLY ) {
595+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading : false , paths : [ path ] )
596+ }
597+ }
613598
614- var dirStack = [ path]
615- var itemPath = " "
616- while let currentDir = dirStack. popLast ( ) {
617- do {
618- itemPath = currentDir
619- guard alreadyConfirmed || shouldRemoveItemAtPath ( itemPath, isURL: isURL) else {
620- continue
621- }
599+ if !DeleteFileW( $0) {
600+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
601+ }
622602
623- if try FileManager . default. _fileSystemRepresentation ( withPath: itemPath, RemoveDirectoryW) {
624- continue
603+ return
625604 }
626- guard GetLastError ( ) == ERROR_DIR_NOT_EMPTY else {
627- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ itemPath] )
628- }
629- dirStack. append ( itemPath)
630605
631- let root = URL ( fileURLWithPath: itemPath, isDirectory: true )
632- try walk ( directory: root) { ( entry, attributes) in
633- if entry == " . " || entry == " .. " { return }
634-
635- let isDirectory = attributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY && attributes & FILE_ATTRIBUTE_REPARSE_POINT == 0
636- let path = root. appendingPathComponent ( entry, isDirectory: isDirectory)
637- if isDirectory {
638- dirStack. append ( path. path)
639- } else {
640- path. withUnsafeFileSystemRepresentation {
641- guard alreadyConfirmed || shouldRemoveItemAtPath ( path. path, isURL: isURL) else {
642- return
643- }
606+ var stack : [ String ] = [ path]
607+ while let directory = stack. popLast ( ) {
608+ do {
609+ guard alreadyConfirmed || shouldRemoveItemAtPath ( directory, isURL: isURL) else {
610+ continue
611+ }
644612
645- " \\ \\ ? \\ \( String ( cString: $0!) ) " . withCString ( encodedAs: UTF16 . self) {
646- if attributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
647- if !SetFileAttributesW( $0, attributes & ~ FILE_ATTRIBUTE_READONLY) {
648- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ entry] )
649- }
613+ let root = URL ( fileURLWithPath: directory, isDirectory: true )
614+ try root. withUnsafeFileSystemRepresentation {
615+ try " \\ \\ ? \\ \( String ( cString: $0!) ) " . withCString ( encodedAs: UTF16 . self) {
616+ if !RemoveDirectoryW( $0) { continue }
617+ guard GetLastError ( ) == ERROR_DIR_NOT_EMPTY else {
618+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ directory] )
650619 }
651- if !DeleteFileW( $0) {
652- throw _NSErrorWithWindowsError ( GeteLastErrro ( ) , reading: false , paths: [ entry] )
620+ stack. append ( root. path)
621+
622+ try walk ( directory: root) { ( entry, attributes) in
623+ if entry == " . " || entry == " .. " { return }
624+
625+ let isDirectory = attributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY && attributes & FILE_ATTRIBUTE_REPARSE_POINT == 0
626+ let path = root. appendingPathComponent ( entry, isDirectory: isDirectory)
627+ if isDirectory {
628+ stack. append ( path. path)
629+ } else {
630+ guard alreadyConfirmed || shouldRemoveItemAtPath ( path. path, isURL: isURL) else {
631+ return
632+ }
633+
634+ path. withUnsafeFileSystemRepresentation {
635+ " \\ \\ ? \\ \( String ( cString: $0!) ) " . withCString ( encodedAs: UTF16 . self) {
636+ if attributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
637+ if !SetFileAttributesW( $0, attributes & ~ FILE_ATTRIBUTE_READONLY) {
638+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ entry] )
639+ }
640+ }
641+ if !DeleteFileW( $0) {
642+ throw _NSErrorWithWindowsError ( GeteLastErrro ( ) , reading: false , paths: [ entry] )
643+ }
644+ }
645+ }
646+ }
653647 }
654648 }
655649 }
650+ } catch let error {
651+ if !shouldProceedAfterError( error, removingItemAtPath: directory, isURL: isURL) {
652+ throw error
653+ }
656654 }
657655 }
658- } catch {
659- if !shouldProceedAfterError( error, removingItemAtPath: itemPath, isURL: isURL) {
660- throw error
661- }
662656 }
663657 }
664658 }
0 commit comments