Merge pull request #4340 from daurnimator/ntstatus-as-enum

Windows error codes as non-exhaustive enums
This commit is contained in:
Andrew Kelley 2020-01-31 18:27:17 -05:00 committed by GitHub
commit e6a812c827
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 9421 additions and 5356 deletions

View File

@ -160,12 +160,12 @@ pub fn pwriteWindows(fd: fd_t, data: []const u8, offset: u64) os.WindowsWriteErr
var bytes_transferred: windows.DWORD = undefined; var bytes_transferred: windows.DWORD = undefined;
if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) { if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
switch (windows.kernel32.GetLastError()) { switch (windows.kernel32.GetLastError()) {
windows.ERROR.IO_PENDING => unreachable, .IO_PENDING => unreachable,
windows.ERROR.INVALID_USER_BUFFER => return error.SystemResources, .INVALID_USER_BUFFER => return error.SystemResources,
windows.ERROR.NOT_ENOUGH_MEMORY => return error.SystemResources, .NOT_ENOUGH_MEMORY => return error.SystemResources,
windows.ERROR.OPERATION_ABORTED => return error.OperationAborted, .OPERATION_ABORTED => return error.OperationAborted,
windows.ERROR.NOT_ENOUGH_QUOTA => return error.SystemResources, .NOT_ENOUGH_QUOTA => return error.SystemResources,
windows.ERROR.BROKEN_PIPE => return error.BrokenPipe, .BROKEN_PIPE => return error.BrokenPipe,
else => |err| return windows.unexpectedError(err), else => |err| return windows.unexpectedError(err),
} }
} }
@ -320,10 +320,10 @@ pub fn preadWindows(fd: fd_t, data: []u8, offset: u64) !usize {
var bytes_transferred: windows.DWORD = undefined; var bytes_transferred: windows.DWORD = undefined;
if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) { if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
switch (windows.kernel32.GetLastError()) { switch (windows.kernel32.GetLastError()) {
windows.ERROR.IO_PENDING => unreachable, .IO_PENDING => unreachable,
windows.ERROR.OPERATION_ABORTED => return error.OperationAborted, .OPERATION_ABORTED => return error.OperationAborted,
windows.ERROR.BROKEN_PIPE => return error.BrokenPipe, .BROKEN_PIPE => return error.BrokenPipe,
windows.ERROR.HANDLE_EOF => return @as(usize, bytes_transferred), .HANDLE_EOF => return @as(usize, bytes_transferred),
else => |err| return windows.unexpectedError(err), else => |err| return windows.unexpectedError(err),
} }
} }

View File

@ -365,14 +365,21 @@ pub fn formatType(
try output(context, "error."); try output(context, "error.");
return output(context, @errorName(value)); return output(context, @errorName(value));
}, },
.Enum => { .Enum => |enumInfo| {
if (comptime std.meta.trait.hasFn("format")(T)) { if (comptime std.meta.trait.hasFn("format")(T)) {
return value.format(fmt, options, context, Errors, output); return value.format(fmt, options, context, Errors, output);
} }
try output(context, @typeName(T)); try output(context, @typeName(T));
try output(context, "."); if (enumInfo.is_exhaustive) {
return formatType(@tagName(value), "", options, context, Errors, output, max_depth); try output(context, ".");
return formatType(@tagName(value), "", options, context, Errors, output, max_depth);
} else {
// TODO: when @tagName works on exhaustive enums print known enum strings
try output(context, "(");
try formatType(@enumToInt(value), "", options, context, Errors, output, max_depth);
try output(context, ")");
}
}, },
.Union => { .Union => {
if (comptime std.meta.trait.hasFn("format")(T)) { if (comptime std.meta.trait.hasFn("format")(T)) {

View File

@ -598,8 +598,8 @@ pub const Dir = struct {
self.index = 0; self.index = 0;
self.end_index = io.Information; self.end_index = io.Information;
switch (rc) { switch (rc) {
w.STATUS.SUCCESS => {}, .SUCCESS => {},
w.STATUS.ACCESS_DENIED => return error.AccessDenied, .ACCESS_DENIED => return error.AccessDenied,
else => return w.unexpectedStatus(rc), else => return w.unexpectedStatus(rc),
} }
} }
@ -837,16 +837,16 @@ pub const Dir = struct {
0, 0,
); );
switch (rc) { switch (rc) {
w.STATUS.SUCCESS => return result, .SUCCESS => return result,
w.STATUS.OBJECT_NAME_INVALID => unreachable, .OBJECT_NAME_INVALID => unreachable,
w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
w.STATUS.OBJECT_PATH_NOT_FOUND => return error.FileNotFound, .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
w.STATUS.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
w.STATUS.SHARING_VIOLATION => return error.SharingViolation, .SHARING_VIOLATION => return error.SharingViolation,
w.STATUS.ACCESS_DENIED => return error.AccessDenied, .ACCESS_DENIED => return error.AccessDenied,
w.STATUS.PIPE_BUSY => return error.PipeBusy, .PIPE_BUSY => return error.PipeBusy,
w.STATUS.OBJECT_PATH_SYNTAX_BAD => unreachable, .OBJECT_PATH_SYNTAX_BAD => unreachable,
w.STATUS.OBJECT_NAME_COLLISION => return error.PathAlreadyExists, .OBJECT_NAME_COLLISION => return error.PathAlreadyExists,
else => return w.unexpectedStatus(rc), else => return w.unexpectedStatus(rc),
} }
} }
@ -990,11 +990,11 @@ pub const Dir = struct {
0, 0,
); );
switch (rc) { switch (rc) {
w.STATUS.SUCCESS => return result, .SUCCESS => return result,
w.STATUS.OBJECT_NAME_INVALID => unreachable, .OBJECT_NAME_INVALID => unreachable,
w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
w.STATUS.OBJECT_PATH_NOT_FOUND => return error.FileNotFound, .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
w.STATUS.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
else => return w.unexpectedStatus(rc), else => return w.unexpectedStatus(rc),
} }
} }

View File

@ -225,10 +225,10 @@ pub const File = struct {
var info: windows.FILE_ALL_INFORMATION = undefined; var info: windows.FILE_ALL_INFORMATION = undefined;
const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation); const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
switch (rc) { switch (rc) {
windows.STATUS.SUCCESS => {}, .SUCCESS => {},
windows.STATUS.BUFFER_OVERFLOW => {}, .BUFFER_OVERFLOW => {},
windows.STATUS.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
windows.STATUS.ACCESS_DENIED => return error.AccessDenied, .ACCESS_DENIED => return error.AccessDenied,
else => return windows.unexpectedStatus(rc), else => return windows.unexpectedStatus(rc),
} }
return Stat{ return Stat{

View File

@ -126,7 +126,7 @@ else if (builtin.os == .windows)
// then unset the WAKE bit so that another unlocker can wake up a thread. // then unset the WAKE bit so that another unlocker can wake up a thread.
} else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) { } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) {
const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null); const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0); assert(rc == .SUCCESS);
_ = @atomicRmw(u32, &self.waiters, .Sub, WAKE, .Monotonic); _ = @atomicRmw(u32, &self.waiters, .Sub, WAKE, .Monotonic);
} }
} }
@ -154,7 +154,7 @@ else if (builtin.os == .windows)
// try to decrease the waiter count & set the WAKE bit meaning a thread is waking up // try to decrease the waiter count & set the WAKE bit meaning a thread is waking up
if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) { if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) {
const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0); assert(rc == .SUCCESS);
return; return;
} }
} }

View File

@ -1176,15 +1176,15 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*:0]const u16, flags: u32) UnlinkatEr
null, null,
0, 0,
); );
if (rc == w.STATUS.SUCCESS) { if (rc == .SUCCESS) {
rc = w.ntdll.NtClose(tmp_handle); rc = w.ntdll.NtClose(tmp_handle);
} }
switch (rc) { switch (rc) {
w.STATUS.SUCCESS => return, .SUCCESS => return,
w.STATUS.OBJECT_NAME_INVALID => unreachable, .OBJECT_NAME_INVALID => unreachable,
w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound, .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
w.STATUS.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
w.STATUS.FILE_IS_A_DIRECTORY => return error.IsDir, .FILE_IS_A_DIRECTORY => return error.IsDir,
else => return w.unexpectedStatus(rc), else => return w.unexpectedStatus(rc),
} }
} }
@ -2345,9 +2345,9 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v
return; return;
} }
switch (windows.kernel32.GetLastError()) { switch (windows.kernel32.GetLastError()) {
windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
windows.ERROR.ACCESS_DENIED => return error.PermissionDenied, .ACCESS_DENIED => return error.PermissionDenied,
else => |err| return windows.unexpectedError(err), else => |err| return windows.unexpectedError(err),
} }
} }

View File

@ -73,14 +73,14 @@ pub fn CreateFileW(
if (result == INVALID_HANDLE_VALUE) { if (result == INVALID_HANDLE_VALUE) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.SHARING_VIOLATION => return error.SharingViolation, .SHARING_VIOLATION => return error.SharingViolation,
ERROR.ALREADY_EXISTS => return error.PathAlreadyExists, .ALREADY_EXISTS => return error.PathAlreadyExists,
ERROR.FILE_EXISTS => return error.PathAlreadyExists, .FILE_EXISTS => return error.PathAlreadyExists,
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.ACCESS_DENIED => return error.AccessDenied, .ACCESS_DENIED => return error.AccessDenied,
ERROR.PIPE_BUSY => return error.PipeBusy, .PIPE_BUSY => return error.PipeBusy,
ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong, .FILENAME_EXCED_RANGE => return error.NameTooLong,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -133,7 +133,7 @@ pub fn DeviceIoControl(
overlapped, overlapped,
) == 0) { ) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.IO_PENDING => if (overlapped == null) unreachable, .IO_PENDING => if (overlapped == null) unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -144,7 +144,7 @@ pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWOR
var bytes: DWORD = undefined; var bytes: DWORD = undefined;
if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @boolToInt(wait)) == 0) { if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @boolToInt(wait)) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable, .IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -247,8 +247,8 @@ pub fn FindFirstFile(dir_path: []const u8, find_file_data: *WIN32_FIND_DATAW) Fi
if (handle == INVALID_HANDLE_VALUE) { if (handle == INVALID_HANDLE_VALUE) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -262,7 +262,7 @@ pub const FindNextFileError = error{Unexpected};
pub fn FindNextFile(handle: HANDLE, find_file_data: *WIN32_FIND_DATAW) FindNextFileError!bool { pub fn FindNextFile(handle: HANDLE, find_file_data: *WIN32_FIND_DATAW) FindNextFileError!bool {
if (kernel32.FindNextFileW(handle, find_file_data) == 0) { if (kernel32.FindNextFileW(handle, find_file_data) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.NO_MORE_FILES => return false, .NO_MORE_FILES => return false,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -279,7 +279,7 @@ pub fn CreateIoCompletionPort(
) CreateIoCompletionPortError!HANDLE { ) CreateIoCompletionPortError!HANDLE {
const handle = kernel32.CreateIoCompletionPort(file_handle, existing_completion_port, completion_key, concurrent_thread_count) orelse { const handle = kernel32.CreateIoCompletionPort(file_handle, existing_completion_port, completion_key, concurrent_thread_count) orelse {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
}; };
@ -323,9 +323,9 @@ pub fn GetQueuedCompletionStatus(
dwMilliseconds, dwMilliseconds,
) == FALSE) { ) == FALSE) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.ABANDONED_WAIT_0 => return GetQueuedCompletionStatusResult.Aborted, .ABANDONED_WAIT_0 => return GetQueuedCompletionStatusResult.Aborted,
ERROR.OPERATION_ABORTED => return GetQueuedCompletionStatusResult.Cancelled, .OPERATION_ABORTED => return GetQueuedCompletionStatusResult.Cancelled,
ERROR.HANDLE_EOF => return GetQueuedCompletionStatusResult.EOF, .HANDLE_EOF => return GetQueuedCompletionStatusResult.EOF,
else => |err| { else => |err| {
if (std.debug.runtime_safety) { if (std.debug.runtime_safety) {
std.debug.panic("unexpected error: {}\n", .{err}); std.debug.panic("unexpected error: {}\n", .{err});
@ -353,8 +353,8 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize {
var amt_read: DWORD = undefined; var amt_read: DWORD = undefined;
if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) { if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.OPERATION_ABORTED => continue, .OPERATION_ABORTED => continue,
ERROR.BROKEN_PIPE => return index, .BROKEN_PIPE => return index,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -378,12 +378,12 @@ pub fn WriteFile(handle: HANDLE, bytes: []const u8) WriteFileError!void {
// TODO replace this @intCast with a loop that writes all the bytes // TODO replace this @intCast with a loop that writes all the bytes
if (kernel32.WriteFile(handle, bytes.ptr, @intCast(u32, bytes.len), &bytes_written, null) == 0) { if (kernel32.WriteFile(handle, bytes.ptr, @intCast(u32, bytes.len), &bytes_written, null) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.INVALID_USER_BUFFER => return error.SystemResources, .INVALID_USER_BUFFER => return error.SystemResources,
ERROR.NOT_ENOUGH_MEMORY => return error.SystemResources, .NOT_ENOUGH_MEMORY => return error.SystemResources,
ERROR.OPERATION_ABORTED => return error.OperationAborted, .OPERATION_ABORTED => return error.OperationAborted,
ERROR.NOT_ENOUGH_QUOTA => return error.SystemResources, .NOT_ENOUGH_QUOTA => return error.SystemResources,
ERROR.IO_PENDING => unreachable, // this function is for blocking files only .IO_PENDING => unreachable, // this function is for blocking files only
ERROR.BROKEN_PIPE => return error.BrokenPipe, .BROKEN_PIPE => return error.BrokenPipe,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -457,12 +457,12 @@ pub fn DeleteFile(filename: []const u8) DeleteFileError!void {
pub fn DeleteFileW(filename: [*:0]const u16) DeleteFileError!void { pub fn DeleteFileW(filename: [*:0]const u16) DeleteFileError!void {
if (kernel32.DeleteFileW(filename) == 0) { if (kernel32.DeleteFileW(filename) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.ACCESS_DENIED => return error.AccessDenied, .ACCESS_DENIED => return error.AccessDenied,
ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong, .FILENAME_EXCED_RANGE => return error.NameTooLong,
ERROR.INVALID_PARAMETER => return error.NameTooLong, .INVALID_PARAMETER => return error.NameTooLong,
ERROR.SHARING_VIOLATION => return error.FileBusy, .SHARING_VIOLATION => return error.FileBusy,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -498,8 +498,8 @@ pub fn CreateDirectory(pathname: []const u8, attrs: ?*SECURITY_ATTRIBUTES) Creat
pub fn CreateDirectoryW(pathname: [*:0]const u16, attrs: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!void { pub fn CreateDirectoryW(pathname: [*:0]const u16, attrs: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!void {
if (kernel32.CreateDirectoryW(pathname, attrs) == 0) { if (kernel32.CreateDirectoryW(pathname, attrs) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.ALREADY_EXISTS => return error.PathAlreadyExists, .ALREADY_EXISTS => return error.PathAlreadyExists,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -519,8 +519,8 @@ pub fn RemoveDirectory(dir_path: []const u8) RemoveDirectoryError!void {
pub fn RemoveDirectoryW(dir_path_w: [*:0]const u16) RemoveDirectoryError!void { pub fn RemoveDirectoryW(dir_path_w: [*:0]const u16) RemoveDirectoryError!void {
if (kernel32.RemoveDirectoryW(dir_path_w) == 0) { if (kernel32.RemoveDirectoryW(dir_path_w) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.DIR_NOT_EMPTY => return error.DirNotEmpty, .DIR_NOT_EMPTY => return error.DirNotEmpty,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -551,8 +551,8 @@ pub fn SetFilePointerEx_BEGIN(handle: HANDLE, offset: u64) SetFilePointerError!v
const ipos = @bitCast(LARGE_INTEGER, offset); const ipos = @bitCast(LARGE_INTEGER, offset);
if (kernel32.SetFilePointerEx(handle, ipos, null, FILE_BEGIN) == 0) { if (kernel32.SetFilePointerEx(handle, ipos, null, FILE_BEGIN) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
ERROR.INVALID_HANDLE => unreachable, .INVALID_HANDLE => unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -562,8 +562,8 @@ pub fn SetFilePointerEx_BEGIN(handle: HANDLE, offset: u64) SetFilePointerError!v
pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError!void { pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError!void {
if (kernel32.SetFilePointerEx(handle, offset, null, FILE_CURRENT) == 0) { if (kernel32.SetFilePointerEx(handle, offset, null, FILE_CURRENT) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
ERROR.INVALID_HANDLE => unreachable, .INVALID_HANDLE => unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -573,8 +573,8 @@ pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError
pub fn SetFilePointerEx_END(handle: HANDLE, offset: i64) SetFilePointerError!void { pub fn SetFilePointerEx_END(handle: HANDLE, offset: i64) SetFilePointerError!void {
if (kernel32.SetFilePointerEx(handle, offset, null, FILE_END) == 0) { if (kernel32.SetFilePointerEx(handle, offset, null, FILE_END) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
ERROR.INVALID_HANDLE => unreachable, .INVALID_HANDLE => unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -585,8 +585,8 @@ pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 {
var result: LARGE_INTEGER = undefined; var result: LARGE_INTEGER = undefined;
if (kernel32.SetFilePointerEx(handle, 0, &result, FILE_CURRENT) == 0) { if (kernel32.SetFilePointerEx(handle, 0, &result, FILE_CURRENT) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
ERROR.INVALID_HANDLE => unreachable, .INVALID_HANDLE => unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -611,11 +611,11 @@ pub fn GetFinalPathNameByHandleW(
const rc = kernel32.GetFinalPathNameByHandleW(hFile, buf_ptr, buf_len, flags); const rc = kernel32.GetFinalPathNameByHandleW(hFile, buf_ptr, buf_len, flags);
if (rc == 0) { if (rc == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.NOT_ENOUGH_MEMORY => return error.SystemResources, .NOT_ENOUGH_MEMORY => return error.SystemResources,
ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong, .FILENAME_EXCED_RANGE => return error.NameTooLong,
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -649,9 +649,9 @@ pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWO
const rc = kernel32.GetFileAttributesW(lpFileName); const rc = kernel32.GetFileAttributesW(lpFileName);
if (rc == INVALID_FILE_ATTRIBUTES) { if (rc == INVALID_FILE_ATTRIBUTES) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.ACCESS_DENIED => return error.PermissionDenied, .ACCESS_DENIED => return error.PermissionDenied,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -801,7 +801,7 @@ pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: [*]u16, nSize: DWORD) G
const rc = kernel32.GetEnvironmentVariableW(lpName, lpBuffer, nSize); const rc = kernel32.GetEnvironmentVariableW(lpName, lpBuffer, nSize);
if (rc == 0) { if (rc == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.ENVVAR_NOT_FOUND => return error.EnvironmentVariableNotFound, .ENVVAR_NOT_FOUND => return error.EnvironmentVariableNotFound,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -840,11 +840,11 @@ pub fn CreateProcessW(
lpProcessInformation, lpProcessInformation,
) == 0) { ) == 0) {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.ACCESS_DENIED => return error.AccessDenied, .ACCESS_DENIED => return error.AccessDenied,
ERROR.INVALID_PARAMETER => unreachable, .INVALID_PARAMETER => unreachable,
ERROR.INVALID_NAME => return error.InvalidName, .INVALID_NAME => return error.InvalidName,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
} }
@ -858,9 +858,9 @@ pub const LoadLibraryError = error{
pub fn LoadLibraryW(lpLibFileName: [*:0]const u16) LoadLibraryError!HMODULE { pub fn LoadLibraryW(lpLibFileName: [*:0]const u16) LoadLibraryError!HMODULE {
return kernel32.LoadLibraryW(lpLibFileName) orelse { return kernel32.LoadLibraryW(lpLibFileName) orelse {
switch (kernel32.GetLastError()) { switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound, .FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound, .PATH_NOT_FOUND => return error.FileNotFound,
ERROR.MOD_NOT_FOUND => return error.FileNotFound, .MOD_NOT_FOUND => return error.FileNotFound,
else => |err| return unexpectedError(err), else => |err| return unexpectedError(err),
} }
}; };
@ -1037,28 +1037,28 @@ inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {
/// Call this when you made a windows DLL call or something that does SetLastError /// Call this when you made a windows DLL call or something that does SetLastError
/// and you get an unexpected error. /// and you get an unexpected error.
pub fn unexpectedError(err: DWORD) std.os.UnexpectedError { pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
if (std.os.unexpected_error_tracing) { if (std.os.unexpected_error_tracing) {
// 614 is the length of the longest windows error desciption // 614 is the length of the longest windows error desciption
var buf_u16: [614]u16 = undefined; var buf_u16: [614]u16 = undefined;
var buf_u8: [614]u8 = undefined; var buf_u8: [614]u8 = undefined;
var len = kernel32.FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.NEUTRAL, SUBLANG.DEFAULT), buf_u16[0..].ptr, buf_u16.len / @sizeOf(TCHAR), null); var len = kernel32.FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.NEUTRAL, SUBLANG.DEFAULT), buf_u16[0..].ptr, buf_u16.len / @sizeOf(TCHAR), null);
_ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable; _ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable;
std.debug.warn("error.Unexpected: GetLastError({}): {}\n", .{ err, buf_u8[0..len] }); std.debug.warn("error.Unexpected: GetLastError({}): {}\n", .{ @enumToInt(err), buf_u8[0..len] });
std.debug.dumpCurrentStackTrace(null); std.debug.dumpCurrentStackTrace(null);
} }
return error.Unexpected; return error.Unexpected;
} }
pub fn unexpectedWSAError(err: c_int) std.os.UnexpectedError { pub fn unexpectedWSAError(err: c_int) std.os.UnexpectedError {
return unexpectedError(@intCast(DWORD, err)); return unexpectedError(@intToEnum(Win32Error, @intCast(u16, err)));
} }
/// Call this when you made a windows NtDll call /// Call this when you made a windows NtDll call
/// and you get an unexpected status. /// and you get an unexpected status.
pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError { pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {
if (std.os.unexpected_error_tracing) { if (std.os.unexpected_error_tracing) {
std.debug.warn("error.Unexpected NTSTATUS=0x{x}\n", .{status}); std.debug.warn("error.Unexpected NTSTATUS=0x{x}\n", .{@enumToInt(status)});
std.debug.dumpCurrentStackTrace(null); std.debug.dumpCurrentStackTrace(null);
} }
return error.Unexpected; return error.Unexpected;

View File

@ -5,8 +5,8 @@ const std = @import("../../std.zig");
const assert = std.debug.assert; const assert = std.debug.assert;
const maxInt = std.math.maxInt; const maxInt = std.math.maxInt;
pub const ERROR = @import("error.zig"); pub usingnamespace @import("win32error.zig");
pub const STATUS = @import("status.zig"); pub usingnamespace @import("ntstatus.zig");
pub const LANG = @import("lang.zig"); pub const LANG = @import("lang.zig");
pub const SUBLANG = @import("sublang.zig"); pub const SUBLANG = @import("sublang.zig");
@ -62,7 +62,6 @@ pub const ULONGLONG = u64;
pub const LONGLONG = i64; pub const LONGLONG = i64;
pub const HLOCAL = HANDLE; pub const HLOCAL = HANDLE;
pub const LANGID = c_ushort; pub const LANGID = c_ushort;
pub const NTSTATUS = ULONG;
pub const va_list = *@OpaqueType(); pub const va_list = *@OpaqueType();

File diff suppressed because it is too large Load Diff

View File

@ -73,7 +73,7 @@ pub extern "kernel32" fn FindFirstFileW(lpFileName: [*:0]const u16, lpFindFileDa
pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) BOOL; pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) BOOL;
pub extern "kernel32" fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) BOOL; pub extern "kernel32" fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) BOOL;
pub extern "kernel32" fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: [*]u16, nSize: DWORD, Arguments: ?*va_list) callconv(.Stdcall) DWORD; pub extern "kernel32" fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: Win32Error, dwLanguageId: DWORD, lpBuffer: [*]u16, nSize: DWORD, Arguments: ?*va_list) callconv(.Stdcall) DWORD;
pub extern "kernel32" fn FreeEnvironmentStringsW(penv: [*:0]u16) callconv(.Stdcall) BOOL; pub extern "kernel32" fn FreeEnvironmentStringsW(penv: [*:0]u16) callconv(.Stdcall) BOOL;
@ -104,7 +104,7 @@ pub extern "kernel32" fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u1
pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) callconv(.Stdcall) HMODULE; pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) callconv(.Stdcall) HMODULE;
pub extern "kernel32" fn GetLastError() callconv(.Stdcall) DWORD; pub extern "kernel32" fn GetLastError() callconv(.Stdcall) Win32Error;
pub extern "kernel32" fn GetFileInformationByHandle( pub extern "kernel32" fn GetFileInformationByHandle(
hFile: HANDLE, hFile: HANDLE,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -283,7 +283,7 @@ const AtomicEvent = struct {
var waiting = wake_count; var waiting = wake_count;
while (waiting != 0) : (waiting -= 1) { while (waiting != 0) : (waiting -= 1) {
const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == 0); assert(rc == .SUCCESS);
} }
} }
@ -302,7 +302,7 @@ const AtomicEvent = struct {
// NtWaitForKeyedEvent doesnt have spurious wake-ups // NtWaitForKeyedEvent doesnt have spurious wake-ups
var rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, timeout_ptr); var rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, timeout_ptr);
switch (rc) { switch (rc) {
windows.WAIT_TIMEOUT => { .TIMEOUT => {
// update the wait count to signal that we're not waiting anymore. // update the wait count to signal that we're not waiting anymore.
// if the .set() thread already observed that we are, perform a // if the .set() thread already observed that we are, perform a
// matching NtWaitForKeyedEvent so that the .set() thread doesn't // matching NtWaitForKeyedEvent so that the .set() thread doesn't
@ -311,7 +311,7 @@ const AtomicEvent = struct {
while (true) { while (true) {
if (waiting == WAKE) { if (waiting == WAKE) {
rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null); rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
assert(rc == windows.WAIT_OBJECT_0); assert(rc == .WAIT_0);
break; break;
} else { } else {
waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - WAIT, .Acquire, .Monotonic) orelse break; waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - WAIT, .Acquire, .Monotonic) orelse break;
@ -320,7 +320,7 @@ const AtomicEvent = struct {
} }
return error.TimedOut; return error.TimedOut;
}, },
windows.WAIT_OBJECT_0 => {}, .WAIT_0 => {},
else => unreachable, else => unreachable,
} }
} }
@ -336,7 +336,7 @@ const AtomicEvent = struct {
EMPTY => handle = @cmpxchgWeak(usize, &event_handle, EMPTY, LOADING, .Acquire, .Monotonic) orelse { EMPTY => handle = @cmpxchgWeak(usize, &event_handle, EMPTY, LOADING, .Acquire, .Monotonic) orelse {
const handle_ptr = @ptrCast(*windows.HANDLE, &handle); const handle_ptr = @ptrCast(*windows.HANDLE, &handle);
const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE; const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
if (windows.ntdll.NtCreateKeyedEvent(handle_ptr, access_mask, null, 0) != 0) if (windows.ntdll.NtCreateKeyedEvent(handle_ptr, access_mask, null, 0) != .SUCCESS)
handle = 0; handle = 0;
@atomicStore(usize, &event_handle, handle, .Monotonic); @atomicStore(usize, &event_handle, handle, .Monotonic);
return @intToPtr(?windows.HANDLE, handle); return @intToPtr(?windows.HANDLE, handle);