authorgravatar for lucascarvalhosantos91@gmail.comLucas Santos <lucascarvalhosantos91@gmail.com> 2024-07-15 14:49:51-03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-15 10:49:51-07:00
log89942ebd03b2943cbbe84b575a024e156ca5bf52
tree0892910484a47d30d4c5f2dccff9f16d0162687e
parentcf36d3fdd3674bfb95f22aa7bc7ff450ebdc1c08
signaturebadge-check Signed by PGP key B5690EEEBB952194

Better implementation of GetLastError. (#20623)

Instead of calling the dynamically loaded kernel32.GetLastError, we can extract it from the TEB. As shown by [Wine](https://github.com/wine-mirror/wine/blob/34b1606019982b71818780bc84b76460f650af31/include/winternl.h#L439), the last error lives at offset 0x34 of the TEB in 32-bit Windows and at offset 0x68 in 64-bit Windows.

9 files changed, 56 insertions(+), 47 deletions(-)

lib/std/Thread.zig+1-1
...@@ -554,7 +554,7 @@ const WindowsThreadImpl = struct {...@@ -554,7 +554,7 @@ const WindowsThreadImpl = struct {
554 0,554 0,
555 null,555 null,
556 ) orelse {556 ) orelse {
557 const errno = windows.kernel32.GetLastError();557 const errno = windows.GetLastError();
558 return windows.unexpectedError(errno);558 return windows.unexpectedError(errno);
559 };559 };
560560
lib/std/Thread/Condition.zig+1-1
...@@ -178,7 +178,7 @@ const WindowsImpl = struct {...@@ -178,7 +178,7 @@ const WindowsImpl = struct {
178178
179 // Return error.Timeout if we know the timeout elapsed correctly.179 // Return error.Timeout if we know the timeout elapsed correctly.
180 if (rc == os.windows.FALSE) {180 if (rc == os.windows.FALSE) {
181 assert(os.windows.kernel32.GetLastError() == .TIMEOUT);181 assert(os.windows.GetLastError() == .TIMEOUT);
182 if (!timeout_overflowed) return error.Timeout;182 if (!timeout_overflowed) return error.Timeout;
183 }183 }
184 }184 }
lib/std/crypto/Certificate/Bundle.zig+1-1
...@@ -132,7 +132,7 @@ fn rescanWindows(cb: *Bundle, gpa: Allocator) RescanWindowsError!void {...@@ -132,7 +132,7 @@ fn rescanWindows(cb: *Bundle, gpa: Allocator) RescanWindowsError!void {
132 cb.map.clearRetainingCapacity();132 cb.map.clearRetainingCapacity();
133133
134 const w = std.os.windows;134 const w = std.os.windows;
135 const GetLastError = w.kernel32.GetLastError;135 const GetLastError = w.GetLastError;
136 const root = [4:0]u16{ 'R', 'O', 'O', 'T' };136 const root = [4:0]u16{ 'R', 'O', 'O', 'T' };
137 const store = w.crypt32.CertOpenSystemStoreW(null, &root) orelse switch (GetLastError()) {137 const store = w.crypt32.CertOpenSystemStoreW(null, &root) orelse switch (GetLastError()) {
138 .FILE_NOT_FOUND => return error.FileNotFound,138 .FILE_NOT_FOUND => return error.FileNotFound,
lib/std/debug.zig+1-1
...@@ -1781,7 +1781,7 @@ pub const DebugInfo = struct {...@@ -1781,7 +1781,7 @@ pub const DebugInfo = struct {
17811781
1782 const handle = windows.kernel32.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE | windows.TH32CS_SNAPMODULE32, 0);1782 const handle = windows.kernel32.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE | windows.TH32CS_SNAPMODULE32, 0);
1783 if (handle == windows.INVALID_HANDLE_VALUE) {1783 if (handle == windows.INVALID_HANDLE_VALUE) {
1784 switch (windows.kernel32.GetLastError()) {1784 switch (windows.GetLastError()) {
1785 else => |err| return windows.unexpectedError(err),1785 else => |err| return windows.unexpectedError(err),
1786 }1786 }
1787 }1787 }
lib/std/io.zig+3-3
...@@ -567,7 +567,7 @@ pub fn Poller(comptime StreamEnum: type) type {...@@ -567,7 +567,7 @@ pub fn Poller(comptime StreamEnum: type) type {
567 windows.INFINITE,567 windows.INFINITE,
568 );568 );
569 if (status == windows.WAIT_FAILED)569 if (status == windows.WAIT_FAILED)
570 return windows.unexpectedError(windows.kernel32.GetLastError());570 return windows.unexpectedError(windows.GetLastError());
571 if (status == windows.WAIT_TIMEOUT)571 if (status == windows.WAIT_TIMEOUT)
572 return true;572 return true;
573573
...@@ -584,7 +584,7 @@ pub fn Poller(comptime StreamEnum: type) type {...@@ -584,7 +584,7 @@ pub fn Poller(comptime StreamEnum: type) type {
584 &self.windows.overlapped[stream_idx],584 &self.windows.overlapped[stream_idx],
585 &read_bytes,585 &read_bytes,
586 0,586 0,
587 )) switch (windows.kernel32.GetLastError()) {587 )) switch (windows.GetLastError()) {
588 .BROKEN_PIPE => {588 .BROKEN_PIPE => {
589 self.windows.active.removeAt(active_idx);589 self.windows.active.removeAt(active_idx);
590 continue;590 continue;
...@@ -664,7 +664,7 @@ fn windowsAsyncRead(...@@ -664,7 +664,7 @@ fn windowsAsyncRead(
664 const buf = try fifo.writableWithSize(bump_amt);664 const buf = try fifo.writableWithSize(bump_amt);
665 var read_bytes: u32 = undefined;665 var read_bytes: u32 = undefined;
666 const read_result = windows.kernel32.ReadFile(handle, buf.ptr, math.cast(u32, buf.len) orelse math.maxInt(u32), &read_bytes, overlapped);666 const read_result = windows.kernel32.ReadFile(handle, buf.ptr, math.cast(u32, buf.len) orelse math.maxInt(u32), &read_bytes, overlapped);
667 if (read_result == 0) return switch (windows.kernel32.GetLastError()) {667 if (read_result == 0) return switch (windows.GetLastError()) {
668 .IO_PENDING => .pending,668 .IO_PENDING => .pending,
669 .BROKEN_PIPE => .closed,669 .BROKEN_PIPE => .closed,
670 else => |err| windows.unexpectedError(err),670 else => |err| windows.unexpectedError(err),
lib/std/os.zig+1-1
...@@ -61,7 +61,7 @@ pub fn accessW(path: [*:0]const u16) windows.GetFileAttributesError!void {...@@ -61,7 +61,7 @@ pub fn accessW(path: [*:0]const u16) windows.GetFileAttributesError!void {
61 if (ret != windows.INVALID_FILE_ATTRIBUTES) {61 if (ret != windows.INVALID_FILE_ATTRIBUTES) {
62 return;62 return;
63 }63 }
64 switch (windows.kernel32.GetLastError()) {64 switch (windows.GetLastError()) {
65 .FILE_NOT_FOUND => return error.FileNotFound,65 .FILE_NOT_FOUND => return error.FileNotFound,
66 .PATH_NOT_FOUND => return error.FileNotFound,66 .PATH_NOT_FOUND => return error.FileNotFound,
67 .ACCESS_DENIED => return error.PermissionDenied,67 .ACCESS_DENIED => return error.PermissionDenied,
lib/std/os/windows.zig+44-35
...@@ -172,6 +172,10 @@ pub fn GetCurrentThreadId() DWORD {...@@ -172,6 +172,10 @@ pub fn GetCurrentThreadId() DWORD {
172 return @truncate(@intFromPtr(teb().ClientId.UniqueThread));172 return @truncate(@intFromPtr(teb().ClientId.UniqueThread));
173}173}
174174
175pub fn GetLastError() Win32Error {
176 return @enumFromInt(teb().LastErrorValue);
177}
178
175pub const CreatePipeError = error{ Unexpected, SystemResources };179pub const CreatePipeError = error{ Unexpected, SystemResources };
176180
177var npfs: ?HANDLE = null;181var npfs: ?HANDLE = null;
...@@ -309,7 +313,7 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: ?LPCWSTR, flags:...@@ -309,7 +313,7 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: ?LPCWSTR, flags:
309 if (handle) |h| {313 if (handle) |h| {
310 return h;314 return h;
311 } else {315 } else {
312 switch (kernel32.GetLastError()) {316 switch (GetLastError()) {
313 else => |err| return unexpectedError(err),317 else => |err| return unexpectedError(err),
314 }318 }
315 }319 }
...@@ -385,7 +389,7 @@ pub fn DeviceIoControl(...@@ -385,7 +389,7 @@ pub fn DeviceIoControl(
385pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {389pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
386 var bytes: DWORD = undefined;390 var bytes: DWORD = undefined;
387 if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @intFromBool(wait)) == 0) {391 if (kernel32.GetOverlappedResult(h, overlapped, &bytes, @intFromBool(wait)) == 0) {
388 switch (kernel32.GetLastError()) {392 switch (GetLastError()) {
389 .IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,393 .IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
390 else => |err| return unexpectedError(err),394 else => |err| return unexpectedError(err),
391 }395 }
...@@ -397,7 +401,7 @@ pub const SetHandleInformationError = error{Unexpected};...@@ -397,7 +401,7 @@ pub const SetHandleInformationError = error{Unexpected};
397401
398pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInformationError!void {402pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInformationError!void {
399 if (kernel32.SetHandleInformation(h, mask, flags) == 0) {403 if (kernel32.SetHandleInformation(h, mask, flags) == 0) {
400 switch (kernel32.GetLastError()) {404 switch (GetLastError()) {
401 else => |err| return unexpectedError(err),405 else => |err| return unexpectedError(err),
402 }406 }
403 }407 }
...@@ -417,7 +421,7 @@ pub fn RtlGenRandom(output: []u8) RtlGenRandomError!void {...@@ -417,7 +421,7 @@ pub fn RtlGenRandom(output: []u8) RtlGenRandomError!void {
417 const to_read: ULONG = @min(buff.len, max_read_size);421 const to_read: ULONG = @min(buff.len, max_read_size);
418422
419 if (advapi32.RtlGenRandom(buff.ptr, to_read) == 0) {423 if (advapi32.RtlGenRandom(buff.ptr, to_read) == 0) {
420 return unexpectedError(kernel32.GetLastError());424 return unexpectedError(GetLastError());
421 }425 }
422426
423 total_read += to_read;427 total_read += to_read;
...@@ -440,7 +444,7 @@ pub fn WaitForSingleObjectEx(handle: HANDLE, milliseconds: DWORD, alertable: boo...@@ -440,7 +444,7 @@ pub fn WaitForSingleObjectEx(handle: HANDLE, milliseconds: DWORD, alertable: boo
440 WAIT_ABANDONED => return error.WaitAbandoned,444 WAIT_ABANDONED => return error.WaitAbandoned,
441 WAIT_OBJECT_0 => return,445 WAIT_OBJECT_0 => return,
442 WAIT_TIMEOUT => return error.WaitTimeOut,446 WAIT_TIMEOUT => return error.WaitTimeOut,
443 WAIT_FAILED => switch (kernel32.GetLastError()) {447 WAIT_FAILED => switch (GetLastError()) {
444 else => |err| return unexpectedError(err),448 else => |err| return unexpectedError(err),
445 },449 },
446 else => return error.Unexpected,450 else => return error.Unexpected,
...@@ -468,7 +472,7 @@ pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, millisec...@@ -468,7 +472,7 @@ pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, millisec
468 return error.WaitAbandoned;472 return error.WaitAbandoned;
469 },473 },
470 WAIT_TIMEOUT => return error.WaitTimeOut,474 WAIT_TIMEOUT => return error.WaitTimeOut,
471 WAIT_FAILED => switch (kernel32.GetLastError()) {475 WAIT_FAILED => switch (GetLastError()) {
472 else => |err| return unexpectedError(err),476 else => |err| return unexpectedError(err),
473 },477 },
474 else => return error.Unexpected,478 else => return error.Unexpected,
...@@ -484,7 +488,7 @@ pub fn CreateIoCompletionPort(...@@ -484,7 +488,7 @@ pub fn CreateIoCompletionPort(
484 concurrent_thread_count: DWORD,488 concurrent_thread_count: DWORD,
485) CreateIoCompletionPortError!HANDLE {489) CreateIoCompletionPortError!HANDLE {
486 const handle = kernel32.CreateIoCompletionPort(file_handle, existing_completion_port, completion_key, concurrent_thread_count) orelse {490 const handle = kernel32.CreateIoCompletionPort(file_handle, existing_completion_port, completion_key, concurrent_thread_count) orelse {
487 switch (kernel32.GetLastError()) {491 switch (GetLastError()) {
488 .INVALID_PARAMETER => unreachable,492 .INVALID_PARAMETER => unreachable,
489 else => |err| return unexpectedError(err),493 else => |err| return unexpectedError(err),
490 }494 }
...@@ -501,7 +505,7 @@ pub fn PostQueuedCompletionStatus(...@@ -501,7 +505,7 @@ pub fn PostQueuedCompletionStatus(
501 lpOverlapped: ?*OVERLAPPED,505 lpOverlapped: ?*OVERLAPPED,
502) PostQueuedCompletionStatusError!void {506) PostQueuedCompletionStatusError!void {
503 if (kernel32.PostQueuedCompletionStatus(completion_port, bytes_transferred_count, completion_key, lpOverlapped) == 0) {507 if (kernel32.PostQueuedCompletionStatus(completion_port, bytes_transferred_count, completion_key, lpOverlapped) == 0) {
504 switch (kernel32.GetLastError()) {508 switch (GetLastError()) {
505 else => |err| return unexpectedError(err),509 else => |err| return unexpectedError(err),
506 }510 }
507 }511 }
...@@ -528,7 +532,7 @@ pub fn GetQueuedCompletionStatus(...@@ -528,7 +532,7 @@ pub fn GetQueuedCompletionStatus(
528 lpOverlapped,532 lpOverlapped,
529 dwMilliseconds,533 dwMilliseconds,
530 ) == FALSE) {534 ) == FALSE) {
531 switch (kernel32.GetLastError()) {535 switch (GetLastError()) {
532 .ABANDONED_WAIT_0 => return GetQueuedCompletionStatusResult.Aborted,536 .ABANDONED_WAIT_0 => return GetQueuedCompletionStatusResult.Aborted,
533 .OPERATION_ABORTED => return GetQueuedCompletionStatusResult.Cancelled,537 .OPERATION_ABORTED => return GetQueuedCompletionStatusResult.Cancelled,
534 .HANDLE_EOF => return GetQueuedCompletionStatusResult.EOF,538 .HANDLE_EOF => return GetQueuedCompletionStatusResult.EOF,
...@@ -568,7 +572,7 @@ pub fn GetQueuedCompletionStatusEx(...@@ -568,7 +572,7 @@ pub fn GetQueuedCompletionStatusEx(
568 );572 );
569573
570 if (success == FALSE) {574 if (success == FALSE) {
571 return switch (kernel32.GetLastError()) {575 return switch (GetLastError()) {
572 .ABANDONED_WAIT_0 => error.Aborted,576 .ABANDONED_WAIT_0 => error.Aborted,
573 .OPERATION_ABORTED => error.Cancelled,577 .OPERATION_ABORTED => error.Cancelled,
574 .HANDLE_EOF => error.EOF,578 .HANDLE_EOF => error.EOF,
...@@ -618,7 +622,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz...@@ -618,7 +622,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64) ReadFileError!usiz
618 break :blk &overlapped_data;622 break :blk &overlapped_data;
619 } else null;623 } else null;
620 if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) {624 if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) {
621 switch (kernel32.GetLastError()) {625 switch (GetLastError()) {
622 .IO_PENDING => unreachable,626 .IO_PENDING => unreachable,
623 .OPERATION_ABORTED => continue,627 .OPERATION_ABORTED => continue,
624 .BROKEN_PIPE => return 0,628 .BROKEN_PIPE => return 0,
...@@ -667,7 +671,7 @@ pub fn WriteFile(...@@ -667,7 +671,7 @@ pub fn WriteFile(
667 } else null;671 } else null;
668 const adjusted_len = math.cast(u32, bytes.len) orelse maxInt(u32);672 const adjusted_len = math.cast(u32, bytes.len) orelse maxInt(u32);
669 if (kernel32.WriteFile(handle, bytes.ptr, adjusted_len, &bytes_written, overlapped) == 0) {673 if (kernel32.WriteFile(handle, bytes.ptr, adjusted_len, &bytes_written, overlapped) == 0) {
670 switch (kernel32.GetLastError()) {674 switch (GetLastError()) {
671 .INVALID_USER_BUFFER => return error.SystemResources,675 .INVALID_USER_BUFFER => return error.SystemResources,
672 .NOT_ENOUGH_MEMORY => return error.SystemResources,676 .NOT_ENOUGH_MEMORY => return error.SystemResources,
673 .OPERATION_ABORTED => return error.OperationAborted,677 .OPERATION_ABORTED => return error.OperationAborted,
...@@ -728,7 +732,7 @@ pub fn GetCurrentDirectory(buffer: []u8) GetCurrentDirectoryError![]u8 {...@@ -728,7 +732,7 @@ pub fn GetCurrentDirectory(buffer: []u8) GetCurrentDirectoryError![]u8 {
728 var wtf16le_buf: [PATH_MAX_WIDE]u16 = undefined;732 var wtf16le_buf: [PATH_MAX_WIDE]u16 = undefined;
729 const result = kernel32.GetCurrentDirectoryW(wtf16le_buf.len, &wtf16le_buf);733 const result = kernel32.GetCurrentDirectoryW(wtf16le_buf.len, &wtf16le_buf);
730 if (result == 0) {734 if (result == 0) {
731 switch (kernel32.GetLastError()) {735 switch (GetLastError()) {
732 else => |err| return unexpectedError(err),736 else => |err| return unexpectedError(err),
733 }737 }
734 }738 }
...@@ -1109,7 +1113,7 @@ pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) Move...@@ -1109,7 +1113,7 @@ pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) Move
11091113
1110pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DWORD) MoveFileError!void {1114pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DWORD) MoveFileError!void {
1111 if (kernel32.MoveFileExW(old_path, new_path, flags) == 0) {1115 if (kernel32.MoveFileExW(old_path, new_path, flags) == 0) {
1112 switch (kernel32.GetLastError()) {1116 switch (GetLastError()) {
1113 .FILE_NOT_FOUND => return error.FileNotFound,1117 .FILE_NOT_FOUND => return error.FileNotFound,
1114 .ACCESS_DENIED => return error.AccessDenied,1118 .ACCESS_DENIED => return error.AccessDenied,
1115 else => |err| return unexpectedError(err),1119 else => |err| return unexpectedError(err),
...@@ -1125,7 +1129,7 @@ pub const GetStdHandleError = error{...@@ -1125,7 +1129,7 @@ pub const GetStdHandleError = error{
1125pub fn GetStdHandle(handle_id: DWORD) GetStdHandleError!HANDLE {1129pub fn GetStdHandle(handle_id: DWORD) GetStdHandleError!HANDLE {
1126 const handle = kernel32.GetStdHandle(handle_id) orelse return error.NoStandardHandleAttached;1130 const handle = kernel32.GetStdHandle(handle_id) orelse return error.NoStandardHandleAttached;
1127 if (handle == INVALID_HANDLE_VALUE) {1131 if (handle == INVALID_HANDLE_VALUE) {
1128 switch (kernel32.GetLastError()) {1132 switch (GetLastError()) {
1129 else => |err| return unexpectedError(err),1133 else => |err| return unexpectedError(err),
1130 }1134 }
1131 }1135 }
...@@ -1141,7 +1145,7 @@ pub fn SetFilePointerEx_BEGIN(handle: HANDLE, offset: u64) SetFilePointerError!v...@@ -1141,7 +1145,7 @@ pub fn SetFilePointerEx_BEGIN(handle: HANDLE, offset: u64) SetFilePointerError!v
1141 // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-setfilepointerex1145 // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-setfilepointerex
1142 const ipos = @as(LARGE_INTEGER, @bitCast(offset));1146 const ipos = @as(LARGE_INTEGER, @bitCast(offset));
1143 if (kernel32.SetFilePointerEx(handle, ipos, null, FILE_BEGIN) == 0) {1147 if (kernel32.SetFilePointerEx(handle, ipos, null, FILE_BEGIN) == 0) {
1144 switch (kernel32.GetLastError()) {1148 switch (GetLastError()) {
1145 .INVALID_PARAMETER => unreachable,1149 .INVALID_PARAMETER => unreachable,
1146 .INVALID_HANDLE => unreachable,1150 .INVALID_HANDLE => unreachable,
1147 else => |err| return unexpectedError(err),1151 else => |err| return unexpectedError(err),
...@@ -1152,7 +1156,7 @@ pub fn SetFilePointerEx_BEGIN(handle: HANDLE, offset: u64) SetFilePointerError!v...@@ -1152,7 +1156,7 @@ pub fn SetFilePointerEx_BEGIN(handle: HANDLE, offset: u64) SetFilePointerError!v
1152/// The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_CURRENT`.1156/// The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_CURRENT`.
1153pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError!void {1157pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError!void {
1154 if (kernel32.SetFilePointerEx(handle, offset, null, FILE_CURRENT) == 0) {1158 if (kernel32.SetFilePointerEx(handle, offset, null, FILE_CURRENT) == 0) {
1155 switch (kernel32.GetLastError()) {1159 switch (GetLastError()) {
1156 .INVALID_PARAMETER => unreachable,1160 .INVALID_PARAMETER => unreachable,
1157 .INVALID_HANDLE => unreachable,1161 .INVALID_HANDLE => unreachable,
1158 else => |err| return unexpectedError(err),1162 else => |err| return unexpectedError(err),
...@@ -1163,7 +1167,7 @@ pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError...@@ -1163,7 +1167,7 @@ pub fn SetFilePointerEx_CURRENT(handle: HANDLE, offset: i64) SetFilePointerError
1163/// The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_END`.1167/// The SetFilePointerEx function with the `dwMoveMethod` parameter set to `FILE_END`.
1164pub fn SetFilePointerEx_END(handle: HANDLE, offset: i64) SetFilePointerError!void {1168pub fn SetFilePointerEx_END(handle: HANDLE, offset: i64) SetFilePointerError!void {
1165 if (kernel32.SetFilePointerEx(handle, offset, null, FILE_END) == 0) {1169 if (kernel32.SetFilePointerEx(handle, offset, null, FILE_END) == 0) {
1166 switch (kernel32.GetLastError()) {1170 switch (GetLastError()) {
1167 .INVALID_PARAMETER => unreachable,1171 .INVALID_PARAMETER => unreachable,
1168 .INVALID_HANDLE => unreachable,1172 .INVALID_HANDLE => unreachable,
1169 else => |err| return unexpectedError(err),1173 else => |err| return unexpectedError(err),
...@@ -1175,7 +1179,7 @@ pub fn SetFilePointerEx_END(handle: HANDLE, offset: i64) SetFilePointerError!voi...@@ -1175,7 +1179,7 @@ pub fn SetFilePointerEx_END(handle: HANDLE, offset: i64) SetFilePointerError!voi
1175pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 {1179pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 {
1176 var result: LARGE_INTEGER = undefined;1180 var result: LARGE_INTEGER = undefined;
1177 if (kernel32.SetFilePointerEx(handle, 0, &result, FILE_CURRENT) == 0) {1181 if (kernel32.SetFilePointerEx(handle, 0, &result, FILE_CURRENT) == 0) {
1178 switch (kernel32.GetLastError()) {1182 switch (GetLastError()) {
1179 .INVALID_PARAMETER => unreachable,1183 .INVALID_PARAMETER => unreachable,
1180 .INVALID_HANDLE => unreachable,1184 .INVALID_HANDLE => unreachable,
1181 else => |err| return unexpectedError(err),1185 else => |err| return unexpectedError(err),
...@@ -1489,7 +1493,7 @@ pub const GetFileSizeError = error{Unexpected};...@@ -1489,7 +1493,7 @@ pub const GetFileSizeError = error{Unexpected};
1489pub fn GetFileSizeEx(hFile: HANDLE) GetFileSizeError!u64 {1493pub fn GetFileSizeEx(hFile: HANDLE) GetFileSizeError!u64 {
1490 var file_size: LARGE_INTEGER = undefined;1494 var file_size: LARGE_INTEGER = undefined;
1491 if (kernel32.GetFileSizeEx(hFile, &file_size) == 0) {1495 if (kernel32.GetFileSizeEx(hFile, &file_size) == 0) {
1492 switch (kernel32.GetLastError()) {1496 switch (GetLastError()) {
1493 else => |err| return unexpectedError(err),1497 else => |err| return unexpectedError(err),
1494 }1498 }
1495 }1499 }
...@@ -1510,7 +1514,7 @@ pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD {...@@ -1510,7 +1514,7 @@ pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD {
1510pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWORD {1514pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWORD {
1511 const rc = kernel32.GetFileAttributesW(lpFileName);1515 const rc = kernel32.GetFileAttributesW(lpFileName);
1512 if (rc == INVALID_FILE_ATTRIBUTES) {1516 if (rc == INVALID_FILE_ATTRIBUTES) {
1513 switch (kernel32.GetLastError()) {1517 switch (GetLastError()) {
1514 .FILE_NOT_FOUND => return error.FileNotFound,1518 .FILE_NOT_FOUND => return error.FileNotFound,
1515 .PATH_NOT_FOUND => return error.FileNotFound,1519 .PATH_NOT_FOUND => return error.FileNotFound,
1516 .ACCESS_DENIED => return error.PermissionDenied,1520 .ACCESS_DENIED => return error.PermissionDenied,
...@@ -1721,7 +1725,7 @@ const GetModuleFileNameError = error{Unexpected};...@@ -1721,7 +1725,7 @@ const GetModuleFileNameError = error{Unexpected};
1721pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![:0]u16 {1725pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![:0]u16 {
1722 const rc = kernel32.GetModuleFileNameW(hModule, buf_ptr, buf_len);1726 const rc = kernel32.GetModuleFileNameW(hModule, buf_ptr, buf_len);
1723 if (rc == 0) {1727 if (rc == 0) {
1724 switch (kernel32.GetLastError()) {1728 switch (GetLastError()) {
1725 else => |err| return unexpectedError(err),1729 else => |err| return unexpectedError(err),
1726 }1730 }
1727 }1731 }
...@@ -1732,7 +1736,7 @@ pub const TerminateProcessError = error{ PermissionDenied, Unexpected };...@@ -1732,7 +1736,7 @@ pub const TerminateProcessError = error{ PermissionDenied, Unexpected };
17321736
1733pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) TerminateProcessError!void {1737pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) TerminateProcessError!void {
1734 if (kernel32.TerminateProcess(hProcess, uExitCode) == 0) {1738 if (kernel32.TerminateProcess(hProcess, uExitCode) == 0) {
1735 switch (kernel32.GetLastError()) {1739 switch (GetLastError()) {
1736 Win32Error.ACCESS_DENIED => return error.PermissionDenied,1740 Win32Error.ACCESS_DENIED => return error.PermissionDenied,
1737 else => |err| return unexpectedError(err),1741 else => |err| return unexpectedError(err),
1738 }1742 }
...@@ -1743,7 +1747,7 @@ pub const VirtualAllocError = error{Unexpected};...@@ -1743,7 +1747,7 @@ pub const VirtualAllocError = error{Unexpected};
17431747
1744pub fn VirtualAlloc(addr: ?LPVOID, size: usize, alloc_type: DWORD, flProtect: DWORD) VirtualAllocError!LPVOID {1748pub fn VirtualAlloc(addr: ?LPVOID, size: usize, alloc_type: DWORD, flProtect: DWORD) VirtualAllocError!LPVOID {
1745 return kernel32.VirtualAlloc(addr, size, alloc_type, flProtect) orelse {1749 return kernel32.VirtualAlloc(addr, size, alloc_type, flProtect) orelse {
1746 switch (kernel32.GetLastError()) {1750 switch (GetLastError()) {
1747 else => |err| return unexpectedError(err),1751 else => |err| return unexpectedError(err),
1748 }1752 }
1749 };1753 };
...@@ -1792,7 +1796,7 @@ pub const VirtualQueryError = error{Unexpected};...@@ -1792,7 +1796,7 @@ pub const VirtualQueryError = error{Unexpected};
1792pub fn VirtualQuery(lpAddress: ?LPVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T) VirtualQueryError!SIZE_T {1796pub fn VirtualQuery(lpAddress: ?LPVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T) VirtualQueryError!SIZE_T {
1793 const rc = kernel32.VirtualQuery(lpAddress, lpBuffer, dwLength);1797 const rc = kernel32.VirtualQuery(lpAddress, lpBuffer, dwLength);
1794 if (rc == 0) {1798 if (rc == 0) {
1795 switch (kernel32.GetLastError()) {1799 switch (GetLastError()) {
1796 else => |err| return unexpectedError(err),1800 else => |err| return unexpectedError(err),
1797 }1801 }
1798 }1802 }
...@@ -1804,7 +1808,7 @@ pub const SetConsoleTextAttributeError = error{Unexpected};...@@ -1804,7 +1808,7 @@ pub const SetConsoleTextAttributeError = error{Unexpected};
18041808
1805pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetConsoleTextAttributeError!void {1809pub fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) SetConsoleTextAttributeError!void {
1806 if (kernel32.SetConsoleTextAttribute(hConsoleOutput, wAttributes) == 0) {1810 if (kernel32.SetConsoleTextAttribute(hConsoleOutput, wAttributes) == 0) {
1807 switch (kernel32.GetLastError()) {1811 switch (GetLastError()) {
1808 else => |err| return unexpectedError(err),1812 else => |err| return unexpectedError(err),
1809 }1813 }
1810 }1814 }
...@@ -1817,7 +1821,7 @@ pub fn SetConsoleCtrlHandler(handler_routine: ?HANDLER_ROUTINE, add: bool) !void...@@ -1817,7 +1821,7 @@ pub fn SetConsoleCtrlHandler(handler_routine: ?HANDLER_ROUTINE, add: bool) !void
1817 );1821 );
18181822
1819 if (success == FALSE) {1823 if (success == FALSE) {
1820 return switch (kernel32.GetLastError()) {1824 return switch (GetLastError()) {
1821 else => |err| unexpectedError(err),1825 else => |err| unexpectedError(err),
1822 };1826 };
1823 }1827 }
...@@ -1826,7 +1830,7 @@ pub fn SetConsoleCtrlHandler(handler_routine: ?HANDLER_ROUTINE, add: bool) !void...@@ -1826,7 +1830,7 @@ pub fn SetConsoleCtrlHandler(handler_routine: ?HANDLER_ROUTINE, add: bool) !void
1826pub fn SetFileCompletionNotificationModes(handle: HANDLE, flags: UCHAR) !void {1830pub fn SetFileCompletionNotificationModes(handle: HANDLE, flags: UCHAR) !void {
1827 const success = kernel32.SetFileCompletionNotificationModes(handle, flags);1831 const success = kernel32.SetFileCompletionNotificationModes(handle, flags);
1828 if (success == FALSE) {1832 if (success == FALSE) {
1829 return switch (kernel32.GetLastError()) {1833 return switch (GetLastError()) {
1830 else => |err| unexpectedError(err),1834 else => |err| unexpectedError(err),
1831 };1835 };
1832 }1836 }
...@@ -1850,7 +1854,7 @@ pub const GetEnvironmentVariableError = error{...@@ -1850,7 +1854,7 @@ pub const GetEnvironmentVariableError = error{
1850pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: [*]u16, nSize: DWORD) GetEnvironmentVariableError!DWORD {1854pub fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: [*]u16, nSize: DWORD) GetEnvironmentVariableError!DWORD {
1851 const rc = kernel32.GetEnvironmentVariableW(lpName, lpBuffer, nSize);1855 const rc = kernel32.GetEnvironmentVariableW(lpName, lpBuffer, nSize);
1852 if (rc == 0) {1856 if (rc == 0) {
1853 switch (kernel32.GetLastError()) {1857 switch (GetLastError()) {
1854 .ENVVAR_NOT_FOUND => return error.EnvironmentVariableNotFound,1858 .ENVVAR_NOT_FOUND => return error.EnvironmentVariableNotFound,
1855 else => |err| return unexpectedError(err),1859 else => |err| return unexpectedError(err),
1856 }1860 }
...@@ -1891,7 +1895,7 @@ pub fn CreateProcessW(...@@ -1891,7 +1895,7 @@ pub fn CreateProcessW(
1891 lpStartupInfo,1895 lpStartupInfo,
1892 lpProcessInformation,1896 lpProcessInformation,
1893 ) == 0) {1897 ) == 0) {
1894 switch (kernel32.GetLastError()) {1898 switch (GetLastError()) {
1895 .FILE_NOT_FOUND => return error.FileNotFound,1899 .FILE_NOT_FOUND => return error.FileNotFound,
1896 .PATH_NOT_FOUND => return error.FileNotFound,1900 .PATH_NOT_FOUND => return error.FileNotFound,
1897 .ACCESS_DENIED => return error.AccessDenied,1901 .ACCESS_DENIED => return error.AccessDenied,
...@@ -1934,7 +1938,7 @@ pub const LoadLibraryError = error{...@@ -1934,7 +1938,7 @@ pub const LoadLibraryError = error{
19341938
1935pub fn LoadLibraryW(lpLibFileName: [*:0]const u16) LoadLibraryError!HMODULE {1939pub fn LoadLibraryW(lpLibFileName: [*:0]const u16) LoadLibraryError!HMODULE {
1936 return kernel32.LoadLibraryW(lpLibFileName) orelse {1940 return kernel32.LoadLibraryW(lpLibFileName) orelse {
1937 switch (kernel32.GetLastError()) {1941 switch (GetLastError()) {
1938 .FILE_NOT_FOUND => return error.FileNotFound,1942 .FILE_NOT_FOUND => return error.FileNotFound,
1939 .PATH_NOT_FOUND => return error.FileNotFound,1943 .PATH_NOT_FOUND => return error.FileNotFound,
1940 .MOD_NOT_FOUND => return error.FileNotFound,1944 .MOD_NOT_FOUND => return error.FileNotFound,
...@@ -1962,7 +1966,7 @@ pub const LoadLibraryFlags = enum(DWORD) {...@@ -1962,7 +1966,7 @@ pub const LoadLibraryFlags = enum(DWORD) {
19621966
1963pub fn LoadLibraryExW(lpLibFileName: [*:0]const u16, dwFlags: LoadLibraryFlags) LoadLibraryError!HMODULE {1967pub fn LoadLibraryExW(lpLibFileName: [*:0]const u16, dwFlags: LoadLibraryFlags) LoadLibraryError!HMODULE {
1964 return kernel32.LoadLibraryExW(lpLibFileName, null, @intFromEnum(dwFlags)) orelse {1968 return kernel32.LoadLibraryExW(lpLibFileName, null, @intFromEnum(dwFlags)) orelse {
1965 switch (kernel32.GetLastError()) {1969 switch (GetLastError()) {
1966 .FILE_NOT_FOUND => return error.FileNotFound,1970 .FILE_NOT_FOUND => return error.FileNotFound,
1967 .PATH_NOT_FOUND => return error.FileNotFound,1971 .PATH_NOT_FOUND => return error.FileNotFound,
1968 .MOD_NOT_FOUND => return error.FileNotFound,1972 .MOD_NOT_FOUND => return error.FileNotFound,
...@@ -2019,7 +2023,7 @@ pub fn SetFileTime(...@@ -2019,7 +2023,7 @@ pub fn SetFileTime(
2019) SetFileTimeError!void {2023) SetFileTimeError!void {
2020 const rc = kernel32.SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);2024 const rc = kernel32.SetFileTime(hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);
2021 if (rc == 0) {2025 if (rc == 0) {
2022 switch (kernel32.GetLastError()) {2026 switch (GetLastError()) {
2023 else => |err| return unexpectedError(err),2027 else => |err| return unexpectedError(err),
2024 }2028 }
2025 }2029 }
...@@ -2709,7 +2713,7 @@ fn testNtToWin32Namespace(expected: []const u16, path: []const u16) !void {...@@ -2709,7 +2713,7 @@ fn testNtToWin32Namespace(expected: []const u16, path: []const u16) !void {
2709fn getFullPathNameW(path: [*:0]const u16, out: []u16) !usize {2713fn getFullPathNameW(path: [*:0]const u16, out: []u16) !usize {
2710 const result = kernel32.GetFullPathNameW(path, @as(u32, @intCast(out.len)), out.ptr, null);2714 const result = kernel32.GetFullPathNameW(path, @as(u32, @intCast(out.len)), out.ptr, null);
2711 if (result == 0) {2715 if (result == 0) {
2712 switch (kernel32.GetLastError()) {2716 switch (GetLastError()) {
2713 else => |err| return unexpectedError(err),2717 else => |err| return unexpectedError(err),
2714 }2718 }
2715 }2719 }
...@@ -4430,7 +4434,8 @@ pub const TEB = extern struct {...@@ -4430,7 +4434,8 @@ pub const TEB = extern struct {
4430 ActiveRpcHandle: PVOID,4434 ActiveRpcHandle: PVOID,
4431 ThreadLocalStoragePointer: PVOID,4435 ThreadLocalStoragePointer: PVOID,
4432 ProcessEnvironmentBlock: *PEB,4436 ProcessEnvironmentBlock: *PEB,
4433 Reserved2: [399]PVOID,4437 LastErrorValue: ULONG,
4438 Reserved2: [399 * @sizeOf(PVOID) - @sizeOf(ULONG)]u8,
4434 Reserved3: [1952]u8,4439 Reserved3: [1952]u8,
4435 TlsSlots: [64]PVOID,4440 TlsSlots: [64]PVOID,
4436 Reserved4: [8]u8,4441 Reserved4: [8]u8,
...@@ -4450,12 +4455,16 @@ comptime {...@@ -4450,12 +4455,16 @@ comptime {
4450 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28);4455 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x28);
4451 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C);4456 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x2C);
4452 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);4457 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x30);
4458 assert(@offsetOf(TEB, "LastErrorValue") == 0x34);
4459 assert(@offsetOf(TEB, "TlsSlots") == 0xe10);
4453 } else if (@sizeOf(usize) == 8) {4460 } else if (@sizeOf(usize) == 8) {
4454 assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38);4461 assert(@offsetOf(TEB, "EnvironmentPointer") == 0x38);
4455 assert(@offsetOf(TEB, "ClientId") == 0x40);4462 assert(@offsetOf(TEB, "ClientId") == 0x40);
4456 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50);4463 assert(@offsetOf(TEB, "ActiveRpcHandle") == 0x50);
4457 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58);4464 assert(@offsetOf(TEB, "ThreadLocalStoragePointer") == 0x58);
4458 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);4465 assert(@offsetOf(TEB, "ProcessEnvironmentBlock") == 0x60);
4466 assert(@offsetOf(TEB, "LastErrorValue") == 0x68);
4467 assert(@offsetOf(TEB, "TlsSlots") == 0x1480);
4459 }4468 }
4460}4469}
44614470
lib/std/posix.zig+1-1
...@@ -6912,7 +6912,7 @@ pub fn fsync(fd: fd_t) SyncError!void {...@@ -6912,7 +6912,7 @@ pub fn fsync(fd: fd_t) SyncError!void {
6912 if (native_os == .windows) {6912 if (native_os == .windows) {
6913 if (windows.kernel32.FlushFileBuffers(fd) != 0)6913 if (windows.kernel32.FlushFileBuffers(fd) != 0)
6914 return;6914 return;
6915 switch (windows.kernel32.GetLastError()) {6915 switch (windows.GetLastError()) {
6916 .SUCCESS => return,6916 .SUCCESS => return,
6917 .INVALID_HANDLE => unreachable,6917 .INVALID_HANDLE => unreachable,
6918 .ACCESS_DENIED => return error.AccessDenied, // a sync was performed but the system couldn't update the access time6918 .ACCESS_DENIED => return error.AccessDenied, // a sync was performed but the system couldn't update the access time
lib/std/process/Child.zig+3-3
...@@ -1358,7 +1358,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons...@@ -1358,7 +1358,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
1358 sattr,1358 sattr,
1359 );1359 );
1360 if (read_handle == windows.INVALID_HANDLE_VALUE) {1360 if (read_handle == windows.INVALID_HANDLE_VALUE) {
1361 switch (windows.kernel32.GetLastError()) {1361 switch (windows.GetLastError()) {
1362 else => |err| return windows.unexpectedError(err),1362 else => |err| return windows.unexpectedError(err),
1363 }1363 }
1364 }1364 }
...@@ -1375,7 +1375,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons...@@ -1375,7 +1375,7 @@ fn windowsMakeAsyncPipe(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *cons
1375 null,1375 null,
1376 );1376 );
1377 if (write_handle == windows.INVALID_HANDLE_VALUE) {1377 if (write_handle == windows.INVALID_HANDLE_VALUE) {
1378 switch (windows.kernel32.GetLastError()) {1378 switch (windows.GetLastError()) {
1379 else => |err| return windows.unexpectedError(err),1379 else => |err| return windows.unexpectedError(err),
1380 }1380 }
1381 }1381 }
...@@ -1529,7 +1529,7 @@ fn windowsCmdExePath(allocator: mem.Allocator) error{ OutOfMemory, Unexpected }!...@@ -1529,7 +1529,7 @@ fn windowsCmdExePath(allocator: mem.Allocator) error{ OutOfMemory, Unexpected }!
1529 // TODO: Get the system directory from PEB.ReadOnlyStaticServerData1529 // TODO: Get the system directory from PEB.ReadOnlyStaticServerData
1530 const len = windows.kernel32.GetSystemDirectoryW(@ptrCast(unused_slice), @intCast(unused_slice.len));1530 const len = windows.kernel32.GetSystemDirectoryW(@ptrCast(unused_slice), @intCast(unused_slice.len));
1531 if (len == 0) {1531 if (len == 0) {
1532 switch (windows.kernel32.GetLastError()) {1532 switch (windows.GetLastError()) {
1533 else => |err| return windows.unexpectedError(err),1533 else => |err| return windows.unexpectedError(err),
1534 }1534 }
1535 }1535 }