diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 3e42ee5f2d08..4e72b1557c6a 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -899,7 +899,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil 0, ); switch (rc) { - .SUCCESS => return CloseHandle(tmp_handle), + .SUCCESS => {}, .OBJECT_NAME_INVALID => unreachable, .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, @@ -910,6 +910,21 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil .CANNOT_DELETE => return error.AccessDenied, else => return unexpectedStatus(rc), } + defer CloseHandle(tmp_handle); + + var info = FILE_DISPOSITION_INFORMATION_EX{ + .Flags = FILE_DISPOSITION_DELETE | + FILE_DISPOSITION_POSIX_SEMANTICS | + FILE_DISPOSITION_ON_CLOSE | + FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE, + }; + rc = ntdll.NtSetInformationFile(tmp_handle, &io, &info, @sizeOf(FILE_DISPOSITION_INFORMATION_EX), .FileDispositionInformationEx); + switch (rc) { + .SUCCESS => {}, + // CANNOT_DELETE indicates that the file is currently mapped + .CANNOT_DELETE => return error.FileBusy, + else => return unexpectedStatus(rc), + } } pub const MoveFileError = error{ FileNotFound, AccessDenied, Unexpected }; @@ -2282,6 +2297,18 @@ pub const FILE_NAME_INFORMATION = extern struct { FileName: [1]WCHAR, }; +pub const FILE_DISPOSITION_INFORMATION_EX = extern struct { + /// combination of FILE_DISPOSITION_* flags + Flags: ULONG, +}; + +const FILE_DISPOSITION_DO_NOT_DELETE: ULONG = 0x00000000; +const FILE_DISPOSITION_DELETE: ULONG = 0x00000001; +const FILE_DISPOSITION_POSIX_SEMANTICS: ULONG = 0x00000002; +const FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK: ULONG = 0x00000004; +const FILE_DISPOSITION_ON_CLOSE: ULONG = 0x00000008; +const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE: ULONG = 0x00000010; + pub const FILE_RENAME_INFORMATION = extern struct { ReplaceIfExists: BOOLEAN, RootDirectory: ?HANDLE,