diff options
| author | xEgoist <egoist@egoistic.dev> | 2023-04-16 00:38:25 -0500 |
|---|---|---|
| committer | xEgoist <egoist@egoistic.dev> | 2023-04-16 15:18:15 -0500 |
| commit | 911f74e93b15024c7a2a15ca6845bd0ddbdf9b3c (patch) | |
| tree | 6496bc16c1f1ce236465e438f1f978acd4976c3d /lib | |
| parent | 7fad555e5e16e6cb71554981394387a0622093b0 (diff) | |
| download | zig-911f74e93b15024c7a2a15ca6845bd0ddbdf9b3c.tar.gz zig-911f74e93b15024c7a2a15ca6845bd0ddbdf9b3c.zip | |
windows: use NtSetInformationFile in DeleteFile.
Using `FILE_DELETE_ON_CLOSE` can silently succeed without reporting any error
on non-empty directory. This commit adds usage of NtSetInformationFile
which will report `DIRECTORY_NOT_EMPTY`.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/std/os/windows.zig | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index f8672bc58d..e195989e7e 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -870,6 +870,7 @@ pub const DeleteFileError = error{ Unexpected, NotDir, IsDir, + DirNotEmpty, }; pub const DeleteFileOptions = struct { @@ -879,9 +880,9 @@ pub const DeleteFileOptions = struct { pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void { const create_options_flags: ULONG = if (options.remove_dir) - FILE_DELETE_ON_CLOSE | FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT + FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT else - FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT; // would we ever want to delete the target instead? + FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT; // would we ever want to delete the target instead? const path_len_bytes = @intCast(u16, sub_path_w.len * 2); var nt_name = UNICODE_STRING{ @@ -924,7 +925,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, @@ -935,6 +936,22 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil .CANNOT_DELETE => return error.AccessDenied, else => return unexpectedStatus(rc), } + var file_dispo = FILE_DISPOSITION_INFORMATION{ + .DeleteFile = TRUE, + }; + rc = ntdll.NtSetInformationFile( + tmp_handle, + &io, + &file_dispo, + @sizeOf(FILE_DISPOSITION_INFORMATION), + .FileDispositionInformation, + ); + CloseHandle(tmp_handle); + switch (rc) { + .SUCCESS => return, + .DIRECTORY_NOT_EMPTY => return error.DirNotEmpty, + else => return unexpectedStatus(rc), + } } pub const MoveFileError = error{ FileNotFound, AccessDenied, Unexpected }; @@ -2470,6 +2487,10 @@ pub const FILE_INFORMATION_CLASS = enum(c_int) { FileMaximumInformation, }; +pub const FILE_DISPOSITION_INFORMATION = extern struct { + DeleteFile: BOOLEAN, +}; + pub const FILE_FS_DEVICE_INFORMATION = extern struct { DeviceType: DEVICE_TYPE, Characteristics: ULONG, |
