| author | |
| committer | |
| log | a89d5cfc3eaaf97b914abc5d355099ec8357925d |
| tree | 7c4ff9d033abd54aec89601906f8c6b0358fc0f9 |
| parent | 0d31877444bf6c21307dfd3c412f9673dfd8acab |
Replace them with `std.os.windows.OpenFile` instead. To allow
creation/opening of directories, `std.os.windows.OpenFileOptions`
now features a `.expect_dir: bool` member which is meant to emualate
POSIX's `O_DIRECTORY` flag.5 files changed, 90 insertions(+), 169 deletions(-)
lib/std/child_process.zig+8-13| ... | ... | @@ -480,25 +480,20 @@ pub const ChildProcess = struct { |
| 480 | 480 | |
| 481 | 481 | const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); |
| 482 | 482 | |
| 483 | // TODO use CreateFileW here since we are using a string literal for the path | |
| 484 | 483 | const nul_handle = if (any_ignore) |
| 485 | windows.CreateFile( | |
| 486 | "NUL", | |
| 487 | windows.GENERIC_READ, | |
| 488 | windows.FILE_SHARE_READ, | |
| 489 | null, | |
| 490 | windows.OPEN_EXISTING, | |
| 491 | windows.FILE_ATTRIBUTE_NORMAL, | |
| 492 | null, | |
| 493 | ) catch |err| switch (err) { | |
| 494 | error.SharingViolation => unreachable, // not possible for "NUL" | |
| 484 | windows.OpenFile(&[_]u16{ 'N', 'U', 'L' }, .{ | |
| 485 | .dir = std.fs.cwd().fd, | |
| 486 | .access_mask = windows.GENERIC_READ, | |
| 487 | .share_access = windows.FILE_SHARE_READ, | |
| 488 | .creation = windows.OPEN_EXISTING, | |
| 489 | .io_mode = .blocking, | |
| 490 | }) catch |err| switch (err) { | |
| 495 | 491 | error.PathAlreadyExists => unreachable, // not possible for "NUL" |
| 496 | 492 | error.PipeBusy => unreachable, // not possible for "NUL" |
| 497 | error.InvalidUtf8 => unreachable, // not possible for "NUL" | |
| 498 | error.BadPathName => unreachable, // not possible for "NUL" | |
| 499 | 493 | error.FileNotFound => unreachable, // not possible for "NUL" |
| 500 | 494 | error.AccessDenied => unreachable, // not possible for "NUL" |
| 501 | 495 | error.NameTooLong => unreachable, // not possible for "NUL" |
| 496 | error.WouldBlock => unreachable, // not possible for "NUL" | |
| 502 | 497 | else => |e| return e, |
| 503 | 498 | } |
| 504 | 499 | else |
lib/std/fs.zig+2-4| ... | ... | @@ -225,8 +225,7 @@ pub fn makeDirAbsoluteZ(absolute_path_z: [*:0]const u8) !void { |
| 225 | 225 | /// Same as `makeDirAbsolute` except the parameter is a null-terminated WTF-16 encoded string. |
| 226 | 226 | pub fn makeDirAbsoluteW(absolute_path_w: [*:0]const u16) !void { |
| 227 | 227 | assert(path.isAbsoluteWindowsW(absolute_path_w)); |
| 228 | const handle = try os.windows.CreateDirectoryW(null, absolute_path_w, null); | |
| 229 | os.windows.CloseHandle(handle); | |
| 228 | return os.mkdirW(absolute_path_w, default_new_dir_mode); | |
| 230 | 229 | } |
| 231 | 230 | |
| 232 | 231 | pub const deleteDir = @compileError("deprecated; use dir.deleteDir or deleteDirAbsolute"); |
| ... | ... | @@ -881,8 +880,7 @@ pub const Dir = struct { |
| 881 | 880 | } |
| 882 | 881 | |
| 883 | 882 | pub fn makeDirW(self: Dir, sub_path: [*:0]const u16) !void { |
| 884 | const handle = try os.windows.CreateDirectoryW(self.fd, sub_path, null); | |
| 885 | os.windows.CloseHandle(handle); | |
| 883 | try os.mkdiratW(self.fd, sub_path, default_new_dir_mode); | |
| 886 | 884 | } |
| 887 | 885 | |
| 888 | 886 | /// Calls makeDir recursively to make an entire path. Returns success if the path |
lib/std/fs/watch.zig+7-9| ... | ... | @@ -374,15 +374,13 @@ pub fn Watch(comptime V: type) type { |
| 374 | 374 | defer if (!basename_utf16le_null_consumed) self.allocator.free(basename_utf16le_null); |
| 375 | 375 | const basename_utf16le_no_null = basename_utf16le_null[0 .. basename_utf16le_null.len - 1]; |
| 376 | 376 | |
| 377 | const dir_handle = try windows.CreateFileW( | |
| 378 | dirname_utf16le.ptr, | |
| 379 | windows.FILE_LIST_DIRECTORY, | |
| 380 | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE | windows.FILE_SHARE_WRITE, | |
| 381 | null, | |
| 382 | windows.OPEN_EXISTING, | |
| 383 | windows.FILE_FLAG_BACKUP_SEMANTICS | windows.FILE_FLAG_OVERLAPPED, | |
| 384 | null, | |
| 385 | ); | |
| 377 | const dir_handle = try windows.OpenFile(dirname_utf16le, .{ | |
| 378 | .dir = std.fs.cwd().fd, | |
| 379 | .access_mask = windows.FILE_LIST_DIRECTORY, | |
| 380 | .creation = windows.FILE_OPEN, | |
| 381 | .io_mode = .blocking, | |
| 382 | .expect_dir = true, | |
| 383 | }); | |
| 386 | 384 | var dir_handle_consumed = false; |
| 387 | 385 | defer if (!dir_handle_consumed) windows.CloseHandle(dir_handle); |
| 388 | 386 |
lib/std/os.zig+65-19| ... | ... | @@ -2146,7 +2146,18 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirErr |
| 2146 | 2146 | } |
| 2147 | 2147 | |
| 2148 | 2148 | pub fn mkdiratW(dir_fd: fd_t, sub_path_w: [*:0]const u16, mode: u32) MakeDirError!void { |
| 2149 | const sub_dir_handle = try windows.CreateDirectoryW(dir_fd, sub_path_w, null); | |
| 2149 | const sub_dir_handle = windows.OpenFile(std.mem.spanZ(sub_path_w), .{ | |
| 2150 | .dir = dir_fd, | |
| 2151 | .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, | |
| 2152 | .creation = windows.FILE_CREATE, | |
| 2153 | .io_mode = .blocking, | |
| 2154 | .expect_dir = true, | |
| 2155 | }) catch |err| switch (err) { | |
| 2156 | error.IsDir => unreachable, | |
| 2157 | error.PipeBusy => unreachable, | |
| 2158 | error.WouldBlock => unreachable, | |
| 2159 | else => |e| return e, | |
| 2160 | }; | |
| 2150 | 2161 | windows.CloseHandle(sub_dir_handle); |
| 2151 | 2162 | } |
| 2152 | 2163 | |
| ... | ... | @@ -2175,9 +2186,8 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { |
| 2175 | 2186 | if (builtin.os.tag == .wasi) { |
| 2176 | 2187 | @compileError("mkdir is not supported in WASI; use mkdirat instead"); |
| 2177 | 2188 | } else if (builtin.os.tag == .windows) { |
| 2178 | const sub_dir_handle = try windows.CreateDirectory(null, dir_path, null); | |
| 2179 | windows.CloseHandle(sub_dir_handle); | |
| 2180 | return; | |
| 2189 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); | |
| 2190 | return mkdirW(dir_path_w.span().ptr, mode); | |
| 2181 | 2191 | } else { |
| 2182 | 2192 | const dir_path_c = try toPosixPath(dir_path); |
| 2183 | 2193 | return mkdirZ(&dir_path_c, mode); |
| ... | ... | @@ -2188,9 +2198,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { |
| 2188 | 2198 | pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void { |
| 2189 | 2199 | if (builtin.os.tag == .windows) { |
| 2190 | 2200 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); |
| 2191 | const sub_dir_handle = try windows.CreateDirectoryW(null, dir_path_w.span().ptr, null); | |
| 2192 | windows.CloseHandle(sub_dir_handle); | |
| 2193 | return; | |
| 2201 | return mkdirW(dir_path_w.span().ptr, mode); | |
| 2194 | 2202 | } |
| 2195 | 2203 | switch (errno(system.mkdir(dir_path, mode))) { |
| 2196 | 2204 | 0 => return, |
| ... | ... | @@ -2211,6 +2219,23 @@ pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void { |
| 2211 | 2219 | } |
| 2212 | 2220 | } |
| 2213 | 2221 | |
| 2222 | /// Windows-only. Same as `mkdir` but the parameters is null-terminated, WTF16 encoded. | |
| 2223 | pub fn mkdirW(dir_path_w: [*:0]const u16, mode: u32) MakeDirError!void { | |
| 2224 | const sub_dir_handle = windows.OpenFile(std.mem.spanZ(dir_path_w), .{ | |
| 2225 | .dir = std.fs.cwd().fd, | |
| 2226 | .access_mask = windows.GENERIC_READ | windows.SYNCHRONIZE, | |
| 2227 | .creation = windows.FILE_CREATE, | |
| 2228 | .io_mode = .blocking, | |
| 2229 | .expect_dir = true, | |
| 2230 | }) catch |err| switch (err) { | |
| 2231 | error.IsDir => unreachable, | |
| 2232 | error.PipeBusy => unreachable, | |
| 2233 | error.WouldBlock => unreachable, | |
| 2234 | else => |e| return e, | |
| 2235 | }; | |
| 2236 | windows.CloseHandle(sub_dir_handle); | |
| 2237 | } | |
| 2238 | ||
| 2214 | 2239 | pub const DeleteDirError = error{ |
| 2215 | 2240 | AccessDenied, |
| 2216 | 2241 | FileBusy, |
| ... | ... | @@ -4013,19 +4038,40 @@ pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealP |
| 4013 | 4038 | /// Same as `realpath` except `pathname` is null-terminated and UTF16LE-encoded. |
| 4014 | 4039 | /// TODO use ntdll for better semantics |
| 4015 | 4040 | pub fn realpathW(pathname: [*:0]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
| 4016 | const h_file = try windows.CreateFileW( | |
| 4017 | pathname, | |
| 4018 | windows.GENERIC_READ, | |
| 4019 | windows.FILE_SHARE_READ, | |
| 4020 | null, | |
| 4021 | windows.OPEN_EXISTING, | |
| 4022 | windows.FILE_FLAG_BACKUP_SEMANTICS, | |
| 4023 | null, | |
| 4024 | ); | |
| 4025 | defer windows.CloseHandle(h_file); | |
| 4041 | const w = windows; | |
| 4042 | ||
| 4043 | const dir = std.fs.cwd().fd; | |
| 4044 | const access_mask = w.GENERIC_READ | w.SYNCHRONIZE; | |
| 4045 | const share_access = w.FILE_SHARE_READ; | |
| 4046 | const creation = w.FILE_OPEN; | |
| 4047 | const h_file = blk: { | |
| 4048 | const res = w.OpenFile(std.mem.spanZ(pathname), .{ | |
| 4049 | .dir = dir, | |
| 4050 | .access_mask = access_mask, | |
| 4051 | .share_access = share_access, | |
| 4052 | .creation = creation, | |
| 4053 | .io_mode = .blocking, | |
| 4054 | }) catch |err| switch (err) { | |
| 4055 | error.IsDir => break :blk w.OpenFile(std.mem.spanZ(pathname), .{ | |
| 4056 | .dir = dir, | |
| 4057 | .access_mask = access_mask, | |
| 4058 | .share_access = share_access, | |
| 4059 | .creation = creation, | |
| 4060 | .io_mode = .blocking, | |
| 4061 | .expect_dir = true, | |
| 4062 | }) catch |er| switch (er) { | |
| 4063 | error.WouldBlock => unreachable, | |
| 4064 | else => |e2| return e2, | |
| 4065 | }, | |
| 4066 | error.WouldBlock => unreachable, | |
| 4067 | else => |e| return e, | |
| 4068 | }; | |
| 4069 | break :blk res; | |
| 4070 | }; | |
| 4071 | defer w.CloseHandle(h_file); | |
| 4026 | 4072 | |
| 4027 | var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined; | |
| 4028 | const wide_slice = try windows.GetFinalPathNameByHandleW(h_file, &wide_buf, wide_buf.len, windows.VOLUME_NAME_DOS); | |
| 4073 | var wide_buf: [w.PATH_MAX_WIDE]u16 = undefined; | |
| 4074 | const wide_slice = try w.GetFinalPathNameByHandleW(h_file, &wide_buf, wide_buf.len, w.VOLUME_NAME_DOS); | |
| 4029 | 4075 | |
| 4030 | 4076 | // Windows returns \\?\ prepended to the path. |
| 4031 | 4077 | // We strip it to make this function consistent across platforms. |
lib/std/os/windows.zig+8-124| ... | ... | @@ -49,52 +49,10 @@ pub const CreateFileError = error{ |
| 49 | 49 | Unexpected, |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | pub fn CreateFile( | |
| 53 | file_path: []const u8, | |
| 54 | desired_access: DWORD, | |
| 55 | share_mode: DWORD, | |
| 56 | lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, | |
| 57 | creation_disposition: DWORD, | |
| 58 | flags_and_attrs: DWORD, | |
| 59 | hTemplateFile: ?HANDLE, | |
| 60 | ) CreateFileError!HANDLE { | |
| 61 | const file_path_w = try sliceToPrefixedFileW(file_path); | |
| 62 | return CreateFileW(file_path_w.span().ptr, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile); | |
| 63 | } | |
| 64 | ||
| 65 | pub fn CreateFileW( | |
| 66 | file_path_w: [*:0]const u16, | |
| 67 | desired_access: DWORD, | |
| 68 | share_mode: DWORD, | |
| 69 | lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, | |
| 70 | creation_disposition: DWORD, | |
| 71 | flags_and_attrs: DWORD, | |
| 72 | hTemplateFile: ?HANDLE, | |
| 73 | ) CreateFileError!HANDLE { | |
| 74 | const result = kernel32.CreateFileW(file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile); | |
| 75 | ||
| 76 | if (result == INVALID_HANDLE_VALUE) { | |
| 77 | switch (kernel32.GetLastError()) { | |
| 78 | .SHARING_VIOLATION => return error.SharingViolation, | |
| 79 | .ALREADY_EXISTS => return error.PathAlreadyExists, | |
| 80 | .FILE_EXISTS => return error.PathAlreadyExists, | |
| 81 | .FILE_NOT_FOUND => return error.FileNotFound, | |
| 82 | .PATH_NOT_FOUND => return error.FileNotFound, | |
| 83 | .ACCESS_DENIED => return error.AccessDenied, | |
| 84 | .PIPE_BUSY => return error.PipeBusy, | |
| 85 | .FILENAME_EXCED_RANGE => return error.NameTooLong, | |
| 86 | else => |err| return unexpectedError(err), | |
| 87 | } | |
| 88 | } | |
| 89 | ||
| 90 | return result; | |
| 91 | } | |
| 92 | ||
| 93 | 52 | pub const OpenError = error{ |
| 94 | 53 | IsDir, |
| 95 | 54 | FileNotFound, |
| 96 | 55 | NoDevice, |
| 97 | SharingViolation, | |
| 98 | 56 | AccessDenied, |
| 99 | 57 | PipeBusy, |
| 100 | 58 | PathAlreadyExists, |
| ... | ... | @@ -111,15 +69,16 @@ pub const OpenFileOptions = struct { |
| 111 | 69 | share_access_nonblocking: bool = false, |
| 112 | 70 | creation: ULONG, |
| 113 | 71 | io_mode: std.io.ModeOverride, |
| 72 | expect_dir: bool = false, | |
| 114 | 73 | }; |
| 115 | 74 | |
| 116 | 75 | /// TODO when share_access_nonblocking is false, this implementation uses |
| 117 | 76 | /// untinterruptible sleep() to block. This is not the final iteration of the API. |
| 118 | 77 | pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HANDLE { |
| 119 | if (mem.eql(u16, sub_path_w, &[_]u16{'.'})) { | |
| 78 | if (mem.eql(u16, sub_path_w, &[_]u16{'.'}) and !options.expect_dir) { | |
| 120 | 79 | return error.IsDir; |
| 121 | 80 | } |
| 122 | if (mem.eql(u16, sub_path_w, &[_]u16{ '.', '.' })) { | |
| 81 | if (mem.eql(u16, sub_path_w, &[_]u16{ '.', '.' }) and !options.expect_dir) { | |
| 123 | 82 | return error.IsDir; |
| 124 | 83 | } |
| 125 | 84 | |
| ... | ... | @@ -145,8 +104,9 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 145 | 104 | |
| 146 | 105 | var delay: usize = 1; |
| 147 | 106 | while (true) { |
| 148 | var flags: ULONG = undefined; | |
| 149 | 107 | const blocking_flag: ULONG = if (options.io_mode == .blocking) FILE_SYNCHRONOUS_IO_NONALERT else 0; |
| 108 | const file_or_dir_flag: ULONG = if (options.expect_dir) FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT else FILE_NON_DIRECTORY_FILE; | |
| 109 | const flags: ULONG = file_or_dir_flag | blocking_flag; | |
| 150 | 110 | const rc = ntdll.NtCreateFile( |
| 151 | 111 | &result, |
| 152 | 112 | options.access_mask, |
| ... | ... | @@ -156,7 +116,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 156 | 116 | FILE_ATTRIBUTE_NORMAL, |
| 157 | 117 | options.share_access, |
| 158 | 118 | options.creation, |
| 159 | FILE_NON_DIRECTORY_FILE | blocking_flag, | |
| 119 | flags, | |
| 160 | 120 | null, |
| 161 | 121 | 0, |
| 162 | 122 | ); |
| ... | ... | @@ -183,7 +143,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 183 | 143 | .PIPE_BUSY => return error.PipeBusy, |
| 184 | 144 | .OBJECT_PATH_SYNTAX_BAD => unreachable, |
| 185 | 145 | .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, |
| 186 | .FILE_IS_A_DIRECTORY => return error.IsDir, | |
| 146 | .FILE_IS_A_DIRECTORY => if (options.expect_dir) unreachable else return error.IsDir, | |
| 187 | 147 | else => return unexpectedStatus(rc), |
| 188 | 148 | } |
| 189 | 149 | } |
| ... | ... | @@ -733,7 +693,6 @@ pub fn CreateSymbolicLinkW( |
| 733 | 693 | error.WouldBlock => unreachable, |
| 734 | 694 | error.IsDir => return error.PathAlreadyExists, |
| 735 | 695 | error.PipeBusy => unreachable, |
| 736 | error.SharingViolation => return error.AccessDenied, | |
| 737 | 696 | else => |e| return e, |
| 738 | 697 | }; |
| 739 | 698 | } |
| ... | ... | @@ -915,80 +874,6 @@ pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DW |
| 915 | 874 | } |
| 916 | 875 | } |
| 917 | 876 | |
| 918 | pub const CreateDirectoryError = error{ | |
| 919 | NameTooLong, | |
| 920 | PathAlreadyExists, | |
| 921 | FileNotFound, | |
| 922 | NoDevice, | |
| 923 | AccessDenied, | |
| 924 | InvalidUtf8, | |
| 925 | BadPathName, | |
| 926 | Unexpected, | |
| 927 | }; | |
| 928 | ||
| 929 | /// Returns an open directory handle which the caller is responsible for closing with `CloseHandle`. | |
| 930 | pub fn CreateDirectory(dir: ?HANDLE, pathname: []const u8, sa: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!HANDLE { | |
| 931 | const pathname_w = try sliceToPrefixedFileW(pathname); | |
| 932 | return CreateDirectoryW(dir, pathname_w.span().ptr, sa); | |
| 933 | } | |
| 934 | ||
| 935 | /// Same as `CreateDirectory` except takes a WTF-16 encoded path. | |
| 936 | pub fn CreateDirectoryW( | |
| 937 | dir: ?HANDLE, | |
| 938 | sub_path_w: [*:0]const u16, | |
| 939 | sa: ?*SECURITY_ATTRIBUTES, | |
| 940 | ) CreateDirectoryError!HANDLE { | |
| 941 | const path_len_bytes = math.cast(u16, mem.lenZ(sub_path_w) * 2) catch |err| switch (err) { | |
| 942 | error.Overflow => return error.NameTooLong, | |
| 943 | }; | |
| 944 | var nt_name = UNICODE_STRING{ | |
| 945 | .Length = path_len_bytes, | |
| 946 | .MaximumLength = path_len_bytes, | |
| 947 | .Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)), | |
| 948 | }; | |
| 949 | ||
| 950 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { | |
| 951 | // Windows does not recognize this, but it does work with empty string. | |
| 952 | nt_name.Length = 0; | |
| 953 | } | |
| 954 | ||
| 955 | var attr = OBJECT_ATTRIBUTES{ | |
| 956 | .Length = @sizeOf(OBJECT_ATTRIBUTES), | |
| 957 | .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w)) null else dir, | |
| 958 | .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here. | |
| 959 | .ObjectName = &nt_name, | |
| 960 | .SecurityDescriptor = if (sa) |ptr| ptr.lpSecurityDescriptor else null, | |
| 961 | .SecurityQualityOfService = null, | |
| 962 | }; | |
| 963 | var io: IO_STATUS_BLOCK = undefined; | |
| 964 | var result_handle: HANDLE = undefined; | |
| 965 | const rc = ntdll.NtCreateFile( | |
| 966 | &result_handle, | |
| 967 | GENERIC_READ | SYNCHRONIZE, | |
| 968 | &attr, | |
| 969 | &io, | |
| 970 | null, | |
| 971 | FILE_ATTRIBUTE_NORMAL, | |
| 972 | FILE_SHARE_READ, | |
| 973 | FILE_CREATE, | |
| 974 | FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, | |
| 975 | null, | |
| 976 | 0, | |
| 977 | ); | |
| 978 | switch (rc) { | |
| 979 | .SUCCESS => return result_handle, | |
| 980 | .OBJECT_NAME_INVALID => unreachable, | |
| 981 | .OBJECT_NAME_NOT_FOUND => return error.FileNotFound, | |
| 982 | .OBJECT_PATH_NOT_FOUND => return error.FileNotFound, | |
| 983 | .NO_MEDIA_IN_DEVICE => return error.NoDevice, | |
| 984 | .INVALID_PARAMETER => unreachable, | |
| 985 | .ACCESS_DENIED => return error.AccessDenied, | |
| 986 | .OBJECT_PATH_SYNTAX_BAD => unreachable, | |
| 987 | .OBJECT_NAME_COLLISION => return error.PathAlreadyExists, | |
| 988 | else => return unexpectedStatus(rc), | |
| 989 | } | |
| 990 | } | |
| 991 | ||
| 992 | 877 | pub const RemoveDirectoryError = error{ |
| 993 | 878 | FileNotFound, |
| 994 | 879 | DirNotEmpty, |
| ... | ... | @@ -1493,8 +1378,7 @@ pub fn cStrToPrefixedFileW(s: [*:0]const u8) !PathSpace { |
| 1493 | 1378 | } |
| 1494 | 1379 | |
| 1495 | 1380 | /// Converts the path `s` to WTF16, null-terminated. If the path is absolute, |
| 1496 | /// it will get NT-style prefix `\??\` prepended automatically. For prepending | |
| 1497 | /// Win32-style prefix, see `sliceToWin32PrefixedFileW` instead. | |
| 1381 | /// it will get NT-style prefix `\??\` prepended automatically. | |
| 1498 | 1382 | pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace { |
| 1499 | 1383 | // TODO https://github.com/ziglang/zig/issues/2765 |
| 1500 | 1384 | var path_space: PathSpace = undefined; |