@@ -937,25 +937,50 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil
937
937
.DELETE_PENDING = > return ,
938
938
else = > return unexpectedStatus (rc ),
939
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 ,
955
- .CANNOT_DELETE = > return error .AccessDenied ,
956
- .MEDIA_WRITE_PROTECTED = > return error .AccessDenied ,
957
- .ACCESS_DENIED = > return error .AccessDenied ,
958
- else = > return unexpectedStatus (rc ),
940
+ defer CloseHandle (tmp_handle );
941
+ if (comptime builtin .target .os .version_range .windows .min .isAtLeast (.win10_rs1 )) {
942
+ // Deletion with posix semantics.
943
+ var info = FILE_DISPOSITION_INFORMATION_EX {
944
+ .Flags = FILE_DISPOSITION_DELETE |
945
+ FILE_DISPOSITION_POSIX_SEMANTICS |
946
+ FILE_DISPOSITION_ON_CLOSE |
947
+ FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE ,
948
+ };
949
+
950
+ rc = ntdll .NtSetInformationFile (
951
+ tmp_handle ,
952
+ & io ,
953
+ & info ,
954
+ @sizeOf (FILE_DISPOSITION_INFORMATION_EX ),
955
+ .FileDispositionInformationEx ,
956
+ );
957
+ switch (rc ) {
958
+ .SUCCESS = > {},
959
+ .CANNOT_DELETE = > return error .FileBusy , // file is currently mapped
960
+ else = > return unexpectedStatus (rc ),
961
+ }
962
+ } else {
963
+ // Deletion with file pending semantics, which requires waiting or moving
964
+ // files to get them removed (from here).
965
+ var file_dispo = FILE_DISPOSITION_INFORMATION {
966
+ .DeleteFile = TRUE ,
967
+ };
968
+ rc = ntdll .NtSetInformationFile (
969
+ tmp_handle ,
970
+ & io ,
971
+ & file_dispo ,
972
+ @sizeOf (FILE_DISPOSITION_INFORMATION ),
973
+ .FileDispositionInformation ,
974
+ );
975
+ switch (rc ) {
976
+ .SUCCESS = > {},
977
+ .DIRECTORY_NOT_EMPTY = > return error .DirNotEmpty ,
978
+ .INVALID_PARAMETER = > unreachable ,
979
+ .CANNOT_DELETE = > return error .AccessDenied ,
980
+ .MEDIA_WRITE_PROTECTED = > return error .AccessDenied ,
981
+ .ACCESS_DENIED = > return error .AccessDenied ,
982
+ else = > return unexpectedStatus (rc ),
983
+ }
959
984
}
960
985
}
961
986
@@ -2397,6 +2422,18 @@ pub const FILE_NAME_INFORMATION = extern struct {
2397
2422
FileName : [1 ]WCHAR ,
2398
2423
};
2399
2424
2425
+ pub const FILE_DISPOSITION_INFORMATION_EX = extern struct {
2426
+ /// combination of FILE_DISPOSITION_* flags
2427
+ Flags : ULONG ,
2428
+ };
2429
+
2430
+ const FILE_DISPOSITION_DO_NOT_DELETE : ULONG = 0x00000000 ;
2431
+ const FILE_DISPOSITION_DELETE : ULONG = 0x00000001 ;
2432
+ const FILE_DISPOSITION_POSIX_SEMANTICS : ULONG = 0x00000002 ;
2433
+ const FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK : ULONG = 0x00000004 ;
2434
+ const FILE_DISPOSITION_ON_CLOSE : ULONG = 0x00000008 ;
2435
+ const FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE : ULONG = 0x00000010 ;
2436
+
2400
2437
pub const FILE_RENAME_INFORMATION = extern struct {
2401
2438
ReplaceIfExists : BOOLEAN ,
2402
2439
RootDirectory : ? HANDLE ,
0 commit comments