| ... | ... | @@ -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, |
| ... | ... | @@ -932,7 +933,28 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil |
| 932 | 933 | .FILE_IS_A_DIRECTORY => return error.IsDir, |
| 933 | 934 | .NOT_A_DIRECTORY => return error.NotDir, |
| 934 | 935 | .SHARING_VIOLATION => return error.FileBusy, |
| 936 | .ACCESS_DENIED => return error.AccessDenied, |
| 937 | .DELETE_PENDING => return, |
| 938 | else => return unexpectedStatus(rc), |
| 939 | } |
| 940 | var file_dispo = FILE_DISPOSITION_INFORMATION{ |
| 941 | .DeleteFile = TRUE, |
| 942 | }; |
| 943 | rc = ntdll.NtSetInformationFile( |
| 944 | tmp_handle, |
| 945 | &io, |
| 946 | &file_dispo, |
| 947 | @sizeOf(FILE_DISPOSITION_INFORMATION), |
| 948 | .FileDispositionInformation, |
| 949 | ); |
| 950 | CloseHandle(tmp_handle); |
| 951 | switch (rc) { |
| 952 | .SUCCESS => return, |
| 953 | .DIRECTORY_NOT_EMPTY => return error.DirNotEmpty, |
| 954 | .INVALID_PARAMETER => unreachable, |
| 935 | 955 | .CANNOT_DELETE => return error.AccessDenied, |
| 956 | .MEDIA_WRITE_PROTECTED => return error.AccessDenied, |
| 957 | .ACCESS_DENIED => return error.AccessDenied, |
| 936 | 958 | else => return unexpectedStatus(rc), |
| 937 | 959 | } |
| 938 | 960 | } |
| ... | ... | @@ -2470,6 +2492,10 @@ pub const FILE_INFORMATION_CLASS = enum(c_int) { |
| 2470 | 2492 | FileMaximumInformation, |
| 2471 | 2493 | }; |
| 2472 | 2494 | |
| 2495 | pub const FILE_DISPOSITION_INFORMATION = extern struct { |
| 2496 | DeleteFile: BOOLEAN, |
| 2497 | }; |
| 2498 | |
| 2473 | 2499 | pub const FILE_FS_DEVICE_INFORMATION = extern struct { |
| 2474 | 2500 | DeviceType: DEVICE_TYPE, |
| 2475 | 2501 | Characteristics: ULONG, |