authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-03-14 10:03:09-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-03-18 20:13:59-04:00
log9ac1386c10736bc249f3891f34f23424531917a5
tree6d4add363167dc82c3cceb70ce22ac0e360c61b7
parent08416b44f92a0917ad8b71829704674477752788

std.Io.Threaded: windows networking without ws2_32


30 files changed, 2314 insertions(+), 3357 deletions(-)

ci/x86_64-windows-debug.ps1+1-1
...@@ -85,7 +85,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\...@@ -85,7 +85,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\
85CheckLastExitCode85CheckLastExitCode
8686
87Write-Output "Build and run behavior tests with msvc..."87Write-Output "Build and run behavior tests with msvc..."
88cl /I..\lib /W3 /Z7 behavior-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /link /nologo /debug /subsystem:console kernel32.lib ntdll.lib libcmt.lib ws2_32.lib88cl /I..\lib /W3 /Z7 behavior-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /link /nologo /debug /subsystem:console kernel32.lib ntdll.lib libcmt.lib
89CheckLastExitCode89CheckLastExitCode
9090
91.\behavior-x86_64-windows-msvc91.\behavior-x86_64-windows-msvc
ci/x86_64-windows-release.ps1+1-1
...@@ -104,7 +104,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\...@@ -104,7 +104,7 @@ Enter-VsDevShell -VsInstallPath "C:\Program Files (x86)\Microsoft Visual Studio\
104CheckLastExitCode104CheckLastExitCode
105105
106Write-Output "Build and run behavior tests with msvc..."106Write-Output "Build and run behavior tests with msvc..."
107cl /I..\lib /W3 /Z7 behavior-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /link /nologo /debug /subsystem:console kernel32.lib ntdll.lib libcmt.lib ws2_32.lib107cl /I..\lib /W3 /Z7 behavior-x86_64-windows-msvc.c compiler_rt-x86_64-windows-msvc.c /link /nologo /debug /subsystem:console kernel32.lib ntdll.lib libcmt.lib
108CheckLastExitCode108CheckLastExitCode
109109
110.\behavior-x86_64-windows-msvc110.\behavior-x86_64-windows-msvc
lib/std/Build/Watch.zig+2-2
...@@ -354,7 +354,7 @@ const Os = switch (builtin.os.tag) {...@@ -354,7 +354,7 @@ const Os = switch (builtin.os.tag) {
354 }354 }
355 }355 }
356356
357 fn notifyApc(apc_context: ?*anyopaque, iosb: *windows.IO_STATUS_BLOCK, _: windows.ULONG) callconv(.winapi) void {357 fn notifyApc(apc_context: ?*anyopaque, iosb: *windows.IO_STATUS_BLOCK, _: windows.ULONG) align(std.Io.Threaded.apc_align) callconv(.winapi) void {
358 const w: *Watch = @ptrCast(@alignCast(apc_context));358 const w: *Watch = @ptrCast(@alignCast(apc_context));
359 const dir: *Directory = @fieldParentPtr("iosb", iosb);359 const dir: *Directory = @fieldParentPtr("iosb", iosb);
360 assert(iosb.u.Status != .PENDING);360 assert(iosb.u.Status != .PENDING);
...@@ -369,7 +369,7 @@ const Os = switch (builtin.os.tag) {...@@ -369,7 +369,7 @@ const Os = switch (builtin.os.tag) {
369 var dir_handle: windows.HANDLE = undefined;369 var dir_handle: windows.HANDLE = undefined;
370 const root_fd = path.root_dir.handle.handle;370 const root_fd = path.root_dir.handle.handle;
371 const sub_path = path.subPathOrDot();371 const sub_path = path.subPathOrDot();
372 const sub_path_w = try Io.Threaded.sliceToPrefixedFileW(root_fd, sub_path); // TODO eliminate this call372 const sub_path_w = try Io.Threaded.sliceToPrefixedFileW(root_fd, sub_path, .{}); // TODO eliminate this call
373 var iosb: windows.IO_STATUS_BLOCK = undefined;373 var iosb: windows.IO_STATUS_BLOCK = undefined;
374 switch (windows.ntdll.NtCreateFile(374 switch (windows.ntdll.NtCreateFile(
375 &dir_handle,375 &dir_handle,
lib/std/Io.zig+3-3
...@@ -235,10 +235,10 @@ pub const VTable = struct {...@@ -235,10 +235,10 @@ pub const VTable = struct {
235 random: *const fn (?*anyopaque, buffer: []u8) void,235 random: *const fn (?*anyopaque, buffer: []u8) void,
236 randomSecure: *const fn (?*anyopaque, buffer: []u8) RandomSecureError!void,236 randomSecure: *const fn (?*anyopaque, buffer: []u8) RandomSecureError!void,
237237
238 netListenIp: *const fn (?*anyopaque, address: net.IpAddress, net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Server,238 netListenIp: *const fn (?*anyopaque, address: *const net.IpAddress, net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Socket,
239 netAccept: *const fn (?*anyopaque, server: net.Socket.Handle) net.Server.AcceptError!net.Stream,239 netAccept: *const fn (?*anyopaque, server: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket,
240 netBindIp: *const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket,240 netBindIp: *const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket,
241 netConnectIp: *const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Stream,241 netConnectIp: *const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Socket,
242 netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle,242 netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle,
243 netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle,243 netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle,
244 netSocketCreatePair: *const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket,244 netSocketCreatePair: *const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket,
lib/std/Io/Dispatch.zig+6-4
...@@ -4784,9 +4784,9 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {...@@ -4784,9 +4784,9 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
47844784
4785fn netListenIpUnavailable(4785fn netListenIpUnavailable(
4786 userdata: ?*anyopaque,4786 userdata: ?*anyopaque,
4787 address: net.IpAddress,4787 address: *const net.IpAddress,
4788 options: net.IpAddress.ListenOptions,4788 options: net.IpAddress.ListenOptions,
4789) net.IpAddress.ListenError!net.Server {4789) net.IpAddress.ListenError!net.Socket {
4790 const ev: *Evented = @ptrCast(@alignCast(userdata));4790 const ev: *Evented = @ptrCast(@alignCast(userdata));
4791 _ = ev;4791 _ = ev;
4792 _ = address;4792 _ = address;
...@@ -4797,10 +4797,12 @@ fn netListenIpUnavailable(...@@ -4797,10 +4797,12 @@ fn netListenIpUnavailable(
4797fn netAcceptUnavailable(4797fn netAcceptUnavailable(
4798 userdata: ?*anyopaque,4798 userdata: ?*anyopaque,
4799 listen_handle: net.Socket.Handle,4799 listen_handle: net.Socket.Handle,
4800) net.Server.AcceptError!net.Stream {4800 options: net.Server.AcceptOptions,
4801) net.Server.AcceptError!net.Socket {
4801 const ev: *Evented = @ptrCast(@alignCast(userdata));4802 const ev: *Evented = @ptrCast(@alignCast(userdata));
4802 _ = ev;4803 _ = ev;
4803 _ = listen_handle;4804 _ = listen_handle;
4805 _ = options;
4804 return error.NetworkDown;4806 return error.NetworkDown;
4805}4807}
48064808
...@@ -4820,7 +4822,7 @@ fn netConnectIpUnavailable(...@@ -4820,7 +4822,7 @@ fn netConnectIpUnavailable(
4820 userdata: ?*anyopaque,4822 userdata: ?*anyopaque,
4821 address: *const net.IpAddress,4823 address: *const net.IpAddress,
4822 options: net.IpAddress.ConnectOptions,4824 options: net.IpAddress.ConnectOptions,
4823) net.IpAddress.ConnectError!net.Stream {4825) net.IpAddress.ConnectError!net.Socket {
4824 const ev: *Evented = @ptrCast(@alignCast(userdata));4826 const ev: *Evented = @ptrCast(@alignCast(userdata));
4825 _ = ev;4827 _ = ev;
4826 _ = address;4828 _ = address;
lib/std/Io/Kqueue.zig+9-14
...@@ -13,6 +13,7 @@ const IpAddress = std.Io.net.IpAddress;...@@ -13,6 +13,7 @@ const IpAddress = std.Io.net.IpAddress;
13const errnoBug = std.Io.Threaded.errnoBug;13const errnoBug = std.Io.Threaded.errnoBug;
14const closeFd = std.Io.Threaded.closeFd;14const closeFd = std.Io.Threaded.closeFd;
15const posix = std.posix;15const posix = std.posix;
16const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;
1617
17/// Must be a thread-safe allocator.18/// Must be a thread-safe allocator.
18gpa: Allocator,19gpa: Allocator,
...@@ -1000,19 +1001,20 @@ fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -1000,19 +1001,20 @@ fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
10001001
1001fn netListenIp(1002fn netListenIp(
1002 userdata: ?*anyopaque,1003 userdata: ?*anyopaque,
1003 address: net.IpAddress,1004 address: *const net.IpAddress,
1004 options: net.IpAddress.ListenOptions,1005 options: net.IpAddress.ListenOptions,
1005) net.IpAddress.ListenError!net.Server {1006) net.IpAddress.ListenError!net.Socket {
1006 const k: *Kqueue = @ptrCast(@alignCast(userdata));1007 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1007 _ = k;1008 _ = k;
1008 _ = address;1009 _ = address;
1009 _ = options;1010 _ = options;
1010 @panic("TODO");1011 @panic("TODO");
1011}1012}
1012fn netAccept(userdata: ?*anyopaque, server: net.Socket.Handle) net.Server.AcceptError!net.Stream {1013fn netAccept(userdata: ?*anyopaque, server: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket {
1013 const k: *Kqueue = @ptrCast(@alignCast(userdata));1014 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1014 _ = k;1015 _ = k;
1015 _ = server;1016 _ = server;
1017 _ = options;
1016 @panic("TODO");1018 @panic("TODO");
1017}1019}
1018fn netBindIp(1020fn netBindIp(
...@@ -1028,12 +1030,9 @@ fn netBindIp(...@@ -1028,12 +1030,9 @@ fn netBindIp(
1028 var addr_len = Io.Threaded.addressToPosix(address, &storage);1030 var addr_len = Io.Threaded.addressToPosix(address, &storage);
1029 try posixBind(k, socket_fd, &storage.any, addr_len);1031 try posixBind(k, socket_fd, &storage.any, addr_len);
1030 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);1032 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);
1031 return .{1033 return .{ .handle = socket_fd, .address = Io.Threaded.addressFromPosix(&storage) };
1032 .handle = socket_fd,
1033 .address = Io.Threaded.addressFromPosix(&storage),
1034 };
1035}1034}
1036fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Stream {1035fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Socket {
1037 if (options.timeout != .none) @panic("TODO");1036 if (options.timeout != .none) @panic("TODO");
1038 const k: *Kqueue = @ptrCast(@alignCast(userdata));1037 const k: *Kqueue = @ptrCast(@alignCast(userdata));
1039 const family = Io.Threaded.posixAddressFamily(address);1038 const family = Io.Threaded.posixAddressFamily(address);
...@@ -1046,10 +1045,7 @@ fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: n...@@ -1046,10 +1045,7 @@ fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: n
1046 var addr_len = Io.Threaded.addressToPosix(address, &storage);1045 var addr_len = Io.Threaded.addressToPosix(address, &storage);
1047 try posixConnect(k, socket_fd, &storage.any, addr_len);1046 try posixConnect(k, socket_fd, &storage.any, addr_len);
1048 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);1047 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);
1049 return .{ .socket = .{1048 return .{ .handle = socket_fd, .address = Io.Threaded.addressFromPosix(&storage) };
1050 .handle = socket_fd,
1051 .address = Io.Threaded.addressFromPosix(&storage),
1052 } };
1053}1049}
10541050
1055fn posixConnect(k: *Kqueue, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {1051fn posixConnect(k: *Kqueue, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
...@@ -1345,8 +1341,7 @@ fn openSocketPosix(...@@ -1345,8 +1341,7 @@ fn openSocketPosix(
1345 Unexpected,1341 Unexpected,
1346 Canceled,1342 Canceled,
1347}!posix.socket_t {1343}!posix.socket_t {
1348 const mode = Io.Threaded.posixSocketMode(options.mode);1344 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
1349 const protocol = Io.Threaded.posixProtocol(options.protocol);
1350 const socket_fd = while (true) {1345 const socket_fd = while (true) {
1351 try k.checkCancel();1346 try k.checkCancel();
1352 const flags: u32 = mode | if (Io.Threaded.socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;1347 const flags: u32 = mode | if (Io.Threaded.socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
lib/std/Io/Reader.zig+1-1
...@@ -1997,7 +1997,7 @@ pub fn writableVectorPosix(r: *Reader, buffer: []std.posix.iovec, data: []const...@@ -1997,7 +1997,7 @@ pub fn writableVectorPosix(r: *Reader, buffer: []std.posix.iovec, data: []const
19971997
1998pub fn writableVectorWsa(1998pub fn writableVectorWsa(
1999 r: *Reader,1999 r: *Reader,
2000 buffer: []std.os.windows.ws2_32.WSABUF,2000 buffer: []std.os.windows.AFD.WSABUF(.@"var"),
2001 data: []const []u8,2001 data: []const []u8,
2002) Error!struct { usize, usize } {2002) Error!struct { usize, usize } {
2003 var i: usize = 0;2003 var i: usize = 0;
lib/std/Io/Threaded.zig+974-1213
...@@ -11,8 +11,8 @@ const Io = std.Io;...@@ -11,8 +11,8 @@ const Io = std.Io;
11const net = std.Io.net;11const net = std.Io.net;
12const File = std.Io.File;12const File = std.Io.File;
13const Dir = std.Io.Dir;13const Dir = std.Io.Dir;
14const HostName = std.Io.net.HostName;14const HostName = net.HostName;
15const IpAddress = std.Io.net.IpAddress;15const IpAddress = net.IpAddress;
16const process = std.process;16const process = std.process;
17const Allocator = std.mem.Allocator;17const Allocator = std.mem.Allocator;
18const Alignment = std.mem.Alignment;18const Alignment = std.mem.Alignment;
...@@ -47,8 +47,6 @@ busy_count: usize = 0,...@@ -47,8 +47,6 @@ busy_count: usize = 0,
47worker_threads: std.atomic.Value(?*Thread),47worker_threads: std.atomic.Value(?*Thread),
48pid: Pid = .unknown,48pid: Pid = .unknown,
4949
50wsa: if (is_windows) Wsa else struct {} = .{},
51
52have_signal_handler: bool,50have_signal_handler: bool,
53old_sig_io: if (have_sig_io) posix.Sigaction else void,51old_sig_io: if (have_sig_io) posix.Sigaction else void,
54old_sig_pipe: if (have_sig_pipe) posix.Sigaction else void,52old_sig_pipe: if (have_sig_pipe) posix.Sigaction else void,
...@@ -77,6 +75,8 @@ argv0: Argv0,...@@ -77,6 +75,8 @@ argv0: Argv0,
77environ_initialized: bool,75environ_initialized: bool,
78environ: Environ,76environ: Environ,
7977
78dl: Dl = .init,
79
80null_file: NullFile = .{},80null_file: NullFile = .{},
81random_file: RandomFile = .{},81random_file: RandomFile = .{},
82pipe_file: PipeFile = .{},82pipe_file: PipeFile = .{},
...@@ -90,6 +90,67 @@ const SystemBasicInformation = if (!is_windows) struct {} else struct {...@@ -90,6 +90,67 @@ const SystemBasicInformation = if (!is_windows) struct {} else struct {
90 initialized: std.atomic.Value(bool) = .{ .raw = false },90 initialized: std.atomic.Value(bool) = .{ .raw = false },
91};91};
9292
93const Dl = switch (native_os) {
94 .windows => struct {
95 iphlpapi_dll: std.atomic.Value(?*anyopaque),
96 ConvertInterfaceNameToLuidW: std.atomic.Value(?*const fn (
97 InterfaceName: [*:0]const windows.WCHAR,
98 InterfaceLuid: *windows.NET.LUID,
99 ) callconv(.winapi) windows.Win32Error),
100 ConvertInterfaceLuidToIndex: std.atomic.Value(?*const fn (
101 InterfaceLuid: *const windows.NET.LUID,
102 InterfaceIndex: *windows.NET.IFINDEX,
103 ) callconv(.winapi) windows.Win32Error),
104 ConvertInterfaceIndexToLuid: std.atomic.Value(?*const fn (
105 InterfaceIndex: std.os.windows.NET.IFINDEX,
106 InterfaceLuid: *std.os.windows.NET.LUID,
107 ) callconv(.winapi) windows.Win32Error),
108 ConvertInterfaceLuidToNameW: std.atomic.Value(?*const fn (
109 InterfaceLuid: *const std.os.windows.NET.LUID,
110 InterfaceName: std.os.windows.PWSTR,
111 Length: std.os.windows.SIZE_T,
112 ) callconv(.winapi) std.os.windows.Win32Error),
113
114 dnsapi_dll: std.atomic.Value(?*anyopaque),
115 DnsQueryEx: std.atomic.Value(?*const fn (
116 pQueryRequest: *const windows.DNS.QUERY.REQUEST,
117 pQueryResults: *windows.DNS.QUERY.RESULT,
118 pCancelHandle: ?*windows.DNS.QUERY.CANCEL,
119 ) callconv(.winapi) windows.DNS.STATUS),
120 //DnsCancelQuery: std.atomic.Value(?*const fn (
121 // pCancelHandle: *const windows.DNS.QUERY.CANCEL,
122 //) callconv(.winapi) windows.DNS.STATUS),
123 DnsFree: std.atomic.Value(?*const fn (
124 pRecordList: ?*anyopaque,
125 FreeType: windows.DNS.FREE_TYPE,
126 ) callconv(.winapi) void),
127
128 const init: Dl = .{
129 .iphlpapi_dll = .init(null),
130 .ConvertInterfaceNameToLuidW = .init(null),
131 .ConvertInterfaceLuidToIndex = .init(null),
132 .ConvertInterfaceIndexToLuid = .init(null),
133 .ConvertInterfaceLuidToNameW = .init(null),
134
135 .dnsapi_dll = .init(null),
136 .DnsQueryEx = .init(null),
137 //.DnsCancelQuery = .init(null),
138 .DnsFree = .init(null),
139 };
140 fn deinit(dl: *Dl) void {
141 if (dl.iphlpapi_dll.raw) |iphlpapi_dll| switch (windows.ntdll.LdrUnloadDll(iphlpapi_dll)) {
142 .SUCCESS => {},
143 else => |status| windows.unexpectedStatus(status) catch {},
144 };
145 dl.* = .init;
146 }
147 },
148 else => struct {
149 const init: Dl = .{};
150 fn deinit(_: Dl) void {}
151 },
152};
153
93pub const Csprng = struct {154pub const Csprng = struct {
94 rng: std.Random.DefaultCsprng,155 rng: std.Random.DefaultCsprng,
95156
...@@ -375,6 +436,17 @@ pub const UseFchmodat2 = if (have_fchmodat2 and !have_fchmodat_flags) enum {...@@ -375,6 +436,17 @@ pub const UseFchmodat2 = if (have_fchmodat2 and !have_fchmodat_flags) enum {
375 pub const default: UseFchmodat2 = .disabled;436 pub const default: UseFchmodat2 = .disabled;
376};437};
377438
439pub const apc_align = @max(default_fn_align, 2);
440
441const default_fn_align = switch (builtin.mode) {
442 .Debug, .ReleaseSafe, .ReleaseFast => switch (builtin.cpu.arch) {
443 else => |arch| @compileError("Unsupported architecture: " ++ @tagName(arch)),
444 .arm, .thumb => 4,
445 .aarch64, .x86, .x86_64 => 16,
446 },
447 .ReleaseSmall => 1,
448};
449
378const Runnable = struct {450const Runnable = struct {
379 node: std.SinglyLinkedList.Node,451 node: std.SinglyLinkedList.Node,
380 startFn: *const fn (*Runnable, *Thread, *Threaded) void,452 startFn: *const fn (*Runnable, *Thread, *Threaded) void,
...@@ -1496,18 +1568,6 @@ const AlertableSyscall = struct {...@@ -1496,18 +1568,6 @@ const AlertableSyscall = struct {
1496 s.finish();1568 s.finish();
1497 return windows.unexpectedStatus(status);1569 return windows.unexpectedStatus(status);
1498 }1570 }
1499
1500 fn unexpectedWsaError(s: AlertableSyscall, err: ws2_32.WinsockError) Io.UnexpectedError {
1501 @branchHint(.cold);
1502 s.finish();
1503 return windows.unexpectedWsaError(err);
1504 }
1505
1506 fn wsaErrorBug(s: AlertableSyscall, err: ws2_32.WinsockError) Io.UnexpectedError {
1507 @branchHint(.cold);
1508 s.finish();
1509 return windows.wsaErrorBug(err);
1510 }
1511};1571};
15121572
1513pub fn waitForApcOrAlert() void {1573pub fn waitForApcOrAlert() void {
...@@ -1667,13 +1727,11 @@ pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void {...@@ -1667,13 +1727,11 @@ pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void {
16671727
1668pub fn deinit(t: *Threaded) void {1728pub fn deinit(t: *Threaded) void {
1669 t.join();1729 t.join();
1670 if (is_windows and t.wsa.status == .initialized) {
1671 if (ws2_32.WSACleanup() != 0) recoverableOsBugDetected();
1672 }
1673 if (posix.Sigaction != void and t.have_signal_handler) {1730 if (posix.Sigaction != void and t.have_signal_handler) {
1674 if (have_sig_io) posix.sigaction(.IO, &t.old_sig_io, null);1731 if (have_sig_io) posix.sigaction(.IO, &t.old_sig_io, null);
1675 if (have_sig_pipe) posix.sigaction(.PIPE, &t.old_sig_pipe, null);1732 if (have_sig_pipe) posix.sigaction(.PIPE, &t.old_sig_pipe, null);
1676 }1733 }
1734 t.dl.deinit();
1677 t.null_file.deinit();1735 t.null_file.deinit();
1678 t.random_file.deinit();1736 t.random_file.deinit();
1679 t.pipe_file.deinit();1737 t.pipe_file.deinit();
...@@ -1717,6 +1775,7 @@ fn worker(t: *Threaded) void {...@@ -1717,6 +1775,7 @@ fn worker(t: *Threaded) void {
1717 .SPECIFIC = .{1775 .SPECIFIC = .{
1718 .THREAD = .{1776 .THREAD = .{
1719 .TERMINATE = true, // for `NtCancelSynchronousIoFile`1777 .TERMINATE = true, // for `NtCancelSynchronousIoFile`
1778 .ALERT = true, // for `NtAlertThread`
1720 },1779 },
1721 },1780 },
1722 },1781 },
...@@ -2914,7 +2973,7 @@ fn batchApc(...@@ -2914,7 +2973,7 @@ fn batchApc(
2914 apc_context: ?*anyopaque,2973 apc_context: ?*anyopaque,
2915 iosb: *windows.IO_STATUS_BLOCK,2974 iosb: *windows.IO_STATUS_BLOCK,
2916 _: windows.ULONG,2975 _: windows.ULONG,
2917) callconv(.winapi) void {2976) align(apc_align) callconv(.winapi) void {
2918 const b: *Io.Batch = @ptrCast(@alignCast(apc_context));2977 const b: *Io.Batch = @ptrCast(@alignCast(apc_context));
2919 const operation_userdata: *WindowsBatchOperationUserdata = @fieldParentPtr("iosb", iosb);2978 const operation_userdata: *WindowsBatchOperationUserdata = @fieldParentPtr("iosb", iosb);
2920 const erased_userdata = operation_userdata.toErased();2979 const erased_userdata = operation_userdata.toErased();
...@@ -3278,7 +3337,7 @@ fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, pe...@@ -3278,7 +3337,7 @@ fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, pe
3278 _ = t;3337 _ = t;
3279 _ = permissions; // TODO use this value3338 _ = permissions; // TODO use this value
32803339
3281 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);3340 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
3282 const attr: windows.OBJECT.ATTRIBUTES = .{3341 const attr: windows.OBJECT.ATTRIBUTES = .{
3283 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,3342 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
3284 .Attributes = .{ .INHERIT = false },3343 .Attributes = .{ .INHERIT = false },
...@@ -3446,7 +3505,7 @@ fn dirCreateDirPathOpenWindows(...@@ -3446,7 +3505,7 @@ fn dirCreateDirPathOpenWindows(
3446 };3505 };
34473506
3448 components: while (true) {3507 components: while (true) {
3449 const sub_path_w = try sliceToPrefixedFileW(dir.handle, component.path);3508 const sub_path_w = try sliceToPrefixedFileW(dir.handle, component.path, .{});
3450 const attr: windows.OBJECT.ATTRIBUTES = .{3509 const attr: windows.OBJECT.ATTRIBUTES = .{
3451 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,3510 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
3452 .ObjectName = @constCast(&sub_path_w.string()),3511 .ObjectName = @constCast(&sub_path_w.string()),
...@@ -4144,7 +4203,7 @@ fn dirAccessWindows(...@@ -4144,7 +4203,7 @@ fn dirAccessWindows(
4144 _ = options; // TODO4203 _ = options; // TODO
41454204
4146 if (std.mem.eql(u8, sub_path, ".") or std.mem.eql(u8, sub_path, "..")) return;4205 if (std.mem.eql(u8, sub_path, ".") or std.mem.eql(u8, sub_path, "..")) return;
4147 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);4206 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
4148 const attr: windows.OBJECT.ATTRIBUTES = .{4207 const attr: windows.OBJECT.ATTRIBUTES = .{
4149 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,4208 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
4150 .ObjectName = @constCast(&sub_path_w.string()),4209 .ObjectName = @constCast(&sub_path_w.string()),
...@@ -4353,7 +4412,7 @@ fn dirCreateFileWindows(...@@ -4353,7 +4412,7 @@ fn dirCreateFileWindows(
4353 if (std.mem.eql(u8, sub_path, ".")) return error.IsDir;4412 if (std.mem.eql(u8, sub_path, ".")) return error.IsDir;
4354 if (std.mem.eql(u8, sub_path, "..")) return error.IsDir;4413 if (std.mem.eql(u8, sub_path, "..")) return error.IsDir;
43554414
4356 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);4415 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
4357 const attr: windows.OBJECT.ATTRIBUTES = .{4416 const attr: windows.OBJECT.ATTRIBUTES = .{
4358 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,4417 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
4359 .ObjectName = @constCast(&sub_path_w.string()),4418 .ObjectName = @constCast(&sub_path_w.string()),
...@@ -4943,7 +5002,7 @@ fn dirOpenFileWindows(...@@ -4943,7 +5002,7 @@ fn dirOpenFileWindows(
4943) File.OpenError!File {5002) File.OpenError!File {
4944 const t: *Threaded = @ptrCast(@alignCast(userdata));5003 const t: *Threaded = @ptrCast(@alignCast(userdata));
4945 _ = t;5004 _ = t;
4946 const sub_path_w_array = try sliceToPrefixedFileW(dir.handle, sub_path);5005 const sub_path_w_array = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
4947 const sub_path_w = sub_path_w_array.span();5006 const sub_path_w = sub_path_w_array.span();
4948 const dir_handle = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle;5007 const dir_handle = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle;
4949 return dirOpenFileWtf16(dir_handle, sub_path_w, flags);5008 return dirOpenFileWtf16(dir_handle, sub_path_w, flags);
...@@ -5197,7 +5256,7 @@ fn dirOpenDirPosix(...@@ -5197,7 +5256,7 @@ fn dirOpenDirPosix(
5197 _ = t;5256 _ = t;
51985257
5199 if (is_windows) {5258 if (is_windows) {
5200 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);5259 const sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
5201 return dirOpenDirWindows(dir, sub_path_w.span(), options);5260 return dirOpenDirWindows(dir, sub_path_w.span(), options);
5202 }5261 }
52035262
...@@ -6027,7 +6086,7 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8,...@@ -6027,7 +6086,7 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8,
6027 const t: *Threaded = @ptrCast(@alignCast(userdata));6086 const t: *Threaded = @ptrCast(@alignCast(userdata));
6028 _ = t;6087 _ = t;
60296088
6030 var path_name_w = try sliceToPrefixedFileW(dir.handle, sub_path);6089 var path_name_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
60316090
6032 const h_file = handle: {6091 const h_file = handle: {
6033 if (OpenFile(path_name_w.span(), .{6092 if (OpenFile(path_name_w.span(), .{
...@@ -6182,6 +6241,7 @@ pub fn GetFinalPathNameByHandle(...@@ -6182,6 +6241,7 @@ pub fn GetFinalPathNameByHandle(
6182 .out = &output_buf,6241 .out = &output_buf,
6183 })).u.Status) {6242 })).u.Status) {
6184 .SUCCESS => {},6243 .SUCCESS => {},
6244 .CANCELLED => unreachable,
6185 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,6245 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
6186 else => |status| return windows.unexpectedStatus(status),6246 else => |status| return windows.unexpectedStatus(status),
6187 }6247 }
...@@ -6241,6 +6301,7 @@ pub fn GetFinalPathNameByHandle(...@@ -6241,6 +6301,7 @@ pub fn GetFinalPathNameByHandle(
6241 .out = &vol_output_buf,6301 .out = &vol_output_buf,
6242 })).u.Status) {6302 })).u.Status) {
6243 .SUCCESS => {},6303 .SUCCESS => {},
6304 .CANCELLED => unreachable,
6244 .UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,6305 .UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,
6245 else => |status| return windows.unexpectedStatus(status),6306 else => |status| return windows.unexpectedStatus(status),
6246 }6307 }
...@@ -6383,6 +6444,10 @@ const Wtf16ToPrefixedFileWError = error{...@@ -6383,6 +6444,10 @@ const Wtf16ToPrefixedFileWError = error{
6383 FileNotFound,6444 FileNotFound,
6384} || Dir.PathNameError || Io.Cancelable || Io.UnexpectedError;6445} || Dir.PathNameError || Io.Cancelable || Io.UnexpectedError;
63856446
6447const Wtf16ToPrefixedFileWOptions = struct {
6448 allow_relative: bool = true,
6449};
6450
6386/// Converts the `path` to WTF16, null-terminated. If the path contains any6451/// Converts the `path` to WTF16, null-terminated. If the path contains any
6387/// namespace prefix, or is anything but a relative path (rooted, drive relative,6452/// namespace prefix, or is anything but a relative path (rooted, drive relative,
6388/// etc) the result will have the NT-style prefix `\??\`.6453/// etc) the result will have the NT-style prefix `\??\`.
...@@ -6394,7 +6459,7 @@ const Wtf16ToPrefixedFileWError = error{...@@ -6394,7 +6459,7 @@ const Wtf16ToPrefixedFileWError = error{
6394/// is non-null, or the CWD if it is null.6459/// is non-null, or the CWD if it is null.
6395/// - Special case device names like COM1, NUL, etc are not handled specially (TODO)6460/// - Special case device names like COM1, NUL, etc are not handled specially (TODO)
6396/// - . and space are not stripped from the end of relative paths (potential TODO)6461/// - . and space are not stripped from the end of relative paths (potential TODO)
6397pub fn wToPrefixedFileW(dir: ?windows.HANDLE, path: [:0]const u16) Wtf16ToPrefixedFileWError!WindowsPathSpace {6462pub fn wToPrefixedFileW(dir: ?windows.HANDLE, path: [:0]const u16, options: Wtf16ToPrefixedFileWOptions) Wtf16ToPrefixedFileWError!WindowsPathSpace {
6398 const nt_prefix = [_]u16{ '\\', '?', '?', '\\' };6463 const nt_prefix = [_]u16{ '\\', '?', '?', '\\' };
6399 if (windows.hasCommonNtPrefix(u16, path)) {6464 if (windows.hasCommonNtPrefix(u16, path)) {
6400 // TODO: Figure out a way to design an API that can avoid the copy for NT,6465 // TODO: Figure out a way to design an API that can avoid the copy for NT,
...@@ -6409,58 +6474,54 @@ pub fn wToPrefixedFileW(dir: ?windows.HANDLE, path: [:0]const u16) Wtf16ToPrefix...@@ -6409,58 +6474,54 @@ pub fn wToPrefixedFileW(dir: ?windows.HANDLE, path: [:0]const u16) Wtf16ToPrefix
6409 } else {6474 } else {
6410 const path_type = Dir.path.getWin32PathType(u16, path);6475 const path_type = Dir.path.getWin32PathType(u16, path);
6411 var path_space: WindowsPathSpace = undefined;6476 var path_space: WindowsPathSpace = undefined;
6412 if (path_type == .local_device) {6477 if (path_type == .local_device) switch (getLocalDevicePathType(u16, path)) {
6413 switch (getLocalDevicePathType(u16, path)) {6478 .verbatim => {
6414 .verbatim => {6479 path_space.data[0..nt_prefix.len].* = nt_prefix;
6415 path_space.data[0..nt_prefix.len].* = nt_prefix;6480 const len_after_prefix = path.len - nt_prefix.len;
6416 const len_after_prefix = path.len - nt_prefix.len;6481 @memcpy(path_space.data[nt_prefix.len..][0..len_after_prefix], path[nt_prefix.len..]);
6417 @memcpy(path_space.data[nt_prefix.len..][0..len_after_prefix], path[nt_prefix.len..]);6482 path_space.len = path.len;
6418 path_space.len = path.len;
6419 path_space.data[path_space.len] = 0;
6420 return path_space;
6421 },
6422 .local_device, .fake_verbatim => {
6423 const path_byte_len = windows.ntdll.RtlGetFullPathName_U(
6424 path.ptr,
6425 path_space.data.len * 2,
6426 &path_space.data,
6427 null,
6428 );
6429 if (path_byte_len == 0) {
6430 // TODO: This may not be the right error
6431 return error.BadPathName;
6432 } else if (path_byte_len / 2 > path_space.data.len) {
6433 return error.NameTooLong;
6434 }
6435 path_space.len = path_byte_len / 2;
6436 // Both prefixes will be normalized but retained, so all
6437 // we need to do now is replace them with the NT prefix
6438 path_space.data[0..nt_prefix.len].* = nt_prefix;
6439 return path_space;
6440 },
6441 }
6442 }
6443 relative: {
6444 if (path_type == .relative) {
6445 // TODO: Handle special case device names like COM1, AUX, NUL, CONIN$, CONOUT$, etc.
6446 // See https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
6447
6448 // TODO: Potentially strip all trailing . and space characters from the
6449 // end of the path. This is something that both RtlDosPathNameToNtPathName_U
6450 // and RtlGetFullPathName_U do. Technically, trailing . and spaces
6451 // are allowed, but such paths may not interact well with Windows (i.e.
6452 // files with these paths can't be deleted from explorer.exe, etc).
6453 // This could be something that normalizePath may want to do.
6454
6455 @memcpy(path_space.data[0..path.len], path);
6456 // Try to normalize, but if we get too many parent directories,
6457 // then we need to start over and use RtlGetFullPathName_U instead.
6458 path_space.len = windows.normalizePath(u16, path_space.data[0..path.len]) catch |err| switch (err) {
6459 error.TooManyParentDirs => break :relative,
6460 };
6461 path_space.data[path_space.len] = 0;6483 path_space.data[path_space.len] = 0;
6462 return path_space;6484 return path_space;
6463 }6485 },
6486 .local_device, .fake_verbatim => {
6487 const path_byte_len = windows.ntdll.RtlGetFullPathName_U(
6488 path.ptr,
6489 path_space.data.len * 2,
6490 &path_space.data,
6491 null,
6492 );
6493 if (path_byte_len == 0) {
6494 // TODO: This may not be the right error
6495 return error.BadPathName;
6496 } else if (path_byte_len / 2 > path_space.data.len) {
6497 return error.NameTooLong;
6498 }
6499 path_space.len = path_byte_len / 2;
6500 // Both prefixes will be normalized but retained, so all
6501 // we need to do now is replace them with the NT prefix
6502 path_space.data[0..nt_prefix.len].* = nt_prefix;
6503 return path_space;
6504 },
6505 };
6506 if (options.allow_relative and path_type == .relative) relative: {
6507 // TODO: Handle special case device names like COM1, AUX, NUL, CONIN$, CONOUT$, etc.
6508 // See https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html
6509
6510 // TODO: Potentially strip all trailing . and space characters from the
6511 // end of the path. This is something that both RtlDosPathNameToNtPathName_U
6512 // and RtlGetFullPathName_U do. Technically, trailing . and spaces
6513 // are allowed, but such paths may not interact well with Windows (i.e.
6514 // files with these paths can't be deleted from explorer.exe, etc).
6515 // This could be something that normalizePath may want to do.
6516
6517 @memcpy(path_space.data[0..path.len], path);
6518 // Try to normalize, but if we get too many parent directories,
6519 // then we need to start over and use RtlGetFullPathName_U instead.
6520 path_space.len = windows.normalizePath(u16, path_space.data[0..path.len]) catch |err| switch (err) {
6521 error.TooManyParentDirs => break :relative,
6522 };
6523 path_space.data[path_space.len] = 0;
6524 return path_space;
6464 }6525 }
6465 // We now know we are going to return an absolute NT path, so6526 // We now know we are going to return an absolute NT path, so
6466 // we can unconditionally prefix it with the NT prefix.6527 // we can unconditionally prefix it with the NT prefix.
...@@ -6591,13 +6652,13 @@ pub const Wtf8ToPrefixedFileWError = Wtf16ToPrefixedFileWError;...@@ -6591,13 +6652,13 @@ pub const Wtf8ToPrefixedFileWError = Wtf16ToPrefixedFileWError;
65916652
6592/// Same as `wToPrefixedFileW` but accepts a WTF-8 encoded path.6653/// Same as `wToPrefixedFileW` but accepts a WTF-8 encoded path.
6593/// https://wtf-8.codeberg.page/6654/// https://wtf-8.codeberg.page/
6594pub fn sliceToPrefixedFileW(dir: ?windows.HANDLE, path: []const u8) Wtf8ToPrefixedFileWError!WindowsPathSpace {6655pub fn sliceToPrefixedFileW(dir: ?windows.HANDLE, path: []const u8, options: Wtf16ToPrefixedFileWOptions) Wtf8ToPrefixedFileWError!WindowsPathSpace {
6595 var temp_path: WindowsPathSpace = undefined;6656 var temp_path: WindowsPathSpace = undefined;
6596 temp_path.len = std.unicode.wtf8ToWtf16Le(&temp_path.data, path) catch |err| switch (err) {6657 temp_path.len = std.unicode.wtf8ToWtf16Le(&temp_path.data, path) catch |err| switch (err) {
6597 error.InvalidWtf8 => return error.BadPathName,6658 error.InvalidWtf8 => return error.BadPathName,
6598 };6659 };
6599 temp_path.data[temp_path.len] = 0;6660 temp_path.data[temp_path.len] = 0;
6600 return wToPrefixedFileW(dir, temp_path.span());6661 return wToPrefixedFileW(dir, temp_path.span(), options);
6601}6662}
66026663
6603pub const WindowsPathSpace = struct {6664pub const WindowsPathSpace = struct {
...@@ -7068,7 +7129,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov...@@ -7068,7 +7129,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov
7068 // Can't remove the parent directory with an open handle.7129 // Can't remove the parent directory with an open handle.
7069 return error.FileBusy;7130 return error.FileBusy;
7070 }7131 }
7071 var sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);7132 var sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
7072 if (std.mem.eql(u8, sub_path, ".")) {7133 if (std.mem.eql(u8, sub_path, ".")) {
7073 // Windows does not recognize this, but it does work with empty string.7134 // Windows does not recognize this, but it does work with empty string.
7074 sub_path_w.len = 0;7135 sub_path_w.len = 0;
...@@ -7336,9 +7397,9 @@ fn dirRenameWindowsInner(...@@ -7336,9 +7397,9 @@ fn dirRenameWindowsInner(
7336 replace_if_exists: bool,7397 replace_if_exists: bool,
7337) Dir.RenamePreserveError!void {7398) Dir.RenamePreserveError!void {
7338 const w = windows;7399 const w = windows;
7339 const old_path_w_buf = try sliceToPrefixedFileW(old_dir.handle, old_sub_path);7400 const old_path_w_buf = try sliceToPrefixedFileW(old_dir.handle, old_sub_path, .{});
7340 const old_path_w = old_path_w_buf.span();7401 const old_path_w = old_path_w_buf.span();
7341 const new_path_w_buf = try sliceToPrefixedFileW(new_dir.handle, new_sub_path);7402 const new_path_w_buf = try sliceToPrefixedFileW(new_dir.handle, new_sub_path, .{});
7342 const new_path_w = new_path_w_buf.span();7403 const new_path_w = new_path_w_buf.span();
73437404
7344 const src_fd = src_fd: {7405 const src_fd = src_fd: {
...@@ -7673,7 +7734,7 @@ fn dirSymLinkWindows(...@@ -7673,7 +7734,7 @@ fn dirSymLinkWindows(
7673 std.mem.nativeToLittle(u16, '\\'),7734 std.mem.nativeToLittle(u16, '\\'),
7674 );7735 );
76757736
7676 const sym_link_path_w = try sliceToPrefixedFileW(dir.handle, sym_link_path);7737 const sym_link_path_w = try sliceToPrefixedFileW(dir.handle, sym_link_path, .{});
76777738
7678 const SYMLINK_DATA = extern struct {7739 const SYMLINK_DATA = extern struct {
7679 ReparseTag: w.IO_REPARSE_TAG,7740 ReparseTag: w.IO_REPARSE_TAG,
...@@ -7738,7 +7799,7 @@ fn dirSymLinkWindows(...@@ -7738,7 +7799,7 @@ fn dirSymLinkWindows(
7738 break :target_path target_path_w.span(),7799 break :target_path target_path_w.span(),
7739 }7800 }
7740 }7801 }
7741 var prefixed_target_path = try wToPrefixedFileW(dir.handle, target_path_w.span());7802 var prefixed_target_path = try wToPrefixedFileW(dir.handle, target_path_w.span(), .{});
7742 // We do this after prefixing to ensure that drive-relative paths are treated as absolute7803 // We do this after prefixing to ensure that drive-relative paths are treated as absolute
7743 is_target_absolute = Dir.path.isAbsoluteWindowsWtf16(prefixed_target_path.span());7804 is_target_absolute = Dir.path.isAbsoluteWindowsWtf16(prefixed_target_path.span());
7744 break :target_path prefixed_target_path.span();7805 break :target_path prefixed_target_path.span();
...@@ -7770,6 +7831,8 @@ fn dirSymLinkWindows(...@@ -7770,6 +7831,8 @@ fn dirSymLinkWindows(
7770 .in = buffer[0..buf_len],7831 .in = buffer[0..buf_len],
7771 })).u.Status) {7832 })).u.Status) {
7772 .SUCCESS => {},7833 .SUCCESS => {},
7834 .CANCELLED => unreachable,
7835 .INSUFFICIENT_RESOURCES => return error.SystemResources,
7773 .PRIVILEGE_NOT_HELD => return error.PermissionDenied,7836 .PRIVILEGE_NOT_HELD => return error.PermissionDenied,
7774 .ACCESS_DENIED => return error.AccessDenied,7837 .ACCESS_DENIED => return error.AccessDenied,
7775 .INVALID_DEVICE_REQUEST => return error.FileSystem,7838 .INVALID_DEVICE_REQUEST => return error.FileSystem,
...@@ -7887,7 +7950,7 @@ fn dirReadLink(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []...@@ -7887,7 +7950,7 @@ fn dirReadLink(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []
7887fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {7950fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
7888 // This gets used once for `sub_path` and then reused again temporarily7951 // This gets used once for `sub_path` and then reused again temporarily
7889 // before converting back to `buffer`.7952 // before converting back to `buffer`.
7890 var sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);7953 var sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
7891 const attr: windows.OBJECT.ATTRIBUTES = .{7954 const attr: windows.OBJECT.ATTRIBUTES = .{
7892 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,7955 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
7893 .ObjectName = @constCast(&sub_path_w.string()),7956 .ObjectName = @constCast(&sub_path_w.string()),
...@@ -8532,6 +8595,7 @@ fn isTty(file: File) Io.Cancelable!bool {...@@ -8532,6 +8595,7 @@ fn isTty(file: File) Io.Cancelable!bool {
8532 .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})),8595 .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})),
8533 })).u.Status) {8596 })).u.Status) {
8534 .SUCCESS => return true,8597 .SUCCESS => return true,
8598 .CANCELLED => unreachable,
8535 .INVALID_HANDLE => return isCygwinPty(file),8599 .INVALID_HANDLE => return isCygwinPty(file),
8536 else => return false,8600 else => return false,
8537 }8601 }
...@@ -8618,6 +8682,7 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE...@@ -8618,6 +8682,7 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE
8618 .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})),8682 .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})),
8619 })).u.Status) {8683 })).u.Status) {
8620 .SUCCESS => {},8684 .SUCCESS => {},
8685 .CANCELLED => unreachable,
8621 .INVALID_HANDLE => return if (!try isCygwinPty(file)) error.NotTerminalDevice,8686 .INVALID_HANDLE => return if (!try isCygwinPty(file)) error.NotTerminalDevice,
8622 else => return error.NotTerminalDevice,8687 else => return error.NotTerminalDevice,
8623 }8688 }
...@@ -8644,6 +8709,7 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE...@@ -8644,6 +8709,7 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE
8644 .in = @ptrCast(&set_console_mode.request(file, 0, .{}, 0, .{})),8709 .in = @ptrCast(&set_console_mode.request(file, 0, .{}, 0, .{})),
8645 })).u.Status) {8710 })).u.Status) {
8646 .SUCCESS => {},8711 .SUCCESS => {},
8712 .CANCELLED => unreachable,
8647 else => |status| return windows.unexpectedStatus(status),8713 else => |status| return windows.unexpectedStatus(status),
8648 }8714 }
8649}8715}
...@@ -8667,6 +8733,7 @@ fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool {...@@ -8667,6 +8733,7 @@ fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool {
8667 })).u.Status) {8733 })).u.Status) {
8668 .SUCCESS => if (get_console_mode.Data & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0)8734 .SUCCESS => if (get_console_mode.Data & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0)
8669 return true,8735 return true,
8736 .CANCELLED => unreachable,
8670 .INVALID_HANDLE => return isCygwinPty(file),8737 .INVALID_HANDLE => return isCygwinPty(file),
8671 else => return false,8738 else => return false,
8672 }8739 }
...@@ -9673,7 +9740,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingEr...@@ -9673,7 +9740,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingEr
9673 return ntReadFileResult(&iosb);9740 return ntReadFileResult(&iosb);
9674}9741}
96759742
9676fn flagApc(userdata: ?*anyopaque, _: *windows.IO_STATUS_BLOCK, _: windows.ULONG) callconv(.winapi) void {9743fn flagApc(userdata: ?*anyopaque, _: *windows.IO_STATUS_BLOCK, _: windows.ULONG) align(apc_align) callconv(.winapi) void {
9677 const flag: *bool = @ptrCast(userdata);9744 const flag: *bool = @ptrCast(userdata);
9678 flag.* = true;9745 flag.* = true;
9679}9746}
...@@ -10157,7 +10224,7 @@ fn processExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) process.O...@@ -10157,7 +10224,7 @@ fn processExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) process.O
10157 // not the path that the symlink points to. However, because we are opening10224 // not the path that the symlink points to. However, because we are opening
10158 // the file, we can let the openFileW call follow the symlink for us.10225 // the file, we can let the openFileW call follow the symlink for us.
10159 const image_path_name = windows.peb().ProcessParameters.ImagePathName.sliceZ();10226 const image_path_name = windows.peb().ProcessParameters.ImagePathName.sliceZ();
10160 const prefixed_path_w = try wToPrefixedFileW(null, image_path_name);10227 const prefixed_path_w = try wToPrefixedFileW(null, image_path_name, .{});
10161 return dirOpenFileWtf16(null, prefixed_path_w.span(), flags);10228 return dirOpenFileWtf16(null, prefixed_path_w.span(), flags);
10162 },10229 },
10163 .driverkit,10230 .driverkit,
...@@ -10364,6 +10431,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut...@@ -10364,6 +10431,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut
10364 var path_name_w_buf = try wToPrefixedFileW(10431 var path_name_w_buf = try wToPrefixedFileW(
10365 null,10432 null,
10366 windows.peb().ProcessParameters.ImagePathName.sliceZ(),10433 windows.peb().ProcessParameters.ImagePathName.sliceZ(),
10434 .{},
10367 );10435 );
1036810436
10369 const h_file = handle: {10437 const h_file = handle: {
...@@ -11177,22 +11245,6 @@ fn netWriteFile(...@@ -11177,22 +11245,6 @@ fn netWriteFile(
11177 @panic("TODO implement netWriteFile");11245 @panic("TODO implement netWriteFile");
11178}11246}
1117911247
11180fn netWriteFileUnavailable(
11181 userdata: ?*anyopaque,
11182 socket_handle: net.Socket.Handle,
11183 header: []const u8,
11184 file_reader: *File.Reader,
11185 limit: Io.Limit,
11186) net.Stream.Writer.WriteFileError!usize {
11187 const t: *Threaded = @ptrCast(@alignCast(userdata));
11188 _ = t;
11189 _ = socket_handle;
11190 _ = header;
11191 _ = file_reader;
11192 _ = limit;
11193 return error.NetworkDown;
11194}
11195
11196fn fileWriteFilePositional(11248fn fileWriteFilePositional(
11197 userdata: ?*anyopaque,11249 userdata: ?*anyopaque,
11198 file: File,11250 file: File,
...@@ -11635,27 +11687,24 @@ fn sleepNanosleep(t: *Threaded, timeout: Io.Timeout) Io.Cancelable!void {...@@ -11635,27 +11687,24 @@ fn sleepNanosleep(t: *Threaded, timeout: Io.Timeout) Io.Cancelable!void {
1163511687
11636fn netListenIpPosix(11688fn netListenIpPosix(
11637 userdata: ?*anyopaque,11689 userdata: ?*anyopaque,
11638 address: IpAddress,11690 address: *const IpAddress,
11639 options: IpAddress.ListenOptions,11691 options: IpAddress.ListenOptions,
11640) IpAddress.ListenError!net.Server {11692) IpAddress.ListenError!net.Socket {
11641 if (!have_networking) return error.NetworkDown;11693 if (!have_networking) return error.NetworkDown;
11642 const t: *Threaded = @ptrCast(@alignCast(userdata));11694 const t: *Threaded = @ptrCast(@alignCast(userdata));
11643 _ = t;11695 _ = t;
11644 const family = posixAddressFamily(&address);11696 const family = posixAddressFamily(address);
11645 const socket_fd = try openSocketPosix(family, .{11697 const socket_fd = try openSocketPosix(family, .{ .mode = options.mode, .protocol = options.protocol });
11646 .mode = options.mode,
11647 .protocol = options.protocol,
11648 });
11649 errdefer closeFd(socket_fd);11698 errdefer closeFd(socket_fd);
1165011699
11651 if (options.reuse_address) {11700 if (options.reuse_address) {
11652 try setSocketOption(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);11701 try setSocketOptionPosix(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);
11653 if (@hasDecl(posix.SO, "REUSEPORT"))11702 if (@hasDecl(posix.SO, "REUSEPORT"))
11654 try setSocketOption(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEPORT, 1);11703 try setSocketOptionPosix(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEPORT, 1);
11655 }11704 }
1165611705
11657 var storage: PosixAddress = undefined;11706 var storage: PosixAddress = undefined;
11658 var addr_len = addressToPosix(&address, &storage);11707 var addr_len = addressToPosix(address, &storage);
11659 try posixBind(socket_fd, &storage.any, addr_len);11708 try posixBind(socket_fd, &storage.any, addr_len);
1166011709
11661 const syscall: Syscall = try .start();11710 const syscall: Syscall = try .start();
...@@ -11676,112 +11725,37 @@ fn netListenIpPosix(...@@ -11676,112 +11725,37 @@ fn netListenIpPosix(
11676 }11725 }
1167711726
11678 try posixGetSockName(socket_fd, &storage.any, &addr_len);11727 try posixGetSockName(socket_fd, &storage.any, &addr_len);
11679 return .{11728 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
11680 .socket = .{
11681 .handle = socket_fd,
11682 .address = addressFromPosix(&storage),
11683 },
11684 };
11685}11729}
1168611730
11687fn netListenIpWindows(11731fn netListenIpWindows(
11688 userdata: ?*anyopaque,11732 userdata: ?*anyopaque,
11689 address: IpAddress,11733 address: *const IpAddress,
11690 options: IpAddress.ListenOptions,11734 options: IpAddress.ListenOptions,
11691) IpAddress.ListenError!net.Server {11735) IpAddress.ListenError!net.Socket {
11692 if (!have_networking) return error.NetworkDown;11736 if (!have_networking) return error.NetworkDown;
11693 const t: *Threaded = @ptrCast(@alignCast(userdata));11737 const t: *Threaded = @ptrCast(@alignCast(userdata));
11694 const family = posixAddressFamily(&address);11738 _ = t;
11695 const socket_handle = try openSocketWsa(t, family, .{11739 const family = posixAddressFamily(address);
11696 .mode = options.mode,11740 const socket_handle = try openSocketAfd(family, .{ .mode = options.mode, .protocol = options.protocol });
11697 .protocol = options.protocol,11741 errdefer windows.CloseHandle(socket_handle);
11698 });11742 if (options.reuse_address) try setSocketOptionAfd(socket_handle, ws2_32.SOL.SOCKET, ws2_32.SO.REUSEADDR, true);
11699 errdefer closeSocketWindows(socket_handle);11743 const bound_address = try bindSocketIpAfd(socket_handle, address, .Passive);
1170011744 switch ((try deviceIoControl(&.{
11701 if (options.reuse_address)11745 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
11702 try setSocketOptionWsa(t, socket_handle, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);11746 .code = windows.IOCTL.AFD.START_LISTEN,
1170311747 .in = @ptrCast(&windows.AFD.LISTEN_INFO{
11704 var storage: WsaAddress = undefined;11748 .UseSAN = windows.FALSE,
11705 var addr_len = addressToWsa(&address, &storage);11749 .MaximumConnectionQueue = options.kernel_backlog,
1170611750 .UseDelayedAcceptance = windows.FALSE,
11707 var syscall: AlertableSyscall = try .start();11751 }),
11708 while (true) {11752 })).u.Status) {
11709 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);11753 .SUCCESS => {},
11710 if (rc != ws2_32.SOCKET_ERROR) {11754 .CANCELLED => unreachable,
11711 syscall.finish();11755 .INSUFFICIENT_RESOURCES => return error.SystemResources,
11712 break;11756 else => |status| return windows.unexpectedStatus(status),
11713 }
11714 switch (ws2_32.WSAGetLastError()) {
11715 .NOTINITIALISED => {
11716 syscall.finish();
11717 try initializeWsa(t);
11718 syscall = try .start();
11719 continue;
11720 },
11721 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
11722 try syscall.checkCancel();
11723 continue;
11724 },
11725 .EADDRINUSE => return syscall.fail(error.AddressInUse),
11726 .EADDRNOTAVAIL => return syscall.fail(error.AddressUnavailable),
11727 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
11728 .EFAULT => |err| return syscall.wsaErrorBug(err),
11729 .EINVAL => |err| return syscall.wsaErrorBug(err),
11730 .ENOBUFS => return syscall.fail(error.SystemResources),
11731 .ENETDOWN => return syscall.fail(error.NetworkDown),
11732 else => |err| return syscall.unexpectedWsaError(err),
11733 }
11734 }
11735
11736 syscall = try .start();
11737 while (true) {
11738 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
11739 if (rc != ws2_32.SOCKET_ERROR) {
11740 syscall.finish();
11741 break;
11742 }
11743 switch (ws2_32.WSAGetLastError()) {
11744 .NOTINITIALISED => {
11745 syscall.finish();
11746 try initializeWsa(t);
11747 syscall = try .start();
11748 continue;
11749 },
11750 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
11751 try syscall.checkCancel();
11752 continue;
11753 },
11754 .ENETDOWN => return syscall.fail(error.NetworkDown),
11755 .EADDRINUSE => return syscall.fail(error.AddressInUse),
11756 .EMFILE, .ENOBUFS => return syscall.fail(error.SystemResources),
11757 .EISCONN => |err| return syscall.wsaErrorBug(err),
11758 .EINVAL => |err| return syscall.wsaErrorBug(err),
11759 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
11760 .EOPNOTSUPP => |err| return syscall.wsaErrorBug(err),
11761 .EINPROGRESS => |err| return syscall.wsaErrorBug(err),
11762 else => |err| return syscall.unexpectedWsaError(err),
11763 }
11764 }11757 }
1176511758 return .{ .handle = socket_handle, .address = bound_address };
11766 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
11767
11768 return .{
11769 .socket = .{
11770 .handle = socket_handle,
11771 .address = addressFromWsa(&storage),
11772 },
11773 };
11774}
11775
11776fn netListenIpUnavailable(
11777 userdata: ?*anyopaque,
11778 address: IpAddress,
11779 options: IpAddress.ListenOptions,
11780) IpAddress.ListenError!net.Server {
11781 _ = userdata;
11782 _ = address;
11783 _ = options;
11784 return error.NetworkDown;
11785}11759}
1178611760
11787fn netListenUnixPosix(11761fn netListenUnixPosix(
...@@ -11833,85 +11807,40 @@ fn netListenUnixWindows(...@@ -11833,85 +11807,40 @@ fn netListenUnixWindows(
11833 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;11807 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
11834 if (!have_networking) return error.NetworkDown;11808 if (!have_networking) return error.NetworkDown;
11835 const t: *Threaded = @ptrCast(@alignCast(userdata));11809 const t: *Threaded = @ptrCast(@alignCast(userdata));
1183611810 _ = t;
11837 const socket_handle = openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {11811 const is_abstract = address.isAbstract();
11812 const wps = if (!is_abstract) sliceToPrefixedFileW(null, address.path, .{
11813 .allow_relative = false,
11814 }) catch |err| switch (err) {
11815 error.NameTooLong, error.BadPathName => return error.AddressUnavailable,
11816 else => |e| return e,
11817 } else undefined;
11818 const socket_handle = openSocketAfd(ws2_32.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
11838 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,11819 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
11839 else => |e| return e,11820 else => |e| return e,
11840 };11821 };
11841 errdefer closeSocketWindows(socket_handle);11822 errdefer windows.CloseHandle(socket_handle);
1184211823 if (!is_abstract) try socketOptionAfd(socket_handle, .special, 0, ws2_32.SO.UNIX_PATH, @constCast(
11843 var storage: WsaAddress = undefined;11824 @as([]const u8, @ptrCast(&windows.AFD.SOCKOPT_INFO.UNIX_PATH{
11844 const addr_len = addressUnixToWsa(address, &storage);11825 .Path = wps.data,
1184511826 }))[0 .. @offsetOf(windows.AFD.SOCKOPT_INFO.UNIX_PATH, "Path") + @sizeOf(windows.WCHAR) * wps.len],
11846 var syscall: AlertableSyscall = try .start();11827 ));
11847 while (true) {11828 try bindSocketUnixAfd(socket_handle, address);
11848 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);11829 switch ((try deviceIoControl(&.{
11849 if (rc != ws2_32.SOCKET_ERROR) {11830 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
11850 syscall.finish();11831 .code = windows.IOCTL.AFD.START_LISTEN,
11851 break;11832 .in = @ptrCast(&windows.AFD.LISTEN_INFO{
11852 }11833 .UseSAN = windows.FALSE,
11853 switch (ws2_32.WSAGetLastError()) {11834 .MaximumConnectionQueue = options.kernel_backlog,
11854 .NOTINITIALISED => {11835 .UseDelayedAcceptance = windows.FALSE,
11855 syscall.finish();11836 }),
11856 try initializeWsa(t);11837 })).u.Status) {
11857 syscall = try .start();11838 .SUCCESS => {},
11858 continue;11839 .CANCELLED => unreachable,
11859 },11840 .INSUFFICIENT_RESOURCES => return error.SystemResources,
11860 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {11841 else => |status| return windows.unexpectedStatus(status),
11861 try syscall.checkCancel();
11862 continue;
11863 },
11864 .EADDRINUSE => return syscall.fail(error.AddressInUse),
11865 .EADDRNOTAVAIL => return syscall.fail(error.AddressUnavailable),
11866 .ENOBUFS => return syscall.fail(error.SystemResources),
11867 .ENETDOWN => return syscall.fail(error.NetworkDown),
11868 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
11869 .EFAULT => |err| return syscall.wsaErrorBug(err),
11870 .EINVAL => |err| return syscall.wsaErrorBug(err),
11871 else => |err| return syscall.unexpectedWsaError(err),
11872 }
11873 }
11874
11875 syscall = try .start();
11876 while (true) {
11877 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
11878 if (rc != ws2_32.SOCKET_ERROR) {
11879 syscall.finish();
11880 return socket_handle;
11881 }
11882 switch (ws2_32.WSAGetLastError()) {
11883 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
11884 try syscall.checkCancel();
11885 continue;
11886 },
11887 .NOTINITIALISED => {
11888 syscall.finish();
11889 try initializeWsa(t);
11890 syscall = try .start();
11891 continue;
11892 },
11893 .ENETDOWN => return syscall.fail(error.NetworkDown),
11894 .EADDRINUSE => return syscall.fail(error.AddressInUse),
11895 .EMFILE, .ENOBUFS => return syscall.fail(error.SystemResources),
11896 .EISCONN => |err| return syscall.wsaErrorBug(err),
11897 .EINVAL => |err| return syscall.wsaErrorBug(err),
11898 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
11899 .EOPNOTSUPP => |err| return syscall.wsaErrorBug(err),
11900 .EINPROGRESS => |err| return syscall.wsaErrorBug(err),
11901 else => |err| return syscall.unexpectedWsaError(err),
11902 }
11903 }11842 }
11904}11843 return socket_handle;
11905
11906fn netListenUnixUnavailable(
11907 userdata: ?*anyopaque,
11908 address: *const net.UnixAddress,
11909 options: net.UnixAddress.ListenOptions,
11910) net.UnixAddress.ListenError!net.Socket.Handle {
11911 _ = userdata;
11912 _ = address;
11913 _ = options;
11914 return error.AddressFamilyUnsupported;
11915}11844}
1191611845
11917fn posixBindUnix(11846fn posixBindUnix(
...@@ -12103,40 +12032,7 @@ fn posixGetSockName(...@@ -12103,40 +12032,7 @@ fn posixGetSockName(
12103 }12032 }
12104}12033}
1210512034
12106fn wsaGetSockName(12035fn setSocketOptionPosix(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {
12107 t: *Threaded,
12108 handle: ws2_32.SOCKET,
12109 addr: *ws2_32.sockaddr,
12110 addr_len: *i32,
12111) !void {
12112 var syscall: AlertableSyscall = try .start();
12113 while (true) {
12114 const rc = ws2_32.getsockname(handle, addr, addr_len);
12115 if (rc != ws2_32.SOCKET_ERROR) {
12116 syscall.finish();
12117 return;
12118 }
12119 switch (ws2_32.WSAGetLastError()) {
12120 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12121 try syscall.checkCancel();
12122 continue;
12123 },
12124 .NOTINITIALISED => {
12125 syscall.finish();
12126 try initializeWsa(t);
12127 syscall = try .start();
12128 continue;
12129 },
12130 .ENETDOWN => return syscall.fail(error.NetworkDown),
12131 .EFAULT => |err| return syscall.wsaErrorBug(err),
12132 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
12133 .EINVAL => |err| return syscall.wsaErrorBug(err),
12134 else => |err| return syscall.unexpectedWsaError(err),
12135 }
12136 }
12137}
12138
12139fn setSocketOption(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {
12140 const o: []const u8 = @ptrCast(&option);12036 const o: []const u8 = @ptrCast(&option);
12141 const syscall: Syscall = try .start();12037 const syscall: Syscall = try .start();
12142 while (true) {12038 while (true) {
...@@ -12163,32 +12059,26 @@ fn setSocketOption(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void...@@ -12163,32 +12059,26 @@ fn setSocketOption(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void
12163 }12059 }
12164}12060}
1216512061
12166fn setSocketOptionWsa(t: *Threaded, socket: Io.net.Socket.Handle, level: i32, opt_name: u32, option: u32) !void {12062fn setSocketOptionAfd(socket: net.Socket.Handle, level: i32, opt_name: u32, opt_val: anytype) !void {
12167 const o: []const u8 = @ptrCast(&option);12063 try socketOptionAfd(socket, .set, level, opt_name, @ptrCast(@constCast(&opt_val)));
12168 var syscall: AlertableSyscall = try .start();12064}
12169 while (true) {12065
12170 const rc = ws2_32.setsockopt(socket, level, @bitCast(opt_name), o.ptr, @intCast(o.len));12066fn socketOptionAfd(socket: net.Socket.Handle, mode: windows.AFD.SOCKOPT_INFO.Mode, level: i32, opt_name: u32, opt_val: []u8) !void {
12171 if (rc != ws2_32.SOCKET_ERROR) {12067 switch ((try deviceIoControl(&.{
12172 syscall.finish();12068 .file = .{ .handle = socket, .flags = .{ .nonblocking = true } },
12173 return;12069 .code = windows.IOCTL.AFD.SOCKOPT,
12174 }12070 .in = @ptrCast(&windows.AFD.SOCKOPT_INFO{
12175 switch (ws2_32.WSAGetLastError()) {12071 .mode = mode,
12176 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {12072 .level = level,
12177 try syscall.checkCancel();12073 .optname = opt_name,
12178 continue;12074 .optval = opt_val.ptr,
12179 },12075 .optlen = opt_val.len,
12180 .NOTINITIALISED => {12076 }),
12181 syscall.finish();12077 })).u.Status) {
12182 try initializeWsa(t);12078 .SUCCESS => return,
12183 syscall = try .start();12079 .CANCELLED => unreachable,
12184 continue;12080 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12185 },12081 else => |status| return windows.unexpectedStatus(status),
12186 .ENETDOWN => return syscall.fail(error.NetworkDown),
12187 .EFAULT => |err| return syscall.wsaErrorBug(err),
12188 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
12189 .EINVAL => |err| return syscall.wsaErrorBug(err),
12190 else => |err| return syscall.unexpectedWsaError(err),
12191 }
12192 }12082 }
12193}12083}
1219412084
...@@ -12196,98 +12086,55 @@ fn netConnectIpPosix(...@@ -12196,98 +12086,55 @@ fn netConnectIpPosix(
12196 userdata: ?*anyopaque,12086 userdata: ?*anyopaque,
12197 address: *const IpAddress,12087 address: *const IpAddress,
12198 options: IpAddress.ConnectOptions,12088 options: IpAddress.ConnectOptions,
12199) IpAddress.ConnectError!net.Stream {12089) IpAddress.ConnectError!net.Socket {
12200 if (!have_networking) return error.NetworkDown;12090 if (!have_networking) return error.NetworkDown;
12201 if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");12091 if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");
12202 const t: *Threaded = @ptrCast(@alignCast(userdata));12092 const t: *Threaded = @ptrCast(@alignCast(userdata));
12203 _ = t;12093 _ = t;
12204 const family = posixAddressFamily(address);12094 const family = posixAddressFamily(address);
12205 const socket_fd = try openSocketPosix(family, .{12095 const socket_fd = try openSocketPosix(family, .{ .mode = options.mode, .protocol = options.protocol });
12206 .mode = options.mode,
12207 .protocol = options.protocol,
12208 });
12209 errdefer closeFd(socket_fd);12096 errdefer closeFd(socket_fd);
12210 var storage: PosixAddress = undefined;12097 var storage: PosixAddress = undefined;
12211 var addr_len = addressToPosix(address, &storage);12098 var addr_len = addressToPosix(address, &storage);
12212 try posixConnect(socket_fd, &storage.any, addr_len);12099 try posixConnect(socket_fd, &storage.any, addr_len);
12213 try posixGetSockName(socket_fd, &storage.any, &addr_len);12100 try posixGetSockName(socket_fd, &storage.any, &addr_len);
12214 return .{ .socket = .{12101 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
12215 .handle = socket_fd,
12216 .address = addressFromPosix(&storage),
12217 } };
12218}12102}
1221912103
12220fn netConnectIpWindows(12104fn netConnectIpWindows(
12221 userdata: ?*anyopaque,12105 userdata: ?*anyopaque,
12222 address: *const IpAddress,12106 address: *const IpAddress,
12223 options: IpAddress.ConnectOptions,12107 options: IpAddress.ConnectOptions,
12224) IpAddress.ConnectError!net.Stream {12108) IpAddress.ConnectError!net.Socket {
12225 if (!have_networking) return error.NetworkDown;12109 if (!have_networking) return error.NetworkDown;
12226 if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");12110 if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");
12227 const t: *Threaded = @ptrCast(@alignCast(userdata));12111 const t: *Threaded = @ptrCast(@alignCast(userdata));
12112 _ = t;
12228 const family = posixAddressFamily(address);12113 const family = posixAddressFamily(address);
12229 const socket_handle = try openSocketWsa(t, family, .{12114 const socket_handle = try openSocketAfd(family, .{ .mode = options.mode, .protocol = options.protocol });
12230 .mode = options.mode,12115 errdefer windows.CloseHandle(socket_handle);
12231 .protocol = options.protocol,12116 try setSocketOptionAfd(socket_handle, ws2_32.SOL.SOCKET, ws2_32.SO.REUSE_UNICASTPORT, true);
12232 });12117 const bound_address = bindSocketIpAfd(socket_handle, &switch (address.*) {
12233 errdefer closeSocketWindows(socket_handle);12118 .ip4 => .{ .ip4 = .unspecified(0) },
1223412119 .ip6 => .{ .ip6 = .unspecified(0) },
12235 var storage: WsaAddress = undefined;12120 }, .Active) catch |err| switch (err) {
12236 var addr_len = addressToWsa(address, &storage);12121 error.AddressInUse => return error.Unexpected,
1223712122 else => |e| return e,
12238 var syscall: AlertableSyscall = try .start();12123 };
12239 while (true) {12124 const Storage = extern struct { Reserved0: [3]usize = @splat(0), Address: PosixAddress };
12240 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);12125 var storage: Storage = .{ .Address = undefined };
12241 if (rc != ws2_32.SOCKET_ERROR) {12126 const addr_len = addressToPosix(address, &storage.Address);
12242 syscall.finish();12127 switch ((try deviceIoControl(&.{
12243 break;12128 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12244 }12129 .code = windows.IOCTL.AFD.CONNECT,
12245 switch (ws2_32.WSAGetLastError()) {12130 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12246 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {12131 })).u.Status) {
12247 try syscall.checkCancel();12132 .SUCCESS => {},
12248 continue;12133 .CANCELLED => unreachable,
12249 },12134 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12250 .NOTINITIALISED => {12135 else => |status| return windows.unexpectedStatus(status),
12251 syscall.finish();12136 }
12252 try initializeWsa(t);12137 return .{ .handle = socket_handle, .address = bound_address };
12253 syscall = try .start();
12254 continue;
12255 },
12256 .EADDRNOTAVAIL => return syscall.fail(error.AddressUnavailable),
12257 .ECONNREFUSED => return syscall.fail(error.ConnectionRefused),
12258 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
12259 .ETIMEDOUT => return syscall.fail(error.Timeout),
12260 .EHOSTUNREACH => return syscall.fail(error.HostUnreachable),
12261 .ENETUNREACH => return syscall.fail(error.NetworkUnreachable),
12262 .EFAULT => |err| return syscall.wsaErrorBug(err),
12263 .EINVAL => |err| return syscall.wsaErrorBug(err),
12264 .EISCONN => |err| return syscall.wsaErrorBug(err),
12265 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
12266 .EWOULDBLOCK => return syscall.fail(error.WouldBlock),
12267 .EACCES => return syscall.fail(error.AccessDenied),
12268 .ENOBUFS => return syscall.fail(error.SystemResources),
12269 .EAFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported),
12270 else => |err| return syscall.unexpectedWsaError(err),
12271 }
12272 }
12273
12274 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
12275
12276 return .{ .socket = .{
12277 .handle = socket_handle,
12278 .address = addressFromWsa(&storage),
12279 } };
12280}
12281
12282fn netConnectIpUnavailable(
12283 userdata: ?*anyopaque,
12284 address: *const IpAddress,
12285 options: IpAddress.ConnectOptions,
12286) IpAddress.ConnectError!net.Stream {
12287 _ = userdata;
12288 _ = address;
12289 _ = options;
12290 return error.NetworkDown;
12291}12138}
1229212139
12293fn netConnectUnixPosix(12140fn netConnectUnixPosix(
...@@ -12298,6 +12145,7 @@ fn netConnectUnixPosix(...@@ -12298,6 +12145,7 @@ fn netConnectUnixPosix(
12298 const t: *Threaded = @ptrCast(@alignCast(userdata));12145 const t: *Threaded = @ptrCast(@alignCast(userdata));
12299 _ = t;12146 _ = t;
12300 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {12147 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
12148 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
12301 error.OptionUnsupported => return error.Unexpected,12149 error.OptionUnsupported => return error.Unexpected,
12302 else => |e| return e,12150 else => |e| return e,
12303 };12151 };
...@@ -12315,54 +12163,45 @@ fn netConnectUnixWindows(...@@ -12315,54 +12163,45 @@ fn netConnectUnixWindows(
12315 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;12163 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
12316 if (!have_networking) return error.NetworkDown;12164 if (!have_networking) return error.NetworkDown;
12317 const t: *Threaded = @ptrCast(@alignCast(userdata));12165 const t: *Threaded = @ptrCast(@alignCast(userdata));
1231812166 _ = t;
12319 const socket_handle = try openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream });12167 const is_abstract = address.isAbstract();
12320 errdefer closeSocketWindows(socket_handle);12168 const wps = if (!is_abstract) sliceToPrefixedFileW(null, address.path, .{
12321 var storage: WsaAddress = undefined;12169 .allow_relative = false,
12322 const addr_len = addressUnixToWsa(address, &storage);12170 }) catch |err| switch (err) {
1232312171 error.NameTooLong, error.BadPathName => return error.FileNotFound,
12324 var syscall: AlertableSyscall = try .start();12172 else => |e| return e,
12325 while (true) {12173 } else undefined;
12326 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);12174 const socket_handle = openSocketAfd(ws2_32.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
12327 if (rc != ws2_32.SOCKET_ERROR) {12175 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
12328 syscall.finish();12176 else => |e| return e,
12329 break;12177 };
12330 }12178 errdefer windows.CloseHandle(socket_handle);
12331 switch (ws2_32.WSAGetLastError()) {12179 if (!is_abstract) try socketOptionAfd(socket_handle, .special, 0, ws2_32.SO.UNIX_PATH, @constCast(
12332 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {12180 @as([]const u8, @ptrCast(&windows.AFD.SOCKOPT_INFO.UNIX_PATH{
12333 try syscall.checkCancel();12181 .Path = wps.data,
12334 continue;12182 }))[0 .. @offsetOf(windows.AFD.SOCKOPT_INFO.UNIX_PATH, "Path") + @sizeOf(windows.WCHAR) * wps.len],
12335 },12183 ));
12336 .NOTINITIALISED => {12184 bindSocketUnixAfd(socket_handle, &(net.UnixAddress.init("") catch |err| switch (err) {
12337 syscall.finish();12185 error.NameTooLong => unreachable,
12338 try initializeWsa(t);12186 })) catch |err| switch (err) {
12339 syscall = try .start();12187 error.AddressInUse => return error.Unexpected,
12340 continue;12188 else => |e| return e,
12341 },12189 };
12342 .ECONNREFUSED => return syscall.fail(error.FileNotFound),12190 const Storage = extern struct { Reserved0: [3]usize = @splat(0), Address: UnixAddress };
12343 .EWOULDBLOCK => return syscall.fail(error.WouldBlock),12191 var storage: Storage = .{ .Address = undefined };
12344 .EACCES => return syscall.fail(error.AccessDenied),12192 const addr_len = addressUnixToPosix(address, &storage.Address);
12345 .ENOBUFS => return syscall.fail(error.SystemResources),12193 switch ((try deviceIoControl(&.{
12346 .EAFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported),12194 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12347 .EFAULT => |err| return syscall.wsaErrorBug(err),12195 .code = windows.IOCTL.AFD.CONNECT,
12348 .EINVAL => |err| return syscall.wsaErrorBug(err),12196 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12349 .EISCONN => |err| return syscall.wsaErrorBug(err),12197 })).u.Status) {
12350 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),12198 .SUCCESS => {},
12351 else => |err| return syscall.unexpectedWsaError(err),12199 .CANCELLED => unreachable,
12352 }12200 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12353 }12201 else => |status| return windows.unexpectedStatus(status),
1235412202 }
12355 return socket_handle;12203 return socket_handle;
12356}12204}
12357
12358fn netConnectUnixUnavailable(
12359 userdata: ?*anyopaque,
12360 address: *const net.UnixAddress,
12361) net.UnixAddress.ConnectError!net.Socket.Handle {
12362 _ = userdata;
12363 _ = address;
12364 return error.AddressFamilyUnsupported;
12365}
1236612205
12367fn netBindIpPosix(12206fn netBindIpPosix(
12368 userdata: ?*anyopaque,12207 userdata: ?*anyopaque,
...@@ -12379,10 +12218,7 @@ fn netBindIpPosix(...@@ -12379,10 +12218,7 @@ fn netBindIpPosix(
12379 var addr_len = addressToPosix(address, &storage);12218 var addr_len = addressToPosix(address, &storage);
12380 try posixBind(socket_fd, &storage.any, addr_len);12219 try posixBind(socket_fd, &storage.any, addr_len);
12381 try posixGetSockName(socket_fd, &storage.any, &addr_len);12220 try posixGetSockName(socket_fd, &storage.any, &addr_len);
12382 return .{12221 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
12383 .handle = socket_fd,
12384 .address = addressFromPosix(&storage),
12385 };
12386}12222}
1238712223
12388fn netBindIpWindows(12224fn netBindIpWindows(
...@@ -12392,62 +12228,12 @@ fn netBindIpWindows(...@@ -12392,62 +12228,12 @@ fn netBindIpWindows(
12392) IpAddress.BindError!net.Socket {12228) IpAddress.BindError!net.Socket {
12393 if (!have_networking) return error.NetworkDown;12229 if (!have_networking) return error.NetworkDown;
12394 const t: *Threaded = @ptrCast(@alignCast(userdata));12230 const t: *Threaded = @ptrCast(@alignCast(userdata));
12231 _ = t;
12395 const family = posixAddressFamily(address);12232 const family = posixAddressFamily(address);
12396 const socket_handle = try openSocketWsa(t, family, .{12233 const socket_handle = try openSocketAfd(family, options);
12397 .mode = options.mode,12234 errdefer windows.CloseHandle(socket_handle);
12398 .protocol = options.protocol,12235 const bound_address = try bindSocketIpAfd(socket_handle, address, .Active);
12399 });12236 return .{ .handle = socket_handle, .address = bound_address };
12400 errdefer closeSocketWindows(socket_handle);
12401
12402 var storage: WsaAddress = undefined;
12403 var addr_len = addressToWsa(address, &storage);
12404
12405 var syscall: AlertableSyscall = try .start();
12406 while (true) {
12407 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
12408 if (rc != ws2_32.SOCKET_ERROR) {
12409 syscall.finish();
12410 break;
12411 }
12412 switch (ws2_32.WSAGetLastError()) {
12413 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12414 try syscall.checkCancel();
12415 continue;
12416 },
12417 .NOTINITIALISED => {
12418 syscall.finish();
12419 try initializeWsa(t);
12420 syscall = try .start();
12421 continue;
12422 },
12423 .EADDRINUSE => return syscall.fail(error.AddressInUse),
12424 .EADDRNOTAVAIL => return syscall.fail(error.AddressUnavailable),
12425 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
12426 .EFAULT => |err| return syscall.wsaErrorBug(err),
12427 .EINVAL => |err| return syscall.wsaErrorBug(err),
12428 .ENOBUFS => return syscall.fail(error.SystemResources),
12429 .ENETDOWN => return syscall.fail(error.NetworkDown),
12430 else => |err| return syscall.unexpectedWsaError(err),
12431 }
12432 }
12433
12434 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
12435
12436 return .{
12437 .handle = socket_handle,
12438 .address = addressFromWsa(&storage),
12439 };
12440}
12441
12442fn netBindIpUnavailable(
12443 userdata: ?*anyopaque,
12444 address: *const IpAddress,
12445 options: IpAddress.BindOptions,
12446) IpAddress.BindError!net.Socket {
12447 _ = userdata;
12448 _ = address;
12449 _ = options;
12450 return error.NetworkDown;
12451}12237}
1245212238
12453fn openSocketPosix(12239fn openSocketPosix(
...@@ -12465,8 +12251,7 @@ fn openSocketPosix(...@@ -12465,8 +12251,7 @@ fn openSocketPosix(
12465 Unexpected,12251 Unexpected,
12466 Canceled,12252 Canceled,
12467}!posix.socket_t {12253}!posix.socket_t {
12468 const mode = posixSocketMode(options.mode);12254 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
12469 const protocol = posixProtocol(options.protocol);
12470 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;12255 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
12471 const syscall: Syscall = try .start();12256 const syscall: Syscall = try .start();
12472 const socket_fd = while (true) {12257 const socket_fd = while (true) {
...@@ -12498,7 +12283,7 @@ fn openSocketPosix(...@@ -12498,7 +12283,7 @@ fn openSocketPosix(
1249812283
12499 if (options.ip6_only) {12284 if (options.ip6_only) {
12500 if (posix.IPV6 == void) return error.OptionUnsupported;12285 if (posix.IPV6 == void) return error.OptionUnsupported;
12501 try setSocketOption(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 0);12286 try setSocketOptionPosix(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 0);
12502 }12287 }
1250312288
12504 return socket_fd;12289 return socket_fd;
...@@ -12530,8 +12315,7 @@ fn netSocketCreatePair(...@@ -12530,8 +12315,7 @@ fn netSocketCreatePair(
12530 .ip4 => posix.AF.INET,12315 .ip4 => posix.AF.INET,
12531 .ip6 => posix.AF.INET6,12316 .ip6 => posix.AF.INET6,
12532 };12317 };
12533 const mode = posixSocketMode(options.mode);12318 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
12534 const protocol = posixProtocol(options.protocol);
12535 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;12319 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
1253612320
12537 var sockets: [2]posix.socket_t = undefined;12321 var sockets: [2]posix.socket_t = undefined;
...@@ -12573,56 +12357,102 @@ fn netSocketCreatePair(...@@ -12573,56 +12357,102 @@ fn netSocketCreatePair(
12573 };12357 };
12574}12358}
1257512359
12576fn netSocketCreatePairUnavailable(12360fn openSocketAfd(family: ws2_32.ADDRESS_FAMILY, options: IpAddress.BindOptions) !net.Socket.Handle {
12577 userdata: ?*anyopaque,12361 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
12578 options: net.Socket.CreatePairOptions,12362 var handle: windows.HANDLE = undefined;
12579) net.Socket.CreatePairError![2]net.Socket {12363 var iosb: windows.IO_STATUS_BLOCK = undefined;
12580 _ = userdata;12364 var syscall: Syscall = try .start();
12581 _ = options;12365 while (true) switch (windows.ntdll.NtCreateFile(
12582 return error.OperationUnsupported;12366 &handle,
12367 .{
12368 .STANDARD = .{ .RIGHTS = .{ .WRITE_DAC = true }, .SYNCHRONIZE = true },
12369 .GENERIC = .{ .WRITE = true, .READ = true },
12370 },
12371 &.{
12372 .ObjectName = @constCast(&windows.UNICODE_STRING.init(
12373 windows.AFD.DEVICE_NAME ++ .{ '\\', 'E', 'n', 'd', 'p', 'o', 'i', 'n', 't' },
12374 )),
12375 },
12376 &iosb,
12377 null,
12378 .{},
12379 .{ .READ = true, .WRITE = true },
12380 .OPEN_IF,
12381 .{ .IO = .ASYNCHRONOUS },
12382 &windows.AFD.OPEN_PACKET.FULL_EA_INFORMATION{ .Value = .{
12383 .EndpointType = .{
12384 .CONNECTIONLESS = switch (options.mode) {
12385 .stream, .seqpacket, .rdm => false,
12386 .dgram, .raw => true,
12387 },
12388 .MESSAGEMODE = options.mode != .stream,
12389 .RAW = options.mode == .raw,
12390 },
12391 .GroupID = 0,
12392 .AddressFamily = family,
12393 .SocketType = @bitCast(mode),
12394 .Protocol = @bitCast(protocol),
12395 .TransportDeviceNameLength = 0,
12396 .TransportDeviceName = undefined,
12397 } },
12398 @sizeOf(windows.AFD.OPEN_PACKET.FULL_EA_INFORMATION),
12399 )) {
12400 .SUCCESS => {
12401 syscall.finish();
12402 return handle;
12403 },
12404 .CANCELLED => {
12405 try syscall.checkCancel();
12406 continue;
12407 },
12408 .PROTOCOL_NOT_SUPPORTED => return syscall.fail(error.AddressFamilyUnsupported),
12409 .NO_SUCH_FILE => return syscall.fail(error.ProtocolUnsupportedByAddressFamily),
12410 else => |status| return syscall.unexpectedNtstatus(status),
12411 };
12583}12412}
1258412413
12585fn openSocketWsa(12414fn bindSocketIpAfd(socket_handle: net.Socket.Handle, address: *const IpAddress, mode: windows.AFD.BIND_INFO.MODE) !IpAddress {
12586 t: *Threaded,12415 const Storage = extern struct { Info: windows.AFD.BIND_INFO, Address: PosixAddress };
12587 family: posix.sa_family_t,12416 var storage: Storage = .{ .Info = .{ .Mode = mode }, .Address = undefined };
12588 options: IpAddress.BindOptions,12417 const addr_len = addressToPosix(address, &storage.Address);
12589) !ws2_32.SOCKET {12418 switch ((try deviceIoControl(&.{
12590 const mode = posixSocketMode(options.mode);12419 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12591 const protocol = posixProtocol(options.protocol);12420 .code = windows.IOCTL.AFD.BIND,
12592 // WSA_FLAG_OVERLAPPED is chosen here because without this different12421 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12593 // threads cannot use the same open socket handle.12422 .out = @as([]u8, @ptrCast(&storage.Address))[0..addr_len],
12594 const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;12423 })).u.Status) {
12595 var syscall: AlertableSyscall = try .start();12424 .SUCCESS => {},
12596 while (true) {12425 .CANCELLED => unreachable,
12597 const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);12426 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12598 if (rc != ws2_32.INVALID_SOCKET) {12427 .SHARING_VIOLATION => return error.AddressInUse,
12599 syscall.finish();12428 else => |status| return windows.unexpectedStatus(status),
12600 return rc;12429 }
12601 }12430 return addressFromPosix(&storage.Address);
12602 switch (ws2_32.WSAGetLastError()) {12431}
12603 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {12432
12604 try syscall.checkCancel();12433fn bindSocketUnixAfd(socket_handle: net.Socket.Handle, address: *const net.UnixAddress) !void {
12605 continue;12434 const Storage = extern struct { Info: windows.AFD.BIND_INFO, Address: UnixAddress };
12606 },12435 var storage: Storage = .{ .Info = .{ .Mode = .Unix }, .Address = undefined };
12607 .NOTINITIALISED => {12436 const addr_len = addressUnixToPosix(address, &storage.Address);
12608 syscall.finish();12437 switch ((try deviceIoControl(&.{
12609 try initializeWsa(t);12438 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12610 syscall = try .start();12439 .code = windows.IOCTL.AFD.BIND,
12611 continue;12440 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12612 },12441 .out = @ptrCast(&storage.Address),
12613 .EAFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported),12442 })).u.Status) {
12614 .EMFILE => return syscall.fail(error.ProcessFdQuotaExceeded),12443 .SUCCESS => {},
12615 .ENOBUFS => return syscall.fail(error.SystemResources),12444 .CANCELLED => unreachable,
12616 .EPROTONOSUPPORT => return syscall.fail(error.ProtocolUnsupportedByAddressFamily),12445 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12617 else => |err| return syscall.unexpectedWsaError(err),12446 .ADDRESS_ALREADY_EXISTS => return error.AddressInUse,
12618 }12447 else => |status| return windows.unexpectedStatus(status),
12619 }12448 }
12620}12449}
1262112450
12622fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {12451fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket {
12623 if (!have_networking) return error.NetworkDown;12452 if (!have_networking) return error.NetworkDown;
12624 const t: *Threaded = @ptrCast(@alignCast(userdata));12453 const t: *Threaded = @ptrCast(@alignCast(userdata));
12625 _ = t;12454 _ = t;
12455 options;
12626 var storage: PosixAddress = undefined;12456 var storage: PosixAddress = undefined;
12627 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);12457 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
12628 const syscall: Syscall = try .start();12458 const syscall: Syscall = try .start();
...@@ -12664,55 +12494,71 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -12664,55 +12494,71 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
12664 },12494 },
12665 }12495 }
12666 };12496 };
12667 return .{ .socket = .{12497 return .{ .handle = fd, .address = addressFromPosix(&storage) };
12668 .handle = fd,
12669 .address = addressFromPosix(&storage),
12670 } };
12671}12498}
1267212499
12673fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {12500fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket {
12674 if (!have_networking) return error.NetworkDown;12501 if (!have_networking) return error.NetworkDown;
12675 const t: *Threaded = @ptrCast(@alignCast(userdata));12502 const t: *Threaded = @ptrCast(@alignCast(userdata));
12676 var storage: WsaAddress = undefined;12503 const Storage = extern struct {
12677 var addr_len: i32 = @sizeOf(WsaAddress);12504 Info: windows.AFD.LISTEN_RESPONSE_INFO,
12678 var syscall: AlertableSyscall = try .start();12505 RemoteAddress: extern union { posix: PosixAddress, unix: UnixAddress },
12679 while (true) {12506 };
12680 const rc = ws2_32.accept(listen_handle, &storage.any, &addr_len);12507 var storage: Storage = undefined;
12681 if (rc != ws2_32.INVALID_SOCKET) {12508 switch ((try deviceIoControl(&.{
12682 syscall.finish();12509 .file = .{ .handle = listen_handle, .flags = .{ .nonblocking = true } },
12683 return .{ .socket = .{12510 .code = windows.IOCTL.AFD.WAIT_FOR_LISTEN,
12684 .handle = rc,12511 .out = @ptrCast(&storage),
12685 .address = addressFromWsa(&storage),12512 })).u.Status) {
12686 } };12513 .SUCCESS => {},
12687 }12514 .CANCELLED => unreachable,
12688 switch (ws2_32.WSAGetLastError()) {12515 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12689 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {12516 else => |status| return windows.unexpectedStatus(status),
12690 try syscall.checkCancel();12517 }
12691 continue;12518 errdefer t.deferAcceptAfd(listen_handle, storage.Info);
12692 },12519 const accept_handle = openSocketAfd(
12693 .NOTINITIALISED => {12520 storage.RemoteAddress.posix.any.family,
12694 syscall.finish();12521 .{ .mode = options.mode, .protocol = options.protocol },
12695 try initializeWsa(t);12522 ) catch |err| switch (err) {
12696 syscall = try .start();12523 error.AddressFamilyUnsupported => return error.Unexpected,
12697 continue;12524 error.ProtocolUnsupportedByAddressFamily => return error.Unexpected,
12698 },12525 else => |e| return e,
12699 .ECONNRESET => return syscall.fail(error.ConnectionAborted),12526 };
12700 .EMFILE => return syscall.fail(error.ProcessFdQuotaExceeded),12527 errdefer windows.CloseHandle(accept_handle);
12701 .ENETDOWN => return syscall.fail(error.NetworkDown),12528 switch ((try deviceIoControl(&.{
12702 .ENOBUFS => return syscall.fail(error.SystemResources),12529 .file = .{ .handle = listen_handle, .flags = .{ .nonblocking = true } },
12703 .EFAULT => |err| return syscall.wsaErrorBug(err),12530 .code = windows.IOCTL.AFD.ACCEPT,
12704 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),12531 .in = @ptrCast(&windows.AFD.ACCEPT_INFO{
12705 .EINVAL => |err| return syscall.wsaErrorBug(err),12532 .UseSAN = windows.FALSE,
12706 .EOPNOTSUPP => |err| return syscall.wsaErrorBug(err),12533 .Sequence = storage.Info.Sequence,
12707 else => |err| return syscall.unexpectedWsaError(err),12534 .AcceptHandle = accept_handle,
12708 }12535 }),
12536 })).u.Status) {
12537 .SUCCESS => {},
12538 .CANCELLED => unreachable,
12539 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12540 else => |status| return windows.unexpectedStatus(status),
12709 }12541 }
12542 return .{ .handle = accept_handle, .address = addressFromPosix(&storage.RemoteAddress.posix) };
12710}12543}
1271112544
12712fn netAcceptUnavailable(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {12545fn deferAcceptAfd(t: *Threaded, listen_handle: net.Socket.Handle, info: windows.AFD.LISTEN_RESPONSE_INFO) void {
12713 _ = userdata;12546 const cancel_protection = swapCancelProtection(t, .blocked);
12714 _ = listen_handle;12547 defer _ = swapCancelProtection(t, cancel_protection);
12715 return error.NetworkDown;12548 switch ((deviceIoControl(&.{
12549 .file = .{ .handle = listen_handle, .flags = .{ .nonblocking = true } },
12550 .code = windows.IOCTL.AFD.DEFER_ACCEPT,
12551 .in = @ptrCast(&windows.AFD.DEFER_ACCEPT_INFO{
12552 .Sequence = info.Sequence,
12553 .Reject = windows.FALSE,
12554 }),
12555 }) catch |err| switch (err) {
12556 error.Canceled => unreachable, // blocked
12557 }).u.Status) {
12558 .SUCCESS => {},
12559 .CANCELLED => unreachable,
12560 else => |status| windows.unexpectedStatus(status) catch {},
12561 }
12716}12562}
1271712563
12718fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {12564fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
...@@ -12798,78 +12644,39 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -12798,78 +12644,39 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
12798 }12644 }
12799}12645}
1280012646
12801fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {12647fn netReadWindows(userdata: ?*anyopaque, socket_handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12802 if (!have_networking) return error.NetworkDown;12648 if (!have_networking) return error.NetworkDown;
12803 const t: *Threaded = @ptrCast(@alignCast(userdata));12649 const t: *Threaded = @ptrCast(@alignCast(userdata));
12650 _ = t;
1280412651
12805 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;12652 var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"var") = undefined;
12806 const bufs = b: {12653 var len: u32 = 0;
12807 var i: usize = 0;12654 for (data) |buf| {
12808 var n: usize = 0;12655 if (iovecs.len - len == 0) break;
12809 for (data) |buf| {12656 addAfdBuf(.@"var", &iovecs, &len, buf);
12810 if (iovec_buffer.len - i == 0) break;12657 }
12811 if (buf.len == 0) continue;12658
12812 if (std.math.cast(u32, buf.len)) |len| {12659 const iosb = try deviceIoControl(&.{
12813 iovec_buffer[i] = .{ .buf = buf.ptr, .len = len };12660 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12814 i += 1;12661 .code = windows.IOCTL.AFD.RECEIVE,
12815 n += len;12662 .in = @ptrCast(&windows.AFD.RECV_INFO{
12816 continue;12663 .BufferArray = &iovecs,
12817 }12664 .BufferCount = len,
12818 iovec_buffer[i] = .{ .buf = buf.ptr, .len = std.math.maxInt(u32) };12665 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
12819 i += 1;12666 .TdiFlags = .{ .NORMAL = true },
12820 n += std.math.maxInt(u32);12667 }),
12821 break;12668 });
12822 }12669 switch (iosb.u.Status) {
1282312670 .SUCCESS => return iosb.Information,
12824 const bufs = iovec_buffer[0..i];12671 .CANCELLED => unreachable,
12825 assert(bufs[0].len != 0);12672 .INSUFFICIENT_RESOURCES => return error.SystemResources,
1282612673 else => |status| return windows.unexpectedStatus(status),
12827 break :b bufs;
12828 };
12829
12830 var syscall: AlertableSyscall = try .start();
12831 while (true) {
12832 var flags: u32 = 0;
12833 var n: u32 = undefined;
12834 const rc = ws2_32.WSARecv(handle, bufs.ptr, @intCast(bufs.len), &n, &flags, null, null);
12835 if (rc != ws2_32.SOCKET_ERROR) {
12836 syscall.finish();
12837 return n;
12838 }
12839 switch (ws2_32.WSAGetLastError()) {
12840 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12841 try syscall.checkCancel();
12842 continue;
12843 },
12844 .NOTINITIALISED => {
12845 syscall.finish();
12846 try initializeWsa(t);
12847 syscall = try .start();
12848 continue;
12849 },
12850
12851 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
12852 .ENETDOWN => return syscall.fail(error.NetworkDown),
12853 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),
12854 .ENOTCONN => return syscall.fail(error.SocketUnconnected),
12855 .EFAULT => unreachable, // a pointer is not completely contained in user address space.
12856 .EINVAL => |err| return syscall.wsaErrorBug(err),
12857 .EMSGSIZE => |err| return syscall.wsaErrorBug(err),
12858 else => |err| return syscall.unexpectedWsaError(err),
12859 }
12860 }12674 }
12861}12675}
1286212676
12863fn netReadUnavailable(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
12864 _ = userdata;
12865 _ = fd;
12866 _ = data;
12867 return error.NetworkDown;
12868}
12869
12870fn netSendPosix(12677fn netSendPosix(
12871 userdata: ?*anyopaque,12678 userdata: ?*anyopaque,
12872 handle: net.Socket.Handle,12679 socket_handle: net.Socket.Handle,
12873 messages: []net.OutgoingMessage,12680 messages: []net.OutgoingMessage,
12874 flags: net.SendFlags,12681 flags: net.SendFlags,
12875) struct { ?net.Socket.SendError, usize } {12682) struct { ?net.Socket.SendError, usize } {
...@@ -12887,10 +12694,10 @@ fn netSendPosix(...@@ -12887,10 +12694,10 @@ fn netSendPosix(
12887 var i: usize = 0;12694 var i: usize = 0;
12888 while (messages.len - i != 0) {12695 while (messages.len - i != 0) {
12889 if (have_sendmmsg) {12696 if (have_sendmmsg) {
12890 i += netSendMany(handle, messages[i..], posix_flags) catch |err| return .{ err, i };12697 i += netSendManyPosix(socket_handle, messages[i..], posix_flags) catch |err| return .{ err, i };
12891 continue;12698 continue;
12892 }12699 }
12893 netSendOne(t, handle, &messages[i], posix_flags) catch |err| return .{ err, i };12700 t.netSendOnePosix(socket_handle, &messages[i], posix_flags) catch |err| return .{ err, i };
12894 i += 1;12701 i += 1;
12895 }12702 }
12896 return .{ null, i };12703 return .{ null, i };
...@@ -12898,97 +12705,65 @@ fn netSendPosix(...@@ -12898,97 +12705,65 @@ fn netSendPosix(
1289812705
12899fn netSendWindows(12706fn netSendWindows(
12900 userdata: ?*anyopaque,12707 userdata: ?*anyopaque,
12901 handle: net.Socket.Handle,12708 socket_handle: net.Socket.Handle,
12902 messages: []net.OutgoingMessage,12709 messages: []net.OutgoingMessage,
12903 flags: net.SendFlags,12710 flags: net.SendFlags,
12904) struct { ?net.Socket.SendError, usize } {12711) struct { ?net.Socket.SendError, usize } {
12905 if (!have_networking) return .{ error.NetworkDown, 0 };12712 if (!have_networking) return .{ error.NetworkDown, 0 };
12906 const t: *Threaded = @ptrCast(@alignCast(userdata));12713 const t: *Threaded = @ptrCast(@alignCast(userdata));
12907
12908 // Ignored flags: confirm, eor, fastopen
12909 const windows_flags: u32 =
12910 @as(u32, if (flags.oob) ws2_32.MSG.OOB else 0) |
12911 @as(u32, if (flags.dont_route) ws2_32.MSG.DONTROUTE else 0);
12912
12913 for (messages, 0..) |*m, i| {12714 for (messages, 0..) |*m, i| {
12914 netSendWindowsOne(t, handle, m, windows_flags) catch |err| return .{ err, i };12715 t.netSendOneWindows(socket_handle, m, flags) catch |err| return .{ err, i };
12915 }12716 }
12916 return .{ null, messages.len };12717 return .{ null, messages.len };
12917}12718}
1291812719
12919fn netSendWindowsOne(12720fn netSendOneWindows(
12920 t: *Threaded,12721 t: *Threaded,
12921 handle: net.Socket.Handle,12722 socket_handle: net.Socket.Handle,
12922 message: *net.OutgoingMessage,12723 message: *net.OutgoingMessage,
12923 flags: u32,12724 flags: net.SendFlags,
12924) net.Socket.SendError!void {12725) net.Socket.SendError!void {
12925 var buf: ws2_32.WSABUF = .{12726 _ = t;
12926 .buf = @constCast(message.data_ptr),12727 _ = flags;
12927 .len = std.math.cast(u32, message.data_len) orelse return error.MessageOversize,12728 const iovecs: [1]windows.AFD.WSABUF(.@"const") = .{.{
12928 };12729 .buf = message.data_ptr,
12929 var n: u32 = undefined;12730 .len = std.math.cast(std.os.windows.ULONG, message.data_len) orelse
12930 var address: WsaAddress = undefined;12731 return error.MessageOversize,
12931 const address_size = addressToWsa(message.address, &address);12732 }};
12932 var syscall: AlertableSyscall = try .start();12733 var storage: PosixAddress = undefined;
12933 while (true) {12734 const addr_len = addressToPosix(message.address, &storage);
12934 const rc = ws2_32.WSASendTo(12735 switch ((try deviceIoControl(&.{
12935 handle,12736 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12936 (&buf)[0..1],12737 .code = windows.IOCTL.AFD.SEND_DATAGRAM,
12937 1,12738 .in = @ptrCast(&windows.AFD.SEND_DATAGRAM_INFO{
12938 &n,12739 .BufferArray = &iovecs,
12939 flags,12740 .BufferCount = iovecs.len,
12940 &address.any,12741 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
12941 address_size,12742 .TdiRequest = undefined,
12942 null,12743 .TdiConnInfo = .{
12943 null,12744 .UserDataLength = undefined,
12944 );12745 .UserData = undefined,
12945 if (rc != ws2_32.SOCKET_ERROR) {12746 .OptionsLength = undefined,
12946 syscall.finish();12747 .Options = undefined,
12947 return;12748 .RemoteAddressLength = @bitCast(addr_len),
12948 }12749 .RemoteAddress = &storage,
12949 switch (ws2_32.WSAGetLastError()) {
12950 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12951 try syscall.checkCancel();
12952 continue;
12953 },
12954 .NOTINITIALISED => {
12955 syscall.finish();
12956 try initializeWsa(t);
12957 syscall = try .start();
12958 continue;
12959 },12750 },
1296012751 }),
12961 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),12752 })).u.Status) {
12962 .ENETDOWN => return syscall.fail(error.NetworkDown),12753 .SUCCESS => return,
12963 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),12754 .CANCELLED => unreachable,
12964 .ENOTCONN => return syscall.fail(error.SocketUnconnected),12755 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12965 .EFAULT => unreachable, // a pointer is not completely contained in user address space.12756 else => |status| return windows.unexpectedStatus(status),
12966 .EINVAL => |err| return syscall.wsaErrorBug(err),
12967 .EMSGSIZE => |err| return syscall.wsaErrorBug(err),
12968 else => |err| return syscall.unexpectedWsaError(err),
12969 }
12970 }12757 }
12971}12758}
1297212759
12973fn netSendUnavailable(12760fn netSendOnePosix(
12974 userdata: ?*anyopaque,
12975 handle: net.Socket.Handle,
12976 messages: []net.OutgoingMessage,
12977 flags: net.SendFlags,
12978) struct { ?net.Socket.SendError, usize } {
12979 _ = userdata;
12980 _ = handle;
12981 _ = messages;
12982 _ = flags;
12983 return .{ error.NetworkDown, 0 };
12984}
12985
12986fn netSendOne(
12987 t: *Threaded,12761 t: *Threaded,
12988 handle: net.Socket.Handle,12762 socket_handle: net.Socket.Handle,
12989 message: *net.OutgoingMessage,12763 message: *net.OutgoingMessage,
12990 flags: u32,12764 flags: u32,
12991) net.Socket.SendError!void {12765) net.Socket.SendError!void {
12766 _ = t;
12992 var addr: PosixAddress = undefined;12767 var addr: PosixAddress = undefined;
12993 var iovec: posix.iovec_const = .{ .base = @constCast(message.data_ptr), .len = message.data_len };12768 var iovec: posix.iovec_const = .{ .base = @constCast(message.data_ptr), .len = message.data_len };
12994 const msg: posix.msghdr_const = .{12769 const msg: posix.msghdr_const = .{
...@@ -13003,43 +12778,7 @@ fn netSendOne(...@@ -13003,43 +12778,7 @@ fn netSendOne(
13003 };12778 };
13004 var syscall: if (is_windows) AlertableSyscall else Syscall = try .start();12779 var syscall: if (is_windows) AlertableSyscall else Syscall = try .start();
13005 while (true) {12780 while (true) {
13006 const rc = posix.system.sendmsg(handle, &msg, flags);12781 const rc = posix.system.sendmsg(socket_handle, &msg, flags);
13007 if (is_windows) {
13008 if (rc != ws2_32.SOCKET_ERROR) {
13009 syscall.finish();
13010 message.data_len = @intCast(rc);
13011 return;
13012 }
13013 switch (ws2_32.WSAGetLastError()) {
13014 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
13015 try syscall.checkCancel();
13016 continue;
13017 },
13018 .NOTINITIALISED => {
13019 syscall.finish();
13020 try initializeWsa(t);
13021 syscall = try .start();
13022 continue;
13023 },
13024 .EACCES => return syscall.fail(error.AccessDenied),
13025 .EADDRNOTAVAIL => return syscall.fail(error.AddressUnavailable),
13026 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
13027 .EMSGSIZE => return syscall.fail(error.MessageOversize),
13028 .ENOBUFS => return syscall.fail(error.SystemResources),
13029 .ENOTSOCK => return syscall.fail(error.FileDescriptorNotASocket),
13030 .EAFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported),
13031 .EHOSTUNREACH => return syscall.fail(error.NetworkUnreachable),
13032 .ENETDOWN => return syscall.fail(error.NetworkDown),
13033 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),
13034 .ENETUNREACH => return syscall.fail(error.NetworkUnreachable),
13035 .ENOTCONN => return syscall.fail(error.SocketUnconnected),
13036 .EDESTADDRREQ => unreachable, // A destination address is required.
13037 .EFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
13038 .EINVAL => unreachable,
13039 .ESHUTDOWN => |err| return syscall.wsaErrorBug(err),
13040 else => |err| return syscall.unexpectedWsaError(err),
13041 }
13042 }
13043 switch (posix.errno(rc)) {12782 switch (posix.errno(rc)) {
13044 .SUCCESS => {12783 .SUCCESS => {
13045 syscall.finish();12784 syscall.finish();
...@@ -13074,8 +12813,8 @@ fn netSendOne(...@@ -13074,8 +12813,8 @@ fn netSendOne(
13074 }12813 }
13075}12814}
1307612815
13077fn netSendMany(12816fn netSendManyPosix(
13078 handle: net.Socket.Handle,12817 socket_handle: net.Socket.Handle,
13079 messages: []net.OutgoingMessage,12818 messages: []net.OutgoingMessage,
13080 flags: u32,12819 flags: u32,
13081) net.Socket.SendError!usize {12820) net.Socket.SendError!usize {
...@@ -13106,7 +12845,7 @@ fn netSendMany(...@@ -13106,7 +12845,7 @@ fn netSendMany(
1310612845
13107 const syscall: Syscall = try .start();12846 const syscall: Syscall = try .start();
13108 while (true) {12847 while (true) {
13109 const rc = posix.system.sendmmsg(handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);12848 const rc = posix.system.sendmmsg(socket_handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);
13110 switch (posix.errno(rc)) {12849 switch (posix.errno(rc)) {
13111 .SUCCESS => {12850 .SUCCESS => {
13112 syscall.finish();12851 syscall.finish();
...@@ -13231,11 +12970,12 @@ fn netReceiveWindows(...@@ -13231,11 +12970,12 @@ fn netReceiveWindows(
13231 data_buffer: []u8,12970 data_buffer: []u8,
13232 flags: net.ReceiveFlags,12971 flags: net.ReceiveFlags,
13233) struct { ?net.Socket.ReceiveError, usize } {12972) struct { ?net.Socket.ReceiveError, usize } {
13234 netReceiveWindowsOne(t, socket_handle, &message_buffer[0], data_buffer, flags) catch |err| return .{ err, 0 };12973 t.netReceiveOneWindows(socket_handle, &message_buffer[0], data_buffer, flags) catch |err|
12974 return .{ err, 0 };
13235 return .{ null, 1 };12975 return .{ null, 1 };
13236}12976}
1323712977
13238fn netReceiveWindowsOne(12978fn netReceiveOneWindows(
13239 t: *Threaded,12979 t: *Threaded,
13240 socket_handle: net.Socket.Handle,12980 socket_handle: net.Socket.Handle,
13241 message: *net.IncomingMessage,12981 message: *net.IncomingMessage,
...@@ -13243,69 +12983,49 @@ fn netReceiveWindowsOne(...@@ -13243,69 +12983,49 @@ fn netReceiveWindowsOne(
13243 flags: net.ReceiveFlags,12983 flags: net.ReceiveFlags,
13244) net.Socket.ReceiveError!void {12984) net.Socket.ReceiveError!void {
13245 if (!have_networking) return error.NetworkDown;12985 if (!have_networking) return error.NetworkDown;
1324612986 _ = t;
13247 var windows_flags: u32 =12987 const iovecs: [1]windows.AFD.WSABUF(.@"var") = .{.{
13248 @as(u32, if (flags.oob) ws2_32.MSG.OOB else 0) |
13249 @as(u32, if (flags.peek) ws2_32.MSG.PEEK else 0) |
13250 @as(u32, if (flags.trunc) ws2_32.MSG.TRUNC else 0);
13251
13252 var buf: ws2_32.WSABUF = .{
13253 .buf = data_buffer.ptr,12988 .buf = data_buffer.ptr,
13254 .len = std.math.cast(u32, data_buffer.len) orelse return error.MessageOversize,12989 .len = std.math.cast(std.os.windows.ULONG, data_buffer.len) orelse return error.MessageOversize,
13255 };12990 }};
13256 var n: u32 = undefined;12991 var storage: PosixAddress = undefined;
13257 var from_storage: WsaAddress = undefined;12992 var addr_len: windows.ULONG = @sizeOf(PosixAddress);
13258 var from_storage_len: i32 = @sizeOf(WsaAddress);12993 const iosb = try deviceIoControl(&.{
13259 var syscall: AlertableSyscall = try .start();12994 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
1326012995 .code = windows.IOCTL.AFD.RECEIVE_DATAGRAM,
13261 while (true) {12996 .in = @ptrCast(&windows.AFD.RECV_DATAGRAM_INFO{
13262 const rc = ws2_32.WSARecvFrom(12997 .BufferArray = &iovecs,
13263 socket_handle,12998 .BufferCount = iovecs.len,
13264 (&buf)[0..1],12999 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
13265 1,13000 .TdiFlags = .{ .NORMAL = !flags.oob, .EXPEDITED = flags.oob, .PEEK = flags.peek },
13266 &n,13001 .Address = &storage,
13267 &windows_flags,13002 .AddressLength = &addr_len,
13268 &from_storage.any,13003 }),
13269 &from_storage_len,13004 });
13270 null,13005 switch (iosb.u.Status) {
13271 null,13006 .SUCCESS, .RECEIVE_PARTIAL => |status| message.* = .{
13272 );13007 .from = addressFromPosix(&storage),
13273 if (rc != ws2_32.SOCKET_ERROR) {13008 .data = data_buffer[0..iosb.Information],
13274 syscall.finish();13009 .control = &.{},
13275 message.* = .{13010 .flags = .{
13276 .from = addressFromWsa(&from_storage),13011 .eor = false,
13277 .data = data_buffer[0..n],13012 .trunc = false,
13278 .control = &.{},13013 .ctrunc = false,
13279 .flags = .{13014 .oob = switch (status) {
13280 .eor = false,13015 else => unreachable,
13281 .trunc = (windows_flags & ws2_32.MSG.TRUNC) != 0,13016 .SUCCESS, .RECEIVE_PARTIAL, .BUFFER_OVERFLOW => false,
13282 .ctrunc = (windows_flags & ws2_32.MSG.CTRUNC) != 0,13017 .RECEIVE_EXPEDITED, .RECEIVE_PARTIAL_EXPEDITED => true,
13283 .oob = false,
13284 .errqueue = false,
13285 },13018 },
13286 };13019 .errqueue = false,
13287 return;
13288 }
13289 switch (ws2_32.WSAGetLastError()) {
13290 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
13291 try syscall.checkCancel();
13292 continue;
13293 },13020 },
13294 .NOTINITIALISED => {13021 },
13295 syscall.finish();13022 .RECEIVE_EXPEDITED,
13296 try initializeWsa(t);13023 .RECEIVE_PARTIAL_EXPEDITED,
13297 syscall = try .start();13024 .BUFFER_OVERFLOW,
13298 continue;13025 => |status| return windows.unexpectedStatus(status), // TdiFlags.PARTIAL = false
13299 },13026 .CANCELLED => unreachable,
13300 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),13027 .INSUFFICIENT_RESOURCES => return error.SystemResources,
13301 .ENETDOWN => return syscall.fail(error.NetworkDown),13028 else => |status| return windows.unexpectedStatus(status),
13302 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),
13303 .ENOTCONN => return syscall.fail(error.SocketUnconnected),
13304 .EFAULT => unreachable, // a pointer is not completely contained in user address space.
13305 .EINVAL => |err| return syscall.wsaErrorBug(err),
13306 .EMSGSIZE => |err| return syscall.wsaErrorBug(err),
13307 else => |err| return syscall.unexpectedWsaError(err),
13308 }
13309 }13029 }
13310}13030}
1331113031
...@@ -13412,17 +13132,17 @@ fn netWriteWindows(...@@ -13412,17 +13132,17 @@ fn netWriteWindows(
13412) net.Stream.Writer.Error!usize {13132) net.Stream.Writer.Error!usize {
13413 if (!have_networking) return error.NetworkDown;13133 if (!have_networking) return error.NetworkDown;
13414 const t: *Threaded = @ptrCast(@alignCast(userdata));13134 const t: *Threaded = @ptrCast(@alignCast(userdata));
13415 comptime assert(is_windows);13135 _ = t;
1341613136
13417 var iovecs: [max_iovecs_len]ws2_32.WSABUF = undefined;13137 var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"const") = undefined;
13418 var len: u32 = 0;13138 var len: u32 = 0;
13419 addWsaBuf(&iovecs, &len, header);13139 addAfdBuf(.@"const", &iovecs, &len, header);
13420 for (data[0 .. data.len - 1]) |bytes| addWsaBuf(&iovecs, &len, bytes);13140 for (data[0 .. data.len - 1]) |bytes| addAfdBuf(.@"const", &iovecs, &len, bytes);
13421 const pattern = data[data.len - 1];13141 const pattern = data[data.len - 1];
13422 var backup_buffer: [64]u8 = undefined;13142 var backup_buffer: [64]u8 = undefined;
13423 if (iovecs.len - len != 0) switch (splat) {13143 if (iovecs.len - len != 0) switch (splat) {
13424 0 => {},13144 0 => {},
13425 1 => addWsaBuf(&iovecs, &len, pattern),13145 1 => addAfdBuf(.@"const", &iovecs, &len, pattern),
13426 else => switch (pattern.len) {13146 else => switch (pattern.len) {
13427 0 => {},13147 0 => {},
13428 1 => {13148 1 => {
...@@ -13430,87 +13150,63 @@ fn netWriteWindows(...@@ -13430,87 +13150,63 @@ fn netWriteWindows(
13430 const memset_len = @min(splat_buffer.len, splat);13150 const memset_len = @min(splat_buffer.len, splat);
13431 const buf = splat_buffer[0..memset_len];13151 const buf = splat_buffer[0..memset_len];
13432 @memset(buf, pattern[0]);13152 @memset(buf, pattern[0]);
13433 addWsaBuf(&iovecs, &len, buf);13153 addAfdBuf(.@"const", &iovecs, &len, buf);
13434 var remaining_splat = splat - buf.len;13154 var remaining_splat = splat - buf.len;
13435 while (remaining_splat > splat_buffer.len and len < iovecs.len) {13155 while (remaining_splat > splat_buffer.len and len < iovecs.len) {
13436 addWsaBuf(&iovecs, &len, splat_buffer);13156 addAfdBuf(.@"const", &iovecs, &len, splat_buffer);
13437 remaining_splat -= splat_buffer.len;13157 remaining_splat -= splat_buffer.len;
13438 }13158 }
13439 addWsaBuf(&iovecs, &len, splat_buffer[0..@min(remaining_splat, splat_buffer.len)]);13159 addAfdBuf(.@"const", &iovecs, &len, splat_buffer[0..@min(remaining_splat, splat_buffer.len)]);
13440 },
13441 else => for (0..@min(splat, iovecs.len - len)) |_| {
13442 addWsaBuf(&iovecs, &len, pattern);
13443 },
13444 },
13445 };
13446
13447 var syscall: AlertableSyscall = try .start();
13448 while (true) {
13449 var n: u32 = undefined;
13450 const rc = ws2_32.WSASend(handle, &iovecs, len, &n, 0, null, null);
13451 if (rc != ws2_32.SOCKET_ERROR) {
13452 syscall.finish();
13453 return n;
13454 }
13455 switch (ws2_32.WSAGetLastError()) {
13456 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
13457 try syscall.checkCancel();
13458 continue;
13459 },13160 },
13460 .NOTINITIALISED => {13161 else => for (0..@min(splat, iovecs.len - len)) |_| {
13461 syscall.finish();13162 addAfdBuf(.@"const", &iovecs, &len, pattern);
13462 try initializeWsa(t);
13463 syscall = try .start();
13464 continue;
13465 },13163 },
13164 },
13165 };
1346613166
13467 .ECONNABORTED => return syscall.fail(error.ConnectionResetByPeer),13167 const iosb = try deviceIoControl(&.{
13468 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),13168 .file = .{ .handle = handle, .flags = .{ .nonblocking = true } },
13469 .EINVAL => return syscall.fail(error.SocketUnconnected),13169 .code = windows.IOCTL.AFD.SEND,
13470 .ENETDOWN => return syscall.fail(error.NetworkDown),13170 .in = @ptrCast(&windows.AFD.SEND_INFO{
13471 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),13171 .BufferArray = &iovecs,
13472 .ENOBUFS => return syscall.fail(error.SystemResources),13172 .BufferCount = len,
13473 .ENOTCONN => return syscall.fail(error.SocketUnconnected),13173 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
13474 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),13174 .TdiFlags = .{},
13475 .EOPNOTSUPP => |err| return syscall.wsaErrorBug(err),13175 }),
13476 .ESHUTDOWN => |err| return syscall.wsaErrorBug(err),13176 });
13477 .IO_PENDING => |err| return syscall.wsaErrorBug(err),13177 switch (iosb.u.Status) {
13478 else => |err| return syscall.unexpectedWsaError(err),13178 .SUCCESS => return iosb.Information,
13479 }13179 .CANCELLED => unreachable,
13180 .INSUFFICIENT_RESOURCES => return error.SystemResources,
13181 else => |status| return windows.unexpectedStatus(status),
13480 }13182 }
13481}13183}
1348213184
13483fn addWsaBuf(v: []ws2_32.WSABUF, i: *u32, bytes: []const u8) void {13185fn addAfdBuf(
13186 comptime mutability: windows.AFD.Mutability,
13187 iovecs: []windows.AFD.WSABUF(mutability),
13188 len: *u32,
13189 bytes: switch (mutability) {
13190 .@"const" => []const u8,
13191 .@"var" => []u8,
13192 },
13193) void {
13194 if (bytes.len == 0) return;
13484 const cap = std.math.maxInt(u32);13195 const cap = std.math.maxInt(u32);
13485 var remaining = bytes;13196 var remaining = bytes;
13486 while (remaining.len > cap) {13197 while (remaining.len > cap) {
13487 if (v.len - i.* == 0) return;13198 if (iovecs.len - len.* == 0) return;
13488 v[i.*] = .{ .buf = @constCast(remaining.ptr), .len = cap };13199 iovecs[len.*] = .{ .buf = remaining.ptr, .len = cap };
13489 i.* += 1;13200 len.* += 1;
13490 remaining = remaining[cap..];13201 remaining = remaining[cap..];
13491 } else {13202 } else {
13492 @branchHint(.likely);13203 @branchHint(.likely);
13493 if (v.len - i.* == 0) return;13204 if (iovecs.len - len.* == 0) return;
13494 v[i.*] = .{ .buf = @constCast(remaining.ptr), .len = @intCast(remaining.len) };13205 iovecs[len.*] = .{ .buf = remaining.ptr, .len = @intCast(remaining.len) };
13495 i.* += 1;13206 len.* += 1;
13496 }13207 }
13497}13208}
1349813209
13499fn netWriteUnavailable(
13500 userdata: ?*anyopaque,
13501 handle: net.Socket.Handle,
13502 header: []const u8,
13503 data: []const []const u8,
13504 splat: usize,
13505) net.Stream.Writer.Error!usize {
13506 _ = userdata;
13507 _ = handle;
13508 _ = header;
13509 _ = data;
13510 _ = splat;
13511 return error.NetworkDown;
13512}
13513
13514/// This is either usize or u32. Since, either is fine, let's use the same13210/// This is either usize or u32. Since, either is fine, let's use the same
13515/// `addBuf` function for both writing to a file and sending network messages.13211/// `addBuf` function for both writing to a file and sending network messages.
13516const iovlen_t = switch (native_os) {13212const iovlen_t = switch (native_os) {
...@@ -13530,16 +13226,10 @@ fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void {...@@ -13530,16 +13226,10 @@ fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void {
13530 if (!have_networking) unreachable;13226 if (!have_networking) unreachable;
13531 const t: *Threaded = @ptrCast(@alignCast(userdata));13227 const t: *Threaded = @ptrCast(@alignCast(userdata));
13532 _ = t;13228 _ = t;
13533 switch (native_os) {13229 for (handles) |handle| switch (native_os) {
13534 .windows => for (handles) |handle| closeSocketWindows(handle),13230 .windows => windows.CloseHandle(handle),
13535 else => for (handles) |handle| closeFd(handle),13231 else => closeFd(handle),
13536 }13232 };
13537}
13538
13539fn netCloseUnavailable(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void {
13540 _ = userdata;
13541 _ = handles;
13542 unreachable; // How you gonna close something that was impossible to open?
13543}13233}
1354413234
13545fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {13235fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
...@@ -13577,52 +13267,30 @@ fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.S...@@ -13577,52 +13267,30 @@ fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.S
13577fn netShutdownWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {13267fn netShutdownWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
13578 if (!have_networking) return error.NetworkDown;13268 if (!have_networking) return error.NetworkDown;
13579 const t: *Threaded = @ptrCast(@alignCast(userdata));13269 const t: *Threaded = @ptrCast(@alignCast(userdata));
13270 _ = t;
1358013271
13581 const wsa_how: i32 = switch (how) {13272 // shutdown does not support apcs at all
13582 .recv => ws2_32.SD_RECEIVE,13273 switch ((try deviceIoControl(&.{
13583 .send => ws2_32.SD_SEND,13274 .file = .{ .handle = handle, .flags = .{ .nonblocking = false } },
13584 .both => ws2_32.SD_BOTH,13275 .code = windows.IOCTL.AFD.PARTIAL_DISCONNECT,
13585 };13276 .in = @ptrCast(&windows.AFD.PARTIAL_DISCONNECT_INFO{
1358613277 .DisconnectMode = .{ .SEND = how != .recv, .RECEIVE = how != .send },
13587 var syscall: AlertableSyscall = try .start();13278 .Timeout = -1,
13588 while (true) {13279 }),
13589 const rc = ws2_32.shutdown(handle, wsa_how);13280 })).u.Status) {
13590 if (rc != ws2_32.SOCKET_ERROR) {13281 .SUCCESS => {},
13591 syscall.finish();13282 .CANCELLED => unreachable,
13592 return;13283 .INSUFFICIENT_RESOURCES => return error.SystemResources,
13593 }13284 else => |status| return windows.unexpectedStatus(status),
13594 switch (ws2_32.WSAGetLastError()) {
13595 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
13596 try syscall.checkCancel();
13597 continue;
13598 },
13599 .NOTINITIALISED => {
13600 syscall.finish();
13601 try initializeWsa(t);
13602 syscall = try .start();
13603 continue;
13604 },
13605 .ECONNABORTED => return syscall.fail(error.ConnectionAborted),
13606 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
13607 .ENETDOWN => return syscall.fail(error.NetworkDown),
13608 .ENOTCONN => return syscall.fail(error.SocketUnconnected),
13609 .EINVAL, .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
13610 else => |err| return syscall.unexpectedWsaError(err),
13611 }
13612 }13285 }
13613}13286}
1361413287
13615fn netShutdownUnavailable(_: ?*anyopaque, _: net.Socket.Handle, _: net.ShutdownHow) net.ShutdownError!void {
13616 unreachable; // How you gonna shutdown something that was impossible to open?
13617}
13618
13619fn netInterfaceNameResolve(13288fn netInterfaceNameResolve(
13620 userdata: ?*anyopaque,13289 userdata: ?*anyopaque,
13621 name: *const net.Interface.Name,13290 name: *const net.Interface.Name,
13622) net.Interface.Name.ResolveError!net.Interface {13291) net.Interface.Name.ResolveError!net.Interface {
13623 if (!have_networking) return error.InterfaceNotFound;13292 if (!have_networking) return error.InterfaceNotFound;
13624 const t: *Threaded = @ptrCast(@alignCast(userdata));13293 const t: *Threaded = @ptrCast(@alignCast(userdata));
13625 _ = t;
1362613294
13627 if (native_os == .linux) {13295 if (native_os == .linux) {
13628 const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {13296 const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {
...@@ -13658,8 +13326,66 @@ fn netInterfaceNameResolve(...@@ -13658,8 +13326,66 @@ fn netInterfaceNameResolve(
13658 }13326 }
1365913327
13660 if (is_windows) {13328 if (is_windows) {
13329 var ConvertInterfaceNameToLuidW = t.dl.ConvertInterfaceNameToLuidW.load(.acquire);
13330 var ConvertInterfaceLuidToIndex = t.dl.ConvertInterfaceLuidToIndex.load(.acquire);
13331 if (ConvertInterfaceNameToLuidW == null or ConvertInterfaceLuidToIndex == null) {
13332 const iphlpapi_dll = t.dl.iphlpapi_dll.load(.acquire) orelse iphlpapi_dll: {
13333 try Thread.checkCancel();
13334 var iphlpapi_dll: *anyopaque = undefined;
13335 switch (windows.ntdll.LdrLoadDll(null, null, &.init(
13336 &.{ 'I', 'P', 'H', 'L', 'P', 'A', 'P', 'I', '.', 'D', 'L', 'L' },
13337 ), &iphlpapi_dll)) {
13338 .SUCCESS => {},
13339 .DLL_NOT_FOUND => return error.Unexpected,
13340 else => |status| return windows.unexpectedStatus(status),
13341 }
13342 const handle = t.dl.iphlpapi_dll.cmpxchgStrong(null, iphlpapi_dll, .release, .monotonic) orelse
13343 break :iphlpapi_dll iphlpapi_dll;
13344 switch (windows.ntdll.LdrUnloadDll(iphlpapi_dll)) {
13345 .SUCCESS => break :iphlpapi_dll handle.?,
13346 else => |status| return windows.unexpectedStatus(status),
13347 }
13348 };
13349 switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
13350 &.{
13351 'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
13352 'N', 'a', 'm', 'e', 'T', 'o', 'L', 'u', 'i', 'd', 'W',
13353 },
13354 ), 0, @ptrCast(&ConvertInterfaceNameToLuidW))) {
13355 .SUCCESS => t.dl.ConvertInterfaceNameToLuidW.store(ConvertInterfaceNameToLuidW, .release),
13356 else => |status| return windows.unexpectedStatus(status),
13357 }
13358 switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
13359 &.{
13360 'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
13361 'L', 'u', 'i', 'd', 'T', 'o', 'I', 'n', 'd', 'e', 'x',
13362 },
13363 ), 0, @ptrCast(&ConvertInterfaceLuidToIndex))) {
13364 .SUCCESS => t.dl.ConvertInterfaceLuidToIndex.store(ConvertInterfaceLuidToIndex, .release),
13365 else => |status| return windows.unexpectedStatus(status),
13366 }
13367 }
13661 try Thread.checkCancel();13368 try Thread.checkCancel();
13662 @panic("TODO implement netInterfaceNameResolve for Windows");13369 var name_w: [net.Interface.Name.max_len:0]windows.WCHAR = undefined;
13370 name_w[
13371 std.unicode.wtf8ToWtf16Le(&name_w, name.toSlice()) catch |err| switch (err) {
13372 error.InvalidWtf8 => return error.InterfaceNotFound,
13373 }
13374 ] = 0;
13375 var luid: windows.NET.LUID = undefined;
13376 switch (ConvertInterfaceNameToLuidW.?(&name_w, &luid)) {
13377 .SUCCESS => {},
13378 .INVALID_NAME => return error.InterfaceNotFound,
13379 .INVALID_PARAMETER => unreachable,
13380 else => |err| return windows.unexpectedError(err),
13381 }
13382 var index: windows.NET.IFINDEX = undefined;
13383 switch (ConvertInterfaceLuidToIndex.?(&luid, &index)) {
13384 .SUCCESS => {},
13385 .INVALID_PARAMETER => unreachable,
13386 else => |err| return windows.unexpectedError(err),
13387 }
13388 return .{ .index = @intFromEnum(index) };
13663 }13389 }
1366413390
13665 if (builtin.link_libc) {13391 if (builtin.link_libc) {
...@@ -13672,42 +13398,81 @@ fn netInterfaceNameResolve(...@@ -13672,42 +13398,81 @@ fn netInterfaceNameResolve(
13672 @panic("unimplemented");13398 @panic("unimplemented");
13673}13399}
1367413400
13675fn netInterfaceNameResolveUnavailable(
13676 userdata: ?*anyopaque,
13677 name: *const net.Interface.Name,
13678) net.Interface.Name.ResolveError!net.Interface {
13679 _ = userdata;
13680 _ = name;
13681 return error.InterfaceNotFound;
13682}
13683
13684fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {13401fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
13685 const t: *Threaded = @ptrCast(@alignCast(userdata));13402 const t: *Threaded = @ptrCast(@alignCast(userdata));
13686 _ = t;
13687 try Thread.checkCancel();
1368813403
13689 if (native_os == .linux) {13404 if (native_os == .linux) {
13690 _ = interface;13405 try Thread.checkCancel();
13691 @panic("TODO implement netInterfaceName for linux");13406 @panic("TODO implement netInterfaceName for linux");
13692 }13407 }
1369313408
13694 if (is_windows) {13409 if (is_windows) {
13695 @panic("TODO implement netInterfaceName for windows");13410 var ConvertInterfaceIndexToLuid = t.dl.ConvertInterfaceIndexToLuid.load(.acquire);
13411 var ConvertInterfaceLuidToNameW = t.dl.ConvertInterfaceLuidToNameW.load(.acquire);
13412 if (ConvertInterfaceIndexToLuid == null or ConvertInterfaceLuidToNameW == null) {
13413 const iphlpapi_dll = t.dl.iphlpapi_dll.load(.acquire) orelse iphlpapi_dll: {
13414 try Thread.checkCancel();
13415 var iphlpapi_dll: *anyopaque = undefined;
13416 switch (windows.ntdll.LdrLoadDll(null, null, &.init(
13417 &.{ 'I', 'P', 'H', 'L', 'P', 'A', 'P', 'I', '.', 'D', 'L', 'L' },
13418 ), &iphlpapi_dll)) {
13419 .SUCCESS => {},
13420 .DLL_NOT_FOUND => return error.Unexpected,
13421 else => |status| return windows.unexpectedStatus(status),
13422 }
13423 const handle = t.dl.iphlpapi_dll.cmpxchgStrong(null, iphlpapi_dll, .release, .monotonic) orelse
13424 break :iphlpapi_dll iphlpapi_dll;
13425 switch (windows.ntdll.LdrUnloadDll(iphlpapi_dll)) {
13426 .SUCCESS => break :iphlpapi_dll handle.?,
13427 else => |status| return windows.unexpectedStatus(status),
13428 }
13429 };
13430 switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
13431 &.{
13432 'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
13433 'I', 'n', 'd', 'e', 'x', 'T', 'o', 'L', 'u', 'i', 'd',
13434 },
13435 ), 0, @ptrCast(&ConvertInterfaceIndexToLuid))) {
13436 .SUCCESS => t.dl.ConvertInterfaceIndexToLuid.store(ConvertInterfaceIndexToLuid, .release),
13437 else => |status| return windows.unexpectedStatus(status),
13438 }
13439 switch (windows.ntdll.LdrGetProcedureAddress(iphlpapi_dll, &.init(
13440 &.{
13441 'C', 'o', 'n', 'v', 'e', 'r', 't', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e',
13442 'L', 'u', 'i', 'd', 'T', 'o', 'N', 'a', 'm', 'e', 'W',
13443 },
13444 ), 0, @ptrCast(&ConvertInterfaceLuidToNameW))) {
13445 .SUCCESS => t.dl.ConvertInterfaceLuidToNameW.store(ConvertInterfaceLuidToNameW, .release),
13446 else => |status| return windows.unexpectedStatus(status),
13447 }
13448 }
13449 try Thread.checkCancel();
13450 var luid: windows.NET.LUID = undefined;
13451 switch (ConvertInterfaceIndexToLuid.?(@enumFromInt(interface.index), &luid)) {
13452 .SUCCESS => {},
13453 .FILE_NOT_FOUND => return error.InterfaceNotFound,
13454 .INVALID_PARAMETER => unreachable,
13455 else => |err| return windows.unexpectedError(err),
13456 }
13457 var name_w: [net.Interface.Name.max_len:0]windows.WCHAR = undefined;
13458 switch (ConvertInterfaceLuidToNameW.?(&luid, &name_w, name_w.len)) {
13459 .SUCCESS => {},
13460 .INVALID_PARAMETER => unreachable,
13461 .NOT_ENOUGH_MEMORY => return error.NameTooLong,
13462 else => |err| return windows.unexpectedError(err),
13463 }
13464 var name: [3 * net.Interface.Name.max_len]u8 = undefined;
13465 return .fromSlice(name[0..std.unicode.wtf16LeToWtf8(&name, std.mem.sliceTo(&name_w, 0))]);
13696 }13466 }
1369713467
13698 if (builtin.link_libc) {13468 if (builtin.link_libc) {
13469 try Thread.checkCancel();
13699 @panic("TODO implement netInterfaceName for libc");13470 @panic("TODO implement netInterfaceName for libc");
13700 }13471 }
1370113472
13702 @panic("unimplemented");13473 @panic("unimplemented");
13703}13474}
1370413475
13705fn netInterfaceNameUnavailable(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
13706 _ = userdata;
13707 _ = interface;
13708 return error.Unexpected;
13709}
13710
13711fn netLookup(13476fn netLookup(
13712 userdata: ?*anyopaque,13477 userdata: ?*anyopaque,
13713 host_name: HostName,13478 host_name: HostName,
...@@ -13716,25 +13481,12 @@ fn netLookup(...@@ -13716,25 +13481,12 @@ fn netLookup(
13716) net.HostName.LookupError!void {13481) net.HostName.LookupError!void {
13717 const t: *Threaded = @ptrCast(@alignCast(userdata));13482 const t: *Threaded = @ptrCast(@alignCast(userdata));
13718 defer resolved.close(io(t));13483 defer resolved.close(io(t));
13719 netLookupFallible(t, host_name, resolved, options) catch |err| switch (err) {13484 t.netLookupFallible(host_name, resolved, options) catch |err| switch (err) {
13720 error.Closed => unreachable, // `resolved` must not be closed until `netLookup` returns13485 error.Closed => unreachable, // `resolved` must not be closed until `netLookup` returns
13721 else => |e| return e,13486 else => |e| return e,
13722 };13487 };
13723}13488}
1372413489
13725fn netLookupUnavailable(
13726 userdata: ?*anyopaque,
13727 host_name: HostName,
13728 resolved: *Io.Queue(HostName.LookupResult),
13729 options: HostName.LookupOptions,
13730) net.HostName.LookupError!void {
13731 _ = host_name;
13732 _ = options;
13733 const t: *Threaded = @ptrCast(@alignCast(userdata));
13734 resolved.close(io(t));
13735 return error.NetworkDown;
13736}
13737
13738fn netLookupFallible(13490fn netLookupFallible(
13739 t: *Threaded,13491 t: *Threaded,
13740 host_name: HostName,13492 host_name: HostName,
...@@ -13743,88 +13495,128 @@ fn netLookupFallible(...@@ -13743,88 +13495,128 @@ fn netLookupFallible(
13743) (net.HostName.LookupError || Io.QueueClosedError)!void {13495) (net.HostName.LookupError || Io.QueueClosedError)!void {
13744 if (!have_networking) return error.NetworkDown;13496 if (!have_networking) return error.NetworkDown;
1374513497
13746 const t_io = io(t);13498 const t_io = t.io();
13747 const name = host_name.bytes;13499 const name = host_name.bytes;
13748 assert(name.len <= HostName.max_len);13500 assert(name.len <= HostName.max_len);
1374913501
13750 if (is_windows) {13502 if (is_windows) {
13751 var name_buffer: [HostName.max_len + 1]u16 = undefined;13503 if (options.family == null) {
13752 const name_len = std.unicode.wtf8ToWtf16Le(&name_buffer, host_name.bytes) catch13504 if (IpAddress.parseIp4(name, options.port)) |addr| {
13753 unreachable; // HostName is prevalidated.13505 try resolved.putAll(t_io, &.{
13754 name_buffer[name_len] = 0;13506 .{ .address = addr },
13755 const name_w = name_buffer[0..name_len :0];13507 .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) },
1375613508 });
13757 var port_buffer: [8]u8 = undefined;13509 return;
13758 var port_buffer_wide: [8]u16 = undefined;13510 } else |_| {}
13759 const port = std.fmt.bufPrint(&port_buffer, "{d}", .{options.port}) catch
13760 unreachable; // `port_buffer` is big enough for decimal u16.
13761 for (port, port_buffer_wide[0..port.len]) |byte, *wide|
13762 wide.* = std.mem.nativeToLittle(u16, byte);
13763 port_buffer_wide[port.len] = 0;
13764 const port_w = port_buffer_wide[0..port.len :0];
13765
13766 const hints: ws2_32.ADDRINFOEXW = .{
13767 .flags = .{ .NUMERICSERV = true },
13768 .family = if (options.family) |f| switch (f) {
13769 .ip4 => posix.AF.INET,
13770 .ip6 => posix.AF.INET6,
13771 } else posix.AF.UNSPEC,
13772 .socktype = posix.SOCK.STREAM,
13773 .protocol = posix.IPPROTO.TCP,
13774 .canonname = null,
13775 .addr = null,
13776 .addrlen = 0,
13777 .blob = null,
13778 .bloblen = 0,
13779 .provider = null,
13780 .next = null,
13781 };
13782 var res: *ws2_32.ADDRINFOEXW = undefined;
13783 const timeout: ?*ws2_32.timeval = null;
13784 while (true) {
13785 // TODO: hook this up to cancelation with `NtDelayExecution` and APC callbacks.
13786 try Thread.checkCancel();
13787 // TODO make this append to the queue eagerly rather than blocking until the whole thing finishes
13788 const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null, null));
13789 switch (rc) {
13790 @as(ws2_32.WinsockError, @enumFromInt(0)) => break,
13791 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => continue,
13792 .NOTINITIALISED => {
13793 try initializeWsa(t);
13794 continue;
13795 },
13796 .TRY_AGAIN => return error.NameServerFailure,
13797 .NO_RECOVERY => return error.NameServerFailure,
13798 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
13799 .NOT_ENOUGH_MEMORY => return error.SystemResources,
13800 .HOST_NOT_FOUND => return error.UnknownHostName,
13801 .TYPE_NOT_FOUND => return error.ProtocolUnsupportedByAddressFamily,
13802 .ESOCKTNOSUPPORT => return error.ProtocolUnsupportedBySystem,
13803 .EINVAL => |err| return windows.wsaErrorBug(err),
13804 else => |err| return windows.unexpectedWsaError(err),
13805 }
13806 }13511 }
13807 defer ws2_32.FreeAddrInfoExW(res);
1380813512
13809 var it: ?*ws2_32.ADDRINFOEXW = res;13513 var DnsQueryEx = t.dl.DnsQueryEx.load(.acquire);
13810 var canon_name: ?[*:0]const u16 = null;13514 //var DnsCancelQuery = t.dl.DnsCancelQuery.load(.acquire);
13811 while (it) |info| : (it = info.next) {13515 var DnsFree = t.dl.DnsFree.load(.acquire);
13812 const addr = info.addr orelse continue;13516 if (DnsQueryEx == null or
13813 try resolved.putOne(t_io, .{ .address = addressFromWsa(@alignCast(@fieldParentPtr("any", addr))) });13517 //DnsCancelQuery == null or
1381413518 DnsFree == null)
13815 if (info.canonname) |n| {13519 {
13816 if (canon_name == null) {13520 const dnsapi_dll = t.dl.dnsapi_dll.load(.acquire) orelse dnsapi_dll: {
13817 canon_name = n;13521 try Thread.checkCancel();
13522 var dnsapi_dll: *anyopaque = undefined;
13523 switch (windows.ntdll.LdrLoadDll(null, null, &.init(
13524 &.{ 'd', 'n', 's', 'a', 'p', 'i', '.', 'd', 'l', 'l' },
13525 ), &dnsapi_dll)) {
13526 .SUCCESS => {},
13527 .DLL_NOT_FOUND => return error.Unexpected,
13528 else => |status| return windows.unexpectedStatus(status),
13529 }
13530 const handle = t.dl.dnsapi_dll.cmpxchgStrong(null, dnsapi_dll, .release, .monotonic) orelse
13531 break :dnsapi_dll dnsapi_dll;
13532 switch (windows.ntdll.LdrUnloadDll(dnsapi_dll)) {
13533 .SUCCESS => break :dnsapi_dll handle.?,
13534 else => |status| return windows.unexpectedStatus(status),
13818 }13535 }
13536 };
13537 switch (windows.ntdll.LdrGetProcedureAddress(dnsapi_dll, &.init(
13538 &.{ 'D', 'n', 's', 'Q', 'u', 'e', 'r', 'y', 'E', 'x' },
13539 ), 0, @ptrCast(&DnsQueryEx))) {
13540 .SUCCESS => t.dl.DnsQueryEx.store(DnsQueryEx, .release),
13541 else => |status| return windows.unexpectedStatus(status),
13542 }
13543 //switch (windows.ntdll.LdrGetProcedureAddress(dnsapi_dll, &.init(
13544 // &.{ 'D', 'n', 's', 'C', 'a', 'n', 'c', 'e', 'l', 'Q', 'u', 'e', 'r', 'y' },
13545 //), 0, @ptrCast(&DnsCancelQuery))) {
13546 // .SUCCESS => t.dl.DnsCancelQuery.store(DnsCancelQuery, .release),
13547 // else => |status| return windows.unexpectedStatus(status),
13548 //}
13549 switch (windows.ntdll.LdrGetProcedureAddress(dnsapi_dll, &.init(
13550 &.{ 'D', 'n', 's', 'F', 'r', 'e', 'e' },
13551 ), 0, @ptrCast(&DnsFree))) {
13552 .SUCCESS => t.dl.DnsFree.store(DnsFree, .release),
13553 else => |status| return windows.unexpectedStatus(status),
13819 }13554 }
13820 }13555 }
13821 if (canon_name) |n| {13556 const current_thread = Thread.current;
13822 const len = std.unicode.wtf16LeToWtf8(options.canonical_name_buffer, std.mem.sliceTo(n, 0));13557 var lookup_dns: LookupDnsWindows = .{
13823 try resolved.putOne(t_io, .{ .canonical_name = .{13558 .threaded = t,
13824 .bytes = options.canonical_name_buffer[0..len],13559 .thread = if (current_thread) |thread| thread.handle else undefined,
13825 } });13560 .resolved = resolved,
13561 .options = options,
13562 .results = .{
13563 .Version = 1,
13564 .QueryStatus = undefined,
13565 .QueryOptions = undefined,
13566 .pQueryRecords = undefined,
13567 .Reserved = undefined,
13568 },
13569 .done = false,
13570 };
13571 var host_name_w: [HostName.max_len:0]windows.WCHAR = undefined;
13572 host_name_w[
13573 std.unicode.wtf8ToWtf16Le(&host_name_w, name) catch |err| switch (err) {
13574 error.InvalidWtf8 => return error.UnknownHostName,
13575 }
13576 ] = 0;
13577 //var cancel_token: windows.DNS.QUERY.CANCEL = undefined;
13578 switch (DnsQueryEx.?(&.{
13579 .Version = 1,
13580 .QueryName = &host_name_w,
13581 .QueryType = if (options.family == .ip4) .A else .AAAA,
13582 .QueryOptions = .{
13583 .ADDRCONFIG = true,
13584 .DUAL_ADDR = options.family == null,
13585 .MULTICAST_WAIT = true,
13586 },
13587 .pQueryCompletionCallback = if (current_thread) |_| &LookupDnsWindows.completed else null,
13588 }, &lookup_dns.results,
13589 //&cancel_token,
13590 null)) {
13591 // We must wait for the APC routine.
13592 .SUCCESS, .REQUEST_PENDING => |status| if (current_thread) |_| {
13593 while (!@atomicLoad(bool, &lookup_dns.done, .acquire)) {
13594 // Once we get here we must not return from the function until the
13595 // operation completes, thereby releasing references to `host_name_w`,
13596 // `lookup_dns.results`, and `cancel_token`.
13597 const alertable_syscall = AlertableSyscall.start() catch |err| switch (err) {
13598 error.Canceled => |e| {
13599 //_ = DnsCancelQuery.?(&cancel_token);
13600 while (!@atomicLoad(bool, &lookup_dns.done, .acquire)) waitForApcOrAlert();
13601 return e;
13602 },
13603 };
13604 waitForApcOrAlert();
13605 alertable_syscall.finish();
13606 }
13607 } else switch (status) {
13608 .SUCCESS => try lookup_dns.completedFallible(),
13609 .REQUEST_PENDING => unreachable, // `pQueryCompletionCallback` was `null`
13610 else => unreachable,
13611 },
13612 else => |status| lookup_dns.results.QueryStatus = status,
13613 }
13614 switch (lookup_dns.results.QueryStatus) {
13615 .SUCCESS => return,
13616 .REQUEST_PENDING => unreachable, // already handled
13617 .INVALID_NAME, .NO_RECORDS => return error.UnknownHostName,
13618 else => |status| return windows.unexpectedError(@enumFromInt(@intFromEnum(status))),
13826 }13619 }
13827 return;
13828 }13620 }
1382913621
13830 // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.13622 // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.
...@@ -13855,7 +13647,7 @@ fn netLookupFallible(...@@ -13855,7 +13647,7 @@ fn netLookupFallible(
13855 } else |_| {}13647 } else |_| {}
13856 }13648 }
1385713649
13858 lookupHosts(t, host_name, resolved, options) catch |err| switch (err) {13650 t.lookupHosts(host_name, resolved, options) catch |err| switch (err) {
13859 error.UnknownHostName => {},13651 error.UnknownHostName => {},
13860 else => |e| return e,13652 else => |e| return e,
13861 };13653 };
...@@ -13890,7 +13682,7 @@ fn netLookupFallible(...@@ -13890,7 +13682,7 @@ fn netLookupFallible(
13890 return;13682 return;
13891 }13683 }
1389213684
13893 return lookupDnsSearch(t, host_name, resolved, options);13685 return t.lookupDnsSearch(host_name, resolved, options);
13894 }13686 }
1389513687
13896 if (native_os == .openbsd) {13688 if (native_os == .openbsd) {
...@@ -13908,16 +13700,16 @@ fn netLookupFallible(...@@ -13908,16 +13700,16 @@ fn netLookupFallible(
13908 if (builtin.link_libc) {13700 if (builtin.link_libc) {
13909 // This operating system lacks a way to resolve asynchronously. We are13701 // This operating system lacks a way to resolve asynchronously. We are
13910 // stuck with getaddrinfo.13702 // stuck with getaddrinfo.
13911 var name_buffer: [HostName.max_len + 1]u8 = undefined;13703 var name_buffer: [HostName.max_len:0]u8 = undefined;
13912 @memcpy(name_buffer[0..host_name.bytes.len], host_name.bytes);13704 @memcpy(name_buffer[0..name.len], name);
13913 name_buffer[host_name.bytes.len] = 0;13705 name_buffer[name.len] = 0;
13914 const name_c = name_buffer[0..host_name.bytes.len :0];13706 const name_c = name_buffer[0..name.len :0];
1391513707
13916 var port_buffer: [8]u8 = undefined;13708 var port_buffer: [8]u8 = undefined;
13917 const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable;13709 const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable;
1391813710
13919 const hints: posix.addrinfo = .{13711 const hints: posix.addrinfo = .{
13920 .flags = .{ .NUMERICSERV = true },13712 .flags = .{ .CANONNAME = options.request_canonical_name, .NUMERICSERV = true },
13921 .family = posix.AF.UNSPEC,13713 .family = posix.AF.UNSPEC,
13922 .socktype = posix.SOCK.STREAM,13714 .socktype = posix.SOCK.STREAM,
13923 .protocol = posix.IPPROTO.TCP,13715 .protocol = posix.IPPROTO.TCP,
...@@ -14168,13 +13960,6 @@ const UnixAddress = extern union {...@@ -14168,13 +13960,6 @@ const UnixAddress = extern union {
14168 un: posix.sockaddr.un,13960 un: posix.sockaddr.un,
14169};13961};
1417013962
14171const WsaAddress = extern union {
14172 any: ws2_32.sockaddr,
14173 in: ws2_32.sockaddr.in,
14174 in6: ws2_32.sockaddr.in6,
14175 un: ws2_32.sockaddr.un,
14176};
14177
14178pub fn posixAddressFamily(a: *const IpAddress) posix.sa_family_t {13963pub fn posixAddressFamily(a: *const IpAddress) posix.sa_family_t {
14179 return switch (a.*) {13964 return switch (a.*) {
14180 .ip4 => posix.AF.INET,13965 .ip4 => posix.AF.INET,
...@@ -14190,14 +13975,6 @@ pub fn addressFromPosix(posix_address: *const PosixAddress) IpAddress {...@@ -14190,14 +13975,6 @@ pub fn addressFromPosix(posix_address: *const PosixAddress) IpAddress {
14190 };13975 };
14191}13976}
1419213977
14193fn addressFromWsa(wsa_address: *const WsaAddress) IpAddress {
14194 return switch (wsa_address.any.family) {
14195 posix.AF.INET => .{ .ip4 = address4FromWsa(&wsa_address.in) },
14196 posix.AF.INET6 => .{ .ip6 = address6FromWsa(&wsa_address.in6) },
14197 else => .{ .ip4 = .loopback(0) },
14198 };
14199}
14200
14201pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen_t {13978pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen_t {
14202 return switch (a.*) {13979 return switch (a.*) {
14203 .ip4 => |ip4| {13980 .ip4 => |ip4| {
...@@ -14211,31 +13988,27 @@ pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen...@@ -14211,31 +13988,27 @@ pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen
14211 };13988 };
14212}13989}
1421313990
14214fn addressToWsa(a: *const IpAddress, storage: *WsaAddress) i32 {
14215 return switch (a.*) {
14216 .ip4 => |ip4| {
14217 storage.in = address4ToPosix(ip4);
14218 return @sizeOf(posix.sockaddr.in);
14219 },
14220 .ip6 => |*ip6| {
14221 storage.in6 = address6ToPosix(ip6);
14222 return @sizeOf(posix.sockaddr.in6);
14223 },
14224 };
14225}
14226
14227fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.socklen_t {13991fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.socklen_t {
14228 @memcpy(storage.un.path[0..a.path.len], a.path);
14229 storage.un.family = posix.AF.UNIX;13992 storage.un.family = posix.AF.UNIX;
14230 storage.un.path[a.path.len] = 0;13993 var path_len = switch (native_os) {
14231 return @sizeOf(posix.sockaddr.un);13994 .windows => @min(a.path.len, storage.un.path.len),
14232}13995 else => a.path.len,
1423313996 };
14234fn addressUnixToWsa(a: *const net.UnixAddress, storage: *WsaAddress) i32 {13997 // With the AFD API, `sockaddr.un` is purely informational, so
14235 @memcpy(storage.un.path[0..a.path.len], a.path);13998 // use a suffix which is usually the most relevant part of a path.
14236 storage.un.family = posix.AF.UNIX;13999 @memcpy(storage.un.path[0..path_len], a.path[a.path.len - path_len ..]);
14237 storage.un.path[a.path.len] = 0;14000 if (storage.un.path.len - path_len > 0) {
14238 return @sizeOf(posix.sockaddr.un);14001 @branchHint(.likely);
14002 storage.un.path[path_len] = 0;
14003 path_len += 1;
14004 }
14005 switch (native_os) {
14006 .windows => {
14007 if (storage.un.path[0] == 0) @memset(storage.un.path[path_len..], 0);
14008 return @sizeOf(posix.sockaddr.un);
14009 },
14010 else => return @intCast(@offsetOf(posix.sockaddr.un, "path") + path_len),
14011 }
14239}14012}
1424014013
14241fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {14014fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {
...@@ -14254,22 +14027,6 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address {...@@ -14254,22 +14027,6 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address {
14254 };14027 };
14255}14028}
1425614029
14257fn address4FromWsa(in: *const ws2_32.sockaddr.in) net.Ip4Address {
14258 return .{
14259 .port = std.mem.bigToNative(u16, in.port),
14260 .bytes = @bitCast(in.addr),
14261 };
14262}
14263
14264fn address6FromWsa(in6: *const ws2_32.sockaddr.in6) net.Ip6Address {
14265 return .{
14266 .port = std.mem.bigToNative(u16, in6.port),
14267 .bytes = in6.addr,
14268 .flow = in6.flowinfo,
14269 .interface = .{ .index = in6.scope_id },
14270 };
14271}
14272
14273fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in {14030fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in {
14274 return .{14031 return .{
14275 .port = std.mem.nativeToBig(u16, a.port),14032 .port = std.mem.nativeToBig(u16, a.port),
...@@ -14291,20 +14048,30 @@ pub fn errnoBug(err: posix.E) Io.UnexpectedError {...@@ -14291,20 +14048,30 @@ pub fn errnoBug(err: posix.E) Io.UnexpectedError {
14291 return error.Unexpected;14048 return error.Unexpected;
14292}14049}
1429314050
14294pub fn posixSocketMode(mode: net.Socket.Mode) u32 {14051pub fn posixSocketModeProtocol(family: posix.sa_family_t, mode: net.Socket.Mode, protocol: ?net.Protocol) !struct { u32, u32 } {
14295 return switch (mode) {14052 return .{
14296 .stream => posix.SOCK.STREAM,14053 switch (mode) {
14297 .dgram => posix.SOCK.DGRAM,14054 .stream => posix.SOCK.STREAM,
14298 .seqpacket => posix.SOCK.SEQPACKET,14055 .dgram => posix.SOCK.DGRAM,
14299 .raw => posix.SOCK.RAW,14056 .seqpacket => posix.SOCK.SEQPACKET,
14300 .rdm => posix.SOCK.RDM,14057 .raw => posix.SOCK.RAW,
14058 .rdm => posix.SOCK.RDM,
14059 },
14060 if (protocol) |p| @intFromEnum(p) else if (is_windows) switch (family) {
14061 posix.AF.UNIX => switch (mode) {
14062 .stream => 0,
14063 else => return error.ProtocolUnsupportedByAddressFamily,
14064 },
14065 posix.AF.INET, posix.AF.INET6 => @intFromEnum(@as(net.Protocol, switch (mode) {
14066 .stream => .tcp,
14067 .dgram => .udp,
14068 else => return error.ProtocolUnsupportedByAddressFamily,
14069 })),
14070 else => return error.ProtocolUnsupportedByAddressFamily,
14071 } else 0,
14301 };14072 };
14302}14073}
1430314074
14304pub fn posixProtocol(protocol: ?net.Protocol) u32 {
14305 return @intFromEnum(protocol orelse return 0);
14306}
14307
14308pub fn recoverableOsBugDetected() void {14075pub fn recoverableOsBugDetected() void {
14309 if (is_debug) unreachable;14076 if (is_debug) unreachable;
14310}14077}
...@@ -14528,7 +14295,7 @@ fn lookupDnsSearch(...@@ -14528,7 +14295,7 @@ fn lookupDnsSearch(
14528 while (it.next()) |token| {14295 while (it.next()) |token| {
14529 @memcpy(options.canonical_name_buffer[canon_name.len + 1 ..][0..token.len], token);14296 @memcpy(options.canonical_name_buffer[canon_name.len + 1 ..][0..token.len], token);
14530 const lookup_canon_name = options.canonical_name_buffer[0 .. canon_name.len + 1 + token.len];14297 const lookup_canon_name = options.canonical_name_buffer[0 .. canon_name.len + 1 + token.len];
14531 if (lookupDns(t, lookup_canon_name, &rc, resolved, options)) |result| {14298 if (t.lookupDns(lookup_canon_name, &rc, resolved, options)) |result| {
14532 return result;14299 return result;
14533 } else |err| switch (err) {14300 } else |err| switch (err) {
14534 error.UnknownHostName, error.NoAddressReturned => continue,14301 error.UnknownHostName, error.NoAddressReturned => continue,
...@@ -14537,7 +14304,7 @@ fn lookupDnsSearch(...@@ -14537,7 +14304,7 @@ fn lookupDnsSearch(
14537 }14304 }
1453814305
14539 const lookup_canon_name = options.canonical_name_buffer[0..canon_name.len];14306 const lookup_canon_name = options.canonical_name_buffer[0..canon_name.len];
14540 return lookupDns(t, lookup_canon_name, &rc, resolved, options);14307 return t.lookupDns(lookup_canon_name, &rc, resolved, options);
14541}14308}
1454214309
14543fn lookupDns(14310fn lookupDns(
...@@ -14610,7 +14377,7 @@ fn lookupDns(...@@ -14610,7 +14377,7 @@ fn lookupDns(
14610 send: while (now_ts.nanoseconds < final_ts.nanoseconds) : (now_ts = clock.now(t_io)) {14377 send: while (now_ts.nanoseconds < final_ts.nanoseconds) : (now_ts = clock.now(t_io)) {
14611 const max_messages = queries_buffer.len * HostName.ResolvConf.max_nameservers;14378 const max_messages = queries_buffer.len * HostName.ResolvConf.max_nameservers;
14612 {14379 {
14613 var message_buffer: [max_messages]Io.net.OutgoingMessage = undefined;14380 var message_buffer: [max_messages]net.OutgoingMessage = undefined;
14614 var message_i: usize = 0;14381 var message_i: usize = 0;
14615 for (queries, answers) |query, *answer| {14382 for (queries, answers) |query, *answer| {
14616 if (answer.len != 0) continue;14383 if (answer.len != 0) continue;
...@@ -14632,7 +14399,7 @@ fn lookupDns(...@@ -14632,7 +14399,7 @@ fn lookupDns(
14632 } };14399 } };
1463314400
14634 while (true) {14401 while (true) {
14635 var message_buffer: [max_messages]Io.net.IncomingMessage = @splat(.init);14402 var message_buffer: [max_messages]net.IncomingMessage = @splat(.init);
14636 const buf = answer_buffer[answer_buffer_i..];14403 const buf = answer_buffer[answer_buffer_i..];
14637 const recv_err, const recv_n = socket.receiveManyTimeout(t_io, &message_buffer, buf, .{}, timeout);14404 const recv_err, const recv_n = socket.receiveManyTimeout(t_io, &message_buffer, buf, .{}, timeout);
14638 for (message_buffer[0..recv_n]) |*received_message| {14405 for (message_buffer[0..recv_n]) |*received_message| {
...@@ -14666,7 +14433,7 @@ fn lookupDns(...@@ -14666,7 +14433,7 @@ fn lookupDns(
14666 if (answers_remaining == 0) break :send;14433 if (answers_remaining == 0) break :send;
14667 },14434 },
14668 2 => {14435 2 => {
14669 var retry_message: Io.net.OutgoingMessage = .{14436 var retry_message: net.OutgoingMessage = .{
14670 .address = ns,14437 .address = ns,
14671 .data_ptr = query.ptr,14438 .data_ptr = query.ptr,
14672 .data_len = query.len,14439 .data_len = query.len,
...@@ -14753,7 +14520,7 @@ fn lookupHosts(...@@ -14753,7 +14520,7 @@ fn lookupHosts(
1475314520
14754 var line_buf: [512]u8 = undefined;14521 var line_buf: [512]u8 = undefined;
14755 var file_reader = file.reader(t_io, &line_buf);14522 var file_reader = file.reader(t_io, &line_buf);
14756 return lookupHostsReader(t, host_name, resolved, options, &file_reader.interface) catch |err| switch (err) {14523 return t.lookupHostsReader(host_name, resolved, options, &file_reader.interface) catch |err| switch (err) {
14757 error.ReadFailed => switch (file_reader.err.?) {14524 error.ReadFailed => switch (file_reader.err.?) {
14758 error.Canceled => |e| return e,14525 error.Canceled => |e| return e,
14759 else => {14526 else => {
...@@ -14863,6 +14630,58 @@ fn writeResolutionQuery(q: *[280]u8, op: u4, dname: []const u8, class: u8, ty: H...@@ -14863,6 +14630,58 @@ fn writeResolutionQuery(q: *[280]u8, op: u4, dname: []const u8, class: u8, ty: H
14863 return n;14630 return n;
14864}14631}
1486514632
14633const LookupDnsWindows = struct {
14634 threaded: *Threaded,
14635 thread: Thread.Handle,
14636 resolved: *Io.Queue(HostName.LookupResult),
14637 options: HostName.LookupOptions,
14638 results: windows.DNS.QUERY.RESULT,
14639 done: bool,
14640
14641 fn completed(
14642 pQueryContext: ?*anyopaque,
14643 pQueryResults: *windows.DNS.QUERY.RESULT,
14644 ) callconv(.winapi) void {
14645 _ = pQueryContext;
14646 const lookup_dns: *LookupDnsWindows = @fieldParentPtr("results", pQueryResults);
14647 lookup_dns.completedFallible() catch |err| switch (err) {
14648 error.Closed => unreachable, // `resolved` must not be closed until `netLookup` returns
14649 error.Canceled => unreachable, // called from an uncancelable thread
14650 };
14651 @atomicStore(bool, &lookup_dns.done, true, .release);
14652 _ = windows.ntdll.NtAlertThread(lookup_dns.thread);
14653 }
14654 fn completedFallible(lookup_dns: *LookupDnsWindows) (Io.QueueClosedError || Io.Cancelable)!void {
14655 assert(!lookup_dns.done);
14656 const t = lookup_dns.threaded;
14657 defer t.dl.DnsFree.raw.?(lookup_dns.results.pQueryRecords, .RecordList);
14658 if (lookup_dns.results.QueryStatus != .SUCCESS) return;
14659 const t_io = t.io();
14660 var record_it = lookup_dns.results.pQueryRecords;
14661 while (record_it) |record| : (record_it = record.pNext) switch (record.wType) {
14662 else => {},
14663 .A => try lookup_dns.resolved.putOne(t_io, .{
14664 .address = .{ .ip4 = .{ .bytes = record.Data.A, .port = lookup_dns.options.port } },
14665 }),
14666 .AAAA => {
14667 const ip6: net.Ip6Address = .{
14668 .bytes = record.Data.AAAA,
14669 .port = lookup_dns.options.port,
14670 };
14671 try lookup_dns.resolved.putOne(t_io, .{
14672 .address = if (lookup_dns.options.family) |_| .{ .ip6 = ip6 } else .fromIp6(ip6),
14673 });
14674 },
14675 };
14676 if (lookup_dns.results.pQueryRecords) |record| try lookup_dns.resolved.putOne(t_io, .{
14677 .canonical_name = .{ .bytes = lookup_dns.options.canonical_name_buffer[0..std.unicode.wtf16LeToWtf8(
14678 lookup_dns.options.canonical_name_buffer,
14679 std.mem.span(@as([*:0]const windows.WCHAR, @ptrCast(@alignCast(record.pName)))),
14680 )] },
14681 });
14682 }
14683};
14684
14866fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) HostName {14685fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) HostName {
14867 const dest = canonical_name_buffer[0..name.len];14686 const dest = canonical_name_buffer[0..name.len];
14868 @memcpy(dest, name);14687 @memcpy(dest, name);
...@@ -14879,64 +14698,6 @@ fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) Hos...@@ -14879,64 +14698,6 @@ fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) Hos
14879/// ulock_wait2() uses 64-bit nano-second timeouts (with the same convention)14698/// ulock_wait2() uses 64-bit nano-second timeouts (with the same convention)
14880const darwin_supports_ulock_wait2 = builtin.os.version_range.semver.min.major >= 11;14699const darwin_supports_ulock_wait2 = builtin.os.version_range.semver.min.major >= 11;
1488114700
14882fn closeSocketWindows(s: ws2_32.SOCKET) void {
14883 const rc = ws2_32.closesocket(s);
14884 if (is_debug) switch (rc) {
14885 0 => {},
14886 ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
14887 else => recoverableOsBugDetected(),
14888 },
14889 else => recoverableOsBugDetected(),
14890 };
14891}
14892
14893const Wsa = struct {
14894 status: Status = .uninitialized,
14895 mutex: Io.Mutex = .init,
14896 init_error: ?Wsa.InitError = null,
14897
14898 const Status = enum { uninitialized, initialized, failure };
14899
14900 const InitError = error{
14901 ProcessFdQuotaExceeded,
14902 NetworkDown,
14903 VersionUnsupported,
14904 BlockingOperationInProgress,
14905 } || Io.UnexpectedError;
14906};
14907
14908fn initializeWsa(t: *Threaded) error{ NetworkDown, Canceled }!void {
14909 const wsa = &t.wsa;
14910 mutexLock(&wsa.mutex);
14911 defer mutexUnlock(&wsa.mutex);
14912 switch (wsa.status) {
14913 .uninitialized => {
14914 var wsa_data: ws2_32.WSADATA = undefined;
14915 const minor_version = 2;
14916 const major_version = 2;
14917 switch (ws2_32.WSAStartup((@as(windows.WORD, minor_version) << 8) | major_version, &wsa_data)) {
14918 0 => {
14919 wsa.status = .initialized;
14920 return;
14921 },
14922 else => |err_int| {
14923 wsa.status = .failure;
14924 wsa.init_error = switch (@as(ws2_32.WinsockError, @enumFromInt(@as(u16, @intCast(err_int))))) {
14925 .SYSNOTREADY => error.NetworkDown,
14926 .VERNOTSUPPORTED => error.VersionUnsupported,
14927 .EINPROGRESS => error.BlockingOperationInProgress,
14928 .EPROCLIM => error.ProcessFdQuotaExceeded,
14929 else => |err| windows.unexpectedWsaError(err),
14930 };
14931 },
14932 }
14933 },
14934 .initialized => return,
14935 .failure => {},
14936 }
14937 return error.NetworkDown;
14938}
14939
14940fn doNothingSignalHandler(_: posix.SIG) callconv(.c) void {}14701fn doNothingSignalHandler(_: posix.SIG) callconv(.c) void {}
1494114702
14942const WindowsEnvironStrings = struct {14703const WindowsEnvironStrings = struct {
...@@ -16196,7 +15957,7 @@ fn windowsCreateProcessPathExt(...@@ -16196,7 +15957,7 @@ fn windowsCreateProcessPathExt(
16196 try dir_buf.append(arena, 0);15957 try dir_buf.append(arena, 0);
16197 defer dir_buf.shrinkRetainingCapacity(dir_path_len);15958 defer dir_buf.shrinkRetainingCapacity(dir_path_len);
16198 const dir_path_z = dir_buf.items[0 .. dir_buf.items.len - 1 :0];15959 const dir_path_z = dir_buf.items[0 .. dir_buf.items.len - 1 :0];
16199 const prefixed_path = try wToPrefixedFileW(null, dir_path_z);15960 const prefixed_path = try wToPrefixedFileW(null, dir_path_z, .{});
16200 break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{15961 break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{
16201 .iterate = true,15962 .iterate = true,
16202 }) catch |err| switch (err) {15963 }) catch |err| switch (err) {
lib/std/Io/Threaded/test.zig+3-3
...@@ -282,7 +282,7 @@ test "memory mapping fallback" {...@@ -282,7 +282,7 @@ test "memory mapping fallback" {
282/// Wrapper around RtlDosPathNameToNtPathName_U for use in comparing282/// Wrapper around RtlDosPathNameToNtPathName_U for use in comparing
283/// the behavior of RtlDosPathNameToNtPathName_U with wToPrefixedFileW283/// the behavior of RtlDosPathNameToNtPathName_U with wToPrefixedFileW
284/// Note: RtlDosPathNameToNtPathName_U is not used in the Zig implementation284/// Note: RtlDosPathNameToNtPathName_U is not used in the Zig implementation
285// because it allocates.285/// because it allocates.
286fn RtlDosPathNameToNtPathName_U(path: [:0]const u16) !Io.Threaded.WindowsPathSpace {286fn RtlDosPathNameToNtPathName_U(path: [:0]const u16) !Io.Threaded.WindowsPathSpace {
287 var out: windows.UNICODE_STRING = undefined;287 var out: windows.UNICODE_STRING = undefined;
288 const rc = windows.ntdll.RtlDosPathNameToNtPathName_U(path, &out, null, null);288 const rc = windows.ntdll.RtlDosPathNameToNtPathName_U(path, &out, null, null);
...@@ -303,7 +303,7 @@ fn RtlDosPathNameToNtPathName_U(path: [:0]const u16) !Io.Threaded.WindowsPathSpa...@@ -303,7 +303,7 @@ fn RtlDosPathNameToNtPathName_U(path: [:0]const u16) !Io.Threaded.WindowsPathSpa
303fn testToPrefixedFileNoOracle(comptime path: []const u8, comptime expected_path: []const u8) !void {303fn testToPrefixedFileNoOracle(comptime path: []const u8, comptime expected_path: []const u8) !void {
304 const path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(path);304 const path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(path);
305 const expected_path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(expected_path);305 const expected_path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(expected_path);
306 const actual_path = try Io.Threaded.wToPrefixedFileW(null, path_utf16);306 const actual_path = try Io.Threaded.wToPrefixedFileW(null, path_utf16, .{});
307 std.testing.expectEqualSlices(u16, expected_path_utf16, actual_path.span()) catch |e| {307 std.testing.expectEqualSlices(u16, expected_path_utf16, actual_path.span()) catch |e| {
308 std.debug.print("got '{f}', expected '{f}'\n", .{ std.unicode.fmtUtf16Le(actual_path.span()), std.unicode.fmtUtf16Le(expected_path_utf16) });308 std.debug.print("got '{f}', expected '{f}'\n", .{ std.unicode.fmtUtf16Le(actual_path.span()), std.unicode.fmtUtf16Le(expected_path_utf16) });
309 return e;309 return e;
...@@ -320,7 +320,7 @@ fn testToPrefixedFileWithOracle(comptime path: []const u8, comptime expected_pat...@@ -320,7 +320,7 @@ fn testToPrefixedFileWithOracle(comptime path: []const u8, comptime expected_pat
320/// Test that the Zig conversion matches the conversion that RtlDosPathNameToNtPathName_U does.320/// Test that the Zig conversion matches the conversion that RtlDosPathNameToNtPathName_U does.
321fn testToPrefixedFileOnlyOracle(comptime path: []const u8) !void {321fn testToPrefixedFileOnlyOracle(comptime path: []const u8) !void {
322 const path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(path);322 const path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(path);
323 const zig_result = try Io.Threaded.wToPrefixedFileW(null, path_utf16);323 const zig_result = try Io.Threaded.wToPrefixedFileW(null, path_utf16, .{});
324 const win32_api_result = try RtlDosPathNameToNtPathName_U(path_utf16);324 const win32_api_result = try RtlDosPathNameToNtPathName_U(path_utf16);
325 std.testing.expectEqualSlices(u16, win32_api_result.span(), zig_result.span()) catch |e| {325 std.testing.expectEqualSlices(u16, win32_api_result.span(), zig_result.span()) catch |e| {
326 std.debug.print("got '{f}', expected '{f}'\n", .{ std.unicode.fmtUtf16Le(zig_result.span()), std.unicode.fmtUtf16Le(win32_api_result.span()) });326 std.debug.print("got '{f}', expected '{f}'\n", .{ std.unicode.fmtUtf16Le(zig_result.span()), std.unicode.fmtUtf16Le(win32_api_result.span()) });
lib/std/Io/Uring.zig+9-12
...@@ -32,8 +32,7 @@ const pathToPosix = Io.Threaded.pathToPosix;...@@ -32,8 +32,7 @@ const pathToPosix = Io.Threaded.pathToPosix;
32const pid_t = linux.pid_t;32const pid_t = linux.pid_t;
33const PosixAddress = Io.Threaded.PosixAddress;33const PosixAddress = Io.Threaded.PosixAddress;
34const posixAddressFamily = Io.Threaded.posixAddressFamily;34const posixAddressFamily = Io.Threaded.posixAddressFamily;
35const posixProtocol = Io.Threaded.posixProtocol;35const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;
36const posixSocketMode = Io.Threaded.posixSocketMode;
37const process = std.process;36const process = std.process;
38const recoverableOsBugDetected = Io.Threaded.recoverableOsBugDetected;37const recoverableOsBugDetected = Io.Threaded.recoverableOsBugDetected;
39const setTimestampToPosix = Io.Threaded.setTimestampToPosix;38const setTimestampToPosix = Io.Threaded.setTimestampToPosix;
...@@ -4952,9 +4951,9 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {...@@ -4952,9 +4951,9 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
49524951
4953fn netListenIpUnavailable(4952fn netListenIpUnavailable(
4954 userdata: ?*anyopaque,4953 userdata: ?*anyopaque,
4955 address: net.IpAddress,4954 address: *const net.IpAddress,
4956 options: net.IpAddress.ListenOptions,4955 options: net.IpAddress.ListenOptions,
4957) net.IpAddress.ListenError!net.Server {4956) net.IpAddress.ListenError!net.Socket {
4958 const ev: *Evented = @ptrCast(@alignCast(userdata));4957 const ev: *Evented = @ptrCast(@alignCast(userdata));
4959 _ = ev;4958 _ = ev;
4960 _ = address;4959 _ = address;
...@@ -4965,10 +4964,12 @@ fn netListenIpUnavailable(...@@ -4965,10 +4964,12 @@ fn netListenIpUnavailable(
4965fn netAcceptUnavailable(4964fn netAcceptUnavailable(
4966 userdata: ?*anyopaque,4965 userdata: ?*anyopaque,
4967 listen_handle: net.Socket.Handle,4966 listen_handle: net.Socket.Handle,
4968) net.Server.AcceptError!net.Stream {4967 options: net.Server.AcceptOptions,
4968) net.Server.AcceptError!net.Socket {
4969 const ev: *Evented = @ptrCast(@alignCast(userdata));4969 const ev: *Evented = @ptrCast(@alignCast(userdata));
4970 _ = ev;4970 _ = ev;
4971 _ = listen_handle;4971 _ = listen_handle;
4972 _ = options;
4972 return error.NetworkDown;4973 return error.NetworkDown;
4973}4974}
49744975
...@@ -4987,17 +4988,14 @@ fn netBindIp(...@@ -4987,17 +4988,14 @@ fn netBindIp(
4987 var addr_len = addressToPosix(address, &storage);4988 var addr_len = addressToPosix(address, &storage);
4988 try ev.bind(&maybe_sync.cancel_region, socket_fd, &storage.any, addr_len);4989 try ev.bind(&maybe_sync.cancel_region, socket_fd, &storage.any, addr_len);
4989 try ev.getsockname(try maybe_sync.enterSync(ev), socket_fd, &storage.any, &addr_len);4990 try ev.getsockname(try maybe_sync.enterSync(ev), socket_fd, &storage.any, &addr_len);
4990 return .{4991 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
4991 .handle = socket_fd,
4992 .address = addressFromPosix(&storage),
4993 };
4994}4992}
49954993
4996fn netConnectIpUnavailable(4994fn netConnectIpUnavailable(
4997 userdata: ?*anyopaque,4995 userdata: ?*anyopaque,
4998 address: *const net.IpAddress,4996 address: *const net.IpAddress,
4999 options: net.IpAddress.ConnectOptions,4997 options: net.IpAddress.ConnectOptions,
5000) net.IpAddress.ConnectError!net.Stream {4998) net.IpAddress.ConnectError!net.Socket {
5001 const ev: *Evented = @ptrCast(@alignCast(userdata));4999 const ev: *Evented = @ptrCast(@alignCast(userdata));
5002 _ = ev;5000 _ = ev;
5003 _ = address;5001 _ = address;
...@@ -5941,8 +5939,7 @@ fn socket(...@@ -5941,8 +5939,7 @@ fn socket(
5941 Unexpected,5939 Unexpected,
5942 Canceled,5940 Canceled,
5943}!fd_t {5941}!fd_t {
5944 const mode = posixSocketMode(options.mode);5942 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
5945 const protocol = posixProtocol(options.protocol);
5946 const socket_fd = while (true) {5943 const socket_fd = while (true) {
5947 const thread = try cancel_region.awaitIoUring();5944 const thread = try cancel_region.awaitIoUring();
5948 thread.enqueue().* = .{5945 thread.enqueue().* = .{
lib/std/Io/net.zig+74-48
...@@ -41,6 +41,7 @@ pub const Protocol = enum(u32) {...@@ -41,6 +41,7 @@ pub const Protocol = enum(u32) {
41 ethernet = 143,41 ethernet = 143,
42 raw = 255,42 raw = 255,
43 mptcp = 262,43 mptcp = 262,
44 _,
44};45};
4546
46/// Windows 10 added support for unix sockets in build 17063, redstone 4 is the47/// Windows 10 added support for unix sockets in build 17063, redstone 4 is the
...@@ -159,6 +160,11 @@ pub const IpAddress = union(enum) {...@@ -159,6 +160,11 @@ pub const IpAddress = union(enum) {
159 }160 }
160 }161 }
161162
163 /// Converts from an IPv4-mapped IPv6 address, or returns the IPv6 address directly.
164 pub fn fromIp6(ip6: Ip6Address) IpAddress {
165 return if (Ip4Address.fromIp6(ip6)) |ip4| .{ .ip4 = ip4 } else .{ .ip6 = ip6 };
166 }
167
162 /// Includes the optional scope ("%foo" at the end) in IPv6 addresses.168 /// Includes the optional scope ("%foo" at the end) in IPv6 addresses.
163 ///169 ///
164 /// See `format` for an alternative that omits scopes and does170 /// See `format` for an alternative that omits scopes and does
...@@ -237,8 +243,14 @@ pub const IpAddress = union(enum) {...@@ -237,8 +243,14 @@ pub const IpAddress = union(enum) {
237243
238 /// Waits for a TCP connection. When using this API, `bind` does not need244 /// Waits for a TCP connection. When using this API, `bind` does not need
239 /// to be called. The returned `Server` has an open `stream`.245 /// to be called. The returned `Server` has an open `stream`.
240 pub fn listen(address: IpAddress, io: Io, options: ListenOptions) ListenError!Server {246 pub fn listen(address: *const IpAddress, io: Io, options: ListenOptions) ListenError!Server {
241 return io.vtable.netListenIp(io.userdata, address, options);247 return .{
248 .socket = try io.vtable.netListenIp(io.userdata, address, options),
249 .options = if (Server.AcceptOptions != void) .{
250 .mode = options.mode,
251 .protocol = options.protocol,
252 },
253 };
242 }254 }
243255
244 pub const BindError = error{256 pub const BindError = error{
...@@ -320,8 +332,8 @@ pub const IpAddress = union(enum) {...@@ -320,8 +332,8 @@ pub const IpAddress = union(enum) {
320 };332 };
321333
322 /// Initiates a connection-oriented network stream.334 /// Initiates a connection-oriented network stream.
323 pub fn connect(address: IpAddress, io: Io, options: ConnectOptions) ConnectError!Stream {335 pub fn connect(address: *const IpAddress, io: Io, options: ConnectOptions) ConnectError!Stream {
324 return io.vtable.netConnectIp(io.userdata, &address, options);336 return .{ .socket = try io.vtable.netConnectIp(io.userdata, address, options) };
325 }337 }
326};338};
327339
...@@ -344,6 +356,23 @@ pub const Ip4Address = struct {...@@ -344,6 +356,23 @@ pub const Ip4Address = struct {
344 };356 };
345 }357 }
346358
359 /// Converts from an IPv4-mapped IPv6 address, or returns `null`.
360 pub fn fromIp6(ip6: Ip6Address) ?Ip4Address {
361 return if (std.mem.eql(u8, ip6.bytes[0..12], &.{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) .{
362 .bytes = ip6.bytes[12..].*,
363 .port = ip6.port,
364 } else null;
365 }
366
367 /// Given an `IpAddress`, converts it to an `Ip4Address` directly, or from
368 /// an IPv4-mapped IPv6 address, or returns `null`.
369 pub fn fromAny(addr: IpAddress) ?Ip6Address {
370 return switch (addr) {
371 .ip4 => |ip4| ip4,
372 .ip6 => |ip6| fromIp6(ip6),
373 };
374 }
375
347 pub const ParseError = error{376 pub const ParseError = error{
348 Overflow,377 Overflow,
349 InvalidEnd,378 InvalidEnd,
...@@ -429,9 +458,8 @@ pub const Ip6Address = struct {...@@ -429,9 +458,8 @@ pub const Ip6Address = struct {
429458
430 /// Constructs an IPv4-mapped IPv6 address.459 /// Constructs an IPv4-mapped IPv6 address.
431 pub fn fromIp4(ip4: Ip4Address) Ip6Address {460 pub fn fromIp4(ip4: Ip4Address) Ip6Address {
432 const b = &ip4.bytes;
433 return .{461 return .{
434 .bytes = .{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, b[0], b[1], b[2], b[3] },462 .bytes = .{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff } ++ ip4.bytes,
435 .port = ip4.port,463 .port = ip4.port,
436 };464 };
437 }465 }
...@@ -572,19 +600,6 @@ pub const Ip6Address = struct {...@@ -572,19 +600,6 @@ pub const Ip6Address = struct {
572 }600 }
573 }601 }
574602
575 pub const FromAddressError = Interface.NameError;
576
577 pub fn fromAddress(a: *const Ip6Address, io: Io) FromAddressError!Unresolved {
578 if (a.interface.isNone()) return .{
579 .bytes = a.bytes,
580 .interface_name = null,
581 };
582 return .{
583 .bytes = a.bytes,
584 .interface_name = try a.interface.name(io),
585 };
586 }
587
588 pub fn format(u: *const Unresolved, w: *Io.Writer) Io.Writer.Error!void {603 pub fn format(u: *const Unresolved, w: *Io.Writer) Io.Writer.Error!void {
589 const bytes = &u.bytes;604 const bytes = &u.bytes;
590 if (std.mem.eql(u8, bytes[0..12], &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {605 if (std.mem.eql(u8, bytes[0..12], &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {
...@@ -629,20 +644,13 @@ pub const Ip6Address = struct {...@@ -629,20 +644,13 @@ pub const Ip6Address = struct {
629 }644 }
630645
631 var i: usize = 0;646 var i: usize = 0;
632 var abbrv = false;647 while (parts.len - i != 0) : (i += 1) {
633 while (i < parts.len) : (i += 1) {
634 if (i == longest_start) {648 if (i == longest_start) {
635 // Emit "::" for the longest zero run649 // Emit "::" for the longest zero run
636 if (!abbrv) {650 try w.writeAll(if (i == 0) "::" else ":");
637 try w.writeAll(if (i == 0) "::" else ":");
638 abbrv = true;
639 }
640 i += longest_len - 1; // Skip the compressed range651 i += longest_len - 1; // Skip the compressed range
641 continue;652 continue;
642 }653 }
643 if (abbrv) {
644 abbrv = false;
645 }
646 try w.print("{x}", .{parts[i]});654 try w.print("{x}", .{parts[i]});
647 if (i != parts.len - 1) {655 if (i != parts.len - 1) {
648 try w.writeAll(":");656 try w.writeAll(":");
...@@ -704,24 +712,25 @@ pub const Ip6Address = struct {...@@ -704,24 +712,25 @@ pub const Ip6Address = struct {
704 };712 };
705 }713 }
706714
707 pub const FormatError = Io.Writer.Error || Unresolved.FromAddressError;715 pub const FormatError = Io.Writer.Error || Interface.NameError;
708716
709 /// Includes the optional scope ("%foo" at the end).717 /// Includes the optional scope ("%foo" at the end).
710 ///718 ///
711 /// See `format` for an alternative that omits scopes and does719 /// See `format` for an alternative that omits scopes and does
712 /// not require an `Io` parameter.720 /// not require an `Io` parameter.
713 pub fn formatResolved(a: Ip6Address, io: Io, w: *Io.Writer) FormatError!void {721 pub fn formatResolved(a: *const Ip6Address, io: Io, w: *Io.Writer) FormatError!void {
714 const u: Unresolved = try .fromAddress(io);722 const interface_name = if (a.interface.isNone()) null else try a.interface.name(io);
723 const u: Unresolved = .{
724 .bytes = a.bytes,
725 .interface_name = if (interface_name) |name| name.toSlice() else null,
726 };
715 try w.print("[{f}]:{d}", .{ u, a.port });727 try w.print("[{f}]:{d}", .{ u, a.port });
716 }728 }
717729
718 /// See `formatResolved` for an alternative that additionally prints the optional730 /// See `formatResolved` for an alternative that additionally prints the optional
719 /// scope at the end of addresses and requires an `Io` parameter.731 /// scope at the end of addresses and requires an `Io` parameter.
720 pub fn format(a: Ip6Address, w: *Io.Writer) Io.Writer.Error!void {732 pub fn format(a: *const Ip6Address, w: *Io.Writer) Io.Writer.Error!void {
721 const u: Unresolved = .{733 const u: Unresolved = .{ .bytes = a.bytes, .interface_name = null };
722 .bytes = a.bytes,
723 .interface_name = null,
724 };
725 try w.print("[{f}]:{d}", .{ u, a.port });734 try w.print("[{f}]:{d}", .{ u, a.port });
726 }735 }
727736
...@@ -825,7 +834,10 @@ pub const Ip6Address = struct {...@@ -825,7 +834,10 @@ pub const Ip6Address = struct {
825pub const UnixAddress = struct {834pub const UnixAddress = struct {
826 path: []const u8,835 path: []const u8,
827836
828 pub const max_len = 108;837 pub const max_len = switch (native_os) {
838 .windows => std.os.windows.PATH_MAX_WIDE,
839 else => 108,
840 };
829841
830 pub const InitError = error{NameTooLong};842 pub const InitError = error{NameTooLong};
831843
...@@ -834,6 +846,10 @@ pub const UnixAddress = struct {...@@ -834,6 +846,10 @@ pub const UnixAddress = struct {
834 return .{ .path = p };846 return .{ .path = p };
835 }847 }
836848
849 pub fn isAbstract(ua: *const UnixAddress) bool {
850 return ua.path.len == 0 or ua.path[0] == 0;
851 }
852
837 pub const ListenError = error{853 pub const ListenError = error{
838 AddressFamilyUnsupported,854 AddressFamilyUnsupported,
839 AddressInUse,855 AddressInUse,
...@@ -859,10 +875,13 @@ pub const UnixAddress = struct {...@@ -859,10 +875,13 @@ pub const UnixAddress = struct {
859875
860 pub fn listen(ua: *const UnixAddress, io: Io, options: ListenOptions) ListenError!Server {876 pub fn listen(ua: *const UnixAddress, io: Io, options: ListenOptions) ListenError!Server {
861 assert(ua.path.len <= max_len);877 assert(ua.path.len <= max_len);
862 return .{ .socket = .{878 return .{
863 .handle = try io.vtable.netListenUnix(io.userdata, ua, options),879 .socket = .{
864 .address = .{ .ip4 = .loopback(0) },880 .handle = try io.vtable.netListenUnix(io.userdata, ua, options),
865 } };881 .address = .{ .ip4 = .loopback(0) },
882 },
883 .options = if (Server.AcceptOptions != void) .{ .mode = .stream, .protocol = null },
884 };
866 }885 }
867886
868 pub const ConnectError = error{887 pub const ConnectError = error{
...@@ -871,7 +890,6 @@ pub const UnixAddress = struct {...@@ -871,7 +890,6 @@ pub const UnixAddress = struct {
871 SystemFdQuotaExceeded,890 SystemFdQuotaExceeded,
872 AddressFamilyUnsupported,891 AddressFamilyUnsupported,
873 ProtocolUnsupportedBySystem,892 ProtocolUnsupportedBySystem,
874 ProtocolUnsupportedByAddressFamily,
875 SocketModeUnsupported,893 SocketModeUnsupported,
876 AccessDenied,894 AccessDenied,
877 PermissionDenied,895 PermissionDenied,
...@@ -1006,7 +1024,12 @@ pub const Interface = struct {...@@ -1006,7 +1024,12 @@ pub const Interface = struct {
1006 }1024 }
1007 };1025 };
10081026
1009 pub const NameError = Io.UnexpectedError || Io.Cancelable;1027 pub const NameError = error{
1028 /// Out of range `index`.
1029 InterfaceNotFound,
1030 /// Interface name longer than `Name.max_len`.
1031 NameTooLong,
1032 } || Io.UnexpectedError || Io.Cancelable;
10101033
1011 /// Asserts not `none`.1034 /// Asserts not `none`.
1012 ///1035 ///
...@@ -1047,10 +1070,7 @@ pub const Socket = struct {...@@ -1047,10 +1070,7 @@ pub const Socket = struct {
10471070
1048 /// Underlying platform-defined type which may or may not be1071 /// Underlying platform-defined type which may or may not be
1049 /// interchangeable with a file system file descriptor.1072 /// interchangeable with a file system file descriptor.
1050 pub const Handle = switch (native_os) {1073 pub const Handle = std.posix.fd_t;
1051 .windows => std.os.windows.ws2_32.SOCKET,
1052 else => std.posix.fd_t,
1053 };
10541074
1055 /// Leaves `address` in a valid state.1075 /// Leaves `address` in a valid state.
1056 pub fn close(s: *const Socket, io: Io) void {1076 pub fn close(s: *const Socket, io: Io) void {
...@@ -1377,6 +1397,7 @@ pub const Stream = struct {...@@ -1377,6 +1397,7 @@ pub const Stream = struct {
13771397
1378pub const Server = struct {1398pub const Server = struct {
1379 socket: Socket,1399 socket: Socket,
1400 options: AcceptOptions,
13801401
1381 pub fn deinit(s: *Server, io: Io) void {1402 pub fn deinit(s: *Server, io: Io) void {
1382 s.socket.close(io);1403 s.socket.close(io);
...@@ -1408,9 +1429,14 @@ pub const Server = struct {...@@ -1408,9 +1429,14 @@ pub const Server = struct {
1408 ProtocolFailure,1429 ProtocolFailure,
1409 } || Io.UnexpectedError || Io.Cancelable;1430 } || Io.UnexpectedError || Io.Cancelable;
14101431
1432 pub const AcceptOptions = switch (native_os) {
1433 .windows => struct { mode: Socket.Mode, protocol: ?Protocol },
1434 else => void,
1435 };
1436
1411 /// Blocks until a client connects to the server.1437 /// Blocks until a client connects to the server.
1412 pub fn accept(s: *Server, io: Io) AcceptError!Stream {1438 pub fn accept(s: *Server, io: Io) AcceptError!Stream {
1413 return io.vtable.netAccept(io.userdata, s.socket.handle);1439 return .{ .socket = try io.vtable.netAccept(io.userdata, s.socket.handle, s.options) };
1414 }1440 }
1415};1441};
14161442
lib/std/Io/net/HostName.zig+1
...@@ -125,6 +125,7 @@ pub fn eql(a: HostName, b: HostName) bool {...@@ -125,6 +125,7 @@ pub fn eql(a: HostName, b: HostName) bool {
125125
126pub const LookupOptions = struct {126pub const LookupOptions = struct {
127 port: u16,127 port: u16,
128 request_canonical_name: bool = false,
128 canonical_name_buffer: *[max_len]u8,129 canonical_name_buffer: *[max_len]u8,
129 /// `null` means either.130 /// `null` means either.
130 family: ?IpAddress.Family = null,131 family: ?IpAddress.Family = null,
lib/std/Io/net/test.zig+4-12
...@@ -85,7 +85,7 @@ test "IPv6 address parse failures" {...@@ -85,7 +85,7 @@ test "IPv6 address parse failures" {
85}85}
8686
87test "invalid but parseable IPv6 scope ids" {87test "invalid but parseable IPv6 scope ids" {
88 if (builtin.os.tag != .linux and comptime !builtin.os.tag.isDarwin()) return error.SkipZigTest;88 if (builtin.os.tag != .linux and builtin.os.tag != .windows and comptime !builtin.os.tag.isDarwin()) return error.SkipZigTest;
8989
90 const io = testing.io;90 const io = testing.io;
9191
...@@ -129,6 +129,7 @@ test "resolve DNS" {...@@ -129,6 +129,7 @@ test "resolve DNS" {
129129
130 net.HostName.lookup(try .init("localhost"), io, &results, .{130 net.HostName.lookup(try .init("localhost"), io, &results, .{
131 .port = 80,131 .port = 80,
132 .request_canonical_name = true,
132 .canonical_name_buffer = &canonical_name_buffer,133 .canonical_name_buffer = &canonical_name_buffer,
133 }) catch |err| switch (err) {134 }) catch |err| switch (err) {
134 error.NetworkDown => return error.SkipZigTest,135 error.NetworkDown => return error.SkipZigTest,
...@@ -142,7 +143,8 @@ test "resolve DNS" {...@@ -142,7 +143,8 @@ test "resolve DNS" {
142 if (address.eql(&localhost_v4) or address.eql(&localhost_v6))143 if (address.eql(&localhost_v4) or address.eql(&localhost_v6))
143 addresses_found += 1;144 addresses_found += 1;
144 },145 },
145 .canonical_name => |canonical_name| try testing.expectEqualStrings("localhost", canonical_name.bytes),146 .canonical_name => |canonical_name| if (builtin.os.tag == .linux)
147 try testing.expectEqualStrings("localhost", canonical_name.bytes),
146 } else |err| switch (err) {148 } else |err| switch (err) {
147 error.Closed => {},149 error.Closed => {},
148 error.Canceled => |e| return e,150 error.Canceled => |e| return e,
...@@ -234,11 +236,6 @@ test "listen on an in use port" {...@@ -234,11 +236,6 @@ test "listen on an in use port" {
234}236}
235237
236test "listen on a unix socket, send bytes, receive bytes" {238test "listen on a unix socket, send bytes, receive bytes" {
237 if (builtin.os.tag == .windows) {
238 // https://codeberg.org/ziglang/zig/issues/31499
239 return error.SkipZigTest;
240 }
241
242 const io = testing.io;239 const io = testing.io;
243 const gpa = testing.allocator;240 const gpa = testing.allocator;
244241
...@@ -345,11 +342,6 @@ test "decompress compressed DNS name" {...@@ -345,11 +342,6 @@ test "decompress compressed DNS name" {
345}342}
346343
347test "cancel accept" {344test "cancel accept" {
348 if (builtin.os.tag == .windows) {
349 // https://codeberg.org/ziglang/zig/issues/30865
350 return error.SkipZigTest;
351 }
352
353 const io = testing.io;345 const io = testing.io;
354 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };346 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };
355347
lib/std/Progress.zig+2
...@@ -743,6 +743,7 @@ fn windowsApiWriteMarker(io: Io) WindowsApiError!void {...@@ -743,6 +743,7 @@ fn windowsApiWriteMarker(io: Io) WindowsApiError!void {
743 }, 0, .{})),743 }, 0, .{})),
744 } })).device_io_control.u.Status) {744 } })).device_io_control.u.Status) {
745 .SUCCESS => {},745 .SUCCESS => {},
746 .CANCELLED => unreachable,
746 else => |status| return windows.unexpectedStatus(status),747 else => |status| return windows.unexpectedStatus(status),
747 }748 }
748}749}
...@@ -970,6 +971,7 @@ fn windowsApiMoveToMarker(io: Io, nl_n: usize) WindowsApiError!void {...@@ -970,6 +971,7 @@ fn windowsApiMoveToMarker(io: Io, nl_n: usize) WindowsApiError!void {
970 })),971 })),
971 } })).device_io_control.u.Status) {972 } })).device_io_control.u.Status) {
972 .SUCCESS => {},973 .SUCCESS => {},
974 .CANCELLED => unreachable,
973 else => |status| return windows.unexpectedStatus(status),975 else => |status| return windows.unexpectedStatus(status),
974 }976 }
975 if (read_output_char.Data.nLength >= 1 and buffer[0] == windows_api_start_marker) break;977 if (read_output_char.Data.nLength >= 1 and buffer[0] == windows_api_start_marker) break;
lib/std/Thread.zig+4-4
...@@ -560,9 +560,9 @@ const WindowsThreadImpl = struct {...@@ -560,9 +560,9 @@ const WindowsThreadImpl = struct {
560 },560 },
561 };561 };
562562
563 // Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.563 // Windows appears to only support SYSTEM.BASIC_INFORMATION.AllocationGranularity
564 // Going lower makes it default to that specified in the executable (~1mb).564 // minimum stack size. Going lower makes it default to that specified in the executable
565 // Its also fine if the limit here is incorrect as stack size is only a hint.565 // (~1mb). Its also fine if the limit here is incorrect as stack size is only a hint.
566 const stack_size = @max(64 * 1024, std.math.lossyCast(u32, config.stack_size));566 const stack_size = @max(64 * 1024, std.math.lossyCast(u32, config.stack_size));
567567
568 // Intended to be equivalent to a kernel32.CreateThread call with no flags set.568 // Intended to be equivalent to a kernel32.CreateThread call with no flags set.
...@@ -1741,6 +1741,6 @@ pub fn maybeAttachSignalStack() void {...@@ -1741,6 +1741,6 @@ pub fn maybeAttachSignalStack() void {
1741 }, null) catch |err| switch (err) {1741 }, null) catch |err| switch (err) {
1742 error.SizeTooSmall => unreachable, // `std.options.signal_stack_size` must be sufficient for the target1742 error.SizeTooSmall => unreachable, // `std.options.signal_stack_size` must be sufficient for the target
1743 error.PermissionDenied => unreachable, // called `maybeAttachSignalStack` from a signal handler1743 error.PermissionDenied => unreachable, // called `maybeAttachSignalStack` from a signal handler
1744 error.Unexpected => @panic("unexpected error attaching signal stack"),1744 error.Unexpected => unreachable,
1745 };1745 };
1746}1746}
lib/std/c.zig-3
...@@ -10807,9 +10807,6 @@ pub extern "c" fn recvfrom(...@@ -10807,9 +10807,6 @@ pub extern "c" fn recvfrom(
10807) if (native_os == .windows) c_int else isize;10807) if (native_os == .windows) c_int else isize;
1080810808
10809pub const recvmsg = switch (native_os) {10809pub const recvmsg = switch (native_os) {
10810 // Technically, a form of recvmsg() exists for Windows, but the user has to
10811 // install some kind of callback for it.
10812 // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_wsarecvmsg
10813 .windows => {},10810 .windows => {},
10814 else => private.recvmsg,10811 else => private.recvmsg,
10815};10812};
lib/std/debug/SelfInfo/Windows.zig+1
...@@ -576,6 +576,7 @@ fn loadNtdllProc(si: *SelfInfo, name: []const u8) Io.UnexpectedError!*anyopaque...@@ -576,6 +576,7 @@ fn loadNtdllProc(si: *SelfInfo, name: []const u8) Io.UnexpectedError!*anyopaque
576 &.{ 'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l' },576 &.{ 'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l' },
577 ), &ntdll_handle)) {577 ), &ntdll_handle)) {
578 .SUCCESS => {},578 .SUCCESS => {},
579 .DLL_NOT_FOUND => return error.Unexpected,
579 else => |status| return windows.unexpectedStatus(status),580 else => |status| return windows.unexpectedStatus(status),
580 }581 }
581 si.ntdll_handle = ntdll_handle;582 si.ntdll_handle = ntdll_handle;
lib/std/os/windows.zig+938-53
...@@ -598,6 +598,14 @@ pub const FILE = struct {...@@ -598,6 +598,14 @@ pub const FILE = struct {
598 CurrentByteOffset: LARGE_INTEGER,598 CurrentByteOffset: LARGE_INTEGER,
599 };599 };
600600
601 pub const FULL_EA_INFORMATION = extern struct {
602 NextEntryOffset: ULONG,
603 Flags: UCHAR,
604 EaNameLength: UCHAR,
605 EaValueLength: USHORT,
606 EaName: [0]CHAR,
607 };
608
601 pub const FS_DEVICE_INFORMATION = extern struct {609 pub const FS_DEVICE_INFORMATION = extern struct {
602 DeviceType: DEVICE_TYPE,610 DeviceType: DEVICE_TYPE,
603 Characteristics: ULONG,611 Characteristics: ULONG,
...@@ -864,8 +872,6 @@ pub const FILE = struct {...@@ -864,8 +872,6 @@ pub const FILE = struct {
864 Mode: MODE,872 Mode: MODE,
865 };873 };
866 };874 };
867
868 // ref: km/
869};875};
870876
871pub const DIRECTORY = struct {877pub const DIRECTORY = struct {
...@@ -1108,6 +1114,865 @@ pub const CONSOLE = struct {...@@ -1108,6 +1114,865 @@ pub const CONSOLE = struct {
1108 };1114 };
1109};1115};
11101116
1117pub const AFD = packed struct(ULONG) {
1118 NO_FAST_IO: bool = false,
1119 OVERLAPPED: bool = false,
1120 Reserved0: u30 = 0,
1121
1122 pub const Mutability = enum { @"const", @"var" };
1123 pub fn WSABUF(comptime mutability: Mutability) type {
1124 return extern struct {
1125 len: ULONG,
1126 buf: switch (mutability) {
1127 .@"const" => [*]const u8,
1128 .@"var" => [*]u8,
1129 },
1130 };
1131 }
1132 pub const GUARANTEE = enum(c_int) {
1133 BestEffort,
1134 ControlledLoad,
1135 Predictive,
1136 GuaranteedDelay,
1137 Guaranteed,
1138 _,
1139 };
1140 pub const DEVICE_NAME: []const u16 = &.{ '\\', 'D', 'e', 'v', 'i', 'c', 'e', '\\', 'A', 'f', 'd' };
1141 pub const ENDPOINT_TYPE = packed struct(ULONG) {
1142 CONNECTIONLESS: bool = false,
1143 Reserved1: u3 = 0,
1144 MESSAGEMODE: bool = false,
1145 Reserved5: u3 = 0,
1146 RAW: bool = false,
1147 Reserved9: u22 = 0,
1148 REGISTERED_IO: bool = false,
1149 };
1150 pub const OPEN_PACKET = extern struct {
1151 EndpointType: ENDPOINT_TYPE,
1152 GroupID: LONG,
1153 AddressFamily: LONG,
1154 SocketType: LONG,
1155 Protocol: LONG,
1156 TransportDeviceNameLength: ULONG,
1157 TransportDeviceName: [1]WCHAR,
1158
1159 pub const NAME = "AfdOpenPacketXX";
1160
1161 pub const FULL_EA_INFORMATION = extern struct {
1162 Header: FILE.FULL_EA_INFORMATION = .{
1163 .NextEntryOffset = 0,
1164 .Flags = 0,
1165 .EaNameLength = NAME.len,
1166 .EaValueLength = @sizeOf(OPEN_PACKET),
1167 .EaName = .{},
1168 },
1169 Name: [NAME.len:0]u8 = NAME.*,
1170 Value: OPEN_PACKET,
1171 };
1172 };
1173 pub const BIND_INFO = extern struct {
1174 Mode: MODE,
1175
1176 pub const MODE = enum(ULONG) {
1177 Unix = 0,
1178 Passive = 1,
1179 Active = 2,
1180 _,
1181 };
1182 };
1183 pub const LISTEN_INFO = extern struct {
1184 UseSAN: BOOLEAN,
1185 MaximumConnectionQueue: ULONG,
1186 UseDelayedAcceptance: BOOLEAN,
1187 };
1188 pub const LISTEN_RESPONSE_INFO = extern struct {
1189 Sequence: ULONG,
1190 };
1191 pub const ACCEPT_INFO = extern struct {
1192 UseSAN: BOOLEAN,
1193 Sequence: ULONG,
1194 AcceptHandle: HANDLE,
1195 };
1196 pub const SUPER_ACCEPT_INFO = extern struct {
1197 UseSAN: BOOLEAN,
1198 AcceptHandle: HANDLE,
1199 AcceptEndpoint: PVOID,
1200 AcceptFileObject: PVOID,
1201 ReceiveDataLength: ULONG,
1202 LocalAddressLength: ULONG,
1203 RemoteAddressLength: ULONG,
1204 ListenResponseInfo: LISTEN_RESPONSE_INFO,
1205 };
1206 pub const DEFER_ACCEPT_INFO = extern struct {
1207 Sequence: ULONG,
1208 Reject: BOOLEAN,
1209 };
1210 pub const PARTIAL_DISCONNECT_INFO = extern struct {
1211 DisconnectMode: MODE,
1212 Timeout: LARGE_INTEGER,
1213
1214 pub const MODE = packed struct(ULONG) {
1215 SEND: bool = false,
1216 RECEIVE: bool = false,
1217 ABORTIVE: bool = false,
1218 UNCONNECT_DATAGRAM: bool = false,
1219 Reserved4: u28 = 0,
1220 };
1221 };
1222 pub const RECEIVE_INFORMATION = extern struct {
1223 BytesAvailable: ULONG,
1224 ExpeditedBytesAvailable: ULONG,
1225 };
1226 pub const HANDLE_INFO = extern struct {
1227 TdiAddressHandle: HANDLE,
1228 TdiConnectionHandle: HANDLE,
1229 };
1230 pub const INFORMATION = extern struct {
1231 InformationType: TYPE,
1232 Information: extern union {
1233 Boolean: BOOLEAN,
1234 Ulong: ULONG,
1235 LargeInteger: LARGE_INTEGER,
1236 },
1237
1238 pub const TYPE = enum(ULONG) {
1239 INLINE_MODE = 0x01,
1240 NONBLOCKING_MODE = 0x02,
1241 MAX_SEND_SIZE = 0x03,
1242 SENDS_PENDING = 0x04,
1243 MAX_PATH_SEND_SIZE = 0x05,
1244 RECEIVE_WINDOW_SIZE = 0x06,
1245 SEND_WINDOW_SIZE = 0x07,
1246 CONNECT_TIME = 0x08,
1247 CIRCULAR_QUEUEING = 0x09,
1248 GROUP_ID_AND_TYPE = 0x0A,
1249 _,
1250 };
1251 };
1252 pub const TRANSMIT_FILE_INFO = extern struct {
1253 Offset: LARGE_INTEGER,
1254 WriteLength: LARGE_INTEGER,
1255 SendPacketLength: ULONG,
1256 FileHandle: HANDLE,
1257 Head: PVOID,
1258 HeadLength: ULONG,
1259 Tail: PVOID,
1260 TailLength: ULONG,
1261 Flags: FLAGS,
1262
1263 pub const FLAGS = packed struct(ULONG) {
1264 DISCONNECT: bool = false,
1265 REUSE_SOCKET: bool = false,
1266 WRITE_BEHIND: bool = false,
1267 Reserved3: u25 = 0,
1268 };
1269 };
1270 pub const QUEUE_APC_INFO = extern struct {
1271 Thread: HANDLE,
1272 ApcRoutine: PVOID,
1273 ApcContext: PVOID,
1274 SystemArgument1: PVOID,
1275 SystemArgument2: PVOID,
1276 };
1277 pub const SEND_INFO = extern struct {
1278 BufferArray: [*]const WSABUF(.@"const"),
1279 BufferCount: ULONG,
1280 AfdFlags: AFD,
1281 TdiFlags: TDI.SEND,
1282 };
1283 pub const SEND_DATAGRAM_INFO = extern struct {
1284 BufferArray: [*]const WSABUF(.@"const"),
1285 BufferCount: ULONG,
1286 AfdFlags: AFD,
1287 TdiRequest: TDI.REQUEST.SEND_DATAGRAM,
1288 TdiConnInfo: TDI.CONNECTION.INFORMATION,
1289 };
1290 pub const RECV_INFO = extern struct {
1291 BufferArray: [*]const WSABUF(.@"var"),
1292 BufferCount: ULONG,
1293 AfdFlags: AFD,
1294 TdiFlags: TDI.RECEIVE,
1295 };
1296 pub const RECV_DATAGRAM_INFO = extern struct {
1297 BufferArray: [*]const WSABUF(.@"var"),
1298 BufferCount: ULONG,
1299 AfdFlags: AFD,
1300 TdiFlags: TDI.RECEIVE,
1301 Address: PVOID,
1302 AddressLength: *ULONG,
1303 };
1304 pub const SOCKOPT_INFO = extern struct {
1305 mode: Mode,
1306 level: i32,
1307 optname: u32,
1308 ding: u32 = 1,
1309 optval: *const anyopaque,
1310 optlen: usize,
1311
1312 pub const Mode = enum(u32) { set = 1, get = 2, special = 3, _ };
1313
1314 pub const UNIX_PATH = extern struct { Unknown0: usize = 0, Path: [PATH_MAX_WIDE:0]u16 };
1315 };
1316};
1317
1318pub const TDI = struct {
1319 pub const STATUS = NTSTATUS;
1320 pub const CONNECTION = struct {
1321 pub const CONTEXT = PVOID;
1322 pub const INFORMATION = extern struct {
1323 /// length of user data buffer
1324 UserDataLength: LONG,
1325 /// pointer to user data buffer
1326 UserData: PVOID,
1327 /// length of following buffer
1328 OptionsLength: LONG,
1329 /// pointer to buffer containing options
1330 Options: PVOID,
1331 /// length of following buffer
1332 RemoteAddressLength: LONG,
1333 /// buffer containing the remote address
1334 RemoteAddress: PVOID,
1335 };
1336 };
1337 pub const ADDRESS = struct {
1338 pub const TYPE = enum(USHORT) {
1339 /// unspecified
1340 UNSPEC = 0,
1341 /// local to host (pipes, portals,
1342 UNIX = 1,
1343 /// internetwork: UDP, TCP, etc.
1344 IP = 2,
1345 /// arpanet imp addresses
1346 IMPLINK = 3,
1347 /// pup protocols: e.g. BSP
1348 PUP = 4,
1349 /// mit CHAOS protocols
1350 CHAOS = 5,
1351 /// XEROX NS protocols
1352 NS = 6,
1353 /// Netware IPX
1354 IPX = 6,
1355 /// nbs protocols
1356 NBS = 7,
1357 /// european computer manufacturers
1358 ECMA = 8,
1359 /// datakit protocols
1360 DATAKIT = 9,
1361 /// CCITT protocols, X.25 etc
1362 CCITT = 10,
1363 /// IBM SNA
1364 SNA = 11,
1365 /// DECnet
1366 DECnet = 12,
1367 /// Direct data link interface
1368 DLI = 13,
1369 /// LAT
1370 LAT = 14,
1371 /// NSC Hyperchannel
1372 HYLINK = 15,
1373 /// AppleTalk
1374 APPLETALK = 16,
1375 /// Netbios Addresses
1376 NETBIOS = 17,
1377 @"8022" = 18,
1378 OSI_TSAP = 19,
1379 /// for WzMail
1380 NETONE = 20,
1381 /// Banyan VINES IP
1382 VNS = 21,
1383 /// NETBIOS address extensions
1384 NETBIOS_EX = 22,
1385 /// IP version 6
1386 IP6 = 23,
1387 /// WCHAR Netbios address
1388 NETBIOS_UNICODE_EX = 24,
1389 _,
1390 };
1391 pub const IP = extern struct {
1392 sin_port: USHORT,
1393 in_addr: ULONG,
1394 sin_zero: [8]UCHAR,
1395 };
1396 pub const IP6 = extern struct {
1397 sin_port: USHORT,
1398 flowinfo: ULONG,
1399 addr: [8]USHORT,
1400 scope_id: ULONG,
1401 };
1402 };
1403 pub const REQUEST = extern struct {
1404 Handle: extern union {
1405 AddressHandle: HANDLE,
1406 ConnectionContext: CONNECTION.CONTEXT,
1407 ControlChannel: HANDLE,
1408 },
1409 RequestNotifyObject: PVOID,
1410 RequestContext: PVOID,
1411 TdiStatus: TDI.STATUS,
1412
1413 pub const STATUS = extern struct {
1414 /// status of request completion
1415 Status: TDI.STATUS,
1416 /// the request context
1417 RequestContext: PVOID,
1418 /// number of bytes transferred in the request
1419 BytesTransferred: ULONG,
1420 };
1421 pub const ASSOCIATE = extern struct {
1422 Request: REQUEST,
1423 AddressHandle: HANDLE,
1424 };
1425 pub const CONNECT = extern struct {
1426 Request: REQUEST,
1427 RequestConnectionInformation: *CONNECTION.INFORMATION,
1428 ReturnConnectionInformation: *CONNECTION.INFORMATION,
1429 Timeout: LARGE_INTEGER,
1430 };
1431 pub const ACCEPT = extern struct {
1432 Request: REQUEST,
1433 RequestConnectionInformation: *CONNECTION.INFORMATION,
1434 ReturnConnectionInformation: *CONNECTION.INFORMATION,
1435 };
1436 pub const LISTEN = extern struct {
1437 Request: REQUEST,
1438 RequestConnectionInformation: *CONNECTION.INFORMATION,
1439 ReturnConnectionInformation: *CONNECTION.INFORMATION,
1440 ListenFlags: USHORT,
1441 };
1442 pub const DISCONNECT = extern struct {
1443 Request: REQUEST,
1444 Timeout: LARGE_INTEGER,
1445 };
1446 pub const SEND = extern struct {
1447 Request: REQUEST,
1448 SendFlags: USHORT,
1449 };
1450 pub const RECEIVE = extern struct {
1451 Request: REQUEST,
1452 ReceiveFlags: USHORT,
1453 };
1454 pub const SEND_DATAGRAM = extern struct {
1455 Request: REQUEST,
1456 SendDatagramInformation: *CONNECTION.INFORMATION,
1457 };
1458 };
1459 pub const RECEIVE = packed struct(ULONG) {
1460 Reserved0: u2 = 0,
1461 BROADCAST: bool = false,
1462 MULTICAST: bool = false,
1463 PARTIAL: bool = false,
1464 NORMAL: bool = false,
1465 EXPEDITED: bool = false,
1466 PEEK: bool = false,
1467 NO_RESPONSE_EXP: bool = false,
1468 COPY_LOOKAHEAD: bool = false,
1469 ENTIRE_MESSAGE: bool = false,
1470 AT_DISPATCH_LEVEL: bool = false,
1471 CONTROL_INFO: bool = false,
1472 FORCE_INDICATION: bool = false,
1473 NO_PUSH: bool = false,
1474 Reserved12: u17 = 0,
1475 };
1476 pub const SEND = packed struct(ULONG) {
1477 Reserved0: u5 = 0,
1478 EXPEDITED: bool = false,
1479 PARTIAL: bool = false,
1480 NO_RESPONSE_EXPECTED: bool = false,
1481 NON_BLOCKING: bool = false,
1482 AND_DISCONNECT: bool = false,
1483 Reserved10: u22 = 0,
1484 };
1485};
1486
1487pub const NET = struct {
1488 pub const LUID = packed struct(ULONG64) { Reserved: u24 = 0, Index: u24, IfType: u16 };
1489 pub const IFINDEX = enum(ULONG) { _ };
1490};
1491
1492pub const DNS = struct {
1493 pub const INTERFACE_SETTINGS = extern struct {
1494 Version: ULONG,
1495 Flags: ULONG64,
1496 Domain: PWSTR,
1497 NameServer: PWSTR,
1498 SearchList: PWSTR,
1499 RegistrationEnabled: ULONG,
1500 RegisterAdapterName: ULONG,
1501 EnableLLMNR: ULONG,
1502 QueryAdapterName: ULONG,
1503 ProfileNameServer: PWSTR,
1504 };
1505
1506 // ref: shared/windnsdef.h
1507
1508 pub const ADDR_MAX_SOCKADDR_LENGTH = 32;
1509
1510 pub const ADDR = extern struct {
1511 MaxSa: [ADDR_MAX_SOCKADDR_LENGTH]CHAR,
1512 DnsAddrUserDword: [8]DWORD,
1513
1514 pub const ARRAY = extern struct {
1515 MaxCount: DWORD,
1516 AddrCount: DWORD,
1517 Tag: DWORD,
1518 Family: WORD,
1519 WordReserved: WORD,
1520 Flags: DWORD,
1521 MatchFlag: DWORD,
1522 Reserved1: DWORD,
1523 Reserved2: DWORD,
1524 AddrArray: [0]ADDR,
1525 };
1526 };
1527
1528 pub const CUSTOM_SERVER = extern struct {
1529 ServerType: CUSTOM_SERVER.TYPE,
1530 Flags: FLAGS,
1531 Info: extern union {
1532 UDP: void,
1533 DOH: extern struct { Template: PWSTR },
1534 DOT: extern struct { Hostname: PWSTR },
1535 },
1536 MaxSa: [ADDR_MAX_SOCKADDR_LENGTH]CHAR,
1537
1538 pub const TYPE = enum(DWORD) { UDP = 0x1, DOH = 0x2, DOT = 0x3, _ };
1539 pub const FLAGS = packed struct(ULONG64) {
1540 UDP_FALLBACK: bool = false,
1541 UPGRADE_FROM_WELL_KNOWN_SERVERS: bool = false,
1542 Reserved2: u62 = 0,
1543 };
1544 };
1545
1546 // ref: um/WinDNS.h
1547
1548 pub const STATUS = enum(LONG) {
1549 /// The operation completed successfully.
1550 SUCCESS = 0,
1551 /// The parameter is incorrect.
1552 INVALID_PARAMETER = 87,
1553 /// The filename, directory name, or volume label syntax is incorrect.
1554 INVALID_NAME = 123,
1555 /// DNS server unable to interpret format.
1556 FORMAT_ERROR = 9001,
1557 /// DNS server failure.
1558 SERVER_FAILURE = 9002,
1559 /// DNS name does not exist.
1560 NAME_ERROR = 9003,
1561 /// DNS request not supported by name server.
1562 NOT_IMPLEMENTED = 9004,
1563 /// DNS operation refused.
1564 REFUSED = 9005,
1565 /// DNS name that ought not exist, does exist.
1566 YXDOMAIN = 9006,
1567 /// DNS RR set that ought not exist, does exist.
1568 YXRRSET = 9007,
1569 /// DNS RR set that ought to exist, does not exist.
1570 NXRRSET = 9008,
1571 /// DNS server not authoritative for zone.
1572 NOTAUTH = 9009,
1573 /// DNS name in update or prereq is not in zone.
1574 NOTZONE = 9010,
1575 /// DNS signature failed to verify.
1576 BADSIG = 9016,
1577 /// DNS bad key.
1578 BADKEY = 9017,
1579 /// DNS signature validity expired.
1580 BADTIME = 9018,
1581 /// Only the DNS server acting as the key master for the zone may perform this operation.
1582 KEYMASTER_REQUIRED = 9101,
1583 /// This operation is not allowed on a zone that is signed or has signing keys.
1584 NOT_ALLOWED_ON_SIGNED_ZONE = 9102,
1585 /// NSEC3 is not compatible with the RSA-SHA-1 algorithm. Choose a different algorithm or use NSEC.
1586 ///
1587 /// This value was also named DNS_INVALID_NSEC3_PARAMETERS
1588 NSEC3_INCOMPATIBLE_WITH_RSA_SHA1 = 9103,
1589 /// The zone does not have enough signing keys. There must be at least one key signing key (KSK) and at least one zone signing key (ZSK).
1590 NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS = 9104,
1591 /// The specified algorithm is not supported.
1592 UNSUPPORTED_ALGORITHM = 9105,
1593 /// The specified key size is not supported.
1594 INVALID_KEY_SIZE = 9106,
1595 /// One or more of the signing keys for a zone are not accessible to the DNS server. Zone signing will not be operational until this error is resolved.
1596 SIGNING_KEY_NOT_ACCESSIBLE = 9107,
1597 /// The specified key storage provider does not support DPAPI++ data protection. Zone signing will not be operational until this error is resolved.
1598 KSP_DOES_NOT_SUPPORT_PROTECTION = 9108,
1599 /// An unexpected DPAPI++ error was encountered. Zone signing will not be operational until this error is resolved.
1600 UNEXPECTED_DATA_PROTECTION_ERROR = 9109,
1601 /// An unexpected crypto error was encountered. Zone signing may not be operational until this error is resolved.
1602 UNEXPECTED_CNG_ERROR = 9110,
1603 /// The DNS server encountered a signing key with an unknown version. Zone signing will not be operational until this error is resolved.
1604 UNKNOWN_SIGNING_PARAMETER_VERSION = 9111,
1605 /// The specified key service provider cannot be opened by the DNS server.
1606 KSP_NOT_ACCESSIBLE = 9112,
1607 /// The DNS server cannot accept any more signing keys with the specified algorithm and KSK flag value for this zone.
1608 TOO_MANY_SKDS = 9113,
1609 /// The specified rollover period is invalid.
1610 INVALID_ROLLOVER_PERIOD = 9114,
1611 /// The specified initial rollover offset is invalid.
1612 INVALID_INITIAL_ROLLOVER_OFFSET = 9115,
1613 /// The specified signing key is already in process of rolling over keys.
1614 ROLLOVER_IN_PROGRESS = 9116,
1615 /// The specified signing key does not have a standby key to revoke.
1616 STANDBY_KEY_NOT_PRESENT = 9117,
1617 /// This operation is not allowed on a zone signing key (ZSK).
1618 NOT_ALLOWED_ON_ZSK = 9118,
1619 /// This operation is not allowed on an active signing key.
1620 NOT_ALLOWED_ON_ACTIVE_SKD = 9119,
1621 /// The specified signing key is already queued for rollover.
1622 ROLLOVER_ALREADY_QUEUED = 9120,
1623 /// This operation is not allowed on an unsigned zone.
1624 NOT_ALLOWED_ON_UNSIGNED_ZONE = 9121,
1625 /// This operation could not be completed because the DNS server listed as the current key master for this zone is down or misconfigured. Resolve the problem on the current key master for this zone or use another DNS server to seize the key master role.
1626 BAD_KEYMASTER = 9122,
1627 /// The specified signature validity period is invalid.
1628 INVALID_SIGNATURE_VALIDITY_PERIOD = 9123,
1629 /// The specified NSEC3 iteration count is higher than allowed by the minimum key length used in the zone.
1630 INVALID_NSEC3_ITERATION_COUNT = 9124,
1631 /// This operation could not be completed because the DNS server has been configured with DNSSEC features disabled. Enable DNSSEC on the DNS server.
1632 DNSSEC_IS_DISABLED = 9125,
1633 /// This operation could not be completed because the XML stream received is empty or syntactically invalid.
1634 INVALID_XML = 9126,
1635 /// This operation completed, but no trust anchors were added because all of the trust anchors received were either invalid, unsupported, expired, or would not become valid in less than 30 days.
1636 NO_VALID_TRUST_ANCHORS = 9127,
1637 /// The specified signing key is not waiting for parental DS update.
1638 ROLLOVER_NOT_POKEABLE = 9128,
1639 /// Hash collision detected during NSEC3 signing. Specify a different user-provided salt, or use a randomly generated salt, and attempt to sign the zone again.
1640 NSEC3_NAME_COLLISION = 9129,
1641 /// NSEC is not compatible with the NSEC3-RSA-SHA-1 algorithm. Choose a different algorithm or use NSEC3.
1642 NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1 = 9130,
1643 /// No records found for given DNS query.
1644 NO_RECORDS = 9501,
1645 /// Bad DNS packet.
1646 BAD_PACKET = 9502,
1647 /// No DNS packet.
1648 NO_PACKET = 9503,
1649 /// DNS error, check rcode.
1650 RCODE = 9504,
1651 /// Unsecured DNS packet.
1652 UNSECURE_PACKET = 9505,
1653 /// DNS query request is pending.
1654 REQUEST_PENDING = 9506,
1655 /// Invalid DNS type.
1656 INVALID_TYPE = 9551,
1657 /// Invalid IP address.
1658 INVALID_IP_ADDRESS = 9552,
1659 /// Invalid property.
1660 INVALID_PROPERTY = 9553,
1661 /// Try DNS operation again later.
1662 TRY_AGAIN_LATER = 9554,
1663 /// Record for given name and type is not unique.
1664 NOT_UNIQUE = 9555,
1665 /// DNS name does not comply with RFC specifications.
1666 NON_RFC_NAME = 9556,
1667 /// DNS name is a fully-qualified DNS name.
1668 FQDN = 9557,
1669 /// DNS name is dotted (multi-label).
1670 DOTTED_NAME = 9558,
1671 /// DNS name is a single-part name.
1672 SINGLE_PART_NAME = 9559,
1673 /// DNS name contains an invalid character.
1674 INVALID_NAME_CHAR = 9560,
1675 /// DNS name is entirely numeric.
1676 NUMERIC_NAME = 9561,
1677 /// The operation requested is not permitted on a DNS root server.
1678 NOT_ALLOWED_ON_ROOT_SERVER = 9562,
1679 /// The record could not be created because this part of the DNS namespace has been delegated to another server.
1680 NOT_ALLOWED_UNDER_DELEGATION = 9563,
1681 /// The DNS server could not find a set of root hints.
1682 CANNOT_FIND_ROOT_HINTS = 9564,
1683 /// The DNS server found root hints but they were not consistent across all adapters.
1684 INCONSISTENT_ROOT_HINTS = 9565,
1685 /// The specified value is too small for this parameter.
1686 DWORD_VALUE_TOO_SMALL = 9566,
1687 /// The specified value is too large for this parameter.
1688 DWORD_VALUE_TOO_LARGE = 9567,
1689 /// This operation is not allowed while the DNS server is loading zones in the background. Please try again later.
1690 BACKGROUND_LOADING = 9568,
1691 /// The operation requested is not permitted on against a DNS server running on a read-only DC.
1692 NOT_ALLOWED_ON_RODC = 9569,
1693 /// No data is allowed to exist underneath a DNAME record.
1694 NOT_ALLOWED_UNDER_DNAME = 9570,
1695 /// This operation requires credentials delegation.
1696 DELEGATION_REQUIRED = 9571,
1697 /// Name resolution policy table has been corrupted. DNS resolution will fail until it is fixed. Contact your network administrator.
1698 INVALID_POLICY_TABLE = 9572,
1699 /// DNS zone does not exist.
1700 ZONE_DOES_NOT_EXIST = 9601,
1701 /// DNS zone information not available.
1702 NO_ZONE_INFO = 9602,
1703 /// Invalid operation for DNS zone.
1704 INVALID_ZONE_OPERATION = 9603,
1705 /// Invalid DNS zone configuration.
1706 ZONE_CONFIGURATION_ERROR = 9604,
1707 /// DNS zone has no start of authority (SOA) record.
1708 ZONE_HAS_NO_SOA_RECORD = 9605,
1709 /// DNS zone has no Name Server (NS) record.
1710 ZONE_HAS_NO_NS_RECORDS = 9606,
1711 /// DNS zone is locked.
1712 ZONE_LOCKED = 9607,
1713 /// DNS zone creation failed.
1714 ZONE_CREATION_FAILED = 9608,
1715 /// DNS zone already exists.
1716 ZONE_ALREADY_EXISTS = 9609,
1717 /// DNS automatic zone already exists.
1718 AUTOZONE_ALREADY_EXISTS = 9610,
1719 /// Invalid DNS zone type.
1720 INVALID_ZONE_TYPE = 9611,
1721 /// Secondary DNS zone requires master IP address.
1722 SECONDARY_REQUIRES_MASTER_IP = 9612,
1723 /// DNS zone not secondary.
1724 ZONE_NOT_SECONDARY = 9613,
1725 /// Need secondary IP address.
1726 NEED_SECONDARY_ADDRESSES = 9614,
1727 /// WINS initialization failed.
1728 WINS_INIT_FAILED = 9615,
1729 /// Need WINS servers.
1730 NEED_WINS_SERVERS = 9616,
1731 /// NBTSTAT initialization call failed.
1732 NBSTAT_INIT_FAILED = 9617,
1733 /// Invalid delete of start of authority (SOA).
1734 SOA_DELETE_INVALID = 9618,
1735 /// A conditional forwarding zone already exists for that name.
1736 FORWARDER_ALREADY_EXISTS = 9619,
1737 /// This zone must be configured with one or more master DNS server IP addresses.
1738 ZONE_REQUIRES_MASTER_IP = 9620,
1739 /// The operation cannot be performed because this zone is shut down.
1740 ZONE_IS_SHUTDOWN = 9621,
1741 /// This operation cannot be performed because the zone is currently being signed. Please try again later.
1742 ZONE_LOCKED_FOR_SIGNING = 9622,
1743 /// Primary DNS zone requires datafile.
1744 PRIMARY_REQUIRES_DATAFILE = 9651,
1745 /// Invalid datafile name for DNS zone.
1746 INVALID_DATAFILE_NAME = 9652,
1747 /// Failed to open datafile for DNS zone.
1748 DATAFILE_OPEN_FAILURE = 9653,
1749 /// Failed to write datafile for DNS zone.
1750 FILE_WRITEBACK_FAILED = 9654,
1751 /// Failure while reading datafile for DNS zone.
1752 DATAFILE_PARSING = 9655,
1753 /// DNS record does not exist.
1754 RECORD_DOES_NOT_EXIST = 9701,
1755 /// DNS record format error.
1756 RECORD_FORMAT = 9702,
1757 /// Node creation failure in DNS.
1758 NODE_CREATION_FAILED = 9703,
1759 /// Unknown DNS record type.
1760 UNKNOWN_RECORD_TYPE = 9704,
1761 /// DNS record timed out.
1762 RECORD_TIMED_OUT = 9705,
1763 /// Name not in DNS zone.
1764 NAME_NOT_IN_ZONE = 9706,
1765 /// CNAME loop detected.
1766 CNAME_LOOP = 9707,
1767 /// Node is a CNAME DNS record.
1768 NODE_IS_CNAME = 9708,
1769 /// A CNAME record already exists for given name.
1770 CNAME_COLLISION = 9709,
1771 /// Record only at DNS zone root.
1772 RECORD_ONLY_AT_ZONE_ROOT = 9710,
1773 /// DNS record already exists.
1774 RECORD_ALREADY_EXISTS = 9711,
1775 /// Secondary DNS zone data error.
1776 SECONDARY_DATA = 9712,
1777 /// Could not create DNS cache data.
1778 NO_CREATE_CACHE_DATA = 9713,
1779 /// DNS name does not exist.
1780 NAME_DOES_NOT_EXIST = 9714,
1781 /// Could not create pointer (PTR) record.
1782 PTR_CREATE_FAILED = 9715,
1783 /// DNS domain was undeleted.
1784 DOMAIN_UNDELETED = 9716,
1785 /// The directory service is unavailable.
1786 DS_UNAVAILABLE = 9717,
1787 /// DNS zone already exists in the directory service.
1788 DS_ZONE_ALREADY_EXISTS = 9718,
1789 /// DNS server not creating or reading the boot file for the directory service integrated DNS zone.
1790 NO_BOOTFILE_IF_DS_ZONE = 9719,
1791 /// Node is a DNAME DNS record.
1792 NODE_IS_DNAME = 9720,
1793 /// A DNAME record already exists for given name.
1794 DNAME_COLLISION = 9721,
1795 /// An alias loop has been detected with either CNAME or DNAME records.
1796 ALIAS_LOOP = 9722,
1797 /// DNS AXFR (zone transfer) complete.
1798 AXFR_COMPLETE = 9751,
1799 /// DNS zone transfer failed.
1800 AXFR = 9752,
1801 /// Added local WINS server.
1802 ADDED_LOCAL_WINS = 9753,
1803 /// Secure update call needs to continue update request.
1804 CONTINUE_NEEDED = 9801,
1805 /// TCP/IP network protocol not installed.
1806 NO_TCPIP = 9851,
1807 /// No DNS servers configured for local system.
1808 NO_DNS_SERVERS = 9852,
1809 /// The specified directory partition does not exist.
1810 DP_DOES_NOT_EXIST = 9901,
1811 /// The specified directory partition already exists.
1812 DP_ALREADY_EXISTS = 9902,
1813 /// This DNS server is not enlisted in the specified directory partition.
1814 DP_NOT_ENLISTED = 9903,
1815 /// This DNS server is already enlisted in the specified directory partition.
1816 DP_ALREADY_ENLISTED = 9904,
1817 /// The directory partition is not available at this time. Please wait a few minutes and try again.
1818 DP_NOT_AVAILABLE = 9905,
1819 /// The operation failed because the domain naming master FSMO role could not be reached. The domain controller holding the domain naming master FSMO role is down or unable to service the request or is not running Windows Server 2003 or later.
1820 DP_FSMO_ERROR = 9906,
1821 _,
1822 };
1823
1824 pub const TYPE = enum(WORD) {
1825 A = 0x0001,
1826 NS = 0x0002,
1827 MD = 0x0003,
1828 MF = 0x0004,
1829 CNAME = 0x0005,
1830 SOA = 0x0006,
1831 MB = 0x0007,
1832 MG = 0x0008,
1833 MR = 0x0009,
1834 NULL = 0x000a,
1835 WKS = 0x000b,
1836 PTR = 0x000c,
1837 HINFO = 0x000d,
1838 MINFO = 0x000e,
1839 MX = 0x000f,
1840 TEXT = 0x0010,
1841 RP = 0x0011,
1842 AFSDB = 0x0012,
1843 X25 = 0x0013,
1844 ISDN = 0x0014,
1845 RT = 0x0015,
1846 NSAP = 0x0016,
1847 NSAPPTR = 0x0017,
1848 SIG = 0x0018,
1849 KEY = 0x0019,
1850 PX = 0x001a,
1851 GPOS = 0x001b,
1852 AAAA = 0x001c,
1853 LOC = 0x001d,
1854 NXT = 0x001e,
1855 EID = 0x001f,
1856 NIMLOC = 0x0020,
1857 SRV = 0x0021,
1858 ATMA = 0x0022,
1859 NAPTR = 0x0023,
1860 KX = 0x0024,
1861 CERT = 0x0025,
1862 A6 = 0x0026,
1863 DNAME = 0x0027,
1864 SINK = 0x0028,
1865 OPT = 0x0029,
1866 DS = 0x002B,
1867 RRSIG = 0x002E,
1868 NSEC = 0x002F,
1869 DNSKEY = 0x0030,
1870 DHCID = 0x0031,
1871 UINFO = 0x0064,
1872 UID = 0x0065,
1873 GID = 0x0066,
1874 UNSPEC = 0x0067,
1875 ADDRS = 0x00f8,
1876 TKEY = 0x00f9,
1877 TSIG = 0x00fa,
1878 IXFR = 0x00fb,
1879 AXFR = 0x00fc,
1880 MAILB = 0x00fd,
1881 MAILA = 0x00fe,
1882 ALL = 0x00ff,
1883 WINS = 0xff01,
1884 WINSR = 0xff02,
1885 TLSA = 0x0034,
1886 SVCB = 0x0040,
1887 HTTPS = 0x0041,
1888 pub const NBSTAT: TYPE = .WINSR;
1889 pub const ANY: TYPE = .ALL;
1890 };
1891
1892 pub const QUERY = packed struct(ULONG64) {
1893 pub const STANDARD: QUERY = .{};
1894 ACCEPT_TRUNCATED_RESPONSE: bool = false,
1895 USE_TCP_ONLY: bool = false,
1896 NO_RECURSION: bool = false,
1897 BYPASS_CACHE: bool = false,
1898 NO_WIRE_QUERY: bool = false,
1899 NO_LOCAL_NAME: bool = false,
1900 NO_HOSTS_FILE: bool = false,
1901 NO_NETBT: bool = false,
1902 WIRE_ONLY: bool = false,
1903 RETURN_MESSAGE: bool = false,
1904 MULTICAST_ONLY: bool = false,
1905 NO_MULTICAST: bool = false,
1906 TREAT_AS_FQDN: bool = false,
1907 ADDRCONFIG: bool = false,
1908 DUAL_ADDR: bool = false,
1909 Reserved15: u2 = 0,
1910 MULTICAST_WAIT: bool = false,
1911 MULTICAST_VERIFY: bool = false,
1912 Reserved19: u1 = 0,
1913 DONT_RESET_TTL_VALUES: bool = false,
1914 DISABLE_IDN_ENCODING: bool = false,
1915 Reserved22: u1 = 0,
1916 APPEND_MULTILABEL: bool = false,
1917 Reserved24: u34 = 0,
1918 PARSE_ALL_RECORDS: bool = false,
1919 Reserved59: u5 = 0,
1920
1921 pub const REQUEST = extern struct {
1922 Version: DWORD,
1923 QueryName: PCWSTR,
1924 QueryType: TYPE,
1925 QueryOptions: QUERY = .STANDARD,
1926 pDnsServerList: ?*ADDR.ARRAY = null,
1927 InterfaceIndex: ULONG = 0,
1928 pQueryCompletionCallback: ?*const COMPLETION_ROUTINE = null,
1929 pQueryContext: ?*anyopaque = null,
1930
1931 pub const @"3" = extern struct {
1932 Base: REQUEST,
1933 IsNetworkQueryRequired: BOOL = FALSE,
1934 RequiredNetworkIndex: DWORD = 0,
1935 cCustomServers: DWORD = 0,
1936 pCustomServers: ?*CUSTOM_SERVER = null,
1937 };
1938 };
1939 pub const RESULT = extern struct {
1940 Version: ULONG,
1941 QueryStatus: STATUS,
1942 QueryOptions: QUERY,
1943 pQueryRecords: ?*RECORD,
1944 Reserved: ?*anyopaque,
1945 };
1946 pub const CANCEL = extern struct {
1947 Reserved: [32]CHAR align(8),
1948 };
1949 pub const COMPLETION_ROUTINE = fn (
1950 pQueryContext: ?*anyopaque,
1951 pQueryResults: *RESULT,
1952 ) callconv(.winapi) void;
1953 };
1954 pub const FREE_TYPE = enum(c_int) { Flat = 0, RecordList, ParsedMessageFields };
1955 pub const RECORD = extern struct {
1956 pNext: ?*RECORD,
1957 pName: *anyopaque,
1958 wType: TYPE,
1959 wDataLength: WORD,
1960 Flags: FLAGS,
1961 dwTtl: DWORD,
1962 dwReserved: DWORD,
1963 Data: extern union { A: [4]u8, AAAA: [16]u8 },
1964
1965 pub const FLAGS = packed struct(DWORD) {
1966 Section: SECTION,
1967 Delete: u1,
1968 CharSet: u2,
1969 Unused: u3,
1970 Reserved: u24,
1971 };
1972 };
1973 pub const SECTION = enum(u2) { Question, Answer, Authority, Additional };
1974};
1975
1111// ref: km/ntddk.h1976// ref: km/ntddk.h
11121977
1113pub const SYSTEM = struct {1978pub const SYSTEM = struct {
...@@ -1725,6 +2590,68 @@ pub const CTL_CODE = packed struct(ULONG) {...@@ -1725,6 +2590,68 @@ pub const CTL_CODE = packed struct(ULONG) {
1725};2590};
17262591
1727pub const IOCTL = struct {2592pub const IOCTL = struct {
2593 pub const AFD = struct {
2594 const CONTROL_CODE = packed struct {
2595 Method: CTL_CODE.METHOD,
2596 Function: u10,
2597 DeviceType: CTL_CODE.FILE_DEVICE,
2598 Reserved28: u4 = 0,
2599 };
2600 pub const BIND: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 0, .Method = .NEITHER });
2601 pub const CONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 1, .Method = .NEITHER });
2602 pub const START_LISTEN: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 2, .Method = .NEITHER });
2603 pub const WAIT_FOR_LISTEN: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 3, .Method = .BUFFERED });
2604 pub const ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 4, .Method = .BUFFERED });
2605 pub const RECEIVE: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 5, .Method = .NEITHER });
2606 pub const RECEIVE_DATAGRAM: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 6, .Method = .NEITHER });
2607 pub const SEND: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 7, .Method = .NEITHER });
2608 pub const SEND_DATAGRAM: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 8, .Method = .NEITHER });
2609 pub const POLL: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 9, .Method = .BUFFERED });
2610 pub const PARTIAL_DISCONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 10, .Method = .NEITHER });
2611
2612 pub const GET_ADDRESS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 11, .Method = .NEITHER });
2613 pub const QUERY_RECEIVE_INFO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 12, .Method = .NEITHER });
2614 pub const QUERY_HANDLES: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 13, .Method = .NEITHER });
2615 pub const SET_INFORMATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 14, .Method = .NEITHER });
2616 pub const GET_CONTEXT_LENGTH: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 15, .Method = .NEITHER });
2617 pub const GET_CONTEXT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 16, .Method = .NEITHER });
2618 pub const SET_CONTEXT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 17, .Method = .NEITHER });
2619
2620 pub const SET_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 18, .Method = .BUFFERED });
2621 pub const SET_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 19, .Method = .BUFFERED });
2622 pub const SET_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 20, .Method = .BUFFERED });
2623 pub const SET_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 21, .Method = .BUFFERED });
2624 pub const GET_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 22, .Method = .BUFFERED });
2625 pub const GET_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 23, .Method = .BUFFERED });
2626 pub const GET_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 24, .Method = .BUFFERED });
2627 pub const GET_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 25, .Method = .BUFFERED });
2628 pub const SIZE_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 26, .Method = .BUFFERED });
2629 pub const SIZE_CONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 27, .Method = .BUFFERED });
2630 pub const SIZE_DISCONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 28, .Method = .BUFFERED });
2631 pub const SIZE_DISCONNECT_OPTIONS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 29, .Method = .BUFFERED });
2632
2633 pub const GET_INFORMATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 30, .Method = .NEITHER });
2634 pub const TRANSMIT_FILE: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 31, .Method = .NEITHER });
2635 pub const SUPER_ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 32, .Method = .NEITHER });
2636
2637 pub const EVENT_SELECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 33, .Method = .BUFFERED });
2638 pub const ENUM_NETWORK_EVENTS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 34, .Method = .BUFFERED });
2639
2640 pub const DEFER_ACCEPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 35, .Method = .BUFFERED });
2641 pub const WAIT_FOR_LISTEN_LIFO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 36, .Method = .BUFFERED });
2642 pub const SET_QOS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 37, .Method = .BUFFERED });
2643 pub const GET_QOS: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 38, .Method = .BUFFERED });
2644 pub const NO_OPERATION: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 39, .Method = .NEITHER });
2645 pub const VALIDATE_GROUP: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 40, .Method = .BUFFERED });
2646 pub const GET_UNACCEPTED_CONNECT_DATA: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 41, .Method = .BUFFERED });
2647
2648 pub const QUEUE_APC: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 42, .Method = .BUFFERED });
2649
2650 pub const SOCKOPT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 47, .Method = .NEITHER });
2651 pub const SUPER_CONNECT: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 49, .Method = .NEITHER });
2652 pub const RECV_MSG: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 51, .Method = .NEITHER });
2653 pub const RIO: CTL_CODE = @bitCast(CONTROL_CODE{ .DeviceType = .NETWORK, .Function = 70, .Method = .NEITHER });
2654 };
1728 pub const CONDRV = struct {2655 pub const CONDRV = struct {
1729 pub const READ_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 1, .Method = .OUT_DIRECT, .Access = .ANY };2656 pub const READ_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 1, .Method = .OUT_DIRECT, .Access = .ANY };
1730 pub const COMPLETE_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 2, .Method = .NEITHER, .Access = .ANY };2657 pub const COMPLETE_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 2, .Method = .NEITHER, .Access = .ANY };
...@@ -3306,15 +4233,6 @@ pub fn unexpectedError(err: Win32Error) UnexpectedError {...@@ -3306,15 +4233,6 @@ pub fn unexpectedError(err: Win32Error) UnexpectedError {
3306 return error.Unexpected;4233 return error.Unexpected;
3307}4234}
33084235
3309pub fn unexpectedWsaError(err: ws2_32.WinsockError) UnexpectedError {
3310 return unexpectedError(@as(Win32Error, @enumFromInt(@intFromEnum(err))));
3311}
3312
3313pub fn wsaErrorBug(err: ws2_32.WinsockError) UnexpectedError {
3314 if (builtin.mode == .Debug) std.debug.panic("programmer bug caused syscall error: {t}", .{err});
3315 return error.Unexpected;
3316}
3317
3318/// Call this when you made a windows NtDll call4236/// Call this when you made a windows NtDll call
3319/// and you get an unexpected status.4237/// and you get an unexpected status.
3320pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {4238pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
...@@ -3432,6 +4350,15 @@ fn STRING(comptime C: type) type {...@@ -3432,6 +4350,15 @@ fn STRING(comptime C: type) type {
3432 };4350 };
3433 }4351 }
34344352
4353 pub fn initZ(string: [:0]const C) @This() {
4354 const len: USHORT = @intCast(@sizeOf(C) * string.len);
4355 return .{
4356 .Length = len,
4357 .MaximumLength = len + @sizeOf(C),
4358 .Buffer = @constCast(string.ptr),
4359 };
4360 }
4361
3435 pub fn isEmpty(string: *const @This()) bool {4362 pub fn isEmpty(string: *const @This()) bool {
3436 return string.Length == 0;4363 return string.Length == 0;
3437 }4364 }
...@@ -3465,19 +4392,6 @@ pub const IO_STATUS_BLOCK = extern struct {...@@ -3465,19 +4392,6 @@ pub const IO_STATUS_BLOCK = extern struct {
3465 Information: ULONG_PTR,4392 Information: ULONG_PTR,
3466};4393};
34674394
3468pub const OVERLAPPED = extern struct {
3469 Internal: ULONG_PTR,
3470 InternalHigh: ULONG_PTR,
3471 DUMMYUNIONNAME: extern union {
3472 DUMMYSTRUCTNAME: extern struct {
3473 Offset: DWORD,
3474 OffsetHigh: DWORD,
3475 },
3476 Pointer: ?PVOID,
3477 },
3478 hEvent: ?HANDLE,
3479};
3480
3481pub const MAX_PATH = 260;4395pub const MAX_PATH = 260;
34824396
3483pub const SECURITY_ATTRIBUTES = extern struct {4397pub const SECURITY_ATTRIBUTES = extern struct {
...@@ -3525,27 +4439,6 @@ pub const STARTF_USESTDHANDLES = 0x00000100;...@@ -3525,27 +4439,6 @@ pub const STARTF_USESTDHANDLES = 0x00000100;
3525pub const THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) DWORD;4439pub const THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) DWORD;
3526pub const USER_THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) NTSTATUS;4440pub const USER_THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) NTSTATUS;
35274441
3528pub const SYSTEM_INFO = extern struct {
3529 anon1: extern union {
3530 dwOemId: DWORD,
3531 anon2: extern struct {
3532 wProcessorArchitecture: WORD,
3533 wReserved: WORD,
3534 },
3535 },
3536 dwPageSize: DWORD,
3537 lpMinimumApplicationAddress: LPVOID,
3538 lpMaximumApplicationAddress: LPVOID,
3539 dwActiveProcessorMask: DWORD_PTR,
3540 dwNumberOfProcessors: DWORD,
3541 dwProcessorType: DWORD,
3542 dwAllocationGranularity: DWORD,
3543 wProcessorLevel: WORD,
3544 wProcessorRevision: WORD,
3545};
3546
3547pub const HRESULT = c_long;
3548
3549pub const GUID = extern struct {4442pub const GUID = extern struct {
3550 Data1: u32,4443 Data1: u32,
3551 Data2: u16,4444 Data2: u16,
...@@ -3914,14 +4807,6 @@ pub const PATH_MAX_WIDE = 32767;...@@ -3914,14 +4807,6 @@ pub const PATH_MAX_WIDE = 32767;
3914/// TODO: More verification of this assumption.4807/// TODO: More verification of this assumption.
3915pub const NAME_MAX = 255;4808pub const NAME_MAX = 255;
39164809
3917pub const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
3918pub const FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
3919pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
3920pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400;
3921pub const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
3922pub const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
3923pub const FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF;
3924
3925pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002;4810pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002;
3926pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005;4811pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
3927pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d;4812pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d;
lib/std/os/windows/ntdll.zig+8-8
...@@ -114,14 +114,14 @@ pub extern "ntdll" fn NtCreateFile(...@@ -114,14 +114,14 @@ pub extern "ntdll" fn NtCreateFile(
114 ShareAccess: FILE.SHARE,114 ShareAccess: FILE.SHARE,
115 CreateDisposition: FILE.CREATE_DISPOSITION,115 CreateDisposition: FILE.CREATE_DISPOSITION,
116 CreateOptions: FILE.MODE,116 CreateOptions: FILE.MODE,
117 EaBuffer: ?*anyopaque,117 EaBuffer: ?*const anyopaque,
118 EaLength: ULONG,118 EaLength: ULONG,
119) callconv(.winapi) NTSTATUS;119) callconv(.winapi) NTSTATUS;
120120
121pub extern "ntdll" fn NtDeviceIoControlFile(121pub extern "ntdll" fn NtDeviceIoControlFile(
122 FileHandle: HANDLE,122 FileHandle: HANDLE,
123 Event: ?HANDLE,123 Event: ?HANDLE,
124 ApcRoutine: ?*const IO_APC_ROUTINE,124 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
125 ApcContext: ?*anyopaque,125 ApcContext: ?*anyopaque,
126 IoStatusBlock: *IO_STATUS_BLOCK,126 IoStatusBlock: *IO_STATUS_BLOCK,
127 IoControlCode: CTL_CODE,127 IoControlCode: CTL_CODE,
...@@ -134,7 +134,7 @@ pub extern "ntdll" fn NtDeviceIoControlFile(...@@ -134,7 +134,7 @@ pub extern "ntdll" fn NtDeviceIoControlFile(
134pub extern "ntdll" fn NtFsControlFile(134pub extern "ntdll" fn NtFsControlFile(
135 FileHandle: HANDLE,135 FileHandle: HANDLE,
136 Event: ?HANDLE,136 Event: ?HANDLE,
137 ApcRoutine: ?*const IO_APC_ROUTINE,137 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
138 ApcContext: ?*anyopaque,138 ApcContext: ?*anyopaque,
139 IoStatusBlock: *IO_STATUS_BLOCK,139 IoStatusBlock: *IO_STATUS_BLOCK,
140 FsControlCode: CTL_CODE,140 FsControlCode: CTL_CODE,
...@@ -147,7 +147,7 @@ pub extern "ntdll" fn NtFsControlFile(...@@ -147,7 +147,7 @@ pub extern "ntdll" fn NtFsControlFile(
147pub extern "ntdll" fn NtLockFile(147pub extern "ntdll" fn NtLockFile(
148 FileHandle: HANDLE,148 FileHandle: HANDLE,
149 Event: ?HANDLE,149 Event: ?HANDLE,
150 ApcRoutine: ?*const IO_APC_ROUTINE,150 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
151 ApcContext: ?*anyopaque,151 ApcContext: ?*anyopaque,
152 IoStatusBlock: *IO_STATUS_BLOCK,152 IoStatusBlock: *IO_STATUS_BLOCK,
153 ByteOffset: *const LARGE_INTEGER,153 ByteOffset: *const LARGE_INTEGER,
...@@ -169,7 +169,7 @@ pub extern "ntdll" fn NtOpenFile(...@@ -169,7 +169,7 @@ pub extern "ntdll" fn NtOpenFile(
169pub extern "ntdll" fn NtQueryDirectoryFile(169pub extern "ntdll" fn NtQueryDirectoryFile(
170 FileHandle: HANDLE,170 FileHandle: HANDLE,
171 Event: ?HANDLE,171 Event: ?HANDLE,
172 ApcRoutine: ?*const IO_APC_ROUTINE,172 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
173 ApcContext: ?*anyopaque,173 ApcContext: ?*anyopaque,
174 IoStatusBlock: *IO_STATUS_BLOCK,174 IoStatusBlock: *IO_STATUS_BLOCK,
175 FileInformation: *anyopaque,175 FileInformation: *anyopaque,
...@@ -199,7 +199,7 @@ pub extern "ntdll" fn NtQueryVolumeInformationFile(...@@ -199,7 +199,7 @@ pub extern "ntdll" fn NtQueryVolumeInformationFile(
199pub extern "ntdll" fn NtReadFile(199pub extern "ntdll" fn NtReadFile(
200 FileHandle: HANDLE,200 FileHandle: HANDLE,
201 Event: ?HANDLE,201 Event: ?HANDLE,
202 ApcRoutine: ?*const IO_APC_ROUTINE,202 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
203 ApcContext: ?*anyopaque,203 ApcContext: ?*anyopaque,
204 IoStatusBlock: *IO_STATUS_BLOCK,204 IoStatusBlock: *IO_STATUS_BLOCK,
205 Buffer: *anyopaque,205 Buffer: *anyopaque,
...@@ -222,7 +222,7 @@ pub extern "ntdll" fn NtSetInformationFile(...@@ -222,7 +222,7 @@ pub extern "ntdll" fn NtSetInformationFile(
222pub extern "ntdll" fn NtWriteFile(222pub extern "ntdll" fn NtWriteFile(
223 FileHandle: HANDLE,223 FileHandle: HANDLE,
224 Event: ?HANDLE,224 Event: ?HANDLE,
225 ApcRoutine: ?*const IO_APC_ROUTINE,225 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
226 ApcContext: ?*anyopaque,226 ApcContext: ?*anyopaque,
227 IoStatusBlock: *IO_STATUS_BLOCK,227 IoStatusBlock: *IO_STATUS_BLOCK,
228 Buffer: *const anyopaque,228 Buffer: *const anyopaque,
...@@ -527,7 +527,7 @@ pub extern "ntdll" fn NtDelayExecution(...@@ -527,7 +527,7 @@ pub extern "ntdll" fn NtDelayExecution(
527pub extern "ntdll" fn NtNotifyChangeDirectoryFileEx(527pub extern "ntdll" fn NtNotifyChangeDirectoryFileEx(
528 FileHandle: HANDLE,528 FileHandle: HANDLE,
529 Event: ?HANDLE,529 Event: ?HANDLE,
530 ApcRoutine: ?*const IO_APC_ROUTINE,530 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
531 ApcContext: ?*anyopaque,531 ApcContext: ?*anyopaque,
532 IoStatusBlock: *IO_STATUS_BLOCK,532 IoStatusBlock: *IO_STATUS_BLOCK,
533 Buffer: *anyopaque,533 Buffer: *anyopaque,
lib/std/os/windows/win32error.zig+266
...@@ -2503,5 +2503,271 @@ pub const Win32Error = enum(u32) {...@@ -2503,5 +2503,271 @@ pub const Win32Error = enum(u32) {
2503 REQUEST_PAUSED = 3050,2503 REQUEST_PAUSED = 3050,
2504 /// Reissue the given operation as a cached IO operation.2504 /// Reissue the given operation as a cached IO operation.
2505 IO_REISSUE_AS_CACHED = 3950,2505 IO_REISSUE_AS_CACHED = 3950,
2506 /// DNS server unable to interpret format.
2507 DNS_FORMAT_ERROR = 9001,
2508 /// DNS server failure.
2509 DNS_SERVER_FAILURE = 9002,
2510 /// DNS name does not exist.
2511 DNS_NAME_ERROR = 9003,
2512 /// DNS request not supported by name server.
2513 DNS_NOT_IMPLEMENTED = 9004,
2514 /// DNS operation refused.
2515 DNS_REFUSED = 9005,
2516 /// DNS name that ought not exist, does exist.
2517 DNS_YXDOMAIN = 9006,
2518 /// DNS RR set that ought not exist, does exist.
2519 DNS_YXRRSET = 9007,
2520 /// DNS RR set that ought to exist, does not exist.
2521 DNS_NXRRSET = 9008,
2522 /// DNS server not authoritative for zone.
2523 DNS_NOTAUTH = 9009,
2524 /// DNS name in update or prereq is not in zone.
2525 DNS_NOTZONE = 9010,
2526 /// DNS signature failed to verify.
2527 DNS_BADSIG = 9016,
2528 /// DNS bad key.
2529 DNS_BADKEY = 9017,
2530 /// DNS signature validity expired.
2531 DNS_BADTIME = 9018,
2532 /// Only the DNS server acting as the key master for the zone may perform this operation.
2533 DNS_KEYMASTER_REQUIRED = 9101,
2534 /// This operation is not allowed on a zone that is signed or has signing keys.
2535 DNS_NOT_ALLOWED_ON_SIGNED_ZONE = 9102,
2536 /// NSEC3 is not compatible with the RSA-SHA-1 algorithm. Choose a different algorithm or use NSEC.
2537 ///
2538 /// This value was also named DNS_INVALID_NSEC3_PARAMETERS
2539 DNS_NSEC3_INCOMPATIBLE_WITH_RSA_SHA1 = 9103,
2540 /// The zone does not have enough signing keys. There must be at least one key signing key (KSK) and at least one zone signing key (ZSK).
2541 DNS_NOT_ENOUGH_SIGNING_KEY_DESCRIPTORS = 9104,
2542 /// The specified algorithm is not supported.
2543 DNS_UNSUPPORTED_ALGORITHM = 9105,
2544 /// The specified key size is not supported.
2545 DNS_INVALID_KEY_SIZE = 9106,
2546 /// One or more of the signing keys for a zone are not accessible to the DNS server. Zone signing will not be operational until this error is resolved.
2547 DNS_SIGNING_KEY_NOT_ACCESSIBLE = 9107,
2548 /// The specified key storage provider does not support DPAPI++ data protection. Zone signing will not be operational until this error is resolved.
2549 DNS_KSP_DOES_NOT_SUPPORT_PROTECTION = 9108,
2550 /// An unexpected DPAPI++ error was encountered. Zone signing will not be operational until this error is resolved.
2551 DNS_UNEXPECTED_DATA_PROTECTION_ERROR = 9109,
2552 /// An unexpected crypto error was encountered. Zone signing may not be operational until this error is resolved.
2553 DNS_UNEXPECTED_CNG_ERROR = 9110,
2554 /// The DNS server encountered a signing key with an unknown version. Zone signing will not be operational until this error is resolved.
2555 DNS_UNKNOWN_SIGNING_PARAMETER_VERSION = 9111,
2556 /// The specified key service provider cannot be opened by the DNS server.
2557 DNS_KSP_NOT_ACCESSIBLE = 9112,
2558 /// The DNS server cannot accept any more signing keys with the specified algorithm and KSK flag value for this zone.
2559 DNS_TOO_MANY_SKDS = 9113,
2560 /// The specified rollover period is invalid.
2561 DNS_INVALID_ROLLOVER_PERIOD = 9114,
2562 /// The specified initial rollover offset is invalid.
2563 DNS_INVALID_INITIAL_ROLLOVER_OFFSET = 9115,
2564 /// The specified signing key is already in process of rolling over keys.
2565 DNS_ROLLOVER_IN_PROGRESS = 9116,
2566 /// The specified signing key does not have a standby key to revoke.
2567 DNS_STANDBY_KEY_NOT_PRESENT = 9117,
2568 /// This operation is not allowed on a zone signing key (ZSK).
2569 DNS_NOT_ALLOWED_ON_ZSK = 9118,
2570 /// This operation is not allowed on an active signing key.
2571 DNS_NOT_ALLOWED_ON_ACTIVE_SKD = 9119,
2572 /// The specified signing key is already queued for rollover.
2573 DNS_ROLLOVER_ALREADY_QUEUED = 9120,
2574 /// This operation is not allowed on an unsigned zone.
2575 DNS_NOT_ALLOWED_ON_UNSIGNED_ZONE = 9121,
2576 /// This operation could not be completed because the DNS server listed as the current key master for this zone is down or misconfigured. Resolve the problem on the current key master for this zone or use another DNS server to seize the key master role.
2577 DNS_BAD_KEYMASTER = 9122,
2578 /// The specified signature validity period is invalid.
2579 DNS_INVALID_SIGNATURE_VALIDITY_PERIOD = 9123,
2580 /// The specified NSEC3 iteration count is higher than allowed by the minimum key length used in the zone.
2581 DNS_INVALID_NSEC3_ITERATION_COUNT = 9124,
2582 /// This operation could not be completed because the DNS server has been configured with DNSSEC features disabled. Enable DNSSEC on the DNS server.
2583 DNS_DNSSEC_IS_DISABLED = 9125,
2584 /// This operation could not be completed because the XML stream received is empty or syntactically invalid.
2585 DNS_INVALID_XML = 9126,
2586 /// This operation completed, but no trust anchors were added because all of the trust anchors received were either invalid, unsupported, expired, or would not become valid in less than 30 days.
2587 DNS_NO_VALID_TRUST_ANCHORS = 9127,
2588 /// The specified signing key is not waiting for parental DS update.
2589 DNS_ROLLOVER_NOT_POKEABLE = 9128,
2590 /// Hash collision detected during NSEC3 signing. Specify a different user-provided salt, or use a randomly generated salt, and attempt to sign the zone again.
2591 DNS_NSEC3_NAME_COLLISION = 9129,
2592 /// NSEC is not compatible with the NSEC3-RSA-SHA-1 algorithm. Choose a different algorithm or use NSEC3.
2593 DNS_NSEC_INCOMPATIBLE_WITH_NSEC3_RSA_SHA1 = 9130,
2594 /// No records found for given DNS query.
2595 DNS_NO_RECORDS = 9501,
2596 /// Bad DNS packet.
2597 DNS_BAD_PACKET = 9502,
2598 /// No DNS packet.
2599 DNS_NO_PACKET = 9503,
2600 /// DNS error, check rcode.
2601 DNS_RCODE = 9504,
2602 /// Unsecured DNS packet.
2603 DNS_UNSECURE_PACKET = 9505,
2604 /// DNS query request is pending.
2605 DNS_REQUEST_PENDING = 9506,
2606 /// Invalid DNS type.
2607 DNS_INVALID_TYPE = 9551,
2608 /// Invalid IP address.
2609 DNS_INVALID_IP_ADDRESS = 9552,
2610 /// Invalid property.
2611 DNS_INVALID_PROPERTY = 9553,
2612 /// Try DNS operation again later.
2613 DNS_TRY_AGAIN_LATER = 9554,
2614 /// Record for given name and type is not unique.
2615 DNS_NOT_UNIQUE = 9555,
2616 /// DNS name does not comply with RFC specifications.
2617 DNS_NON_RFC_NAME = 9556,
2618 /// DNS name is a fully-qualified DNS name.
2619 DNS_FQDN = 9557,
2620 /// DNS name is dotted (multi-label).
2621 DNS_DOTTED_NAME = 9558,
2622 /// DNS name is a single-part name.
2623 DNS_SINGLE_PART_NAME = 9559,
2624 /// DNS name contains an invalid character.
2625 DNS_INVALID_NAME_CHAR = 9560,
2626 /// DNS name is entirely numeric.
2627 DNS_NUMERIC_NAME = 9561,
2628 /// The operation requested is not permitted on a DNS root server.
2629 DNS_NOT_ALLOWED_ON_ROOT_SERVER = 9562,
2630 /// The record could not be created because this part of the DNS namespace has been delegated to another server.
2631 DNS_NOT_ALLOWED_UNDER_DELEGATION = 9563,
2632 /// The DNS server could not find a set of root hints.
2633 DNS_CANNOT_FIND_ROOT_HINTS = 9564,
2634 /// The DNS server found root hints but they were not consistent across all adapters.
2635 DNS_INCONSISTENT_ROOT_HINTS = 9565,
2636 /// The specified value is too small for this parameter.
2637 DNS_DWORD_VALUE_TOO_SMALL = 9566,
2638 /// The specified value is too large for this parameter.
2639 DNS_DWORD_VALUE_TOO_LARGE = 9567,
2640 /// This operation is not allowed while the DNS server is loading zones in the background. Please try again later.
2641 DNS_BACKGROUND_LOADING = 9568,
2642 /// The operation requested is not permitted on against a DNS server running on a read-only DC.
2643 DNS_NOT_ALLOWED_ON_RODC = 9569,
2644 /// No data is allowed to exist underneath a DNAME record.
2645 DNS_NOT_ALLOWED_UNDER_DNAME = 9570,
2646 /// This operation requires credentials delegation.
2647 DNS_DELEGATION_REQUIRED = 9571,
2648 /// Name resolution policy table has been corrupted. DNS resolution will fail until it is fixed. Contact your network administrator.
2649 DNS_INVALID_POLICY_TABLE = 9572,
2650 /// DNS zone does not exist.
2651 DNS_ZONE_DOES_NOT_EXIST = 9601,
2652 /// DNS zone information not available.
2653 DNS_NO_ZONE_INFO = 9602,
2654 /// Invalid operation for DNS zone.
2655 DNS_INVALID_ZONE_OPERATION = 9603,
2656 /// Invalid DNS zone configuration.
2657 DNS_ZONE_CONFIGURATION_ERROR = 9604,
2658 /// DNS zone has no start of authority (SOA) record.
2659 DNS_ZONE_HAS_NO_SOA_RECORD = 9605,
2660 /// DNS zone has no Name Server (NS) record.
2661 DNS_ZONE_HAS_NO_NS_RECORDS = 9606,
2662 /// DNS zone is locked.
2663 DNS_ZONE_LOCKED = 9607,
2664 /// DNS zone creation failed.
2665 DNS_ZONE_CREATION_FAILED = 9608,
2666 /// DNS zone already exists.
2667 DNS_ZONE_ALREADY_EXISTS = 9609,
2668 /// DNS automatic zone already exists.
2669 DNS_AUTOZONE_ALREADY_EXISTS = 9610,
2670 /// Invalid DNS zone type.
2671 DNS_INVALID_ZONE_TYPE = 9611,
2672 /// Secondary DNS zone requires master IP address.
2673 DNS_SECONDARY_REQUIRES_MASTER_IP = 9612,
2674 /// DNS zone not secondary.
2675 DNS_ZONE_NOT_SECONDARY = 9613,
2676 /// Need secondary IP address.
2677 DNS_NEED_SECONDARY_ADDRESSES = 9614,
2678 /// WINS initialization failed.
2679 DNS_WINS_INIT_FAILED = 9615,
2680 /// Need WINS servers.
2681 DNS_NEED_WINS_SERVERS = 9616,
2682 /// NBTSTAT initialization call failed.
2683 DNS_NBSTAT_INIT_FAILED = 9617,
2684 /// Invalid delete of start of authority (SOA).
2685 DNS_SOA_DELETE_INVALID = 9618,
2686 /// A conditional forwarding zone already exists for that name.
2687 DNS_FORWARDER_ALREADY_EXISTS = 9619,
2688 /// This zone must be configured with one or more master DNS server IP addresses.
2689 DNS_ZONE_REQUIRES_MASTER_IP = 9620,
2690 /// The operation cannot be performed because this zone is shut down.
2691 DNS_ZONE_IS_SHUTDOWN = 9621,
2692 /// This operation cannot be performed because the zone is currently being signed. Please try again later.
2693 DNS_ZONE_LOCKED_FOR_SIGNING = 9622,
2694 /// Primary DNS zone requires datafile.
2695 DNS_PRIMARY_REQUIRES_DATAFILE = 9651,
2696 /// Invalid datafile name for DNS zone.
2697 DNS_INVALID_DATAFILE_NAME = 9652,
2698 /// Failed to open datafile for DNS zone.
2699 DNS_DATAFILE_OPEN_FAILURE = 9653,
2700 /// Failed to write datafile for DNS zone.
2701 DNS_FILE_WRITEBACK_FAILED = 9654,
2702 /// Failure while reading datafile for DNS zone.
2703 DNS_DATAFILE_PARSING = 9655,
2704 /// DNS record does not exist.
2705 DNS_RECORD_DOES_NOT_EXIST = 9701,
2706 /// DNS record format error.
2707 DNS_RECORD_FORMAT = 9702,
2708 /// Node creation failure in DNS.
2709 DNS_NODE_CREATION_FAILED = 9703,
2710 /// Unknown DNS record type.
2711 DNS_UNKNOWN_RECORD_TYPE = 9704,
2712 /// DNS record timed out.
2713 DNS_RECORD_TIMED_OUT = 9705,
2714 /// Name not in DNS zone.
2715 DNS_NAME_NOT_IN_ZONE = 9706,
2716 /// CNAME loop detected.
2717 DNS_CNAME_LOOP = 9707,
2718 /// Node is a CNAME DNS record.
2719 DNS_NODE_IS_CNAME = 9708,
2720 /// A CNAME record already exists for given name.
2721 DNS_CNAME_COLLISION = 9709,
2722 /// Record only at DNS zone root.
2723 DNS_RECORD_ONLY_AT_ZONE_ROOT = 9710,
2724 /// DNS record already exists.
2725 DNS_RECORD_ALREADY_EXISTS = 9711,
2726 /// Secondary DNS zone data error.
2727 DNS_SECONDARY_DATA = 9712,
2728 /// Could not create DNS cache data.
2729 DNS_NO_CREATE_CACHE_DATA = 9713,
2730 /// DNS name does not exist.
2731 DNS_NAME_DOES_NOT_EXIST = 9714,
2732 /// Could not create pointer (PTR) record.
2733 DNS_PTR_CREATE_FAILED = 9715,
2734 /// DNS domain was undeleted.
2735 DNS_DOMAIN_UNDELETED = 9716,
2736 /// The directory service is unavailable.
2737 DNS_DS_UNAVAILABLE = 9717,
2738 /// DNS zone already exists in the directory service.
2739 DNS_DS_ZONE_ALREADY_EXISTS = 9718,
2740 /// DNS server not creating or reading the boot file for the directory service integrated DNS zone.
2741 DNS_NO_BOOTFILE_IF_DS_ZONE = 9719,
2742 /// Node is a DNAME DNS record.
2743 DNS_NODE_IS_DNAME = 9720,
2744 /// A DNAME record already exists for given name.
2745 DNS_DNAME_COLLISION = 9721,
2746 /// An alias loop has been detected with either CNAME or DNAME records.
2747 DNS_ALIAS_LOOP = 9722,
2748 /// DNS AXFR (zone transfer) complete.
2749 DNS_AXFR_COMPLETE = 9751,
2750 /// DNS zone transfer failed.
2751 DNS_AXFR = 9752,
2752 /// Added local WINS server.
2753 DNS_ADDED_LOCAL_WINS = 9753,
2754 /// Secure update call needs to continue update request.
2755 DNS_CONTINUE_NEEDED = 9801,
2756 /// TCP/IP network protocol not installed.
2757 DNS_NO_TCPIP = 9851,
2758 /// No DNS servers configured for local system.
2759 DNS_NO_DNS_SERVERS = 9852,
2760 /// The specified directory partition does not exist.
2761 DNS_DP_DOES_NOT_EXIST = 9901,
2762 /// The specified directory partition already exists.
2763 DNS_DP_ALREADY_EXISTS = 9902,
2764 /// This DNS server is not enlisted in the specified directory partition.
2765 DNS_DP_NOT_ENLISTED = 9903,
2766 /// This DNS server is already enlisted in the specified directory partition.
2767 DNS_DP_ALREADY_ENLISTED = 9904,
2768 /// The directory partition is not available at this time. Please wait a few minutes and try again.
2769 DNS_DP_NOT_AVAILABLE = 9905,
2770 /// The operation failed because the domain naming master FSMO role could not be reached. The domain controller holding the domain naming master FSMO role is down or unable to service the request or is not running Windows Server 2003 or later.
2771 DNS_DP_FSMO_ERROR = 9906,
2506 _,2772 _,
2507};2773};
lib/std/os/windows/ws2_32.zig+3-1922
...@@ -2,447 +2,15 @@ const std = @import("../../std.zig");...@@ -2,447 +2,15 @@ const std = @import("../../std.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3const windows = std.os.windows;3const windows = std.os.windows;
44
5const OVERLAPPED = windows.OVERLAPPED;
6const WORD = windows.WORD;
7const DWORD = windows.DWORD;
8const GUID = windows.GUID;
9const USHORT = windows.USHORT;5const USHORT = windows.USHORT;
10const WCHAR = windows.WCHAR;
11const BOOL = windows.BOOL;
12const HANDLE = windows.HANDLE;
13const HWND = windows.HWND;
14const INT = windows.INT;
15const SHORT = windows.SHORT;
16const CHAR = windows.CHAR;
17const LONG = windows.LONG;6const LONG = windows.LONG;
18const ULONG = windows.ULONG;
19const LPARAM = windows.LPARAM;
20const FARPROC = windows.FARPROC;
21
22pub const SOCKET = *opaque {};
23pub const INVALID_SOCKET = @as(SOCKET, @ptrFromInt(~@as(usize, 0)));
247
25pub const GROUP = u32;8pub const GROUP = u32;
26pub const ADDRESS_FAMILY = u16;9pub const ADDRESS_FAMILY = u16;
27pub const WSAEVENT = HANDLE;
2810
29// Microsoft use the signed c_int for this, but it should never be negative11// Microsoft use the signed c_int for this, but it should never be negative
30pub const socklen_t = u32;12pub const socklen_t = u32;
3113
32pub const LM_HB_Extension = 128;
33pub const LM_HB1_PnP = 1;
34pub const LM_HB1_PDA_Palmtop = 2;
35pub const LM_HB1_Computer = 4;
36pub const LM_HB1_Printer = 8;
37pub const LM_HB1_Modem = 16;
38pub const LM_HB1_Fax = 32;
39pub const LM_HB1_LANAccess = 64;
40pub const LM_HB2_Telephony = 1;
41pub const LM_HB2_FileServer = 2;
42pub const ATMPROTO_AALUSER = 0;
43pub const ATMPROTO_AAL1 = 1;
44pub const ATMPROTO_AAL2 = 2;
45pub const ATMPROTO_AAL34 = 3;
46pub const ATMPROTO_AAL5 = 5;
47pub const SAP_FIELD_ABSENT = 4294967294;
48pub const SAP_FIELD_ANY = 4294967295;
49pub const SAP_FIELD_ANY_AESA_SEL = 4294967290;
50pub const SAP_FIELD_ANY_AESA_REST = 4294967291;
51pub const ATM_E164 = 1;
52pub const ATM_NSAP = 2;
53pub const ATM_AESA = 2;
54pub const ATM_ADDR_SIZE = 20;
55pub const BLLI_L2_ISO_1745 = 1;
56pub const BLLI_L2_Q921 = 2;
57pub const BLLI_L2_X25L = 6;
58pub const BLLI_L2_X25M = 7;
59pub const BLLI_L2_ELAPB = 8;
60pub const BLLI_L2_HDLC_ARM = 9;
61pub const BLLI_L2_HDLC_NRM = 10;
62pub const BLLI_L2_HDLC_ABM = 11;
63pub const BLLI_L2_LLC = 12;
64pub const BLLI_L2_X75 = 13;
65pub const BLLI_L2_Q922 = 14;
66pub const BLLI_L2_USER_SPECIFIED = 16;
67pub const BLLI_L2_ISO_7776 = 17;
68pub const BLLI_L3_X25 = 6;
69pub const BLLI_L3_ISO_8208 = 7;
70pub const BLLI_L3_X223 = 8;
71pub const BLLI_L3_SIO_8473 = 9;
72pub const BLLI_L3_T70 = 10;
73pub const BLLI_L3_ISO_TR9577 = 11;
74pub const BLLI_L3_USER_SPECIFIED = 16;
75pub const BLLI_L3_IPI_SNAP = 128;
76pub const BLLI_L3_IPI_IP = 204;
77pub const BHLI_ISO = 0;
78pub const BHLI_UserSpecific = 1;
79pub const BHLI_HighLayerProfile = 2;
80pub const BHLI_VendorSpecificAppId = 3;
81pub const AAL5_MODE_MESSAGE = 1;
82pub const AAL5_MODE_STREAMING = 2;
83pub const AAL5_SSCS_NULL = 0;
84pub const AAL5_SSCS_SSCOP_ASSURED = 1;
85pub const AAL5_SSCS_SSCOP_NON_ASSURED = 2;
86pub const AAL5_SSCS_FRAME_RELAY = 4;
87pub const BCOB_A = 1;
88pub const BCOB_C = 3;
89pub const BCOB_X = 16;
90pub const TT_NOIND = 0;
91pub const TT_CBR = 4;
92pub const TT_VBR = 8;
93pub const TR_NOIND = 0;
94pub const TR_END_TO_END = 1;
95pub const TR_NO_END_TO_END = 2;
96pub const CLIP_NOT = 0;
97pub const CLIP_SUS = 32;
98pub const UP_P2P = 0;
99pub const UP_P2MP = 1;
100pub const BLLI_L2_MODE_NORMAL = 64;
101pub const BLLI_L2_MODE_EXT = 128;
102pub const BLLI_L3_MODE_NORMAL = 64;
103pub const BLLI_L3_MODE_EXT = 128;
104pub const BLLI_L3_PACKET_16 = 4;
105pub const BLLI_L3_PACKET_32 = 5;
106pub const BLLI_L3_PACKET_64 = 6;
107pub const BLLI_L3_PACKET_128 = 7;
108pub const BLLI_L3_PACKET_256 = 8;
109pub const BLLI_L3_PACKET_512 = 9;
110pub const BLLI_L3_PACKET_1024 = 10;
111pub const BLLI_L3_PACKET_2048 = 11;
112pub const BLLI_L3_PACKET_4096 = 12;
113pub const PI_ALLOWED = 0;
114pub const PI_RESTRICTED = 64;
115pub const PI_NUMBER_NOT_AVAILABLE = 128;
116pub const SI_USER_NOT_SCREENED = 0;
117pub const SI_USER_PASSED = 1;
118pub const SI_USER_FAILED = 2;
119pub const SI_NETWORK = 3;
120pub const CAUSE_LOC_USER = 0;
121pub const CAUSE_LOC_PRIVATE_LOCAL = 1;
122pub const CAUSE_LOC_PUBLIC_LOCAL = 2;
123pub const CAUSE_LOC_TRANSIT_NETWORK = 3;
124pub const CAUSE_LOC_PUBLIC_REMOTE = 4;
125pub const CAUSE_LOC_PRIVATE_REMOTE = 5;
126pub const CAUSE_LOC_INTERNATIONAL_NETWORK = 7;
127pub const CAUSE_LOC_BEYOND_INTERWORKING = 10;
128pub const CAUSE_UNALLOCATED_NUMBER = 1;
129pub const CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK = 2;
130pub const CAUSE_NO_ROUTE_TO_DESTINATION = 3;
131pub const CAUSE_VPI_VCI_UNACCEPTABLE = 10;
132pub const CAUSE_NORMAL_CALL_CLEARING = 16;
133pub const CAUSE_USER_BUSY = 17;
134pub const CAUSE_NO_USER_RESPONDING = 18;
135pub const CAUSE_CALL_REJECTED = 21;
136pub const CAUSE_NUMBER_CHANGED = 22;
137pub const CAUSE_USER_REJECTS_CLIR = 23;
138pub const CAUSE_DESTINATION_OUT_OF_ORDER = 27;
139pub const CAUSE_INVALID_NUMBER_FORMAT = 28;
140pub const CAUSE_STATUS_ENQUIRY_RESPONSE = 30;
141pub const CAUSE_NORMAL_UNSPECIFIED = 31;
142pub const CAUSE_VPI_VCI_UNAVAILABLE = 35;
143pub const CAUSE_NETWORK_OUT_OF_ORDER = 38;
144pub const CAUSE_TEMPORARY_FAILURE = 41;
145pub const CAUSE_ACCESS_INFORMAION_DISCARDED = 43;
146pub const CAUSE_NO_VPI_VCI_AVAILABLE = 45;
147pub const CAUSE_RESOURCE_UNAVAILABLE = 47;
148pub const CAUSE_QOS_UNAVAILABLE = 49;
149pub const CAUSE_USER_CELL_RATE_UNAVAILABLE = 51;
150pub const CAUSE_BEARER_CAPABILITY_UNAUTHORIZED = 57;
151pub const CAUSE_BEARER_CAPABILITY_UNAVAILABLE = 58;
152pub const CAUSE_OPTION_UNAVAILABLE = 63;
153pub const CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED = 65;
154pub const CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS = 73;
155pub const CAUSE_INVALID_CALL_REFERENCE = 81;
156pub const CAUSE_CHANNEL_NONEXISTENT = 82;
157pub const CAUSE_INCOMPATIBLE_DESTINATION = 88;
158pub const CAUSE_INVALID_ENDPOINT_REFERENCE = 89;
159pub const CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = 91;
160pub const CAUSE_TOO_MANY_PENDING_ADD_PARTY = 92;
161pub const CAUSE_AAL_PARAMETERS_UNSUPPORTED = 93;
162pub const CAUSE_MANDATORY_IE_MISSING = 96;
163pub const CAUSE_UNIMPLEMENTED_MESSAGE_TYPE = 97;
164pub const CAUSE_UNIMPLEMENTED_IE = 99;
165pub const CAUSE_INVALID_IE_CONTENTS = 100;
166pub const CAUSE_INVALID_STATE_FOR_MESSAGE = 101;
167pub const CAUSE_RECOVERY_ON_TIMEOUT = 102;
168pub const CAUSE_INCORRECT_MESSAGE_LENGTH = 104;
169pub const CAUSE_PROTOCOL_ERROR = 111;
170pub const CAUSE_COND_UNKNOWN = 0;
171pub const CAUSE_COND_PERMANENT = 1;
172pub const CAUSE_COND_TRANSIENT = 2;
173pub const CAUSE_REASON_USER = 0;
174pub const CAUSE_REASON_IE_MISSING = 4;
175pub const CAUSE_REASON_IE_INSUFFICIENT = 8;
176pub const CAUSE_PU_PROVIDER = 0;
177pub const CAUSE_PU_USER = 8;
178pub const CAUSE_NA_NORMAL = 0;
179pub const CAUSE_NA_ABNORMAL = 4;
180pub const QOS_CLASS0 = 0;
181pub const QOS_CLASS1 = 1;
182pub const QOS_CLASS2 = 2;
183pub const QOS_CLASS3 = 3;
184pub const QOS_CLASS4 = 4;
185pub const TNS_TYPE_NATIONAL = 64;
186pub const TNS_PLAN_CARRIER_ID_CODE = 1;
187pub const SIO_GET_NUMBER_OF_ATM_DEVICES = 1343619073;
188pub const SIO_GET_ATM_ADDRESS = 3491102722;
189pub const SIO_ASSOCIATE_PVC = 2417360899;
190pub const SIO_GET_ATM_CONNECTION_ID = 1343619076;
191pub const RIO_MSG_DONT_NOTIFY = 1;
192pub const RIO_MSG_DEFER = 2;
193pub const RIO_MSG_WAITALL = 4;
194pub const RIO_MSG_COMMIT_ONLY = 8;
195pub const RIO_MAX_CQ_SIZE = 134217728;
196pub const RIO_CORRUPT_CQ = 4294967295;
197pub const WINDOWS_AF_IRDA = 26;
198pub const WCE_AF_IRDA = 22;
199pub const IRDA_PROTO_SOCK_STREAM = 1;
200pub const IRLMP_ENUMDEVICES = 16;
201pub const IRLMP_IAS_SET = 17;
202pub const IRLMP_IAS_QUERY = 18;
203pub const IRLMP_SEND_PDU_LEN = 19;
204pub const IRLMP_EXCLUSIVE_MODE = 20;
205pub const IRLMP_IRLPT_MODE = 21;
206pub const IRLMP_9WIRE_MODE = 22;
207pub const IRLMP_TINYTP_MODE = 23;
208pub const IRLMP_PARAMETERS = 24;
209pub const IRLMP_DISCOVERY_MODE = 25;
210pub const IRLMP_SHARP_MODE = 32;
211pub const IAS_ATTRIB_NO_CLASS = 16;
212pub const IAS_ATTRIB_NO_ATTRIB = 0;
213pub const IAS_ATTRIB_INT = 1;
214pub const IAS_ATTRIB_OCTETSEQ = 2;
215pub const IAS_ATTRIB_STR = 3;
216pub const IAS_MAX_USER_STRING = 256;
217pub const IAS_MAX_OCTET_STRING = 1024;
218pub const IAS_MAX_CLASSNAME = 64;
219pub const IAS_MAX_ATTRIBNAME = 256;
220pub const LmCharSetASCII = 0;
221pub const LmCharSetISO_8859_1 = 1;
222pub const LmCharSetISO_8859_2 = 2;
223pub const LmCharSetISO_8859_3 = 3;
224pub const LmCharSetISO_8859_4 = 4;
225pub const LmCharSetISO_8859_5 = 5;
226pub const LmCharSetISO_8859_6 = 6;
227pub const LmCharSetISO_8859_7 = 7;
228pub const LmCharSetISO_8859_8 = 8;
229pub const LmCharSetISO_8859_9 = 9;
230pub const LmCharSetUNICODE = 255;
231pub const LM_BAUD_1200 = 1200;
232pub const LM_BAUD_2400 = 2400;
233pub const LM_BAUD_9600 = 9600;
234pub const LM_BAUD_19200 = 19200;
235pub const LM_BAUD_38400 = 38400;
236pub const LM_BAUD_57600 = 57600;
237pub const LM_BAUD_115200 = 115200;
238pub const LM_BAUD_576K = 576000;
239pub const LM_BAUD_1152K = 1152000;
240pub const LM_BAUD_4M = 4000000;
241pub const LM_BAUD_16M = 16000000;
242pub const IPX_PTYPE = 16384;
243pub const IPX_FILTERPTYPE = 16385;
244pub const IPX_STOPFILTERPTYPE = 16387;
245pub const IPX_DSTYPE = 16386;
246pub const IPX_EXTENDED_ADDRESS = 16388;
247pub const IPX_RECVHDR = 16389;
248pub const IPX_MAXSIZE = 16390;
249pub const IPX_ADDRESS = 16391;
250pub const IPX_GETNETINFO = 16392;
251pub const IPX_GETNETINFO_NORIP = 16393;
252pub const IPX_SPXGETCONNECTIONSTATUS = 16395;
253pub const IPX_ADDRESS_NOTIFY = 16396;
254pub const IPX_MAX_ADAPTER_NUM = 16397;
255pub const IPX_RERIPNETNUMBER = 16398;
256pub const IPX_RECEIVE_BROADCAST = 16399;
257pub const IPX_IMMEDIATESPXACK = 16400;
258pub const MAX_MCAST_TTL = 255;
259pub const RM_OPTIONSBASE = 1000;
260pub const RM_RATE_WINDOW_SIZE = 1001;
261pub const RM_SET_MESSAGE_BOUNDARY = 1002;
262pub const RM_FLUSHCACHE = 1003;
263pub const RM_SENDER_WINDOW_ADVANCE_METHOD = 1004;
264pub const RM_SENDER_STATISTICS = 1005;
265pub const RM_LATEJOIN = 1006;
266pub const RM_SET_SEND_IF = 1007;
267pub const RM_ADD_RECEIVE_IF = 1008;
268pub const RM_DEL_RECEIVE_IF = 1009;
269pub const RM_SEND_WINDOW_ADV_RATE = 1010;
270pub const RM_USE_FEC = 1011;
271pub const RM_SET_MCAST_TTL = 1012;
272pub const RM_RECEIVER_STATISTICS = 1013;
273pub const RM_HIGH_SPEED_INTRANET_OPT = 1014;
274pub const SENDER_DEFAULT_RATE_KBITS_PER_SEC = 56;
275pub const SENDER_DEFAULT_WINDOW_ADV_PERCENTAGE = 15;
276pub const MAX_WINDOW_INCREMENT_PERCENTAGE = 25;
277pub const SENDER_DEFAULT_LATE_JOINER_PERCENTAGE = 0;
278pub const SENDER_MAX_LATE_JOINER_PERCENTAGE = 75;
279pub const BITS_PER_BYTE = 8;
280pub const LOG2_BITS_PER_BYTE = 3;
281
282pub const SOCKET_DEFAULT2_QM_POLICY = GUID.parse("{aec2ef9c-3a4d-4d3e-8842-239942e39a47}");
283pub const REAL_TIME_NOTIFICATION_CAPABILITY = GUID.parse("{6b59819a-5cae-492d-a901-2a3c2c50164f}");
284pub const REAL_TIME_NOTIFICATION_CAPABILITY_EX = GUID.parse("{6843da03-154a-4616-a508-44371295f96b}");
285pub const ASSOCIATE_NAMERES_CONTEXT = GUID.parse("{59a38b67-d4fe-46e1-ba3c-87ea74ca3049}");
286
287pub const WSAID_CONNECTEX = GUID{
288 .Data1 = 0x25a207b9,
289 .Data2 = 0xddf3,
290 .Data3 = 0x4660,
291 .Data4 = [8]u8{ 0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e },
292};
293
294pub const WSAID_ACCEPTEX = GUID{
295 .Data1 = 0xb5367df1,
296 .Data2 = 0xcbac,
297 .Data3 = 0x11cf,
298 .Data4 = [8]u8{ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 },
299};
300
301pub const WSAID_GETACCEPTEXSOCKADDRS = GUID{
302 .Data1 = 0xb5367df2,
303 .Data2 = 0xcbac,
304 .Data3 = 0x11cf,
305 .Data4 = [8]u8{ 0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 },
306};
307
308pub const WSAID_WSARECVMSG = GUID{
309 .Data1 = 0xf689d7c8,
310 .Data2 = 0x6f1f,
311 .Data3 = 0x436b,
312 .Data4 = [8]u8{ 0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22 },
313};
314
315pub const WSAID_WSAPOLL = GUID{
316 .Data1 = 0x18C76F85,
317 .Data2 = 0xDC66,
318 .Data3 = 0x4964,
319 .Data4 = [8]u8{ 0x97, 0x2E, 0x23, 0xC2, 0x72, 0x38, 0x31, 0x2B },
320};
321
322pub const WSAID_WSASENDMSG = GUID{
323 .Data1 = 0xa441e712,
324 .Data2 = 0x754f,
325 .Data3 = 0x43ca,
326 .Data4 = [8]u8{ 0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d },
327};
328
329pub const TCP_INITIAL_RTO_DEFAULT_RTT = 0;
330pub const TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS = 0;
331pub const SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = 1;
332pub const SOCKET_SETTINGS_ALLOW_INSECURE = 2;
333pub const SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = 1;
334pub const SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = 2;
335pub const SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = 4;
336pub const SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = 8;
337pub const SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE = 1;
338pub const SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID = 1;
339pub const SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID = 2;
340pub const SOCKET_INFO_CONNECTION_SECURED = 1;
341pub const SOCKET_INFO_CONNECTION_ENCRYPTED = 2;
342pub const SOCKET_INFO_CONNECTION_IMPERSONATED = 4;
343pub const IN4ADDR_LOOPBACK = 16777343;
344pub const IN4ADDR_LOOPBACKPREFIX_LENGTH = 8;
345pub const IN4ADDR_LINKLOCALPREFIX_LENGTH = 16;
346pub const IN4ADDR_MULTICASTPREFIX_LENGTH = 4;
347pub const IFF_UP = 1;
348pub const IFF_BROADCAST = 2;
349pub const IFF_LOOPBACK = 4;
350pub const IFF_POINTTOPOINT = 8;
351pub const IFF_MULTICAST = 16;
352pub const IP_OPTIONS = 1;
353pub const IP_HDRINCL = 2;
354pub const IP_TOS = 3;
355pub const IP_TTL = 4;
356pub const IP_MULTICAST_IF = 9;
357pub const IP_MULTICAST_TTL = 10;
358pub const IP_MULTICAST_LOOP = 11;
359pub const IP_ADD_MEMBERSHIP = 12;
360pub const IP_DROP_MEMBERSHIP = 13;
361pub const IP_DONTFRAGMENT = 14;
362pub const IP_ADD_SOURCE_MEMBERSHIP = 15;
363pub const IP_DROP_SOURCE_MEMBERSHIP = 16;
364pub const IP_BLOCK_SOURCE = 17;
365pub const IP_UNBLOCK_SOURCE = 18;
366pub const IP_PKTINFO = 19;
367pub const IP_HOPLIMIT = 21;
368pub const IP_RECVTTL = 21;
369pub const IP_RECEIVE_BROADCAST = 22;
370pub const IP_RECVIF = 24;
371pub const IP_RECVDSTADDR = 25;
372pub const IP_IFLIST = 28;
373pub const IP_ADD_IFLIST = 29;
374pub const IP_DEL_IFLIST = 30;
375pub const IP_UNICAST_IF = 31;
376pub const IP_RTHDR = 32;
377pub const IP_GET_IFLIST = 33;
378pub const IP_RECVRTHDR = 38;
379pub const IP_TCLASS = 39;
380pub const IP_RECVTCLASS = 40;
381pub const IP_RECVTOS = 40;
382pub const IP_ORIGINAL_ARRIVAL_IF = 47;
383pub const IP_ECN = 50;
384pub const IP_PKTINFO_EX = 51;
385pub const IP_WFP_REDIRECT_RECORDS = 60;
386pub const IP_WFP_REDIRECT_CONTEXT = 70;
387pub const IP_MTU_DISCOVER = 71;
388pub const IP_MTU = 73;
389pub const IP_NRT_INTERFACE = 74;
390pub const IP_RECVERR = 75;
391pub const IP_USER_MTU = 76;
392pub const IP_UNSPECIFIED_TYPE_OF_SERVICE = -1;
393pub const IN6ADDR_LINKLOCALPREFIX_LENGTH = 64;
394pub const IN6ADDR_MULTICASTPREFIX_LENGTH = 8;
395pub const IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104;
396pub const IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96;
397pub const IN6ADDR_6TO4PREFIX_LENGTH = 16;
398pub const IN6ADDR_TEREDOPREFIX_LENGTH = 32;
399pub const MCAST_JOIN_GROUP = 41;
400pub const MCAST_LEAVE_GROUP = 42;
401pub const MCAST_BLOCK_SOURCE = 43;
402pub const MCAST_UNBLOCK_SOURCE = 44;
403pub const MCAST_JOIN_SOURCE_GROUP = 45;
404pub const MCAST_LEAVE_SOURCE_GROUP = 46;
405pub const IPV6_HOPOPTS = 1;
406pub const IPV6_HDRINCL = 2;
407pub const IPV6_UNICAST_HOPS = 4;
408pub const IPV6_MULTICAST_IF = 9;
409pub const IPV6_MULTICAST_HOPS = 10;
410pub const IPV6_MULTICAST_LOOP = 11;
411pub const IPV6_ADD_MEMBERSHIP = 12;
412pub const IPV6_DROP_MEMBERSHIP = 13;
413pub const IPV6_DONTFRAG = 14;
414pub const IPV6_PKTINFO = 19;
415pub const IPV6_HOPLIMIT = 21;
416pub const IPV6_PROTECTION_LEVEL = 23;
417pub const IPV6_RECVIF = 24;
418pub const IPV6_RECVDSTADDR = 25;
419pub const IPV6_CHECKSUM = 26;
420pub const IPV6_V6ONLY = 27;
421pub const IPV6_IFLIST = 28;
422pub const IPV6_ADD_IFLIST = 29;
423pub const IPV6_DEL_IFLIST = 30;
424pub const IPV6_UNICAST_IF = 31;
425pub const IPV6_RTHDR = 32;
426pub const IPV6_GET_IFLIST = 33;
427pub const IPV6_RECVRTHDR = 38;
428pub const IPV6_TCLASS = 39;
429pub const IPV6_RECVTCLASS = 40;
430pub const IPV6_ECN = 50;
431pub const IPV6_PKTINFO_EX = 51;
432pub const IPV6_WFP_REDIRECT_RECORDS = 60;
433pub const IPV6_WFP_REDIRECT_CONTEXT = 70;
434pub const IPV6_MTU_DISCOVER = 71;
435pub const IPV6_MTU = 72;
436pub const IPV6_NRT_INTERFACE = 74;
437pub const IPV6_RECVERR = 75;
438pub const IPV6_USER_MTU = 76;
439pub const IP_UNSPECIFIED_HOP_LIMIT = -1;
440pub const PROTECTION_LEVEL_UNRESTRICTED = 10;
441pub const PROTECTION_LEVEL_EDGERESTRICTED = 20;
442pub const PROTECTION_LEVEL_RESTRICTED = 30;
443pub const INET_ADDRSTRLEN = 22;
444pub const INET6_ADDRSTRLEN = 65;
445
446pub const TCP = struct {14pub const TCP = struct {
447 pub const NODELAY = 1;15 pub const NODELAY = 1;
448 pub const EXPEDITED_1122 = 2;16 pub const EXPEDITED_1122 = 2;
...@@ -469,10 +37,6 @@ pub const TCP = struct {...@@ -469,10 +37,6 @@ pub const TCP = struct {
469 pub const BSDURGENT = 28672;37 pub const BSDURGENT = 28672;
470};38};
47139
472pub const UDP_SEND_MSG_SIZE = 2;
473pub const UDP_RECV_MAX_COALESCED_SIZE = 3;
474pub const UDP_COALESCED_INFO = 3;
475
476pub const AF = struct {40pub const AF = struct {
477 pub const UNSPEC = 0;41 pub const UNSPEC = 0;
478 pub const UNIX = 1;42 pub const UNIX = 1;
...@@ -507,6 +71,7 @@ pub const AF = struct {...@@ -507,6 +71,7 @@ pub const AF = struct {
507 pub const TCNPROCESS = 29;71 pub const TCNPROCESS = 29;
508 pub const TCNMESSAGE = 30;72 pub const TCNMESSAGE = 30;
509 pub const ICLFXBM = 31;73 pub const ICLFXBM = 31;
74 pub const BTH = 32;
510 pub const LINK = 33;75 pub const LINK = 33;
511 pub const HYPERV = 34;76 pub const HYPERV = 34;
512};77};
...@@ -517,15 +82,6 @@ pub const SOCK = struct {...@@ -517,15 +82,6 @@ pub const SOCK = struct {
517 pub const RAW = 3;82 pub const RAW = 3;
518 pub const RDM = 4;83 pub const RDM = 4;
519 pub const SEQPACKET = 5;84 pub const SEQPACKET = 5;
520
521 /// WARNING: this flag is not supported by windows socket functions directly,
522 /// it is only supported by std.os.socket. Be sure that this value does
523 /// not share any bits with any of the `SOCK` values.
524 pub const CLOEXEC = 0x10000;
525 /// WARNING: this flag is not supported by windows socket functions directly,
526 /// it is only supported by std.os.socket. Be sure that this value does
527 /// not share any bits with any of the `SOCK` values.
528 pub const NONBLOCK = 0x20000;
529};85};
53086
531pub const SOL = struct {87pub const SOL = struct {
...@@ -581,84 +137,9 @@ pub const SO = struct {...@@ -581,84 +137,9 @@ pub const SO = struct {
581 pub const UPDATE_ACCEPT_CONTEXT = 28683;137 pub const UPDATE_ACCEPT_CONTEXT = 28683;
582 pub const CONNECT_TIME = 28684;138 pub const CONNECT_TIME = 28684;
583 pub const UPDATE_CONNECT_CONTEXT = 28688;139 pub const UPDATE_CONNECT_CONTEXT = 28688;
584};
585140
586pub const WSK_SO_BASE = 16384;141 pub const UNIX_PATH = 0x98000000;
587pub const IOC_UNIX = 0;142};
588pub const IOC_WS2 = 134217728;
589pub const IOC_PROTOCOL = 268435456;
590pub const IOC_VENDOR = 402653184;
591pub const SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_OUT | IOC_IN | IOC_WS2 | 6;
592pub const SIO_BSP_HANDLE = IOC_OUT | IOC_WS2 | 27;
593pub const SIO_BSP_HANDLE_SELECT = IOC_OUT | IOC_WS2 | 28;
594pub const SIO_BSP_HANDLE_POLL = IOC_OUT | IOC_WS2 | 29;
595pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
596pub const IPPORT_TCPMUX = 1;
597pub const IPPORT_ECHO = 7;
598pub const IPPORT_DISCARD = 9;
599pub const IPPORT_SYSTAT = 11;
600pub const IPPORT_DAYTIME = 13;
601pub const IPPORT_NETSTAT = 15;
602pub const IPPORT_QOTD = 17;
603pub const IPPORT_MSP = 18;
604pub const IPPORT_CHARGEN = 19;
605pub const IPPORT_FTP_DATA = 20;
606pub const IPPORT_FTP = 21;
607pub const IPPORT_TELNET = 23;
608pub const IPPORT_SMTP = 25;
609pub const IPPORT_TIMESERVER = 37;
610pub const IPPORT_NAMESERVER = 42;
611pub const IPPORT_WHOIS = 43;
612pub const IPPORT_MTP = 57;
613pub const IPPORT_TFTP = 69;
614pub const IPPORT_RJE = 77;
615pub const IPPORT_FINGER = 79;
616pub const IPPORT_TTYLINK = 87;
617pub const IPPORT_SUPDUP = 95;
618pub const IPPORT_POP3 = 110;
619pub const IPPORT_NTP = 123;
620pub const IPPORT_EPMAP = 135;
621pub const IPPORT_NETBIOS_NS = 137;
622pub const IPPORT_NETBIOS_DGM = 138;
623pub const IPPORT_NETBIOS_SSN = 139;
624pub const IPPORT_IMAP = 143;
625pub const IPPORT_SNMP = 161;
626pub const IPPORT_SNMP_TRAP = 162;
627pub const IPPORT_IMAP3 = 220;
628pub const IPPORT_LDAP = 389;
629pub const IPPORT_HTTPS = 443;
630pub const IPPORT_MICROSOFT_DS = 445;
631pub const IPPORT_EXECSERVER = 512;
632pub const IPPORT_LOGINSERVER = 513;
633pub const IPPORT_CMDSERVER = 514;
634pub const IPPORT_EFSSERVER = 520;
635pub const IPPORT_BIFFUDP = 512;
636pub const IPPORT_WHOSERVER = 513;
637pub const IPPORT_ROUTESERVER = 520;
638pub const IPPORT_RESERVED = 1024;
639pub const IPPORT_REGISTERED_MAX = 49151;
640pub const IPPORT_DYNAMIC_MIN = 49152;
641pub const IPPORT_DYNAMIC_MAX = 65535;
642pub const IN_CLASSA_NET = 4278190080;
643pub const IN_CLASSA_NSHIFT = 24;
644pub const IN_CLASSA_HOST = 16777215;
645pub const IN_CLASSA_MAX = 128;
646pub const IN_CLASSB_NET = 4294901760;
647pub const IN_CLASSB_NSHIFT = 16;
648pub const IN_CLASSB_HOST = 65535;
649pub const IN_CLASSB_MAX = 65536;
650pub const IN_CLASSC_NET = 4294967040;
651pub const IN_CLASSC_NSHIFT = 8;
652pub const IN_CLASSC_HOST = 255;
653pub const IN_CLASSD_NET = 4026531840;
654pub const IN_CLASSD_NSHIFT = 28;
655pub const IN_CLASSD_HOST = 268435455;
656pub const INADDR_LOOPBACK = 2130706433;
657pub const INADDR_NONE = 4294967295;
658pub const IOCPARM_MASK = 127;
659pub const IOC_VOID = 536870912;
660pub const IOC_OUT = 1073741824;
661pub const IOC_IN = 2147483648;
662143
663pub const MSG = struct {144pub const MSG = struct {
664 pub const OOB = 0x1;145 pub const OOB = 0x1;
...@@ -678,215 +159,6 @@ pub const MSG = struct {...@@ -678,215 +159,6 @@ pub const MSG = struct {
678 pub const MAXIOVLEN = 16;159 pub const MAXIOVLEN = 16;
679};160};
680161
681pub const AI = packed struct(u32) {
682 PASSIVE: bool = false,
683 CANONNAME: bool = false,
684 NUMERICHOST: bool = false,
685 NUMERICSERV: bool = false,
686 DNS_ONLY: bool = false,
687 _5: u3 = 0,
688 ALL: bool = false,
689 _9: u1 = 0,
690 ADDRCONFIG: bool = false,
691 V4MAPPED: bool = false,
692 _12: u2 = 0,
693 NON_AUTHORITATIVE: bool = false,
694 SECURE: bool = false,
695 RETURN_PREFERRED_NAMES: bool = false,
696 FQDN: bool = false,
697 FILESERVER: bool = false,
698 DISABLE_IDN_ENCODING: bool = false,
699 _20: u10 = 0,
700 RESOLUTION_HANDLE: bool = false,
701 EXTENDED: bool = false,
702};
703
704pub const FIONBIO = -2147195266;
705pub const ADDRINFOEX_VERSION_2 = 2;
706pub const ADDRINFOEX_VERSION_3 = 3;
707pub const ADDRINFOEX_VERSION_4 = 4;
708
709pub const NS = enum(u32) {
710 ALL = 0,
711 SAP = 1,
712 NDS = 2,
713 PEER_BROWSE = 3,
714 SLP = 5,
715 DHCP = 6,
716 TCPIP_LOCAL = 10,
717 TCPIP_HOSTS = 11,
718 DNS = 12,
719 NETBT = 13,
720 WINS = 14,
721 NLA = 15,
722 NBP = 20,
723 MS = 30,
724 STDA = 31,
725 NTDS = 32,
726 EMAIL = 37,
727 X500 = 40,
728 NIS = 41,
729 NISPLUS = 42,
730 WRQ = 50,
731 NETDES = 60,
732};
733
734pub const NI_NOFQDN = 1;
735pub const NI_NUMERICHOST = 2;
736pub const NI_NAMEREQD = 4;
737pub const NI_NUMERICSERV = 8;
738pub const NI_DGRAM = 16;
739pub const NI_MAXHOST = 1025;
740pub const NI_MAXSERV = 32;
741pub const INCL_WINSOCK_API_PROTOTYPES = 1;
742pub const INCL_WINSOCK_API_TYPEDEFS = 0;
743pub const FD_SETSIZE = 64;
744pub const IMPLINK_IP = 155;
745pub const IMPLINK_LOWEXPER = 156;
746pub const IMPLINK_HIGHEXPER = 158;
747pub const WSADESCRIPTION_LEN = 256;
748pub const WSASYS_STATUS_LEN = 128;
749pub const SOCKET_ERROR = -1;
750pub const FROM_PROTOCOL_INFO = -1;
751pub const PVD_CONFIG = 12289;
752pub const SOMAXCONN = 2147483647;
753pub const MAXGETHOSTSTRUCT = 1024;
754pub const FD_READ_BIT = 0;
755pub const FD_WRITE_BIT = 1;
756pub const FD_OOB_BIT = 2;
757pub const FD_ACCEPT_BIT = 3;
758pub const FD_CONNECT_BIT = 4;
759pub const FD_CLOSE_BIT = 5;
760pub const FD_QOS_BIT = 6;
761pub const FD_GROUP_QOS_BIT = 7;
762pub const FD_ROUTING_INTERFACE_CHANGE_BIT = 8;
763pub const FD_ADDRESS_LIST_CHANGE_BIT = 9;
764pub const FD_MAX_EVENTS = 10;
765pub const CF_ACCEPT = 0;
766pub const CF_REJECT = 1;
767pub const CF_DEFER = 2;
768pub const SD_RECEIVE = 0;
769pub const SD_SEND = 1;
770pub const SD_BOTH = 2;
771pub const SG_UNCONSTRAINED_GROUP = 1;
772pub const SG_CONSTRAINED_GROUP = 2;
773pub const MAX_PROTOCOL_CHAIN = 7;
774pub const BASE_PROTOCOL = 1;
775pub const LAYERED_PROTOCOL = 0;
776pub const WSAPROTOCOL_LEN = 255;
777pub const PFL_MULTIPLE_PROTO_ENTRIES = 1;
778pub const PFL_RECOMMENDED_PROTO_ENTRY = 2;
779pub const PFL_HIDDEN = 4;
780pub const PFL_MATCHES_PROTOCOL_ZERO = 8;
781pub const PFL_NETWORKDIRECT_PROVIDER = 16;
782pub const XP1_CONNECTIONLESS = 1;
783pub const XP1_GUARANTEED_DELIVERY = 2;
784pub const XP1_GUARANTEED_ORDER = 4;
785pub const XP1_MESSAGE_ORIENTED = 8;
786pub const XP1_PSEUDO_STREAM = 16;
787pub const XP1_GRACEFUL_CLOSE = 32;
788pub const XP1_EXPEDITED_DATA = 64;
789pub const XP1_CONNECT_DATA = 128;
790pub const XP1_DISCONNECT_DATA = 256;
791pub const XP1_SUPPORT_BROADCAST = 512;
792pub const XP1_SUPPORT_MULTIPOINT = 1024;
793pub const XP1_MULTIPOINT_CONTROL_PLANE = 2048;
794pub const XP1_MULTIPOINT_DATA_PLANE = 4096;
795pub const XP1_QOS_SUPPORTED = 8192;
796pub const XP1_INTERRUPT = 16384;
797pub const XP1_UNI_SEND = 32768;
798pub const XP1_UNI_RECV = 65536;
799pub const XP1_IFS_HANDLES = 131072;
800pub const XP1_PARTIAL_MESSAGE = 262144;
801pub const XP1_SAN_SUPPORT_SDP = 524288;
802pub const BIGENDIAN = 0;
803pub const LITTLEENDIAN = 1;
804pub const SECURITY_PROTOCOL_NONE = 0;
805pub const JL_SENDER_ONLY = 1;
806pub const JL_RECEIVER_ONLY = 2;
807pub const JL_BOTH = 4;
808pub const WSA_FLAG_OVERLAPPED = 1;
809pub const WSA_FLAG_MULTIPOINT_C_ROOT = 2;
810pub const WSA_FLAG_MULTIPOINT_C_LEAF = 4;
811pub const WSA_FLAG_MULTIPOINT_D_ROOT = 8;
812pub const WSA_FLAG_MULTIPOINT_D_LEAF = 16;
813pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 64;
814pub const WSA_FLAG_NO_HANDLE_INHERIT = 128;
815pub const WSA_FLAG_REGISTERED_IO = 256;
816pub const TH_NETDEV = 1;
817pub const TH_TAPI = 2;
818pub const SERVICE_MULTIPLE = 1;
819pub const NS_LOCALNAME = 19;
820pub const RES_UNUSED_1 = 1;
821pub const RES_FLUSH_CACHE = 2;
822pub const RES_SERVICE = 4;
823pub const LUP_DEEP = 1;
824pub const LUP_CONTAINERS = 2;
825pub const LUP_NOCONTAINERS = 4;
826pub const LUP_NEAREST = 8;
827pub const LUP_RETURN_NAME = 16;
828pub const LUP_RETURN_TYPE = 32;
829pub const LUP_RETURN_VERSION = 64;
830pub const LUP_RETURN_COMMENT = 128;
831pub const LUP_RETURN_ADDR = 256;
832pub const LUP_RETURN_BLOB = 512;
833pub const LUP_RETURN_ALIASES = 1024;
834pub const LUP_RETURN_QUERY_STRING = 2048;
835pub const LUP_RETURN_ALL = 4080;
836pub const LUP_RES_SERVICE = 32768;
837pub const LUP_FLUSHCACHE = 4096;
838pub const LUP_FLUSHPREVIOUS = 8192;
839pub const LUP_NON_AUTHORITATIVE = 16384;
840pub const LUP_SECURE = 32768;
841pub const LUP_RETURN_PREFERRED_NAMES = 65536;
842pub const LUP_DNS_ONLY = 131072;
843pub const LUP_ADDRCONFIG = 1048576;
844pub const LUP_DUAL_ADDR = 2097152;
845pub const LUP_FILESERVER = 4194304;
846pub const LUP_DISABLE_IDN_ENCODING = 8388608;
847pub const LUP_API_ANSI = 16777216;
848pub const LUP_RESOLUTION_HANDLE = 2147483648;
849pub const RESULT_IS_ALIAS = 1;
850pub const RESULT_IS_ADDED = 16;
851pub const RESULT_IS_CHANGED = 32;
852pub const RESULT_IS_DELETED = 64;
853
854pub const POLL = struct {
855 pub const RDNORM = 256;
856 pub const RDBAND = 512;
857 pub const PRI = 1024;
858 pub const WRNORM = 16;
859 pub const WRBAND = 32;
860 pub const ERR = 1;
861 pub const HUP = 2;
862 pub const NVAL = 4;
863 pub const IN = RDNORM | RDBAND;
864 pub const OUT = WRNORM;
865};
866
867pub const TF_DISCONNECT = 1;
868pub const TF_REUSE_SOCKET = 2;
869pub const TF_WRITE_BEHIND = 4;
870pub const TF_USE_DEFAULT_WORKER = 0;
871pub const TF_USE_SYSTEM_THREAD = 16;
872pub const TF_USE_KERNEL_APC = 32;
873pub const TP_ELEMENT_MEMORY = 1;
874pub const TP_ELEMENT_FILE = 2;
875pub const TP_ELEMENT_EOP = 4;
876pub const NLA_ALLUSERS_NETWORK = 1;
877pub const NLA_FRIENDLY_NAME = 2;
878pub const WSPDESCRIPTION_LEN = 255;
879pub const WSS_OPERATION_IN_PROGRESS = 259;
880pub const LSP_SYSTEM = 2147483648;
881pub const LSP_INSPECTOR = 1;
882pub const LSP_REDIRECTOR = 2;
883pub const LSP_PROXY = 4;
884pub const LSP_FIREWALL = 8;
885pub const LSP_INBOUND_MODIFY = 16;
886pub const LSP_OUTBOUND_MODIFY = 32;
887pub const LSP_CRYPTO_COMPRESS = 64;
888pub const LSP_LOCAL_CACHE = 128;
889
890pub const IPPROTO = struct {162pub const IPPROTO = struct {
891 pub const IP = 0;163 pub const IP = 0;
892 pub const ICMP = 1;164 pub const ICMP = 1;
...@@ -902,77 +174,6 @@ pub const IPPROTO = struct {...@@ -902,77 +174,6 @@ pub const IPPROTO = struct {
902 pub const MAX = 256;174 pub const MAX = 256;
903};175};
904176
905pub const IP_DEFAULT_MULTICAST_TTL = 1;
906pub const IP_DEFAULT_MULTICAST_LOOP = 1;
907pub const IP_MAX_MEMBERSHIPS = 20;
908pub const FD_READ = 1;
909pub const FD_WRITE = 2;
910pub const FD_OOB = 4;
911pub const FD_ACCEPT = 8;
912pub const FD_CONNECT = 16;
913pub const FD_CLOSE = 32;
914pub const SERVICE_RESOURCE = 1;
915pub const SERVICE_SERVICE = 2;
916pub const SERVICE_LOCAL = 4;
917pub const SERVICE_FLAG_DEFER = 1;
918pub const SERVICE_FLAG_HARD = 2;
919pub const PROP_COMMENT = 1;
920pub const PROP_LOCALE = 2;
921pub const PROP_DISPLAY_HINT = 4;
922pub const PROP_VERSION = 8;
923pub const PROP_START_TIME = 16;
924pub const PROP_MACHINE = 32;
925pub const PROP_ADDRESSES = 256;
926pub const PROP_SD = 512;
927pub const PROP_ALL = 2147483648;
928pub const SERVICE_ADDRESS_FLAG_RPC_CN = 1;
929pub const SERVICE_ADDRESS_FLAG_RPC_DG = 2;
930pub const SERVICE_ADDRESS_FLAG_RPC_NB = 4;
931pub const NS_DEFAULT = 0;
932pub const NS_VNS = 50;
933pub const NSTYPE_HIERARCHICAL = 1;
934pub const NSTYPE_DYNAMIC = 2;
935pub const NSTYPE_ENUMERABLE = 4;
936pub const NSTYPE_WORKGROUP = 8;
937pub const XP_CONNECTIONLESS = 1;
938pub const XP_GUARANTEED_DELIVERY = 2;
939pub const XP_GUARANTEED_ORDER = 4;
940pub const XP_MESSAGE_ORIENTED = 8;
941pub const XP_PSEUDO_STREAM = 16;
942pub const XP_GRACEFUL_CLOSE = 32;
943pub const XP_EXPEDITED_DATA = 64;
944pub const XP_CONNECT_DATA = 128;
945pub const XP_DISCONNECT_DATA = 256;
946pub const XP_SUPPORTS_BROADCAST = 512;
947pub const XP_SUPPORTS_MULTICAST = 1024;
948pub const XP_BANDWIDTH_ALLOCATION = 2048;
949pub const XP_FRAGMENTATION = 4096;
950pub const XP_ENCRYPTS = 8192;
951pub const RES_SOFT_SEARCH = 1;
952pub const RES_FIND_MULTIPLE = 2;
953pub const SET_SERVICE_PARTIAL_SUCCESS = 1;
954pub const UDP_NOCHECKSUM = 1;
955pub const UDP_CHECKSUM_COVERAGE = 20;
956pub const GAI_STRERROR_BUFFER_SIZE = 1024;
957
958pub const LPCONDITIONPROC = *const fn (
959 lpCallerId: *WSABUF,
960 lpCallerData: *WSABUF,
961 lpSQOS: *QOS,
962 lpGQOS: *QOS,
963 lpCalleeId: *WSABUF,
964 lpCalleeData: *WSABUF,
965 g: *u32,
966 dwCallbackData: usize,
967) callconv(.winapi) i32;
968
969pub const LPWSAOVERLAPPED_COMPLETION_ROUTINE = *const fn (
970 dwError: u32,
971 cbTransferred: u32,
972 lpOverlapped: *OVERLAPPED,
973 dwFlags: u32,
974) callconv(.winapi) void;
975
976pub const FLOWSPEC = extern struct {177pub const FLOWSPEC = extern struct {
977 TokenRate: u32,178 TokenRate: u32,
978 TokenBucketSize: u32,179 TokenBucketSize: u32,
...@@ -984,94 +185,6 @@ pub const FLOWSPEC = extern struct {...@@ -984,94 +185,6 @@ pub const FLOWSPEC = extern struct {
984 MinimumPolicedSize: u32,185 MinimumPolicedSize: u32,
985};186};
986187
987pub const QOS = extern struct {
988 SendingFlowspec: FLOWSPEC,
989 ReceivingFlowspec: FLOWSPEC,
990 ProviderSpecific: WSABUF,
991};
992
993pub const SOCKET_ADDRESS = extern struct {
994 lpSockaddr: *sockaddr,
995 iSockaddrLength: i32,
996};
997
998pub const SOCKET_ADDRESS_LIST = extern struct {
999 iAddressCount: i32,
1000 Address: [1]SOCKET_ADDRESS,
1001};
1002
1003pub const WSADATA = if (@sizeOf(usize) == @sizeOf(u64))
1004 extern struct {
1005 wVersion: WORD,
1006 wHighVersion: WORD,
1007 iMaxSockets: u16,
1008 iMaxUdpDg: u16,
1009 lpVendorInfo: *u8,
1010 szDescription: [WSADESCRIPTION_LEN + 1]u8,
1011 szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
1012 }
1013else
1014 extern struct {
1015 wVersion: WORD,
1016 wHighVersion: WORD,
1017 szDescription: [WSADESCRIPTION_LEN + 1]u8,
1018 szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
1019 iMaxSockets: u16,
1020 iMaxUdpDg: u16,
1021 lpVendorInfo: *u8,
1022 };
1023
1024pub const WSAPROTOCOLCHAIN = extern struct {
1025 ChainLen: c_int,
1026 ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,
1027};
1028
1029pub const WSAPROTOCOL_INFOA = extern struct {
1030 dwServiceFlags1: DWORD,
1031 dwServiceFlags2: DWORD,
1032 dwServiceFlags3: DWORD,
1033 dwServiceFlags4: DWORD,
1034 dwProviderFlags: DWORD,
1035 ProviderId: GUID,
1036 dwCatalogEntryId: DWORD,
1037 ProtocolChain: WSAPROTOCOLCHAIN,
1038 iVersion: c_int,
1039 iAddressFamily: c_int,
1040 iMaxSockAddr: c_int,
1041 iMinSockAddr: c_int,
1042 iSocketType: c_int,
1043 iProtocol: c_int,
1044 iProtocolMaxOffset: c_int,
1045 iNetworkByteOrder: c_int,
1046 iSecurityScheme: c_int,
1047 dwMessageSize: DWORD,
1048 dwProviderReserved: DWORD,
1049 szProtocol: [WSAPROTOCOL_LEN + 1]CHAR,
1050};
1051
1052pub const WSAPROTOCOL_INFOW = extern struct {
1053 dwServiceFlags1: DWORD,
1054 dwServiceFlags2: DWORD,
1055 dwServiceFlags3: DWORD,
1056 dwServiceFlags4: DWORD,
1057 dwProviderFlags: DWORD,
1058 ProviderId: GUID,
1059 dwCatalogEntryId: DWORD,
1060 ProtocolChain: WSAPROTOCOLCHAIN,
1061 iVersion: c_int,
1062 iAddressFamily: c_int,
1063 iMaxSockAddr: c_int,
1064 iMinSockAddr: c_int,
1065 iSocketType: c_int,
1066 iProtocol: c_int,
1067 iProtocolMaxOffset: c_int,
1068 iNetworkByteOrder: c_int,
1069 iSecurityScheme: c_int,
1070 dwMessageSize: DWORD,
1071 dwProviderReserved: DWORD,
1072 szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR,
1073};
1074
1075pub const sockproto = extern struct {188pub const sockproto = extern struct {
1076 sp_family: u16,189 sp_family: u16,
1077 sp_protocol: u16,190 sp_protocol: u16,
...@@ -1082,25 +195,6 @@ pub const linger = extern struct {...@@ -1082,25 +195,6 @@ pub const linger = extern struct {
1082 linger: u16,195 linger: u16,
1083};196};
1084197
1085pub const WSANETWORKEVENTS = extern struct {
1086 lNetworkEvents: i32,
1087 iErrorCode: [10]i32,
1088};
1089
1090pub const ADDRINFOEXW = extern struct {
1091 flags: AI,
1092 family: i32,
1093 socktype: i32,
1094 protocol: i32,
1095 addrlen: usize,
1096 canonname: ?[*:0]u16,
1097 addr: ?*sockaddr,
1098 blob: ?*anyopaque,
1099 bloblen: usize,
1100 provider: ?*GUID,
1101 next: ?*ADDRINFOEXW,
1102};
1103
1104pub const sockaddr = extern struct {198pub const sockaddr = extern struct {
1105 family: ADDRESS_FAMILY,199 family: ADDRESS_FAMILY,
1106 data: [14]u8,200 data: [14]u8,
...@@ -1140,118 +234,6 @@ pub const sockaddr = extern struct {...@@ -1140,118 +234,6 @@ pub const sockaddr = extern struct {
1140 };234 };
1141};235};
1142236
1143pub const WSABUF = extern struct {
1144 len: ULONG,
1145 buf: [*]u8,
1146};
1147
1148pub const msghdr = WSAMSG;
1149pub const msghdr_const = WSAMSG_const;
1150
1151pub const WSAMSG_const = extern struct {
1152 name: *const sockaddr,
1153 namelen: INT,
1154 lpBuffers: [*]const WSABUF,
1155 dwBufferCount: DWORD,
1156 Control: WSABUF,
1157 dwFlags: DWORD,
1158};
1159
1160pub const WSAMSG = extern struct {
1161 name: *sockaddr,
1162 namelen: INT,
1163 lpBuffers: [*]WSABUF,
1164 dwBufferCount: DWORD,
1165 Control: WSABUF,
1166 dwFlags: DWORD,
1167};
1168
1169pub const WSAPOLLFD = pollfd;
1170
1171pub const pollfd = extern struct {
1172 fd: SOCKET,
1173 events: SHORT,
1174 revents: SHORT,
1175};
1176
1177pub const TRANSMIT_FILE_BUFFERS = extern struct {
1178 Head: *anyopaque,
1179 HeadLength: u32,
1180 Tail: *anyopaque,
1181 TailLength: u32,
1182};
1183
1184pub const LPFN_TRANSMITFILE = *const fn (
1185 hSocket: SOCKET,
1186 hFile: HANDLE,
1187 nNumberOfBytesToWrite: u32,
1188 nNumberOfBytesPerSend: u32,
1189 lpOverlapped: ?*OVERLAPPED,
1190 lpTransmitBuffers: ?*TRANSMIT_FILE_BUFFERS,
1191 dwReserved: u32,
1192) callconv(.winapi) BOOL;
1193
1194pub const LPFN_ACCEPTEX = *const fn (
1195 sListenSocket: SOCKET,
1196 sAcceptSocket: SOCKET,
1197 lpOutputBuffer: *anyopaque,
1198 dwReceiveDataLength: u32,
1199 dwLocalAddressLength: u32,
1200 dwRemoteAddressLength: u32,
1201 lpdwBytesReceived: *u32,
1202 lpOverlapped: *OVERLAPPED,
1203) callconv(.winapi) BOOL;
1204
1205pub const LPFN_GETACCEPTEXSOCKADDRS = *const fn (
1206 lpOutputBuffer: *anyopaque,
1207 dwReceiveDataLength: u32,
1208 dwLocalAddressLength: u32,
1209 dwRemoteAddressLength: u32,
1210 LocalSockaddr: **sockaddr,
1211 LocalSockaddrLength: *i32,
1212 RemoteSockaddr: **sockaddr,
1213 RemoteSockaddrLength: *i32,
1214) callconv(.winapi) void;
1215
1216pub const LPFN_WSASENDMSG = *const fn (
1217 s: SOCKET,
1218 lpMsg: *const WSAMSG_const,
1219 dwFlags: u32,
1220 lpNumberOfBytesSent: ?*u32,
1221 lpOverlapped: ?*OVERLAPPED,
1222 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1223) callconv(.winapi) i32;
1224
1225pub const LPFN_WSARECVMSG = *const fn (
1226 s: SOCKET,
1227 lpMsg: *WSAMSG,
1228 lpdwNumberOfBytesRecv: ?*u32,
1229 lpOverlapped: ?*OVERLAPPED,
1230 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1231) callconv(.winapi) i32;
1232
1233pub const LPSERVICE_CALLBACK_PROC = *const fn (
1234 lParam: LPARAM,
1235 hAsyncTaskHandle: HANDLE,
1236) callconv(.winapi) void;
1237
1238pub const SERVICE_ASYNC_INFO = extern struct {
1239 lpServiceCallbackProc: LPSERVICE_CALLBACK_PROC,
1240 lParam: LPARAM,
1241 hAsyncTaskHandle: HANDLE,
1242};
1243
1244pub const LPLOOKUPSERVICE_COMPLETION_ROUTINE = *const fn (
1245 dwError: u32,
1246 dwBytes: u32,
1247 lpOverlapped: *OVERLAPPED,
1248) callconv(.winapi) void;
1249
1250pub const fd_set = extern struct {
1251 fd_count: u32,
1252 fd_array: [64]SOCKET,
1253};
1254
1255pub const hostent = extern struct {237pub const hostent = extern struct {
1256 h_name: [*]u8,238 h_name: [*]u8,
1257 h_aliases: **i8,239 h_aliases: **i8,
...@@ -1264,904 +246,3 @@ pub const timeval = extern struct {...@@ -1264,904 +246,3 @@ pub const timeval = extern struct {
1264 sec: LONG,246 sec: LONG,
1265 usec: LONG,247 usec: LONG,
1266};248};
1267
1268/// https://docs.microsoft.com/en-au/windows/win32/winsock/windows-sockets-error-codes-2
1269pub const WinsockError = enum(u16) {
1270 /// Specified event object handle is invalid.
1271 /// An application attempts to use an event object, but the specified handle is not valid.
1272 INVALID_HANDLE = 6,
1273 /// Insufficient memory available.
1274 /// An application used a Windows Sockets function that directly maps to a Windows function.
1275 /// The Windows function is indicating a lack of required memory resources.
1276 NOT_ENOUGH_MEMORY = 8,
1277 /// One or more parameters are invalid.
1278 /// An application used a Windows Sockets function which directly maps to a Windows function.
1279 /// The Windows function is indicating a problem with one or more parameters.
1280 INVALID_PARAMETER = 87,
1281 /// Overlapped operation aborted.
1282 /// An overlapped operation was canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.
1283 OPERATION_ABORTED = 995,
1284 /// Overlapped I/O event object not in signaled state.
1285 /// The application has tried to determine the status of an overlapped operation which is not yet completed.
1286 /// Applications that use WSAGetOverlappedResult (with the fWait flag set to FALSE) in a polling mode to determine when an overlapped operation has completed, get this error code until the operation is complete.
1287 IO_INCOMPLETE = 996,
1288 /// The application has initiated an overlapped operation that cannot be completed immediately.
1289 /// A completion indication will be given later when the operation has been completed.
1290 IO_PENDING = 997,
1291 /// Interrupted function call.
1292 /// A blocking operation was interrupted by a call to WSACancelBlockingCall.
1293 EINTR = 10004,
1294 /// File handle is not valid.
1295 /// The file handle supplied is not valid.
1296 EBADF = 10009,
1297 /// Permission denied.
1298 /// An attempt was made to access a socket in a way forbidden by its access permissions.
1299 /// An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO.BROADCAST).
1300 /// Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4.0 with SP4 and later), another application, service, or kernel mode driver is bound to the same address with exclusive access.
1301 /// Such exclusive access is a new feature of Windows NT 4.0 with SP4 and later, and is implemented by using the SO.EXCLUSIVEADDRUSE option.
1302 EACCES = 10013,
1303 /// Bad address.
1304 /// The system detected an invalid pointer address in attempting to use a pointer argument of a call.
1305 /// This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small.
1306 /// For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
1307 EFAULT = 10014,
1308 /// Invalid argument.
1309 /// Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function).
1310 /// In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.
1311 EINVAL = 10022,
1312 /// Too many open files.
1313 /// Too many open sockets. Each implementation may have a maximum number of socket handles available, either globally, per process, or per thread.
1314 EMFILE = 10024,
1315 /// Resource temporarily unavailable.
1316 /// This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket.
1317 /// It is a nonfatal error, and the operation should be retried later.
1318 /// It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a nonblocking SOCK.STREAM socket, since some time must elapse for the connection to be established.
1319 EWOULDBLOCK = 10035,
1320 /// Operation now in progress.
1321 /// A blocking operation is currently executing.
1322 /// Windows Sockets only allows a single blocking operation—per- task or thread—to be outstanding, and if any other function call is made (whether or not it references that or any other socket) the function fails with the WSAEINPROGRESS error.
1323 EINPROGRESS = 10036,
1324 /// Operation already in progress.
1325 /// An operation was attempted on a nonblocking socket with an operation already in progress—that is, calling connect a second time on a nonblocking socket that is already connecting, or canceling an asynchronous request (WSAAsyncGetXbyY) that has already been canceled or completed.
1326 EALREADY = 10037,
1327 /// Socket operation on nonsocket.
1328 /// An operation was attempted on something that is not a socket.
1329 /// Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
1330 ENOTSOCK = 10038,
1331 /// Destination address required.
1332 /// A required address was omitted from an operation on a socket.
1333 /// For example, this error is returned if sendto is called with the remote address of ADDR_ANY.
1334 EDESTADDRREQ = 10039,
1335 /// Message too long.
1336 /// A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram was smaller than the datagram itself.
1337 EMSGSIZE = 10040,
1338 /// Protocol wrong type for socket.
1339 /// A protocol was specified in the socket function call that does not support the semantics of the socket type requested.
1340 /// For example, the ARPA Internet UDP protocol cannot be specified with a socket type of SOCK.STREAM.
1341 EPROTOTYPE = 10041,
1342 /// Bad protocol option.
1343 /// An unknown, invalid or unsupported option or level was specified in a getsockopt or setsockopt call.
1344 ENOPROTOOPT = 10042,
1345 /// Protocol not supported.
1346 /// The requested protocol has not been configured into the system, or no implementation for it exists.
1347 /// For example, a socket call requests a SOCK.DGRAM socket, but specifies a stream protocol.
1348 EPROTONOSUPPORT = 10043,
1349 /// Socket type not supported.
1350 /// The support for the specified socket type does not exist in this address family.
1351 /// For example, the optional type SOCK.RAW might be selected in a socket call, and the implementation does not support SOCK.RAW sockets at all.
1352 ESOCKTNOSUPPORT = 10044,
1353 /// Operation not supported.
1354 /// The attempted operation is not supported for the type of object referenced.
1355 /// Usually this occurs when a socket descriptor to a socket that cannot support this operation is trying to accept a connection on a datagram socket.
1356 EOPNOTSUPP = 10045,
1357 /// Protocol family not supported.
1358 /// The protocol family has not been configured into the system or no implementation for it exists.
1359 /// This message has a slightly different meaning from WSAEAFNOSUPPORT.
1360 /// However, it is interchangeable in most cases, and all Windows Sockets functions that return one of these messages also specify WSAEAFNOSUPPORT.
1361 EPFNOSUPPORT = 10046,
1362 /// Address family not supported by protocol family.
1363 /// An address incompatible with the requested protocol was used.
1364 /// All sockets are created with an associated address family (that is, AF.INET for Internet Protocols) and a generic protocol type (that is, SOCK.STREAM).
1365 /// This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto.
1366 EAFNOSUPPORT = 10047,
1367 /// Address already in use.
1368 /// Typically, only one usage of each socket address (protocol/IP address/port) is permitted.
1369 /// This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing.
1370 /// For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO.REUSEADDR).
1371 /// Client applications usually need not call bind at all—connect chooses an unused port automatically.
1372 /// When bind is called with a wildcard address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is committed.
1373 /// This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf.
1374 EADDRINUSE = 10048,
1375 /// Cannot assign requested address.
1376 /// The requested address is not valid in its context.
1377 /// This normally results from an attempt to bind to an address that is not valid for the local computer.
1378 /// This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).
1379 EADDRNOTAVAIL = 10049,
1380 /// Network is down.
1381 /// A socket operation encountered a dead network.
1382 /// This could indicate a serious failure of the network system (that is, the protocol stack that the Windows Sockets DLL runs over), the network interface, or the local network itself.
1383 ENETDOWN = 10050,
1384 /// Network is unreachable.
1385 /// A socket operation was attempted to an unreachable network.
1386 /// This usually means the local software knows no route to reach the remote host.
1387 ENETUNREACH = 10051,
1388 /// Network dropped connection on reset.
1389 /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress.
1390 /// It can also be returned by setsockopt if an attempt is made to set SO.KEEPALIVE on a connection that has already failed.
1391 ENETRESET = 10052,
1392 /// Software caused connection abort.
1393 /// An established connection was aborted by the software in your host computer, possibly due to a data transmission time-out or protocol error.
1394 ECONNABORTED = 10053,
1395 /// Connection reset by peer.
1396 /// An existing connection was forcibly closed by the remote host.
1397 /// This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO.LINGER option on the remote socket).
1398 /// This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress.
1399 /// Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
1400 ECONNRESET = 10054,
1401 /// No buffer space available.
1402 /// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
1403 ENOBUFS = 10055,
1404 /// Socket is already connected.
1405 /// A connect request was made on an already-connected socket.
1406 /// Some implementations also return this error if sendto is called on a connected SOCK.DGRAM socket (for SOCK.STREAM sockets, the to parameter in sendto is ignored) although other implementations treat this as a legal occurrence.
1407 EISCONN = 10056,
1408 /// Socket is not connected.
1409 /// A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using sendto) no address was supplied.
1410 /// Any other type of operation might also return this error—for example, setsockopt setting SO.KEEPALIVE if the connection has been reset.
1411 ENOTCONN = 10057,
1412 /// Cannot send after socket shutdown.
1413 /// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call.
1414 /// By calling shutdown a partial close of a socket is requested, which is a signal that sending or receiving, or both have been discontinued.
1415 ESHUTDOWN = 10058,
1416 /// Too many references.
1417 /// Too many references to some kernel object.
1418 ETOOMANYREFS = 10059,
1419 /// Connection timed out.
1420 /// A connection attempt failed because the connected party did not properly respond after a period of time, or the established connection failed because the connected host has failed to respond.
1421 ETIMEDOUT = 10060,
1422 /// Connection refused.
1423 /// No connection could be made because the target computer actively refused it.
1424 /// This usually results from trying to connect to a service that is inactive on the foreign host—that is, one with no server application running.
1425 ECONNREFUSED = 10061,
1426 /// Cannot translate name.
1427 /// Cannot translate a name.
1428 ELOOP = 10062,
1429 /// Name too long.
1430 /// A name component or a name was too long.
1431 ENAMETOOLONG = 10063,
1432 /// Host is down.
1433 /// A socket operation failed because the destination host is down. A socket operation encountered a dead host.
1434 /// Networking activity on the local host has not been initiated.
1435 /// These conditions are more likely to be indicated by the error WSAETIMEDOUT.
1436 EHOSTDOWN = 10064,
1437 /// No route to host.
1438 /// A socket operation was attempted to an unreachable host. See WSAENETUNREACH.
1439 EHOSTUNREACH = 10065,
1440 /// Directory not empty.
1441 /// Cannot remove a directory that is not empty.
1442 ENOTEMPTY = 10066,
1443 /// Too many processes.
1444 /// A Windows Sockets implementation may have a limit on the number of applications that can use it simultaneously.
1445 /// WSAStartup may fail with this error if the limit has been reached.
1446 EPROCLIM = 10067,
1447 /// User quota exceeded.
1448 /// Ran out of user quota.
1449 EUSERS = 10068,
1450 /// Disk quota exceeded.
1451 /// Ran out of disk quota.
1452 EDQUOT = 10069,
1453 /// Stale file handle reference.
1454 /// The file handle reference is no longer available.
1455 ESTALE = 10070,
1456 /// Item is remote.
1457 /// The item is not available locally.
1458 EREMOTE = 10071,
1459 /// Network subsystem is unavailable.
1460 /// This error is returned by WSAStartup if the Windows Sockets implementation cannot function at this time because the underlying system it uses to provide network services is currently unavailable.
1461 /// Users should check:
1462 /// - That the appropriate Windows Sockets DLL file is in the current path.
1463 /// - That they are not trying to use more than one Windows Sockets implementation simultaneously.
1464 /// - If there is more than one Winsock DLL on your system, be sure the first one in the path is appropriate for the network subsystem currently loaded.
1465 /// - The Windows Sockets implementation documentation to be sure all necessary components are currently installed and configured correctly.
1466 SYSNOTREADY = 10091,
1467 /// Winsock.dll version out of range.
1468 /// The current Windows Sockets implementation does not support the Windows Sockets specification version requested by the application.
1469 /// Check that no old Windows Sockets DLL files are being accessed.
1470 VERNOTSUPPORTED = 10092,
1471 /// Successful WSAStartup not yet performed.
1472 /// Either the application has not called WSAStartup or WSAStartup failed.
1473 /// The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.
1474 NOTINITIALISED = 10093,
1475 /// Graceful shutdown in progress.
1476 /// Returned by WSARecv and WSARecvFrom to indicate that the remote party has initiated a graceful shutdown sequence.
1477 EDISCON = 10101,
1478 /// No more results.
1479 /// No more results can be returned by the WSALookupServiceNext function.
1480 ENOMORE = 10102,
1481 /// Call has been canceled.
1482 /// A call to the WSALookupServiceEnd function was made while this call was still processing. The call has been canceled.
1483 ECANCELLED = 10103,
1484 /// Procedure call table is invalid.
1485 /// The service provider procedure call table is invalid.
1486 /// A service provider returned a bogus procedure table to Ws2_32.dll.
1487 /// This is usually caused by one or more of the function pointers being NULL.
1488 EINVALIDPROCTABLE = 10104,
1489 /// Service provider is invalid.
1490 /// The requested service provider is invalid.
1491 /// This error is returned by the WSCGetProviderInfo and WSCGetProviderInfo32 functions if the protocol entry specified could not be found.
1492 /// This error is also returned if the service provider returned a version number other than 2.0.
1493 EINVALIDPROVIDER = 10105,
1494 /// Service provider failed to initialize.
1495 /// The requested service provider could not be loaded or initialized.
1496 /// This error is returned if either a service provider's DLL could not be loaded (LoadLibrary failed) or the provider's WSPStartup or NSPStartup function failed.
1497 EPROVIDERFAILEDINIT = 10106,
1498 /// System call failure.
1499 /// A system call that should never fail has failed.
1500 /// This is a generic error code, returned under various conditions.
1501 /// Returned when a system call that should never fail does fail.
1502 /// For example, if a call to WaitForMultipleEvents fails or one of the registry functions fails trying to manipulate the protocol/namespace catalogs.
1503 /// Returned when a provider does not return SUCCESS and does not provide an extended error code.
1504 /// Can indicate a service provider implementation error.
1505 SYSCALLFAILURE = 10107,
1506 /// Service not found.
1507 /// No such service is known. The service cannot be found in the specified name space.
1508 SERVICE_NOT_FOUND = 10108,
1509 /// Class type not found.
1510 /// The specified class was not found.
1511 TYPE_NOT_FOUND = 10109,
1512 /// No more results.
1513 /// No more results can be returned by the WSALookupServiceNext function.
1514 E_NO_MORE = 10110,
1515 /// Call was canceled.
1516 /// A call to the WSALookupServiceEnd function was made while this call was still processing. The call has been canceled.
1517 E_CANCELLED = 10111,
1518 /// Database query was refused.
1519 /// A database query failed because it was actively refused.
1520 EREFUSED = 10112,
1521 /// Host not found.
1522 /// No such host is known. The name is not an official host name or alias, or it cannot be found in the database(s) being queried.
1523 /// This error may also be returned for protocol and service queries, and means that the specified name could not be found in the relevant database.
1524 HOST_NOT_FOUND = 11001,
1525 /// Nonauthoritative host not found.
1526 /// This is usually a temporary error during host name resolution and means that the local server did not receive a response from an authoritative server. A retry at some time later may be successful.
1527 TRY_AGAIN = 11002,
1528 /// This is a nonrecoverable error.
1529 /// This indicates that some sort of nonrecoverable error occurred during a database lookup.
1530 /// This may be because the database files (for example, BSD-compatible HOSTS, SERVICES, or PROTOCOLS files) could not be found, or a DNS request was returned by the server with a severe error.
1531 NO_RECOVERY = 11003,
1532 /// Valid name, no data record of requested type.
1533 /// The requested name is valid and was found in the database, but it does not have the correct associated data being resolved for.
1534 /// The usual example for this is a host name-to-address translation attempt (using gethostbyname or WSAAsyncGetHostByName) which uses the DNS (Domain Name Server).
1535 /// An MX record is returned but no A record—indicating the host itself exists, but is not directly reachable.
1536 NO_DATA = 11004,
1537 /// QoS receivers.
1538 /// At least one QoS reserve has arrived.
1539 QOS_RECEIVERS = 11005,
1540 /// QoS senders.
1541 /// At least one QoS send path has arrived.
1542 QOS_SENDERS = 11006,
1543 /// No QoS senders.
1544 /// There are no QoS senders.
1545 QOS_NO_SENDERS = 11007,
1546 /// QoS no receivers.
1547 /// There are no QoS receivers.
1548 QOS_NO_RECEIVERS = 11008,
1549 /// QoS request confirmed.
1550 /// The QoS reserve request has been confirmed.
1551 QOS_REQUEST_CONFIRMED = 11009,
1552 /// QoS admission error.
1553 /// A QoS error occurred due to lack of resources.
1554 QOS_ADMISSION_FAILURE = 11010,
1555 /// QoS policy failure.
1556 /// The QoS request was rejected because the policy system couldn't allocate the requested resource within the existing policy.
1557 QOS_POLICY_FAILURE = 11011,
1558 /// QoS bad style.
1559 /// An unknown or conflicting QoS style was encountered.
1560 QOS_BAD_STYLE = 11012,
1561 /// QoS bad object.
1562 /// A problem was encountered with some part of the filterspec or the provider-specific buffer in general.
1563 QOS_BAD_OBJECT = 11013,
1564 /// QoS traffic control error.
1565 /// An error with the underlying traffic control (TC) API as the generic QoS request was converted for local enforcement by the TC API.
1566 /// This could be due to an out of memory error or to an internal QoS provider error.
1567 QOS_TRAFFIC_CTRL_ERROR = 11014,
1568 /// QoS generic error.
1569 /// A general QoS error.
1570 QOS_GENERIC_ERROR = 11015,
1571 /// QoS service type error.
1572 /// An invalid or unrecognized service type was found in the QoS flowspec.
1573 QOS_ESERVICETYPE = 11016,
1574 /// QoS flowspec error.
1575 /// An invalid or inconsistent flowspec was found in the QOS structure.
1576 QOS_EFLOWSPEC = 11017,
1577 /// Invalid QoS provider buffer.
1578 /// An invalid QoS provider-specific buffer.
1579 QOS_EPROVSPECBUF = 11018,
1580 /// Invalid QoS filter style.
1581 /// An invalid QoS filter style was used.
1582 QOS_EFILTERSTYLE = 11019,
1583 /// Invalid QoS filter type.
1584 /// An invalid QoS filter type was used.
1585 QOS_EFILTERTYPE = 11020,
1586 /// Incorrect QoS filter count.
1587 /// An incorrect number of QoS FILTERSPECs were specified in the FLOWDESCRIPTOR.
1588 QOS_EFILTERCOUNT = 11021,
1589 /// Invalid QoS object length.
1590 /// An object with an invalid ObjectLength field was specified in the QoS provider-specific buffer.
1591 QOS_EOBJLENGTH = 11022,
1592 /// Incorrect QoS flow count.
1593 /// An incorrect number of flow descriptors was specified in the QoS structure.
1594 QOS_EFLOWCOUNT = 11023,
1595 /// Unrecognized QoS object.
1596 /// An unrecognized object was found in the QoS provider-specific buffer.
1597 QOS_EUNKOWNPSOBJ = 11024,
1598 /// Invalid QoS policy object.
1599 /// An invalid policy object was found in the QoS provider-specific buffer.
1600 QOS_EPOLICYOBJ = 11025,
1601 /// Invalid QoS flow descriptor.
1602 /// An invalid QoS flow descriptor was found in the flow descriptor list.
1603 QOS_EFLOWDESC = 11026,
1604 /// Invalid QoS provider-specific flowspec.
1605 /// An invalid or inconsistent flowspec was found in the QoS provider-specific buffer.
1606 QOS_EPSFLOWSPEC = 11027,
1607 /// Invalid QoS provider-specific filterspec.
1608 /// An invalid FILTERSPEC was found in the QoS provider-specific buffer.
1609 QOS_EPSFILTERSPEC = 11028,
1610 /// Invalid QoS shape discard mode object.
1611 /// An invalid shape discard mode object was found in the QoS provider-specific buffer.
1612 QOS_ESDMODEOBJ = 11029,
1613 /// Invalid QoS shaping rate object.
1614 /// An invalid shaping rate object was found in the QoS provider-specific buffer.
1615 QOS_ESHAPERATEOBJ = 11030,
1616 /// Reserved policy QoS element type.
1617 /// A reserved policy element was found in the QoS provider-specific buffer.
1618 QOS_RESERVED_PETYPE = 11031,
1619 _,
1620};
1621
1622pub extern "ws2_32" fn accept(
1623 s: SOCKET,
1624 addr: ?*sockaddr,
1625 addrlen: ?*i32,
1626) callconv(.winapi) SOCKET;
1627
1628pub extern "ws2_32" fn bind(
1629 s: SOCKET,
1630 name: *const sockaddr,
1631 namelen: i32,
1632) callconv(.winapi) i32;
1633
1634pub extern "ws2_32" fn closesocket(
1635 s: SOCKET,
1636) callconv(.winapi) i32;
1637
1638pub extern "ws2_32" fn connect(
1639 s: SOCKET,
1640 name: *const sockaddr,
1641 namelen: i32,
1642) callconv(.winapi) i32;
1643
1644pub extern "ws2_32" fn ioctlsocket(
1645 s: SOCKET,
1646 cmd: i32,
1647 argp: *u32,
1648) callconv(.winapi) i32;
1649
1650pub extern "ws2_32" fn getpeername(
1651 s: SOCKET,
1652 name: *sockaddr,
1653 namelen: *i32,
1654) callconv(.winapi) i32;
1655
1656pub extern "ws2_32" fn getsockname(
1657 s: SOCKET,
1658 name: *sockaddr,
1659 namelen: *i32,
1660) callconv(.winapi) i32;
1661
1662pub extern "ws2_32" fn getsockopt(
1663 s: SOCKET,
1664 level: i32,
1665 optname: i32,
1666 optval: [*]u8,
1667 optlen: *i32,
1668) callconv(.winapi) i32;
1669
1670pub extern "ws2_32" fn htonl(
1671 hostlong: u32,
1672) callconv(.winapi) u32;
1673
1674pub extern "ws2_32" fn htons(
1675 hostshort: u16,
1676) callconv(.winapi) u16;
1677
1678pub extern "ws2_32" fn inet_addr(
1679 cp: ?[*]const u8,
1680) callconv(.winapi) u32;
1681
1682pub extern "ws2_32" fn listen(
1683 s: SOCKET,
1684 backlog: i32,
1685) callconv(.winapi) i32;
1686
1687pub extern "ws2_32" fn ntohl(
1688 netlong: u32,
1689) callconv(.winapi) u32;
1690
1691pub extern "ws2_32" fn ntohs(
1692 netshort: u16,
1693) callconv(.winapi) u16;
1694
1695pub extern "ws2_32" fn recv(
1696 s: SOCKET,
1697 buf: [*]u8,
1698 len: i32,
1699 flags: i32,
1700) callconv(.winapi) i32;
1701
1702pub extern "ws2_32" fn recvfrom(
1703 s: SOCKET,
1704 buf: [*]u8,
1705 len: i32,
1706 flags: i32,
1707 from: ?*sockaddr,
1708 fromlen: ?*i32,
1709) callconv(.winapi) i32;
1710
1711pub extern "ws2_32" fn select(
1712 nfds: i32,
1713 readfds: ?*fd_set,
1714 writefds: ?*fd_set,
1715 exceptfds: ?*fd_set,
1716 timeout: ?*const timeval,
1717) callconv(.winapi) i32;
1718
1719pub extern "ws2_32" fn send(
1720 s: SOCKET,
1721 buf: [*]const u8,
1722 len: i32,
1723 flags: u32,
1724) callconv(.winapi) i32;
1725
1726pub extern "ws2_32" fn sendto(
1727 s: SOCKET,
1728 buf: [*]const u8,
1729 len: i32,
1730 flags: i32,
1731 to: ?*const sockaddr,
1732 tolen: i32,
1733) callconv(.winapi) i32;
1734
1735pub extern "ws2_32" fn setsockopt(
1736 s: SOCKET,
1737 level: i32,
1738 optname: i32,
1739 optval: ?[*]const u8,
1740 optlen: i32,
1741) callconv(.winapi) i32;
1742
1743pub extern "ws2_32" fn shutdown(
1744 s: SOCKET,
1745 how: i32,
1746) callconv(.winapi) i32;
1747
1748pub extern "ws2_32" fn socket(
1749 af: i32,
1750 @"type": i32,
1751 protocol: i32,
1752) callconv(.winapi) SOCKET;
1753
1754pub extern "ws2_32" fn WSAStartup(
1755 wVersionRequired: WORD,
1756 lpWSAData: *WSADATA,
1757) callconv(.winapi) i32;
1758
1759pub extern "ws2_32" fn WSACleanup() callconv(.winapi) i32;
1760
1761pub extern "ws2_32" fn WSASetLastError(iError: i32) callconv(.winapi) void;
1762
1763pub extern "ws2_32" fn WSAGetLastError() callconv(.winapi) WinsockError;
1764
1765pub extern "ws2_32" fn WSAIsBlocking() callconv(.winapi) BOOL;
1766
1767pub extern "ws2_32" fn WSAUnhookBlockingHook() callconv(.winapi) i32;
1768
1769pub extern "ws2_32" fn WSASetBlockingHook(lpBlockFunc: FARPROC) callconv(.winapi) FARPROC;
1770
1771pub extern "ws2_32" fn WSACancelBlockingCall() callconv(.winapi) i32;
1772
1773pub extern "ws2_32" fn WSAAsyncGetServByName(
1774 hWnd: HWND,
1775 wMsg: u32,
1776 name: [*:0]const u8,
1777 proto: ?[*:0]const u8,
1778 buf: [*]u8,
1779 buflen: i32,
1780) callconv(.winapi) HANDLE;
1781
1782pub extern "ws2_32" fn WSAAsyncGetServByPort(
1783 hWnd: HWND,
1784 wMsg: u32,
1785 port: i32,
1786 proto: ?[*:0]const u8,
1787 buf: [*]u8,
1788 buflen: i32,
1789) callconv(.winapi) HANDLE;
1790
1791pub extern "ws2_32" fn WSAAsyncGetProtoByName(
1792 hWnd: HWND,
1793 wMsg: u32,
1794 name: [*:0]const u8,
1795 buf: [*]u8,
1796 buflen: i32,
1797) callconv(.winapi) HANDLE;
1798
1799pub extern "ws2_32" fn WSAAsyncGetProtoByNumber(
1800 hWnd: HWND,
1801 wMsg: u32,
1802 number: i32,
1803 buf: [*]u8,
1804 buflen: i32,
1805) callconv(.winapi) HANDLE;
1806
1807pub extern "ws2_32" fn WSACancelAsyncRequest(hAsyncTaskHandle: HANDLE) callconv(.winapi) i32;
1808
1809pub extern "ws2_32" fn WSAAsyncSelect(
1810 s: SOCKET,
1811 hWnd: HWND,
1812 wMsg: u32,
1813 lEvent: i32,
1814) callconv(.winapi) i32;
1815
1816pub extern "ws2_32" fn WSAAccept(
1817 s: SOCKET,
1818 addr: ?*sockaddr,
1819 addrlen: ?*i32,
1820 lpfnCondition: ?LPCONDITIONPROC,
1821 dwCallbackData: usize,
1822) callconv(.winapi) SOCKET;
1823
1824pub extern "ws2_32" fn WSACloseEvent(hEvent: HANDLE) callconv(.winapi) BOOL;
1825
1826pub extern "ws2_32" fn WSAConnect(
1827 s: SOCKET,
1828 name: *const sockaddr,
1829 namelen: i32,
1830 lpCallerData: ?*WSABUF,
1831 lpCalleeData: ?*WSABUF,
1832 lpSQOS: ?*QOS,
1833 lpGQOS: ?*QOS,
1834) callconv(.winapi) i32;
1835
1836pub extern "ws2_32" fn WSAConnectByNameW(
1837 s: SOCKET,
1838 nodename: [*:0]const u16,
1839 servicename: [*:0]const u16,
1840 LocalAddressLength: ?*u32,
1841 LocalAddress: ?*sockaddr,
1842 RemoteAddressLength: ?*u32,
1843 RemoteAddress: ?*sockaddr,
1844 timeout: ?*const timeval,
1845 Reserved: *OVERLAPPED,
1846) callconv(.winapi) BOOL;
1847
1848pub extern "ws2_32" fn WSAConnectByList(
1849 s: SOCKET,
1850 SocketAddress: *SOCKET_ADDRESS_LIST,
1851 LocalAddressLength: ?*u32,
1852 LocalAddress: ?*sockaddr,
1853 RemoteAddressLength: ?*u32,
1854 RemoteAddress: ?*sockaddr,
1855 timeout: ?*const timeval,
1856 Reserved: *OVERLAPPED,
1857) callconv(.winapi) BOOL;
1858
1859pub extern "ws2_32" fn WSACreateEvent() callconv(.winapi) HANDLE;
1860
1861pub extern "ws2_32" fn WSADuplicateSocketW(
1862 s: SOCKET,
1863 dwProcessId: u32,
1864 lpProtocolInfo: *WSAPROTOCOL_INFOW,
1865) callconv(.winapi) i32;
1866
1867pub extern "ws2_32" fn WSAEnumNetworkEvents(
1868 s: SOCKET,
1869 hEventObject: HANDLE,
1870 lpNetworkEvents: *WSANETWORKEVENTS,
1871) callconv(.winapi) i32;
1872
1873pub extern "ws2_32" fn WSAEnumProtocolsW(
1874 lpiProtocols: ?*i32,
1875 lpProtocolBuffer: ?*WSAPROTOCOL_INFOW,
1876 lpdwBufferLength: *u32,
1877) callconv(.winapi) i32;
1878
1879pub extern "ws2_32" fn WSAEventSelect(
1880 s: SOCKET,
1881 hEventObject: HANDLE,
1882 lNetworkEvents: i32,
1883) callconv(.winapi) i32;
1884
1885pub extern "ws2_32" fn WSAGetOverlappedResult(
1886 s: SOCKET,
1887 lpOverlapped: *OVERLAPPED,
1888 lpcbTransfer: *u32,
1889 fWait: BOOL,
1890 lpdwFlags: *u32,
1891) callconv(.winapi) BOOL;
1892
1893pub extern "ws2_32" fn WSAGetQOSByName(
1894 s: SOCKET,
1895 lpQOSName: *WSABUF,
1896 lpQOS: *QOS,
1897) callconv(.winapi) BOOL;
1898
1899pub extern "ws2_32" fn WSAHtonl(
1900 s: SOCKET,
1901 hostlong: u32,
1902 lpnetlong: *u32,
1903) callconv(.winapi) i32;
1904
1905pub extern "ws2_32" fn WSAHtons(
1906 s: SOCKET,
1907 hostshort: u16,
1908 lpnetshort: *u16,
1909) callconv(.winapi) i32;
1910
1911pub extern "ws2_32" fn WSAIoctl(
1912 s: SOCKET,
1913 dwIoControlCode: u32,
1914 lpvInBuffer: ?*const anyopaque,
1915 cbInBuffer: u32,
1916 lpvOutbuffer: ?*anyopaque,
1917 cbOutbuffer: u32,
1918 lpcbBytesReturned: *u32,
1919 lpOverlapped: ?*OVERLAPPED,
1920 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1921) callconv(.winapi) i32;
1922
1923pub extern "ws2_32" fn WSAJoinLeaf(
1924 s: SOCKET,
1925 name: *const sockaddr,
1926 namelen: i32,
1927 lpCallerdata: ?*WSABUF,
1928 lpCalleeData: ?*WSABUF,
1929 lpSQOS: ?*QOS,
1930 lpGQOS: ?*QOS,
1931 dwFlags: u32,
1932) callconv(.winapi) SOCKET;
1933
1934pub extern "ws2_32" fn WSANtohl(
1935 s: SOCKET,
1936 netlong: u32,
1937 lphostlong: *u32,
1938) callconv(.winapi) u32;
1939
1940pub extern "ws2_32" fn WSANtohs(
1941 s: SOCKET,
1942 netshort: u16,
1943 lphostshort: *u16,
1944) callconv(.winapi) i32;
1945
1946pub extern "ws2_32" fn WSARecv(
1947 s: SOCKET,
1948 lpBuffers: [*]WSABUF,
1949 dwBufferCouynt: u32,
1950 lpNumberOfBytesRecv: ?*u32,
1951 lpFlags: *u32,
1952 lpOverlapped: ?*OVERLAPPED,
1953 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1954) callconv(.winapi) i32;
1955
1956pub extern "ws2_32" fn WSARecvDisconnect(
1957 s: SOCKET,
1958 lpInboundDisconnectData: ?*WSABUF,
1959) callconv(.winapi) i32;
1960
1961pub extern "ws2_32" fn WSARecvFrom(
1962 s: SOCKET,
1963 lpBuffers: [*]WSABUF,
1964 dwBuffercount: u32,
1965 lpNumberOfBytesRecvd: ?*u32,
1966 lpFlags: *u32,
1967 lpFrom: ?*sockaddr,
1968 lpFromlen: ?*i32,
1969 lpOverlapped: ?*OVERLAPPED,
1970 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1971) callconv(.winapi) i32;
1972
1973pub extern "ws2_32" fn WSAResetEvent(hEvent: HANDLE) callconv(.winapi) i32;
1974
1975pub extern "ws2_32" fn WSASend(
1976 s: SOCKET,
1977 lpBuffers: [*]WSABUF,
1978 dwBufferCount: u32,
1979 lpNumberOfBytesSent: ?*u32,
1980 dwFlags: u32,
1981 lpOverlapped: ?*OVERLAPPED,
1982 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1983) callconv(.winapi) i32;
1984
1985pub extern "ws2_32" fn WSASendMsg(
1986 s: SOCKET,
1987 lpMsg: *WSAMSG_const,
1988 dwFlags: u32,
1989 lpNumberOfBytesSent: ?*u32,
1990 lpOverlapped: ?*OVERLAPPED,
1991 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
1992) callconv(.winapi) i32;
1993
1994pub extern "ws2_32" fn WSASendDisconnect(
1995 s: SOCKET,
1996 lpOutboundDisconnectData: ?*WSABUF,
1997) callconv(.winapi) i32;
1998
1999pub extern "ws2_32" fn WSASendTo(
2000 s: SOCKET,
2001 lpBuffers: [*]WSABUF,
2002 dwBufferCount: u32,
2003 lpNumberOfBytesSent: ?*u32,
2004 dwFlags: u32,
2005 lpTo: ?*const sockaddr,
2006 iToLen: i32,
2007 lpOverlapped: ?*OVERLAPPED,
2008 lpCompletionRounte: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
2009) callconv(.winapi) i32;
2010
2011pub extern "ws2_32" fn WSASetEvent(
2012 hEvent: HANDLE,
2013) callconv(.winapi) BOOL;
2014
2015pub extern "ws2_32" fn WSASocketW(
2016 af: i32,
2017 @"type": i32,
2018 protocol: i32,
2019 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
2020 g: u32,
2021 dwFlags: u32,
2022) callconv(.winapi) SOCKET;
2023
2024pub extern "ws2_32" fn WSAWaitForMultipleEvents(
2025 cEvents: u32,
2026 lphEvents: [*]const HANDLE,
2027 fWaitAll: BOOL,
2028 dwTimeout: u32,
2029 fAlertable: BOOL,
2030) callconv(.winapi) u32;
2031
2032pub extern "ws2_32" fn WSAAddressToStringW(
2033 lpsaAddress: *sockaddr,
2034 dwAddressLength: u32,
2035 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
2036 lpszAddressString: [*]u16,
2037 lpdwAddressStringLength: *u32,
2038) callconv(.winapi) i32;
2039
2040pub extern "ws2_32" fn WSAStringToAddressW(
2041 AddressString: [*:0]const u16,
2042 AddressFamily: i32,
2043 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
2044 lpAddrses: *sockaddr,
2045 lpAddressLength: *i32,
2046) callconv(.winapi) i32;
2047
2048pub extern "ws2_32" fn WSAProviderConfigChange(
2049 lpNotificationHandle: *HANDLE,
2050 lpOverlapped: ?*OVERLAPPED,
2051 lpCompletionRoutine: ?LPWSAOVERLAPPED_COMPLETION_ROUTINE,
2052) callconv(.winapi) i32;
2053
2054pub extern "ws2_32" fn WSAPoll(
2055 fdArray: [*]WSAPOLLFD,
2056 fds: u32,
2057 timeout: i32,
2058) callconv(.winapi) i32;
2059
2060pub extern "mswsock" fn WSARecvEx(
2061 s: SOCKET,
2062 buf: [*]u8,
2063 len: i32,
2064 flags: *i32,
2065) callconv(.winapi) i32;
2066
2067pub extern "mswsock" fn TransmitFile(
2068 hSocket: SOCKET,
2069 hFile: HANDLE,
2070 nNumberOfBytesToWrite: u32,
2071 nNumberOfBytesPerSend: u32,
2072 lpOverlapped: ?*OVERLAPPED,
2073 lpTransmitBuffers: ?*TRANSMIT_FILE_BUFFERS,
2074 dwReserved: u32,
2075) callconv(.winapi) BOOL;
2076
2077pub extern "mswsock" fn AcceptEx(
2078 sListenSocket: SOCKET,
2079 sAcceptSocket: SOCKET,
2080 lpOutputBuffer: *anyopaque,
2081 dwReceiveDataLength: u32,
2082 dwLocalAddressLength: u32,
2083 dwRemoteAddressLength: u32,
2084 lpdwBytesReceived: *u32,
2085 lpOverlapped: *OVERLAPPED,
2086) callconv(.winapi) BOOL;
2087
2088pub extern "mswsock" fn GetAcceptExSockaddrs(
2089 lpOutputBuffer: *anyopaque,
2090 dwReceiveDataLength: u32,
2091 dwLocalAddressLength: u32,
2092 dwRemoteAddressLength: u32,
2093 LocalSockaddr: **sockaddr,
2094 LocalSockaddrLength: *i32,
2095 RemoteSockaddr: **sockaddr,
2096 RemoteSockaddrLength: *i32,
2097) callconv(.winapi) void;
2098
2099pub extern "ws2_32" fn WSAProviderCompleteAsyncCall(
2100 hAsyncCall: HANDLE,
2101 iRetCode: i32,
2102) callconv(.winapi) i32;
2103
2104pub extern "mswsock" fn EnumProtocolsW(
2105 lpiProtocols: ?*i32,
2106 lpProtocolBuffer: *anyopaque,
2107 lpdwBufferLength: *u32,
2108) callconv(.winapi) i32;
2109
2110pub extern "mswsock" fn GetAddressByNameW(
2111 dwNameSpace: NS,
2112 lpServiceType: *GUID,
2113 lpServiceName: ?[*:0]u16,
2114 lpiProtocols: ?*i32,
2115 dwResolution: u32,
2116 lpServiceAsyncInfo: ?*SERVICE_ASYNC_INFO,
2117 lpCsaddrBuffer: *anyopaque,
2118 ldwBufferLEngth: *u32,
2119 lpAliasBuffer: ?[*:0]u16,
2120 lpdwAliasBufferLength: *u32,
2121) callconv(.winapi) i32;
2122
2123pub extern "mswsock" fn GetTypeByNameW(
2124 lpServiceName: [*:0]u16,
2125 lpServiceType: *GUID,
2126) callconv(.winapi) i32;
2127
2128pub extern "mswsock" fn GetNameByTypeW(
2129 lpServiceType: *GUID,
2130 lpServiceName: [*:0]u16,
2131 dwNameLength: u32,
2132) callconv(.winapi) i32;
2133
2134pub extern "ws2_32" fn GetAddrInfoExW(
2135 pName: ?[*:0]const u16,
2136 pServiceName: ?[*:0]const u16,
2137 dwNameSpace: NS,
2138 lpNspId: ?*GUID,
2139 hints: ?*const ADDRINFOEXW,
2140 ppResult: **ADDRINFOEXW,
2141 timeout: ?*timeval,
2142 lpOverlapped: ?*OVERLAPPED,
2143 lpCompletionRoutine: ?LPLOOKUPSERVICE_COMPLETION_ROUTINE,
2144 lpNameHandle: ?*HANDLE,
2145) callconv(.winapi) i32;
2146
2147pub extern "ws2_32" fn GetAddrInfoExCancel(
2148 lpHandle: *HANDLE,
2149) callconv(.winapi) i32;
2150
2151pub extern "ws2_32" fn GetAddrInfoExOverlappedResult(
2152 lpOverlapped: *OVERLAPPED,
2153) callconv(.winapi) i32;
2154
2155pub extern "ws2_32" fn FreeAddrInfoExW(
2156 pAddrInfoEx: ?*ADDRINFOEXW,
2157) callconv(.winapi) void;
2158
2159pub extern "ws2_32" fn getnameinfo(
2160 pSockaddr: *const sockaddr,
2161 SockaddrLength: i32,
2162 pNodeBuffer: ?[*]u8,
2163 NodeBufferSize: u32,
2164 pServiceBuffer: ?[*]u8,
2165 ServiceBufferName: u32,
2166 Flags: i32,
2167) callconv(.winapi) i32;
lib/std/posix.zig+4-35
...@@ -268,7 +268,7 @@ pub const LOG = struct {...@@ -268,7 +268,7 @@ pub const LOG = struct {
268 pub const DEBUG = 7;268 pub const DEBUG = 7;
269};269};
270270
271pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t;271pub const socket_t = fd_t;
272272
273/// Obtains errno from the return value of a system function call.273/// Obtains errno from the return value of a system function call.
274///274///
...@@ -500,18 +500,7 @@ pub const GetSockNameError = error{...@@ -500,18 +500,7 @@ pub const GetSockNameError = error{
500500
501pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {501pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
502 if (native_os == .windows) {502 if (native_os == .windows) {
503 const rc = windows.getpeername(sock, addr, addrlen);503 @compileError("use std.Io instead");
504 if (rc == windows.ws2_32.SOCKET_ERROR) {
505 switch (windows.ws2_32.WSAGetLastError()) {
506 .NOTINITIALISED => unreachable,
507 .ENETDOWN => return error.NetworkDown,
508 .EFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value
509 .ENOTSOCK => return error.FileDescriptorNotASocket,
510 .EINVAL => return error.SocketNotBound,
511 else => |err| return windows.unexpectedWSAError(err),
512 }
513 }
514 return;
515 } else {504 } else {
516 const rc = system.getpeername(sock, addr, addrlen);505 const rc = system.getpeername(sock, addr, addrlen);
517 switch (errno(rc)) {506 switch (errno(rc)) {
...@@ -992,16 +981,7 @@ pub const PollError = error{...@@ -992,16 +981,7 @@ pub const PollError = error{
992981
993pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {982pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
994 if (native_os == .windows) {983 if (native_os == .windows) {
995 switch (windows.poll(fds.ptr, @intCast(fds.len), timeout)) {984 @compileError("use std.Io instead");
996 windows.ws2_32.SOCKET_ERROR => switch (windows.ws2_32.WSAGetLastError()) {
997 .NOTINITIALISED => unreachable,
998 .ENETDOWN => return error.NetworkDown,
999 .ENOBUFS => return error.SystemResources,
1000 // TODO: handle more errors
1001 else => |err| return windows.unexpectedWSAError(err),
1002 },
1003 else => |rc| return @intCast(rc),
1004 }
1005 }985 }
1006 while (true) {986 while (true) {
1007 const fds_count = cast(nfds_t, fds.len) orelse return error.SystemResources;987 const fds_count = cast(nfds_t, fds.len) orelse return error.SystemResources;
...@@ -1071,18 +1051,7 @@ pub const SetSockOptError = error{...@@ -1071,18 +1051,7 @@ pub const SetSockOptError = error{
1071/// Set a socket's options.1051/// Set a socket's options.
1072pub fn setsockopt(fd: socket_t, level: i32, optname: u32, opt: []const u8) SetSockOptError!void {1052pub fn setsockopt(fd: socket_t, level: i32, optname: u32, opt: []const u8) SetSockOptError!void {
1073 if (native_os == .windows) {1053 if (native_os == .windows) {
1074 const rc = windows.ws2_32.setsockopt(fd, level, @intCast(optname), opt.ptr, @intCast(opt.len));1054 @compileError("use std.Io instead");
1075 if (rc == windows.ws2_32.SOCKET_ERROR) {
1076 switch (windows.ws2_32.WSAGetLastError()) {
1077 .NOTINITIALISED => unreachable,
1078 .ENETDOWN => return error.NetworkDown,
1079 .EFAULT => unreachable,
1080 .ENOTSOCK => return error.FileDescriptorNotASocket,
1081 .EINVAL => return error.SocketNotBound,
1082 else => |err| return windows.unexpectedWSAError(err),
1083 }
1084 }
1085 return;
1086 } else {1055 } else {
1087 switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(opt.len)))) {1056 switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(opt.len)))) {
1088 .SUCCESS => {},1057 .SUCCESS => {},
test/standalone/coff_dwarf/build.zig-3
...@@ -46,9 +46,6 @@ pub fn build(b: *std.Build) void {...@@ -46,9 +46,6 @@ pub fn build(b: *std.Build) void {
46 lib.root_module.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-gdwarf"} });46 lib.root_module.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-gdwarf"} });
47 exe.root_module.linkLibrary(lib);47 exe.root_module.linkLibrary(lib);
4848
49 if (target.result.os.tag == .windows)
50 exe.root_module.linkSystemLibrary("ws2_32", .{});
51
52 const run = b.addRunArtifact(exe);49 const run = b.addRunArtifact(exe);
53 run.expectExitCode(0);50 run.expectExitCode(0);
54 run.skip_foreign_checks = true;51 run.skip_foreign_checks = true;
test/standalone/issue_5825/build.zig-1
...@@ -34,7 +34,6 @@ pub fn build(b: *std.Build) void {...@@ -34,7 +34,6 @@ pub fn build(b: *std.Build) void {
34 exe.subsystem = .console;34 exe.subsystem = .console;
35 exe.root_module.linkSystemLibrary("kernel32", .{});35 exe.root_module.linkSystemLibrary("kernel32", .{});
36 exe.root_module.linkSystemLibrary("ntdll", .{});36 exe.root_module.linkSystemLibrary("ntdll", .{});
37 exe.root_module.linkSystemLibrary("ws2_32", .{});
38 exe.root_module.addObject(obj);37 exe.root_module.addObject(obj);
3938
40 // TODO: actually check the output39 // TODO: actually check the output
test/standalone/mix_o_files/build.zig-3
...@@ -16,9 +16,6 @@ pub fn build(b: *std.Build) void {...@@ -16,9 +16,6 @@ pub fn build(b: *std.Build) void {
16 }),16 }),
17 });17 });
1818
19 if (target.result.os.tag == .windows)
20 obj.root_module.linkSystemLibrary("ws2_32", .{});
21
22 const exe = b.addExecutable(.{19 const exe = b.addExecutable(.{
23 .name = "test",20 .name = "test",
24 .root_module = b.createModule(.{21 .root_module = b.createModule(.{
test/standalone/shared_library/build.zig-3
...@@ -24,9 +24,6 @@ pub fn build(b: *std.Build) void {...@@ -24,9 +24,6 @@ pub fn build(b: *std.Build) void {
24 }),24 }),
25 });25 });
2626
27 if (target.result.os.tag == .windows)
28 lib.root_module.linkSystemLibrary("ws2_32", .{});
29
30 const exe = b.addExecutable(.{27 const exe = b.addExecutable(.{
31 .name = exe_name,28 .name = exe_name,
32 .root_module = b.createModule(.{29 .root_module = b.createModule(.{
test/standalone/test_obj_link_run/build.zig-1
...@@ -11,7 +11,6 @@ pub fn build(b: *std.Build) void {...@@ -11,7 +11,6 @@ pub fn build(b: *std.Build) void {
11 if (is_windows) {11 if (is_windows) {
12 test_obj.root_module.linkSystemLibrary("ntdll", .{});12 test_obj.root_module.linkSystemLibrary("ntdll", .{});
13 test_obj.root_module.linkSystemLibrary("kernel32", .{});13 test_obj.root_module.linkSystemLibrary("kernel32", .{});
14 test_obj.root_module.linkSystemLibrary("ws2_32", .{});
15 }14 }
1615
17 const test_exe_mod = b.createModule(.{16 const test_exe_mod = b.createModule(.{
test/standalone/windows_argv/build.zig-2
...@@ -20,7 +20,6 @@ pub fn build(b: *std.Build) !void {...@@ -20,7 +20,6 @@ pub fn build(b: *std.Build) !void {
20 .optimize = optimize,20 .optimize = optimize,
21 }),21 }),
22 });22 });
23 lib_gnu.root_module.linkSystemLibrary("ws2_32", .{});
2423
25 const verify_gnu = b.addExecutable(.{24 const verify_gnu = b.addExecutable(.{
26 .name = "verify-gnu",25 .name = "verify-gnu",
...@@ -103,7 +102,6 @@ pub fn build(b: *std.Build) !void {...@@ -103,7 +102,6 @@ pub fn build(b: *std.Build) !void {
103 .flags = &.{ "-DUNICODE", "-D_UNICODE" },102 .flags = &.{ "-DUNICODE", "-D_UNICODE" },
104 });103 });
105 verify_msvc.root_module.linkLibrary(lib_msvc);104 verify_msvc.root_module.linkLibrary(lib_msvc);
106 verify_msvc.root_module.linkSystemLibrary("ws2_32", .{});
107 verify_msvc.root_module.link_libc = true;105 verify_msvc.root_module.link_libc = true;
108106
109 const run_msvc = b.addRunArtifact(fuzz);107 const run_msvc = b.addRunArtifact(fuzz);
test/tests.zig-1
...@@ -2587,7 +2587,6 @@ fn addOneModuleTest(...@@ -2587,7 +2587,6 @@ fn addOneModuleTest(
2587 compile_c.linkSystemLibrary("advapi32", .{});2587 compile_c.linkSystemLibrary("advapi32", .{});
2588 }2588 }
2589 compile_c.linkSystemLibrary("crypt32", .{});2589 compile_c.linkSystemLibrary("crypt32", .{});
2590 compile_c.linkSystemLibrary("ws2_32", .{});
2591 compile_c.linkSystemLibrary("ole32", .{});2590 compile_c.linkSystemLibrary("ole32", .{});
2592 }2591 }
2593 }2592 }
tools/incr-check.zig-4
...@@ -148,7 +148,6 @@ pub fn main(init: std.process.Init) !void {...@@ -148,7 +148,6 @@ pub fn main(init: std.process.Init) !void {
148 "--global-cache-dir",148 "--global-cache-dir",
149 ".global-cache",149 ".global-cache",
150 });150 });
151 if (target.resolved.os.tag == .windows) try child_args.append(arena, "-lws2_32");
152 try child_args.append(arena, "--listen=-");151 try child_args.append(arena, "--listen=-");
153152
154 if (opt_resolved_lib_dir) |resolved_lib_dir| {153 if (opt_resolved_lib_dir) |resolved_lib_dir| {
...@@ -190,9 +189,6 @@ pub fn main(init: std.process.Init) !void {...@@ -190,9 +189,6 @@ pub fn main(init: std.process.Init) !void {
190 opt_resolved_lib_dir.?, // verified earlier189 opt_resolved_lib_dir.?, // verified earlier
191 });190 });
192191
193 if (target.resolved.os.tag == .windows)
194 try cc_child_args.append(arena, "-lws2_32");
195
196 try cc_child_args.append(arena, "-o");192 try cc_child_args.append(arena, "-o");
197 }193 }
198194