authorgravatar for egoist@egoistic.devxEgoist <egoist@egoistic.dev> 2023-04-16 00:38:25-05:00
committergravatar for egoist@egoistic.devxEgoist <egoist@egoistic.dev> 2023-04-16 15:18:15-05:00
log911f74e93b15024c7a2a15ca6845bd0ddbdf9b3c
tree6496bc16c1f1ce236465e438f1f978acd4976c3d
parent7fad555e5e16e6cb71554981394387a0622093b0

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`.

1 files changed, 24 insertions(+), 3 deletions(-)

lib/std/os/windows.zig+24-3
...@@ -870,6 +870,7 @@ pub const DeleteFileError = error{...@@ -870,6 +870,7 @@ pub const DeleteFileError = error{
870 Unexpected,870 Unexpected,
871 NotDir,871 NotDir,
872 IsDir,872 IsDir,
873 DirNotEmpty,
873};874};
874875
875pub const DeleteFileOptions = struct {876pub const DeleteFileOptions = struct {
...@@ -879,9 +880,9 @@ pub const DeleteFileOptions = struct {...@@ -879,9 +880,9 @@ pub const DeleteFileOptions = struct {
879880
880pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void {881pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void {
881 const create_options_flags: ULONG = if (options.remove_dir)882 const create_options_flags: ULONG = if (options.remove_dir)
882 FILE_DELETE_ON_CLOSE | FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT883 FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT
883 else884 else
884 FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT; // would we ever want to delete the target instead?885 FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT; // would we ever want to delete the target instead?
885886
886 const path_len_bytes = @intCast(u16, sub_path_w.len * 2);887 const path_len_bytes = @intCast(u16, sub_path_w.len * 2);
887 var nt_name = UNICODE_STRING{888 var nt_name = UNICODE_STRING{
...@@ -924,7 +925,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -924,7 +925,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
924 0,925 0,
925 );926 );
926 switch (rc) {927 switch (rc) {
927 .SUCCESS => return CloseHandle(tmp_handle),928 .SUCCESS => {},
928 .OBJECT_NAME_INVALID => unreachable,929 .OBJECT_NAME_INVALID => unreachable,
929 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,930 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
930 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,931 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
...@@ -935,6 +936,22 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil...@@ -935,6 +936,22 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
935 .CANNOT_DELETE => return error.AccessDenied,936 .CANNOT_DELETE => return error.AccessDenied,
936 else => return unexpectedStatus(rc),937 else => return unexpectedStatus(rc),
937 }938 }
939 var file_dispo = FILE_DISPOSITION_INFORMATION{
940 .DeleteFile = TRUE,
941 };
942 rc = ntdll.NtSetInformationFile(
943 tmp_handle,
944 &io,
945 &file_dispo,
946 @sizeOf(FILE_DISPOSITION_INFORMATION),
947 .FileDispositionInformation,
948 );
949 CloseHandle(tmp_handle);
950 switch (rc) {
951 .SUCCESS => return,
952 .DIRECTORY_NOT_EMPTY => return error.DirNotEmpty,
953 else => return unexpectedStatus(rc),
954 }
938}955}
939956
940pub const MoveFileError = error{ FileNotFound, AccessDenied, Unexpected };957pub const MoveFileError = error{ FileNotFound, AccessDenied, Unexpected };
...@@ -2470,6 +2487,10 @@ pub const FILE_INFORMATION_CLASS = enum(c_int) {...@@ -2470,6 +2487,10 @@ pub const FILE_INFORMATION_CLASS = enum(c_int) {
2470 FileMaximumInformation,2487 FileMaximumInformation,
2471};2488};
24722489
2490pub const FILE_DISPOSITION_INFORMATION = extern struct {
2491 DeleteFile: BOOLEAN,
2492};
2493
2473pub const FILE_FS_DEVICE_INFORMATION = extern struct {2494pub const FILE_FS_DEVICE_INFORMATION = extern struct {
2474 DeviceType: DEVICE_TYPE,2495 DeviceType: DEVICE_TYPE,
2475 Characteristics: ULONG,2496 Characteristics: ULONG,