Skip to content

Commit cd25218

Browse files
committed
FoundationEssentials: retry with modified permissions
On an access denied, reset the system permissions and retry the rename. The original variant seemed to work, this reduces some of the complexity in the hopes that it is sufficiently robust.
1 parent e682286 commit cd25218

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

Sources/FoundationEssentials/Data/Data+Writing.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,19 @@ private func writeToFileAux(path inPath: PathOrURL, buffer: UnsafeRawBufferPoint
457457

458458
if !SetFileInformationByHandle(hFile, FileRenameInfoEx, pInfo, dwSize) {
459459
let dwError = GetLastError()
460+
if dwError == ERROR_ACCESS_DENIED {
461+
let dwAttributes = GetFileAttributesW(pwszPath)
462+
if dwAttributes > 0,
463+
dwAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) != 0 {
464+
if SetFileAttributesW(pwszPath, dwAttributes & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
465+
if SetFileInformationByHandle(hFile, FileRenameInfoEx, pInfo, dwSize) {
466+
return
467+
}
468+
// Try to restore the attributes, but ignore any error
469+
_ = SetFileAttributesW(pwszPath, dwAttributes)
470+
}
471+
}
472+
}
460473
guard dwError == ERROR_NOT_SAME_DEVICE else {
461474
throw CocoaError.errorWithFilePath(inPath, win32: dwError, reading: false)
462475
}

Sources/FoundationEssentials/WinSDK+Extensions.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,18 @@ package var FILE_ATTRIBUTE_READONLY: DWORD {
137137
DWORD(WinSDK.FILE_ATTRIBUTE_READONLY)
138138
}
139139

140+
package var FILE_ATTRIBUTE_HIDDEN: DWORD {
141+
DWORD(WinSDK.FILE_ATTRIBUTE_HIDDEN)
142+
}
140143

141144
package var FILE_ATTRIBUTE_REPARSE_POINT: DWORD {
142145
DWORD(WinSDK.FILE_ATTRIBUTE_REPARSE_POINT)
143146
}
144147

148+
package var FILE_ATTRIBUTE_SYSTEM: DWORD {
149+
DWORD(WinSDK.FILE_ATTRIBUTE_SYSTEM)
150+
}
151+
145152
package var FILE_FLAG_BACKUP_SEMANTICS: DWORD {
146153
DWORD(WinSDK.FILE_FLAG_BACKUP_SEMANTICS)
147154
}

0 commit comments

Comments
 (0)