diff --git a/Sources/FoundationEssentials/Data/Data+Writing.swift b/Sources/FoundationEssentials/Data/Data+Writing.swift index 6f51c3d16..9dd1bd1b0 100644 --- a/Sources/FoundationEssentials/Data/Data+Writing.swift +++ b/Sources/FoundationEssentials/Data/Data+Writing.swift @@ -457,6 +457,19 @@ private func writeToFileAux(path inPath: PathOrURL, buffer: UnsafeRawBufferPoint if !SetFileInformationByHandle(hFile, FileRenameInfoEx, pInfo, dwSize) { let dwError = GetLastError() + if dwError == ERROR_ACCESS_DENIED { + let dwAttributes = GetFileAttributesW(pwszPath) + if dwAttributes > 0, + dwAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) != 0 { + if SetFileAttributesW(pwszPath, dwAttributes & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) { + if SetFileInformationByHandle(hFile, FileRenameInfoEx, pInfo, dwSize) { + return + } + // Try to restore the attributes, but ignore any error + _ = SetFileAttributesW(pwszPath, dwAttributes) + } + } + } guard dwError == ERROR_NOT_SAME_DEVICE else { throw CocoaError.errorWithFilePath(inPath, win32: dwError, reading: false) } diff --git a/Sources/FoundationEssentials/WinSDK+Extensions.swift b/Sources/FoundationEssentials/WinSDK+Extensions.swift index 6322c4c86..729477a9e 100644 --- a/Sources/FoundationEssentials/WinSDK+Extensions.swift +++ b/Sources/FoundationEssentials/WinSDK+Extensions.swift @@ -137,11 +137,18 @@ package var FILE_ATTRIBUTE_READONLY: DWORD { DWORD(WinSDK.FILE_ATTRIBUTE_READONLY) } +package var FILE_ATTRIBUTE_HIDDEN: DWORD { + DWORD(WinSDK.FILE_ATTRIBUTE_HIDDEN) +} package var FILE_ATTRIBUTE_REPARSE_POINT: DWORD { DWORD(WinSDK.FILE_ATTRIBUTE_REPARSE_POINT) } +package var FILE_ATTRIBUTE_SYSTEM: DWORD { + DWORD(WinSDK.FILE_ATTRIBUTE_SYSTEM) +} + package var FILE_FLAG_BACKUP_SEMANTICS: DWORD { DWORD(WinSDK.FILE_FLAG_BACKUP_SEMANTICS) }