| ... | ... | @@ -870,6 +870,7 @@ pub const DeleteFileError = error{ |
| 870 | 870 | Unexpected, |
| 871 | 871 | NotDir, |
| 872 | 872 | IsDir, |
| 873 | DirNotEmpty, |
| 873 | 874 | }; |
| 874 | 875 | |
| 875 | 876 | pub const DeleteFileOptions = struct { |
| ... | ... | @@ -879,9 +880,9 @@ pub const DeleteFileOptions = struct { |
| 879 | 880 | |
| 880 | 881 | pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFileError!void { |
| 881 | 882 | const create_options_flags: ULONG = if (options.remove_dir) |
| 882 | | FILE_DELETE_ON_CLOSE | FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT |
| 883 | FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT |
| 883 | 884 | 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? |
| 885 | 886 | |
| 886 | 887 | const path_len_bytes = @intCast(u16, sub_path_w.len * 2); |
| 887 | 888 | var nt_name = UNICODE_STRING{ |
| ... | ... | @@ -924,7 +925,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil |
| 924 | 925 | 0, |
| 925 | 926 | ); |
| 926 | 927 | switch (rc) { |
| 927 | | .SUCCESS => return CloseHandle(tmp_handle), |
| 928 | .SUCCESS => {}, |
| 928 | 929 | .OBJECT_NAME_INVALID => unreachable, |
| 929 | 930 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 930 | 931 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, |
| ... | ... | @@ -935,6 +936,22 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil |
| 935 | 936 | .CANNOT_DELETE => return error.AccessDenied, |
| 936 | 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 | } |
| 939 | 956 | |
| 940 | 957 | pub const MoveFileError = error{ FileNotFound, AccessDenied, Unexpected }; |
| ... | ... | @@ -2470,6 +2487,10 @@ pub const FILE_INFORMATION_CLASS = enum(c_int) { |
| 2470 | 2487 | FileMaximumInformation, |
| 2471 | 2488 | }; |
| 2472 | 2489 | |
| 2490 | pub const FILE_DISPOSITION_INFORMATION = extern struct { |
| 2491 | DeleteFile: BOOLEAN, |
| 2492 | }; |
| 2493 | |
| 2473 | 2494 | pub const FILE_FS_DEVICE_INFORMATION = extern struct { |
| 2474 | 2495 | DeviceType: DEVICE_TYPE, |
| 2475 | 2496 | Characteristics: ULONG, |