| ... | @@ -3260,30 +3260,23 @@ fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, pe | ... | @@ -3260,30 +3260,23 @@ fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, pe |
| 3260 | const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path); | 3260 | const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path); |
| 3261 | _ = permissions; // TODO use this value | 3261 | _ = permissions; // TODO use this value |
| 3262 | | 3262 | |
| 3263 | const syscall: Syscall = try .start(); | 3263 | const sub_dir_handle = OpenFile(sub_path_w.span(), .{ |
| 3264 | const sub_dir_handle = while (true) { | 3264 | .dir = dir.handle, |
| 3265 | break windows.OpenFile(sub_path_w.span(), .{ | 3265 | .access_mask = .{ |
| 3266 | .dir = dir.handle, | 3266 | .GENERIC = .{ .READ = true }, |
| 3267 | .access_mask = .{ | 3267 | .STANDARD = .{ .SYNCHRONIZE = true }, |
| 3268 | .GENERIC = .{ .READ = true }, | 3268 | }, |
| 3269 | .STANDARD = .{ .SYNCHRONIZE = true }, | 3269 | .creation = .CREATE, |
| 3270 | }, | 3270 | .filter = .dir_only, |
| 3271 | .creation = .CREATE, | 3271 | }) catch |err| switch (err) { |
| 3272 | .filter = .dir_only, | 3272 | error.IsDir => return error.Unexpected, |
| 3273 | }) catch |err| switch (err) { | 3273 | error.PipeBusy => return error.Unexpected, |
| 3274 | error.IsDir => return syscall.fail(error.Unexpected), | 3274 | error.FileBusy => return error.Unexpected, |
| 3275 | error.PipeBusy => return syscall.fail(error.Unexpected), | 3275 | error.NoDevice => return error.Unexpected, |
| 3276 | error.NoDevice => return syscall.fail(error.Unexpected), | 3276 | error.WouldBlock => return error.Unexpected, |
| 3277 | error.WouldBlock => return syscall.fail(error.Unexpected), | 3277 | error.AntivirusInterference => return error.Unexpected, |
| 3278 | error.AntivirusInterference => return syscall.fail(error.Unexpected), | 3278 | else => |e| return e, |
| 3279 | error.OperationCanceled => { | | |
| 3280 | try syscall.checkCancel(); | | |
| 3281 | continue; | | |
| 3282 | }, | | |
| 3283 | else => |e| return syscall.fail(e), | | |
| 3284 | }; | | |
| 3285 | }; | 3279 | }; |
| 3286 | syscall.finish(); | | |
| 3287 | windows.CloseHandle(sub_dir_handle); | 3280 | windows.CloseHandle(sub_dir_handle); |
| 3288 | } | 3281 | } |
| 3289 | | 3282 | |
| ... | @@ -5987,27 +5980,19 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, | ... | @@ -5987,27 +5980,19 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, |
| 5987 | var path_name_w = try sliceToPrefixedFileW(dir.handle, sub_path); | 5980 | var path_name_w = try sliceToPrefixedFileW(dir.handle, sub_path); |
| 5988 | | 5981 | |
| 5989 | const h_file = handle: { | 5982 | const h_file = handle: { |
| 5990 | const syscall: Syscall = try .start(); | 5983 | if (OpenFile(path_name_w.span(), .{ |
| 5991 | while (true) { | 5984 | .dir = dir.handle, |
| 5992 | if (windows.OpenFile(path_name_w.span(), .{ | 5985 | .access_mask = .{ |
| 5993 | .dir = dir.handle, | 5986 | .GENERIC = .{ .READ = true }, |
| 5994 | .access_mask = .{ | 5987 | .STANDARD = .{ .SYNCHRONIZE = true }, |
| 5995 | .GENERIC = .{ .READ = true }, | 5988 | }, |
| 5996 | .STANDARD = .{ .SYNCHRONIZE = true }, | 5989 | .creation = .OPEN, |
| 5997 | }, | 5990 | .filter = .any, |
| 5998 | .creation = .OPEN, | 5991 | })) |handle| { |
| 5999 | .filter = .any, | 5992 | break :handle handle; |
| 6000 | })) |handle| { | 5993 | } else |err| switch (err) { |
| 6001 | syscall.finish(); | 5994 | error.WouldBlock => unreachable, |
| 6002 | break :handle handle; | 5995 | else => |e| return e, |
| 6003 | } else |err| switch (err) { | | |
| 6004 | error.WouldBlock => unreachable, | | |
| 6005 | error.OperationCanceled => { | | |
| 6006 | try syscall.checkCancel(); | | |
| 6007 | continue; | | |
| 6008 | }, | | |
| 6009 | else => |e| return syscall.fail(e), | | |
| 6010 | } | | |
| 6011 | } | 5996 | } |
| 6012 | }; | 5997 | }; |
| 6013 | defer windows.CloseHandle(h_file); | 5998 | defer windows.CloseHandle(h_file); |
| ... | @@ -6116,7 +6101,7 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -6116,7 +6101,7 @@ pub fn GetFinalPathNameByHandle( |
| 6116 | // Source: https://stackoverflow.com/questions/3012828/using-ioctl-mountmgr-query-points | 6101 | // Source: https://stackoverflow.com/questions/3012828/using-ioctl-mountmgr-query-points |
| 6117 | // This is the NT namespaced version of \\.\MountPointManager | 6102 | // This is the NT namespaced version of \\.\MountPointManager |
| 6118 | const mgmt_path_u16 = std.unicode.utf8ToUtf16LeStringLiteral("\\??\\MountPointManager"); | 6103 | const mgmt_path_u16 = std.unicode.utf8ToUtf16LeStringLiteral("\\??\\MountPointManager"); |
| 6119 | const mgmt_handle = windows.OpenFile(mgmt_path_u16, .{ | 6104 | const mgmt_handle = OpenFile(mgmt_path_u16, .{ |
| 6120 | .access_mask = .{ .STANDARD = .{ .SYNCHRONIZE = true } }, | 6105 | .access_mask = .{ .STANDARD = .{ .SYNCHRONIZE = true } }, |
| 6121 | .creation = .OPEN, | 6106 | .creation = .OPEN, |
| 6122 | }) catch |err| switch (err) { | 6107 | }) catch |err| switch (err) { |
| ... | @@ -6125,12 +6110,12 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -6125,12 +6110,12 @@ pub fn GetFinalPathNameByHandle( |
| 6125 | error.NoDevice => return error.Unexpected, | 6110 | error.NoDevice => return error.Unexpected, |
| 6126 | error.AccessDenied => return error.Unexpected, | 6111 | error.AccessDenied => return error.Unexpected, |
| 6127 | error.PipeBusy => return error.Unexpected, | 6112 | error.PipeBusy => return error.Unexpected, |
| | 6113 | error.FileBusy => return error.Unexpected, |
| 6128 | error.PathAlreadyExists => return error.Unexpected, | 6114 | error.PathAlreadyExists => return error.Unexpected, |
| 6129 | error.WouldBlock => return error.Unexpected, | 6115 | error.WouldBlock => return error.Unexpected, |
| 6130 | error.NetworkNotFound => return error.Unexpected, | 6116 | error.NetworkNotFound => return error.Unexpected, |
| 6131 | error.AntivirusInterference => return error.Unexpected, | 6117 | error.AntivirusInterference => return error.Unexpected, |
| 6132 | error.BadPathName => return error.Unexpected, | 6118 | error.BadPathName => return error.Unexpected, |
| 6133 | error.OperationCanceled => @panic("TODO: better integrate cancelation"), | | |
| 6134 | else => |e| return e, | 6119 | else => |e| return e, |
| 6135 | }; | 6120 | }; |
| 6136 | defer windows.CloseHandle(mgmt_handle); | 6121 | defer windows.CloseHandle(mgmt_handle); |
| ... | @@ -7309,31 +7294,23 @@ fn dirRenameWindowsInner( | ... | @@ -7309,31 +7294,23 @@ fn dirRenameWindowsInner( |
| 7309 | const new_path_w = new_path_w_buf.span(); | 7294 | const new_path_w = new_path_w_buf.span(); |
| 7310 | | 7295 | |
| 7311 | const src_fd = src_fd: { | 7296 | const src_fd = src_fd: { |
| 7312 | const syscall: Syscall = try .start(); | 7297 | if (OpenFile(old_path_w, .{ |
| 7313 | while (true) { | 7298 | .dir = old_dir.handle, |
| 7314 | if (w.OpenFile(old_path_w, .{ | 7299 | .access_mask = .{ |
| 7315 | .dir = old_dir.handle, | 7300 | .GENERIC = .{ .WRITE = true }, |
| 7316 | .access_mask = .{ | 7301 | .STANDARD = .{ |
| 7317 | .GENERIC = .{ .WRITE = true }, | 7302 | .RIGHTS = .{ .DELETE = true }, |
| 7318 | .STANDARD = .{ | 7303 | .SYNCHRONIZE = true, |
| 7319 | .RIGHTS = .{ .DELETE = true }, | | |
| 7320 | .SYNCHRONIZE = true, | | |
| 7321 | }, | | |
| 7322 | }, | | |
| 7323 | .creation = .OPEN, | | |
| 7324 | .filter = .any, // This function is supposed to rename both files and directories. | | |
| 7325 | .follow_symlinks = false, | | |
| 7326 | })) |handle| { | | |
| 7327 | syscall.finish(); | | |
| 7328 | break :src_fd handle; | | |
| 7329 | } else |err| switch (err) { | | |
| 7330 | error.WouldBlock => unreachable, // Not possible without `.share_access_nonblocking = true`. | | |
| 7331 | error.OperationCanceled => { | | |
| 7332 | try syscall.checkCancel(); | | |
| 7333 | continue; | | |
| 7334 | }, | 7304 | }, |
| 7335 | else => |e| return e, | 7305 | }, |
| 7336 | } | 7306 | .creation = .OPEN, |
| | 7307 | .filter = .any, // This function is supposed to rename both files and directories. |
| | 7308 | .follow_symlinks = false, |
| | 7309 | })) |handle| { |
| | 7310 | break :src_fd handle; |
| | 7311 | } else |err| switch (err) { |
| | 7312 | error.WouldBlock => unreachable, // Not possible without `.share_access_nonblocking = true`. |
| | 7313 | else => |e| return e, |
| 7337 | } | 7314 | } |
| 7338 | }; | 7315 | }; |
| 7339 | defer w.CloseHandle(src_fd); | 7316 | defer w.CloseHandle(src_fd); |
| ... | @@ -7662,32 +7639,25 @@ fn dirSymLinkWindows( | ... | @@ -7662,32 +7639,25 @@ fn dirSymLinkWindows( |
| 7662 | }; | 7639 | }; |
| 7663 | | 7640 | |
| 7664 | const symlink_handle = handle: { | 7641 | const symlink_handle = handle: { |
| 7665 | const syscall: Syscall = try .start(); | 7642 | if (OpenFile(sym_link_path_w.span(), .{ |
| 7666 | while (true) { | 7643 | .access_mask = .{ |
| 7667 | if (w.OpenFile(sym_link_path_w.span(), .{ | 7644 | .GENERIC = .{ .READ = true, .WRITE = true }, |
| 7668 | .access_mask = .{ | 7645 | .STANDARD = .{ .SYNCHRONIZE = true }, |
| 7669 | .GENERIC = .{ .READ = true, .WRITE = true }, | 7646 | }, |
| 7670 | .STANDARD = .{ .SYNCHRONIZE = true }, | 7647 | .dir = dir.handle, |
| 7671 | }, | 7648 | .creation = .CREATE, |
| 7672 | .dir = dir.handle, | 7649 | .filter = if (flags.is_directory) .dir_only else .non_directory_only, |
| 7673 | .creation = .CREATE, | 7650 | })) |handle| { |
| 7674 | .filter = if (flags.is_directory) .dir_only else .non_directory_only, | 7651 | break :handle handle; |
| 7675 | })) |handle| { | 7652 | } else |err| switch (err) { |
| 7676 | syscall.finish(); | 7653 | error.IsDir => return error.PathAlreadyExists, |
| 7677 | break :handle handle; | 7654 | error.NotDir => return error.Unexpected, |
| 7678 | } else |err| switch (err) { | 7655 | error.WouldBlock => return error.Unexpected, |
| 7679 | error.IsDir => return syscall.fail(error.PathAlreadyExists), | 7656 | error.PipeBusy => return error.Unexpected, |
| 7680 | error.NotDir => return syscall.fail(error.Unexpected), | 7657 | error.FileBusy => return error.Unexpected, |
| 7681 | error.WouldBlock => return syscall.fail(error.Unexpected), | 7658 | error.NoDevice => return error.Unexpected, |
| 7682 | error.PipeBusy => return syscall.fail(error.Unexpected), | 7659 | error.AntivirusInterference => return error.Unexpected, |
| 7683 | error.NoDevice => return syscall.fail(error.Unexpected), | 7660 | else => |e| return e, |
| 7684 | error.AntivirusInterference => return syscall.fail(error.Unexpected), | | |
| 7685 | error.OperationCanceled => { | | |
| 7686 | try syscall.checkCancel(); | | |
| 7687 | continue; | | |
| 7688 | }, | | |
| 7689 | else => |e| return e, | | |
| 7690 | } | | |
| 7691 | } | 7661 | } |
| 7692 | }; | 7662 | }; |
| 7693 | defer w.CloseHandle(symlink_handle); | 7663 | defer w.CloseHandle(symlink_handle); |
| ... | @@ -10341,27 +10311,20 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut | ... | @@ -10341,27 +10311,20 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut |
| 10341 | var path_name_w_buf = try wToPrefixedFileW(null, image_path_name); | 10311 | var path_name_w_buf = try wToPrefixedFileW(null, image_path_name); |
| 10342 | | 10312 | |
| 10343 | const h_file = handle: { | 10313 | const h_file = handle: { |
| 10344 | const syscall: Syscall = try .start(); | 10314 | if (OpenFile(path_name_w_buf.span(), .{ |
| 10345 | while (true) { | 10315 | .dir = null, |
| 10346 | if (w.OpenFile(path_name_w_buf.span(), .{ | 10316 | .access_mask = .{ |
| 10347 | .dir = null, | 10317 | .GENERIC = .{ .READ = true }, |
| 10348 | .access_mask = .{ | 10318 | .STANDARD = .{ .SYNCHRONIZE = true }, |
| 10349 | .GENERIC = .{ .READ = true }, | 10319 | }, |
| 10350 | .STANDARD = .{ .SYNCHRONIZE = true }, | 10320 | .creation = .OPEN, |
| 10351 | }, | 10321 | .filter = .any, |
| 10352 | .creation = .OPEN, | 10322 | })) |handle| { |
| 10353 | .filter = .any, | 10323 | break :handle handle; |
| 10354 | })) |handle| { | 10324 | } else |err| switch (err) { |
| 10355 | syscall.finish(); | 10325 | error.WouldBlock => unreachable, |
| 10356 | break :handle handle; | 10326 | error.FileBusy => unreachable, |
| 10357 | } else |err| switch (err) { | 10327 | else => |e| return e, |
| 10358 | error.WouldBlock => unreachable, | | |
| 10359 | error.OperationCanceled => { | | |
| 10360 | try syscall.checkCancel(); | | |
| 10361 | continue; | | |
| 10362 | }, | | |
| 10363 | else => |e| return e, | | |
| 10364 | } | | |
| 10365 | } | 10328 | } |
| 10366 | }; | 10329 | }; |
| 10367 | defer w.CloseHandle(h_file); | 10330 | defer w.CloseHandle(h_file); |
| ... | @@ -19055,3 +19018,151 @@ pub fn mutexUnlock(m: *Io.Mutex) void { | ... | @@ -19055,3 +19018,151 @@ pub fn mutexUnlock(m: *Io.Mutex) void { |
| 19055 | }, | 19018 | }, |
| 19056 | } | 19019 | } |
| 19057 | } | 19020 | } |
| | 19021 | |
| | 19022 | const OpenError = error{ |
| | 19023 | IsDir, |
| | 19024 | NotDir, |
| | 19025 | FileNotFound, |
| | 19026 | NoDevice, |
| | 19027 | AccessDenied, |
| | 19028 | PipeBusy, |
| | 19029 | PathAlreadyExists, |
| | 19030 | WouldBlock, |
| | 19031 | NetworkNotFound, |
| | 19032 | AntivirusInterference, |
| | 19033 | FileBusy, |
| | 19034 | } || Dir.PathNameError || Io.Cancelable || Io.UnexpectedError; |
| | 19035 | |
| | 19036 | const OpenFileOptions = struct { |
| | 19037 | access_mask: windows.ACCESS_MASK, |
| | 19038 | dir: ?windows.HANDLE = null, |
| | 19039 | sa: ?*windows.SECURITY_ATTRIBUTES = null, |
| | 19040 | share_access: windows.FILE.SHARE = .VALID_FLAGS, |
| | 19041 | creation: windows.FILE.CREATE_DISPOSITION, |
| | 19042 | filter: Filter = .non_directory_only, |
| | 19043 | /// If false, tries to open path as a reparse point without dereferencing it. |
| | 19044 | /// Defaults to true. |
| | 19045 | follow_symlinks: bool = true, |
| | 19046 | |
| | 19047 | pub const Filter = enum { |
| | 19048 | /// Causes `OpenFile` to return `error.IsDir` if the opened handle would be a directory. |
| | 19049 | non_directory_only, |
| | 19050 | /// Causes `OpenFile` to return `error.NotDir` if the opened handle is not a directory. |
| | 19051 | dir_only, |
| | 19052 | /// `OpenFile` does not discriminate between opening files and directories. |
| | 19053 | any, |
| | 19054 | }; |
| | 19055 | }; |
| | 19056 | |
| | 19057 | /// TODO: inline this logic everywhere and delete this function |
| | 19058 | fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!windows.HANDLE { |
| | 19059 | if (std.mem.eql(u16, sub_path_w, &[_]u16{'.'}) and options.filter == .non_directory_only) { |
| | 19060 | return error.IsDir; |
| | 19061 | } |
| | 19062 | if (std.mem.eql(u16, sub_path_w, &[_]u16{ '.', '.' }) and options.filter == .non_directory_only) { |
| | 19063 | return error.IsDir; |
| | 19064 | } |
| | 19065 | |
| | 19066 | var result: windows.HANDLE = undefined; |
| | 19067 | |
| | 19068 | const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong; |
| | 19069 | var nt_name: windows.UNICODE_STRING = .{ |
| | 19070 | .Length = path_len_bytes, |
| | 19071 | .MaximumLength = path_len_bytes, |
| | 19072 | .Buffer = @constCast(sub_path_w.ptr), |
| | 19073 | }; |
| | 19074 | const attr: windows.OBJECT_ATTRIBUTES = .{ |
| | 19075 | .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w)) null else options.dir, |
| | 19076 | .Attributes = .{ .INHERIT = if (options.sa) |sa| sa.bInheritHandle != windows.FALSE else false }, |
| | 19077 | .ObjectName = &nt_name, |
| | 19078 | .SecurityDescriptor = if (options.sa) |ptr| ptr.lpSecurityDescriptor else null, |
| | 19079 | }; |
| | 19080 | |
| | 19081 | var iosb: windows.IO_STATUS_BLOCK = undefined; |
| | 19082 | |
| | 19083 | // There are multiple kernel bugs being worked around with retries. |
| | 19084 | const max_attempts = 13; |
| | 19085 | var attempt: u5 = 0; |
| | 19086 | |
| | 19087 | var syscall: Syscall = try .start(); |
| | 19088 | while (true) { |
| | 19089 | switch (windows.ntdll.NtCreateFile( |
| | 19090 | &result, |
| | 19091 | options.access_mask, |
| | 19092 | &attr, |
| | 19093 | &iosb, |
| | 19094 | null, |
| | 19095 | .{ .NORMAL = true }, |
| | 19096 | options.share_access, |
| | 19097 | options.creation, |
| | 19098 | .{ |
| | 19099 | .DIRECTORY_FILE = options.filter == .dir_only, |
| | 19100 | .NON_DIRECTORY_FILE = options.filter == .non_directory_only, |
| | 19101 | .IO = if (options.follow_symlinks) .SYNCHRONOUS_NONALERT else .ASYNCHRONOUS, |
| | 19102 | .OPEN_REPARSE_POINT = !options.follow_symlinks, |
| | 19103 | }, |
| | 19104 | null, |
| | 19105 | 0, |
| | 19106 | )) { |
| | 19107 | .SUCCESS => { |
| | 19108 | syscall.finish(); |
| | 19109 | return result; |
| | 19110 | }, |
| | 19111 | .CANCELLED => { |
| | 19112 | try syscall.checkCancel(); |
| | 19113 | continue; |
| | 19114 | }, |
| | 19115 | .SHARING_VIOLATION => { |
| | 19116 | // This occurs if the file attempting to be opened is a running |
| | 19117 | // executable. However, there's a kernel bug: the error may be |
| | 19118 | // incorrectly returned for an indeterminate amount of time |
| | 19119 | // after an executable file is closed. Here we work around the |
| | 19120 | // kernel bug with retry attempts. |
| | 19121 | syscall.finish(); |
| | 19122 | if (max_attempts - attempt == 0) return error.FileBusy; |
| | 19123 | try parking_sleep.sleep(.{ .duration = .{ |
| | 19124 | .raw = .fromMilliseconds((@as(u32, 1) << attempt) >> 1), |
| | 19125 | .clock = .awake, |
| | 19126 | } }); |
| | 19127 | attempt += 1; |
| | 19128 | syscall = try .start(); |
| | 19129 | continue; |
| | 19130 | }, |
| | 19131 | .DELETE_PENDING => { |
| | 19132 | // This error means that there *was* a file in this location on |
| | 19133 | // the file system, but it was deleted. However, the OS is not |
| | 19134 | // finished with the deletion operation, and so this CreateFile |
| | 19135 | // call has failed. There is not really a sane way to handle |
| | 19136 | // this other than retrying the creation after the OS finishes |
| | 19137 | // the deletion. |
| | 19138 | syscall.finish(); |
| | 19139 | if (max_attempts - attempt == 0) return error.FileBusy; |
| | 19140 | try parking_sleep.sleep(.{ .duration = .{ |
| | 19141 | .raw = .fromMilliseconds((@as(u32, 1) << attempt) >> 1), |
| | 19142 | .clock = .awake, |
| | 19143 | } }); |
| | 19144 | attempt += 1; |
| | 19145 | syscall = try .start(); |
| | 19146 | continue; |
| | 19147 | }, |
| | 19148 | .OBJECT_NAME_INVALID => return syscall.fail(error.BadPathName), |
| | 19149 | .OBJECT_NAME_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| | 19150 | .OBJECT_PATH_NOT_FOUND => return syscall.fail(error.FileNotFound), |
| | 19151 | .BAD_NETWORK_PATH => return syscall.fail(error.NetworkNotFound), // \\server was not found |
| | 19152 | .BAD_NETWORK_NAME => return syscall.fail(error.NetworkNotFound), // \\server was found but \\server\share wasn't |
| | 19153 | .NO_MEDIA_IN_DEVICE => return syscall.fail(error.NoDevice), |
| | 19154 | .ACCESS_DENIED => return syscall.fail(error.AccessDenied), |
| | 19155 | .PIPE_BUSY => return syscall.fail(error.PipeBusy), |
| | 19156 | .PIPE_NOT_AVAILABLE => return syscall.fail(error.NoDevice), |
| | 19157 | .OBJECT_NAME_COLLISION => return syscall.fail(error.PathAlreadyExists), |
| | 19158 | .FILE_IS_A_DIRECTORY => return syscall.fail(error.IsDir), |
| | 19159 | .NOT_A_DIRECTORY => return syscall.fail(error.NotDir), |
| | 19160 | .USER_MAPPED_FILE => return syscall.fail(error.AccessDenied), |
| | 19161 | .VIRUS_INFECTED, .VIRUS_DELETED => return syscall.fail(error.AntivirusInterference), |
| | 19162 | .INVALID_PARAMETER => |status| return syscall.ntstatusBug(status), |
| | 19163 | .OBJECT_PATH_SYNTAX_BAD => |status| return syscall.ntstatusBug(status), |
| | 19164 | .INVALID_HANDLE => |status| return syscall.ntstatusBug(status), |
| | 19165 | else => |status| return syscall.unexpectedNtstatus(status), |
| | 19166 | } |
| | 19167 | } |
| | 19168 | } |