@@ -12,10 +12,12 @@ import CoreFoundation
1212#if os(Windows)
1313internal func joinPath( prefix: String , suffix: String ) -> String {
1414 var pszPath : PWSTR ?
15- _ = prefix. withCString ( encodedAs: UTF16 . self) { prefix in
16- _ = suffix. withCString ( encodedAs: UTF16 . self) { suffix in
17- PathAllocCombine ( prefix, suffix, ULONG ( PATHCCH_ALLOW_LONG_PATHS . rawValue) , & pszPath)
18- }
15+
16+ guard !prefix. isEmpty else { return suffix }
17+ guard !suffix. isEmpty else { return prefix }
18+
19+ _ = try ! FileManager . default. _fileSystemRepresentation ( withPath: prefix, andPath: suffix) {
20+ PathAllocCombine ( $0, $1, ULONG ( PATHCCH_ALLOW_LONG_PATHS . rawValue) , & pszPath)
1921 }
2022
2123 let path : String = String ( decodingCString: pszPath!, as: UTF16 . self)
@@ -196,7 +198,7 @@ extension FileManager {
196198 guard path != " " else {
197199 throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . fileReadInvalidFileName. rawValue, userInfo: [ NSFilePathErrorKey : NSString ( path) ] )
198200 }
199- try ( path + " \\ * " ) . withCString ( encodedAs : UTF16 . self ) {
201+ try FileManager . default . _fileSystemRepresentation ( withPath : path + " \\ * " ) {
200202 var ffd : WIN32_FIND_DATAW = WIN32_FIND_DATAW ( )
201203
202204 let hDirectory : HANDLE = FindFirstFileW ( $0, & ffd)
@@ -250,20 +252,19 @@ extension FileManager {
250252 internal func _attributesOfFileSystem( forPath path: String ) throws -> [ FileAttributeKey : Any ] {
251253 var result : [ FileAttributeKey : Any ] = [ : ]
252254
253- try path . withCString ( encodedAs : UTF16 . self ) {
255+ try FileManager . default . _fileSystemRepresentation ( withPath : path ) {
254256 let dwLength : DWORD = GetFullPathNameW ( $0, 0 , nil , nil )
255- guard dwLength != 0 else {
257+ guard dwLength > 0 else {
256258 throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
257259 }
258- var szVolumePath : [ WCHAR ] = Array < WCHAR > ( repeating: 0 , count: Int ( dwLength + 1 ) )
259260
261+ var szVolumePath : [ WCHAR ] = Array < WCHAR > ( repeating: 0 , count: Int ( dwLength + 1 ) )
260262 guard GetVolumePathNameW ( $0, & szVolumePath, dwLength) else {
261263 throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
262264 }
263265
264266 var liTotal : ULARGE_INTEGER = ULARGE_INTEGER ( )
265267 var liFree : ULARGE_INTEGER = ULARGE_INTEGER ( )
266-
267268 guard GetDiskFreeSpaceExW ( & szVolumePath, nil , & liTotal, & liFree) else {
268269 throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ path] )
269270 }
@@ -412,24 +413,26 @@ extension FileManager {
412413 }
413414
414415 internal func _canonicalizedPath( toFileAtPath path: String ) throws -> String {
415- var hFile : HANDLE = INVALID_HANDLE_VALUE
416- path. withCString ( encodedAs: UTF16 . self) { link in
416+ let hFile : HANDLE = try FileManager . default. _fileSystemRepresentation ( withPath: path) {
417417 // BACKUP_SEMANTICS are (confusingly) required in order to receive a
418418 // handle to a directory
419- hFile = CreateFileW ( link , 0 , DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ) ,
420- nil , DWORD ( OPEN_EXISTING ) , DWORD ( FILE_FLAG_BACKUP_SEMANTICS ) ,
421- nil )
422- }
423- guard hFile != INVALID_HANDLE_VALUE else {
424- return try path . withCString ( encodedAs : UTF16 . self ) {
425- var dwLength = GetFullPathNameW ( $0 , 0 , nil , nil )
426- var szPath = Array < WCHAR > ( repeating : 0 , count : Int ( dwLength + 1 ) )
427- dwLength = GetFullPathNameW ( $0 , DWORD ( szPath . count ) , & szPath , nil )
428- guard dwLength > 0 && dwLength <= szPath . count else {
429- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading : true , paths : [ path ] )
430- }
431- return String ( decodingCString : szPath , as : UTF16 . self )
419+ CreateFileW ( $ 0, /*dwDesiredAccess=*/ DWORD ( 0 ) ,
420+ DWORD ( FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ) ,
421+ /*lpSecurityAttributes=*/ nil , DWORD ( OPEN_EXISTING ) ,
422+ DWORD ( FILE_FLAG_BACKUP_SEMANTICS ) , /*hTemplateFile=*/ nil )
423+ }
424+ if hFile == INVALID_HANDLE_VALUE {
425+ return try FileManager . default . _fileSystemRepresentation ( withPath : path ) {
426+ var dwLength = GetFullPathNameW ( $0 , 0 , nil , nil )
427+
428+ var szPath = Array < WCHAR > ( repeating : 0 , count : Int ( dwLength + 1 ) )
429+ dwLength = GetFullPathNameW ( $0 , DWORD ( szPath . count ) , & szPath , nil )
430+ guard dwLength > 0 && dwLength <= szPath . count else {
431+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading : true , paths : [ path ] )
432432 }
433+
434+ return String ( decodingCString: szPath, as: UTF16 . self)
435+ }
433436 }
434437 defer { CloseHandle ( hFile) }
435438
@@ -441,13 +444,11 @@ extension FileManager {
441444 }
442445
443446 internal func _copyRegularFile( atPath srcPath: String , toPath dstPath: String , variant: String = " Copy " ) throws {
444- try srcPath. withCString ( encodedAs: UTF16 . self) { src in
445- try dstPath. withCString ( encodedAs: UTF16 . self) { dst in
446- if !CopyFileW( src, dst, false ) {
447- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ srcPath, dstPath] )
448- }
449- }
447+ try FileManager . default. _fileSystemRepresentation ( withPath: srcPath, andPath: dstPath) {
448+ if !CopyFileW( $0, $1, false ) {
449+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: true , paths: [ srcPath, dstPath] )
450450 }
451+ }
451452 }
452453
453454 internal func _copySymlink( atPath srcPath: String , toPath dstPath: String , variant: String = " Copy " ) throws {
@@ -539,19 +540,9 @@ extension FileManager {
539540 return
540541 }
541542
542- guard path != " " else {
543- throw NSError ( domain: NSCocoaErrorDomain, code: CocoaError . fileReadInvalidFileName. rawValue, userInfo: [ NSFilePathErrorKey : NSString ( path) ] )
544- }
545-
546- let url = URL ( fileURLWithPath: path)
547- var fsrBuf : [ WCHAR ] = Array < WCHAR > ( repeating: 0 , count: Int ( MAX_PATH) )
548- _CFURLGetWideFileSystemRepresentation ( url. _cfObject, false , & fsrBuf, Int ( MAX_PATH) )
549- let length = wcsnlen_s ( & fsrBuf, fsrBuf. count)
550- let fsrPath = String ( utf16CodeUnits: & fsrBuf, count: length)
551-
552543 let faAttributes : WIN32_FILE_ATTRIBUTE_DATA
553544 do {
554- faAttributes = try windowsFileAttributes ( atPath: fsrPath )
545+ faAttributes = try windowsFileAttributes ( atPath: path )
555546 } catch {
556547 // removeItem on POSIX throws fileNoSuchFile rather than
557548 // fileReadNoSuchFile that windowsFileAttributes will
@@ -562,29 +553,33 @@ extension FileManager {
562553 throw error
563554 }
564555 }
556+
565557 if faAttributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY {
566- let readableAttributes = faAttributes. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY)
567- guard fsrPath. withCString ( encodedAs: UTF16 . self, { SetFileAttributesW ( $0, readableAttributes) } ) else {
568- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
569- }
558+ if try ! FileManager. default. _fileSystemRepresentation ( withPath: path, {
559+ SetFileAttributesW ( $0, faAttributes. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY) )
560+ } ) {
561+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
562+ }
570563 }
571564
572565 if faAttributes. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) == 0 {
573- if !fsrPath . withCString ( encodedAs : UTF16 . self , DeleteFileW) {
574- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
575- }
576- return
566+ if try ! FileManager . default . _fileSystemRepresentation ( withPath : path , DeleteFileW) {
567+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ path] )
568+ }
569+ return
577570 }
578- var dirStack = [ fsrPath]
571+
572+ var dirStack = [ path]
579573 var itemPath = " "
580574 while let currentDir = dirStack. popLast ( ) {
581575 do {
582576 itemPath = currentDir
583577 guard alreadyConfirmed || shouldRemoveItemAtPath ( itemPath, isURL: isURL) else {
584578 continue
585579 }
586- guard !itemPath. withCString ( encodedAs: UTF16 . self, RemoveDirectoryW) else {
587- continue
580+
581+ if try FileManager . default. _fileSystemRepresentation ( withPath: itemPath, RemoveDirectoryW) {
582+ continue
588583 }
589584 guard GetLastError ( ) == ERROR_DIR_NOT_EMPTY else {
590585 throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ itemPath] )
@@ -593,7 +588,7 @@ extension FileManager {
593588 var ffd : WIN32_FIND_DATAW = WIN32_FIND_DATAW ( )
594589 let capacity = MemoryLayout . size ( ofValue: ffd. cFileName)
595590
596- let handle : HANDLE = try FileManager . default. _fileSystemRepresentation ( withPath: joinPath ( prefix : itemPath, suffix : " * " ) ) {
591+ let handle : HANDLE = try FileManager . default. _fileSystemRepresentation ( withPath: itemPath + " \\ * " ) {
597592 FindFirstFileW ( $0, & ffd)
598593 }
599594 if handle == INVALID_HANDLE_VALUE {
@@ -610,10 +605,11 @@ extension FileManager {
610605
611606 itemPath = " \( currentDir) \\ \( file) "
612607 if ffd. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY {
613- let readableAttributes = ffd. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY)
614- guard itemPath. withCString ( encodedAs: UTF16 . self, { SetFileAttributesW ( $0, readableAttributes) } ) else {
615- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
616- }
608+ if try ! FileManager. default. _fileSystemRepresentation ( withPath: itemPath, {
609+ SetFileAttributesW ( $0, ffd. dwFileAttributes & DWORD ( bitPattern: ~ FILE_ATTRIBUTE_READONLY) )
610+ } ) {
611+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
612+ }
617613 }
618614
619615 if ( ffd. dwFileAttributes & DWORD ( FILE_ATTRIBUTE_DIRECTORY) != 0 ) {
@@ -624,8 +620,8 @@ extension FileManager {
624620 guard alreadyConfirmed || shouldRemoveItemAtPath ( itemPath, isURL: isURL) else {
625621 continue
626622 }
627- if !itemPath . withCString ( encodedAs : UTF16 . self , DeleteFileW) {
628- throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
623+ if try ! FileManager . default . _fileSystemRepresentation ( withPath : itemPath , DeleteFileW) {
624+ throw _NSErrorWithWindowsError ( GetLastError ( ) , reading: false , paths: [ file] )
629625 }
630626 }
631627 } while FindNextFileW ( handle, & ffd)
@@ -936,7 +932,7 @@ extension FileManager {
936932 var ffd = WIN32_FIND_DATAW ( )
937933 let capacity = MemoryLayout . size ( ofValue: ffd. cFileName)
938934
939- let handle = ( try ? FileManager . default. _fileSystemRepresentation ( withPath: joinPath ( prefix : _lastReturned. path, suffix : " * " ) ) {
935+ let handle = ( try ? FileManager . default. _fileSystemRepresentation ( withPath: _lastReturned. path + " \\ * " ) {
940936 FindFirstFileW ( $0, & ffd)
941937 } ) ?? INVALID_HANDLE_VALUE
942938 if handle == INVALID_HANDLE_VALUE { return firstValidItem ( ) }
0 commit comments