From 1816bb4ab050f46504a2f1e827e9d74f8d253101 Mon Sep 17 00:00:00 2001 From: Jan Philipp Hafer Date: Sat, 2 Sep 2023 12:55:22 +0200 Subject: [PATCH] std.os+windows: isAtLeast(.win10_rs5) in renameatW(), DeleteFile() for posix semantics Usage of FILE_RENAME_IGNORE_READONLY_ATTRIBUTE or FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE for posix semantics require win10_rs5 instead of win10_rs1 necessary for posix semantics. Keep it as simple as possible, since it is reasonable to expect users being able to update win10_rs5 or use non-posix semantics instead. Closes #17049. --- lib/std/os.zig | 8 +++++++- lib/std/os/windows.zig | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index fbd0fd492..0e4606f44 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2631,7 +2631,13 @@ pub fn renameatW( var need_fallback = true; var rc: windows.NTSTATUS = undefined; - if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1)) { + // FILE_RENAME_INFORMATION_EX and FILE_RENAME_POSIX_SEMANTICS require >= win10_rs1, + // but FILE_RENAME_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5. We check >= rs5 here + // so that we only use POSIX_SEMANTICS when we know IGNORE_READONLY_ATTRIBUTE will also be + // supported in order to avoid either (1) using a redundant call that we can know in advance will return + // STATUS_NOT_SUPPORTED or (2) only setting IGNORE_READONLY_ATTRIBUTE when >= rs5 + // and therefore having different behavior when the Windows version is >= rs1 but < rs5. + if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) { const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) + (MAX_PATH_BYTES - 1); var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION_EX)) = undefined; const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) - 1 + new_path_w.len * 2; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index d9cb6b6b2..d40fee8db 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -992,8 +992,9 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil // are only supported on NTFS filesystems, so the version check on its own is only a partial solution. To support non-NTFS filesystems // like FAT32, we need to fallback to FileDispositionInformation if the usage of FileDispositionInformationEx gives // us INVALID_PARAMETER. + // The same reasoning for win10_rs5 as in os.renameatW() applies (FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE requires >= win10_rs5). var need_fallback = true; - if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs1)) { + if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) { // Deletion with posix semantics if the filesystem supports it. var info = FILE_DISPOSITION_INFORMATION_EX{ .Flags = FILE_DISPOSITION_DELETE |