Skip to content

Commit 1e50a03

Browse files
committed
Foundation: add some type conversion extensions for Windows
The file attribute flags are used extensively in the file manipulation code. Explicitly converting to the value to `DWORD` adds no value and clutters the code. Provide an internal overload to translate the type appropriately.
1 parent b70418c commit 1e50a03

6 files changed

+77
-41
lines changed

Sources/Foundation/CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ add_library(Foundation
146146
URLQueryItem.swift
147147
URLResourceKey.swift
148148
UserDefaults.swift
149-
UUID.swift)
149+
UUID.swift
150+
WinSDK+Extensions.swift)
150151
target_compile_definitions(Foundation PRIVATE
151152
DEPLOYMENT_RUNTIME_SWIFT)
152153
target_compile_options(Foundation PUBLIC

Sources/Foundation/FileHandle.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ extension FileHandle {
880880
if error == ERROR_ACCESS_DENIED {
881881
var fileInfo = BY_HANDLE_FILE_INFORMATION()
882882
GetFileInformationByHandle(self._handle, &fileInfo)
883-
if fileInfo.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY) {
883+
if fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY {
884884
translatedError = Int32(ERROR_DIRECTORY_NOT_SUPPORTED)
885885
}
886886
}

Sources/Foundation/FileManager+Win32.swift

+32-32
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ extension FileManager {
228228

229229
try _contentsOfDir(atPath: path, { (entryName, entryType) throws in
230230
contents.append(entryName)
231-
if entryType & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY
232-
&& entryType & FILE_ATTRIBUTE_REPARSE_POINT != FILE_ATTRIBUTE_REPARSE_POINT {
231+
if DWORD(entryType) & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY
232+
&& DWORD(entryType) & FILE_ATTRIBUTE_REPARSE_POINT != FILE_ATTRIBUTE_REPARSE_POINT {
233233
let subPath: String = joinPath(prefix: path, suffix: entryName)
234234
let entries = try subpathsOfDirectory(atPath: subPath)
235235
contents.append(contentsOf: entries.map { joinPath(prefix: entryName, suffix: $0).standardizingPath })
@@ -313,7 +313,7 @@ extension FileManager {
313313
guard let faAttributes = try? windowsFileAttributes(atPath: resolvedDest) else {
314314
throw _NSErrorWithWindowsError(GetLastError(), reading: true, paths: [path, destPath])
315315
}
316-
if faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY) {
316+
if faAttributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY {
317317
dwFlags |= DWORD(SYMBOLIC_LINK_FLAG_DIRECTORY)
318318
}
319319
}
@@ -327,7 +327,7 @@ extension FileManager {
327327

328328
internal func _destinationOfSymbolicLink(atPath path: String) throws -> String {
329329
let faAttributes = try windowsFileAttributes(atPath: path)
330-
guard faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == DWORD(FILE_ATTRIBUTE_REPARSE_POINT) else {
330+
guard faAttributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT else {
331331
throw _NSErrorWithWindowsError(DWORD(ERROR_BAD_ARGUMENTS), reading: false)
332332
}
333333

@@ -484,12 +484,12 @@ extension FileManager {
484484

485485
internal func _copySymlink(atPath srcPath: String, toPath dstPath: String, variant: String = "Copy") throws {
486486
let faAttributes: WIN32_FILE_ATTRIBUTE_DATA = try windowsFileAttributes(atPath: srcPath)
487-
guard faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == DWORD(FILE_ATTRIBUTE_REPARSE_POINT) else {
487+
guard faAttributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT else {
488488
throw _NSErrorWithErrno(EINVAL, reading: true, path: srcPath, extraUserInfo: extraErrorInfo(srcPath: srcPath, dstPath: dstPath, userVariant: variant))
489489
}
490490

491491
let destination = try destinationOfSymbolicLink(atPath: srcPath)
492-
let isDir = try windowsFileAttributes(atPath: srcPath).dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY)
492+
let isDir = try windowsFileAttributes(atPath: srcPath).dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY
493493
if fileExists(atPath: dstPath) {
494494
try removeItem(atPath: dstPath)
495495
}
@@ -585,15 +585,15 @@ extension FileManager {
585585
}
586586
}
587587

588-
if faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY {
588+
if faAttributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
589589
if try !FileManager.default._fileSystemRepresentation(withPath: path, {
590-
SetFileAttributesW($0, faAttributes.dwFileAttributes & ~DWORD(FILE_ATTRIBUTE_READONLY))
590+
SetFileAttributesW($0, faAttributes.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)
591591
}) {
592592
throw _NSErrorWithWindowsError(GetLastError(), reading: false, paths: [path])
593593
}
594594
}
595595

596-
if faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == 0 {
596+
if faAttributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == 0 {
597597
if try !FileManager.default._fileSystemRepresentation(withPath: path, DeleteFileW) {
598598
throw _NSErrorWithWindowsError(GetLastError(), reading: false, paths: [path])
599599
}
@@ -635,15 +635,15 @@ extension FileManager {
635635
}
636636

637637
itemPath = "\(currentDir)\\\(file)"
638-
if ffd.dwFileAttributes & DWORD(FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY {
638+
if ffd.dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
639639
if try !FileManager.default._fileSystemRepresentation(withPath: itemPath, {
640-
SetFileAttributesW($0, ffd.dwFileAttributes & ~DWORD(FILE_ATTRIBUTE_READONLY))
640+
SetFileAttributesW($0, ffd.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)
641641
}) {
642642
throw _NSErrorWithWindowsError(GetLastError(), reading: false, paths: [file])
643643
}
644644
}
645645

646-
if (ffd.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) != 0) {
646+
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0) {
647647
if file != "." && file != ".." {
648648
dirStack.append(itemPath)
649649
}
@@ -682,7 +682,7 @@ extension FileManager {
682682
internal func _fileExists(atPath path: String, isDirectory: UnsafeMutablePointer<ObjCBool>?) -> Bool {
683683
var faAttributes: WIN32_FILE_ATTRIBUTE_DATA = WIN32_FILE_ATTRIBUTE_DATA()
684684
do { faAttributes = try windowsFileAttributes(atPath: path) } catch { return false }
685-
if faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == DWORD(FILE_ATTRIBUTE_REPARSE_POINT) {
685+
if faAttributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
686686
let handle: HANDLE = (try? FileManager.default._fileSystemRepresentation(withPath: path) {
687687
CreateFileW($0, /* dwDesiredAccess= */ DWORD(0),
688688
DWORD(FILE_SHARE_READ), /* lpSecurityAttributes= */ nil,
@@ -695,11 +695,11 @@ extension FileManager {
695695
if let isDirectory = isDirectory {
696696
var info: BY_HANDLE_FILE_INFORMATION = BY_HANDLE_FILE_INFORMATION()
697697
GetFileInformationByHandle(handle, &info)
698-
isDirectory.pointee = ObjCBool(info.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY))
698+
isDirectory.pointee = ObjCBool(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY)
699699
}
700700
} else {
701701
if let isDirectory = isDirectory {
702-
isDirectory.pointee = ObjCBool(faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY))
702+
isDirectory.pointee = ObjCBool(faAttributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY)
703703
}
704704
}
705705
return true
@@ -713,7 +713,7 @@ extension FileManager {
713713

714714
internal func _isWritableFile(atPath path: String) -> Bool {
715715
guard let faAttributes: WIN32_FILE_ATTRIBUTE_DATA = try? windowsFileAttributes(atPath: path) else { return false }
716-
return faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_READONLY) != DWORD(FILE_ATTRIBUTE_READONLY)
716+
return faAttributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY != FILE_ATTRIBUTE_READONLY
717717
}
718718

719719
internal func _isExecutableFile(atPath path: String) -> Bool {
@@ -730,12 +730,12 @@ extension FileManager {
730730
let parent = path._nsObject.deletingLastPathComponent
731731
var faAttributes: WIN32_FILE_ATTRIBUTE_DATA = WIN32_FILE_ATTRIBUTE_DATA()
732732
do { faAttributes = try windowsFileAttributes(atPath: parent) } catch { return false }
733-
if faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_READONLY) == DWORD(FILE_ATTRIBUTE_READONLY) {
733+
if faAttributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
734734
return false
735735
}
736736

737737
do { faAttributes = try windowsFileAttributes(atPath: path) } catch { return false }
738-
if faAttributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_READONLY) == DWORD(FILE_ATTRIBUTE_READONLY) {
738+
if faAttributes.dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY {
739739
return false
740740
}
741741

@@ -785,15 +785,15 @@ extension FileManager {
785785
statInfo.st_ino = 0
786786
statInfo.st_rdev = _dev_t(info.dwVolumeSerialNumber)
787787

788-
let isReparsePoint = info.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) != 0
789-
let isDir = info.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) != 0
788+
let isReparsePoint = info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT != 0
789+
let isDir = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0
790790
let fileMode = isDir ? _S_IFDIR : _S_IFREG
791791
// On a symlink to a directory, Windows sets both the REPARSE_POINT and
792792
// DIRECTORY attributes. Since Windows doesn't provide S_IFLNK and we
793793
// want unix style "symlinks to directories are not directories
794794
// themselves, we say symlinks are regular files
795795
statInfo.st_mode = UInt16(isReparsePoint ? _S_IFREG : fileMode)
796-
let isReadOnly = info.dwFileAttributes & DWORD(FILE_ATTRIBUTE_READONLY) != 0
796+
let isReadOnly = info.dwFileAttributes & FILE_ATTRIBUTE_READONLY != 0
797797
statInfo.st_mode |= UInt16(isReadOnly ? _S_IREAD : (_S_IREAD | _S_IWRITE))
798798
statInfo.st_mode |= UInt16(_S_IEXEC)
799799

@@ -860,21 +860,21 @@ extension FileManager {
860860

861861
let path1Attrs = path1FileInfo.dwFileAttributes
862862
let path2Attrs = path2FileInfo.dwFileAttributes
863-
if path1Attrs & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT
864-
|| path2Attrs & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT {
865-
guard path1Attrs & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT
866-
&& path2Attrs & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT else {
863+
if path1Attrs & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT
864+
|| path2Attrs & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
865+
guard path1Attrs & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT
866+
&& path2Attrs & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT else {
867867
return false
868868
}
869869
guard let pathDest1 = try? _destinationOfSymbolicLink(atPath: path1),
870870
let pathDest2 = try? _destinationOfSymbolicLink(atPath: path2) else {
871871
return false
872872
}
873873
return pathDest1 == pathDest2
874-
} else if DWORD(FILE_ATTRIBUTE_DIRECTORY) & path1Attrs == DWORD(FILE_ATTRIBUTE_DIRECTORY)
875-
|| DWORD(FILE_ATTRIBUTE_DIRECTORY) & path2Attrs == DWORD(FILE_ATTRIBUTE_DIRECTORY) {
876-
guard DWORD(FILE_ATTRIBUTE_DIRECTORY) & path1Attrs == DWORD(FILE_ATTRIBUTE_DIRECTORY)
877-
&& DWORD(FILE_ATTRIBUTE_DIRECTORY) & path2Attrs == FILE_ATTRIBUTE_DIRECTORY else {
874+
} else if FILE_ATTRIBUTE_DIRECTORY & path1Attrs == FILE_ATTRIBUTE_DIRECTORY
875+
|| FILE_ATTRIBUTE_DIRECTORY & path2Attrs == FILE_ATTRIBUTE_DIRECTORY {
876+
guard FILE_ATTRIBUTE_DIRECTORY & path1Attrs == FILE_ATTRIBUTE_DIRECTORY
877+
&& FILE_ATTRIBUTE_DIRECTORY & path2Attrs == FILE_ATTRIBUTE_DIRECTORY else {
878878
return false
879879
}
880880
return _compareDirectories(atPath: path1, andPath: path2)
@@ -966,8 +966,8 @@ extension FileManager {
966966
return firstValidItem()
967967
}
968968

969-
let isDir = attrs.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY) &&
970-
attrs.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == 0
969+
let isDir = attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY &&
970+
attrs.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == 0
971971
if isDir && (level == 0 || !_options.contains(.skipsSubdirectoryDescendants)) {
972972
var ffd = WIN32_FIND_DATAW()
973973
let capacity = MemoryLayout.size(ofValue: ffd.cFileName)
@@ -986,7 +986,7 @@ extension FileManager {
986986
}
987987
if file == "." || file == ".." { continue }
988988
if _options.contains(.skipsHiddenFiles) &&
989-
ffd.dwFileAttributes & DWORD(FILE_ATTRIBUTE_HIDDEN) == DWORD(FILE_ATTRIBUTE_HIDDEN) {
989+
ffd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN == FILE_ATTRIBUTE_HIDDEN {
990990
continue
991991
}
992992
_stack.append(URL(fileURLWithPath: file, relativeTo: _lastReturned))

Sources/Foundation/FileManager.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,8 @@ open class FileManager : NSObject {
431431
}
432432

433433
let hiddenAttrs = isHidden
434-
? attrs | DWORD(FILE_ATTRIBUTE_HIDDEN)
435-
: attrs & ~DWORD(FILE_ATTRIBUTE_HIDDEN)
434+
? attrs | FILE_ATTRIBUTE_HIDDEN
435+
: attrs & ~FILE_ATTRIBUTE_HIDDEN
436436
guard SetFileAttributesW(fsRep, hiddenAttrs) else {
437437
throw _NSErrorWithWindowsError(GetLastError(), reading: false, paths: [path])
438438
}
@@ -604,7 +604,7 @@ open class FileManager : NSObject {
604604

605605
#if os(Windows)
606606
let attrs = attributes.dwFileAttributes
607-
result[._hidden] = attrs & DWORD(FILE_ATTRIBUTE_HIDDEN) != 0
607+
result[._hidden] = attrs & FILE_ATTRIBUTE_HIDDEN != 0
608608
#endif
609609
result[.ownerAccountID] = NSNumber(value: UInt64(s.st_uid))
610610
result[.groupOwnerAccountID] = NSNumber(value: UInt64(s.st_gid))
@@ -1295,9 +1295,9 @@ public struct FileAttributeType : RawRepresentable, Equatable, Hashable {
12951295

12961296
#if os(Windows)
12971297
internal init(attributes: WIN32_FILE_ATTRIBUTE_DATA, atPath path: String) {
1298-
if attributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DEVICE) == DWORD(FILE_ATTRIBUTE_DEVICE) {
1298+
if attributes.dwFileAttributes & FILE_ATTRIBUTE_DEVICE == FILE_ATTRIBUTE_DEVICE {
12991299
self = .typeCharacterSpecial
1300-
} else if attributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_REPARSE_POINT) == DWORD(FILE_ATTRIBUTE_REPARSE_POINT) {
1300+
} else if attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT {
13011301
// A reparse point may or may not actually be a symbolic link, we need to read the reparse tag
13021302
let handle: HANDLE = (try? FileManager.default._fileSystemRepresentation(withPath: path) {
13031303
CreateFileW($0, /*dwDesiredAccess=*/DWORD(0),
@@ -1318,7 +1318,7 @@ public struct FileAttributeType : RawRepresentable, Equatable, Hashable {
13181318
return
13191319
}
13201320
self = tagInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK ? .typeSymbolicLink : .typeRegular
1321-
} else if attributes.dwFileAttributes & DWORD(FILE_ATTRIBUTE_DIRECTORY) == DWORD(FILE_ATTRIBUTE_DIRECTORY) {
1321+
} else if attributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY {
13221322
// Note: Since Windows marks directory symlinks as both
13231323
// directories and reparse points, having this after the
13241324
// reparse point check implicitly encodes Windows

Sources/Foundation/NSPathUtilities.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ internal func _NSCreateTemporaryFile(_ filePath: String) throws -> (Int32, Strin
767767
DWORD(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
768768
nil,
769769
DWORD(OPEN_EXISTING),
770-
DWORD(FILE_ATTRIBUTE_NORMAL),
770+
FILE_ATTRIBUTE_NORMAL,
771771
nil),
772772
h != INVALID_HANDLE_VALUE else {
773773
throw _NSErrorWithWindowsError(GetLastError(), reading: false)
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See https://swift.org/LICENSE.txt for license information
7+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
9+
#if os(Windows)
10+
import WinSDK
11+
12+
internal var FILE_ATTRIBUTE_DEVICE: DWORD {
13+
DWORD(WinSDK.FILE_ATTRIBUTE_DEVICE)
14+
}
15+
16+
internal var FILE_ATTRIBUTE_DIRECTORY: DWORD {
17+
DWORD(WinSDK.FILE_ATTRIBUTE_DIRECTORY)
18+
}
19+
20+
internal var FILE_ATTRIBUTE_NORMAL: DWORD {
21+
DWORD(WinSDK.FILE_ATTRIBUTE_NORMAL)
22+
}
23+
24+
internal var FILE_ATTRIBUTE_HIDDEN: DWORD {
25+
DWORD(WinSDK.FILE_ATTRIBUTE_HIDDEN)
26+
}
27+
28+
internal var FILE_ATTRIBUTE_READONLY: DWORD {
29+
DWORD(WinSDK.FILE_ATTRIBUTE_READONLY)
30+
}
31+
32+
internal var FILE_ATTRIBUTE_REPARSE_POINT: DWORD {
33+
DWORD(WinSDK.FILE_ATTRIBUTE_REPARSE_POINT)
34+
}
35+
#endif

0 commit comments

Comments
 (0)