| ... | @@ -1045,11 +1045,24 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro | ... | @@ -1045,11 +1045,24 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro |
| 1045 | w.ULONG(w.FILE_DELETE_ON_CLOSE) | 1045 | w.ULONG(w.FILE_DELETE_ON_CLOSE) |
| 1046 | else | 1046 | else |
| 1047 | w.ULONG(w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE); | 1047 | w.ULONG(w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE); |
| 1048 | var nt_name: w.UNICODE_STRING = undefined; | 1048 | |
| 1049 | if (w.ntdll.RtlDosPathNameToNtPathName_U(sub_path_w, &nt_name, null, null) == 0) { | 1049 | const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2); |
| 1050 | return error.FileNotFound; | 1050 | var nt_name = w.UNICODE_STRING{ |
| | 1051 | .Length = path_len_bytes, |
| | 1052 | .MaximumLength = path_len_bytes, |
| | 1053 | // The Windows API makes this mutable, but it will not mutate here. |
| | 1054 | .Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)), |
| | 1055 | }; |
| | 1056 | |
| | 1057 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { |
| | 1058 | // Windows does not recognize this, but it does work with empty string. |
| | 1059 | nt_name.Length = 0; |
| 1051 | } | 1060 | } |
| 1052 | defer w.ntdll.RtlFreeUnicodeString(&nt_name); | 1061 | if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) { |
| | 1062 | // Can't remove the parent directory with an open handle. |
| | 1063 | return error.FileBusy; |
| | 1064 | } |
| | 1065 | |
| 1053 | | 1066 | |
| 1054 | var attr = w.OBJECT_ATTRIBUTES{ | 1067 | var attr = w.OBJECT_ATTRIBUTES{ |
| 1055 | .Length = @sizeOf(w.OBJECT_ATTRIBUTES), | 1068 | .Length = @sizeOf(w.OBJECT_ATTRIBUTES), |
| ... | @@ -1082,6 +1095,7 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro | ... | @@ -1082,6 +1095,7 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro |
| 1082 | w.STATUS.OBJECT_NAME_INVALID => unreachable, | 1095 | w.STATUS.OBJECT_NAME_INVALID => unreachable, |
| 1083 | w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, | 1096 | w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, |
| 1084 | w.STATUS.INVALID_PARAMETER => unreachable, | 1097 | w.STATUS.INVALID_PARAMETER => unreachable, |
| | 1098 | w.STATUS.FILE_IS_A_DIRECTORY => return error.IsDir, |
| 1085 | else => return w.unexpectedStatus(rc), | 1099 | else => return w.unexpectedStatus(rc), |
| 1086 | } | 1100 | } |
| 1087 | } | 1101 | } |