aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxEgoist <egoist@egoistic.dev>2023-04-16 00:38:25 -0500
committerxEgoist <egoist@egoistic.dev>2023-04-16 15:18:15 -0500
commit911f74e93b15024c7a2a15ca6845bd0ddbdf9b3c (patch)
tree6496bc16c1f1ce236465e438f1f978acd4976c3d
parent7fad555e5e16e6cb71554981394387a0622093b0 (diff)
downloadzig-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`.
-rw-r--r--lib/std/os/windows.zig27
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,