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\
8585CheckLastExitCode
8686
8787Write-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.lib
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
8989CheckLastExitCode
9090
9191.\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\
104104CheckLastExitCode
105105
106106Write-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.lib
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
108108CheckLastExitCode
109109
110110.\behavior-x86_64-windows-msvc
lib/std/Build/Watch.zig+2-2
......@@ -354,7 +354,7 @@ const Os = switch (builtin.os.tag) {
354354 }
355355 }
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 {
358358 const w: *Watch = @ptrCast(@alignCast(apc_context));
359359 const dir: *Directory = @fieldParentPtr("iosb", iosb);
360360 assert(iosb.u.Status != .PENDING);
......@@ -369,7 +369,7 @@ const Os = switch (builtin.os.tag) {
369369 var dir_handle: windows.HANDLE = undefined;
370370 const root_fd = path.root_dir.handle.handle;
371371 const sub_path = path.subPathOrDot();
372 const sub_path_w = try Io.Threaded.sliceToPrefixedFileW(root_fd, sub_path); // TODO eliminate this call
372 const sub_path_w = try Io.Threaded.sliceToPrefixedFileW(root_fd, sub_path, .{}); // TODO eliminate this call
373373 var iosb: windows.IO_STATUS_BLOCK = undefined;
374374 switch (windows.ntdll.NtCreateFile(
375375 &dir_handle,
lib/std/Io.zig+3-3
......@@ -235,10 +235,10 @@ pub const VTable = struct {
235235 random: *const fn (?*anyopaque, buffer: []u8) void,
236236 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,
239 netAccept: *const fn (?*anyopaque, server: net.Socket.Handle) net.Server.AcceptError!net.Stream,
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, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket,
240240 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,
242242 netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle,
243243 netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle,
244244 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 {
47844784
47854785fn netListenIpUnavailable(
47864786 userdata: ?*anyopaque,
4787 address: net.IpAddress,
4787 address: *const net.IpAddress,
47884788 options: net.IpAddress.ListenOptions,
4789) net.IpAddress.ListenError!net.Server {
4789) net.IpAddress.ListenError!net.Socket {
47904790 const ev: *Evented = @ptrCast(@alignCast(userdata));
47914791 _ = ev;
47924792 _ = address;
......@@ -4797,10 +4797,12 @@ fn netListenIpUnavailable(
47974797fn netAcceptUnavailable(
47984798 userdata: ?*anyopaque,
47994799 listen_handle: net.Socket.Handle,
4800) net.Server.AcceptError!net.Stream {
4800 options: net.Server.AcceptOptions,
4801) net.Server.AcceptError!net.Socket {
48014802 const ev: *Evented = @ptrCast(@alignCast(userdata));
48024803 _ = ev;
48034804 _ = listen_handle;
4805 _ = options;
48044806 return error.NetworkDown;
48054807}
48064808
......@@ -4820,7 +4822,7 @@ fn netConnectIpUnavailable(
48204822 userdata: ?*anyopaque,
48214823 address: *const net.IpAddress,
48224824 options: net.IpAddress.ConnectOptions,
4823) net.IpAddress.ConnectError!net.Stream {
4825) net.IpAddress.ConnectError!net.Socket {
48244826 const ev: *Evented = @ptrCast(@alignCast(userdata));
48254827 _ = ev;
48264828 _ = address;
lib/std/Io/Kqueue.zig+9-14
......@@ -13,6 +13,7 @@ const IpAddress = std.Io.net.IpAddress;
1313const errnoBug = std.Io.Threaded.errnoBug;
1414const closeFd = std.Io.Threaded.closeFd;
1515const posix = std.posix;
16const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;
1617
1718/// Must be a thread-safe allocator.
1819gpa: Allocator,
......@@ -1000,19 +1001,20 @@ fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
10001001
10011002fn netListenIp(
10021003 userdata: ?*anyopaque,
1003 address: net.IpAddress,
1004 address: *const net.IpAddress,
10041005 options: net.IpAddress.ListenOptions,
1005) net.IpAddress.ListenError!net.Server {
1006) net.IpAddress.ListenError!net.Socket {
10061007 const k: *Kqueue = @ptrCast(@alignCast(userdata));
10071008 _ = k;
10081009 _ = address;
10091010 _ = options;
10101011 @panic("TODO");
10111012}
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 {
10131014 const k: *Kqueue = @ptrCast(@alignCast(userdata));
10141015 _ = k;
10151016 _ = server;
1017 _ = options;
10161018 @panic("TODO");
10171019}
10181020fn netBindIp(
......@@ -1028,12 +1030,9 @@ fn netBindIp(
10281030 var addr_len = Io.Threaded.addressToPosix(address, &storage);
10291031 try posixBind(k, socket_fd, &storage.any, addr_len);
10301032 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);
1031 return .{
1032 .handle = socket_fd,
1033 .address = Io.Threaded.addressFromPosix(&storage),
1034 };
1033 return .{ .handle = socket_fd, .address = Io.Threaded.addressFromPosix(&storage) };
10351034}
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 {
10371036 if (options.timeout != .none) @panic("TODO");
10381037 const k: *Kqueue = @ptrCast(@alignCast(userdata));
10391038 const family = Io.Threaded.posixAddressFamily(address);
......@@ -1046,10 +1045,7 @@ fn netConnectIp(userdata: ?*anyopaque, address: *const net.IpAddress, options: n
10461045 var addr_len = Io.Threaded.addressToPosix(address, &storage);
10471046 try posixConnect(k, socket_fd, &storage.any, addr_len);
10481047 try posixGetSockName(k, socket_fd, &storage.any, &addr_len);
1049 return .{ .socket = .{
1050 .handle = socket_fd,
1051 .address = Io.Threaded.addressFromPosix(&storage),
1052 } };
1048 return .{ .handle = socket_fd, .address = Io.Threaded.addressFromPosix(&storage) };
10531049}
10541050
10551051fn posixConnect(k: *Kqueue, socket_fd: posix.socket_t, addr: *const posix.sockaddr, addr_len: posix.socklen_t) !void {
......@@ -1345,8 +1341,7 @@ fn openSocketPosix(
13451341 Unexpected,
13461342 Canceled,
13471343}!posix.socket_t {
1348 const mode = Io.Threaded.posixSocketMode(options.mode);
1349 const protocol = Io.Threaded.posixProtocol(options.protocol);
1344 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
13501345 const socket_fd = while (true) {
13511346 try k.checkCancel();
13521347 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
19971997
19981998pub fn writableVectorWsa(
19991999 r: *Reader,
2000 buffer: []std.os.windows.ws2_32.WSABUF,
2000 buffer: []std.os.windows.AFD.WSABUF(.@"var"),
20012001 data: []const []u8,
20022002) Error!struct { usize, usize } {
20032003 var i: usize = 0;
lib/std/Io/Threaded.zig+974-1213
......@@ -11,8 +11,8 @@ const Io = std.Io;
1111const net = std.Io.net;
1212const File = std.Io.File;
1313const Dir = std.Io.Dir;
14const HostName = std.Io.net.HostName;
15const IpAddress = std.Io.net.IpAddress;
14const HostName = net.HostName;
15const IpAddress = net.IpAddress;
1616const process = std.process;
1717const Allocator = std.mem.Allocator;
1818const Alignment = std.mem.Alignment;
......@@ -47,8 +47,6 @@ busy_count: usize = 0,
4747worker_threads: std.atomic.Value(?*Thread),
4848pid: Pid = .unknown,
4949
50wsa: if (is_windows) Wsa else struct {} = .{},
51
5250have_signal_handler: bool,
5351old_sig_io: if (have_sig_io) posix.Sigaction else void,
5452old_sig_pipe: if (have_sig_pipe) posix.Sigaction else void,
......@@ -77,6 +75,8 @@ argv0: Argv0,
7775environ_initialized: bool,
7876environ: Environ,
7977
78dl: Dl = .init,
79
8080null_file: NullFile = .{},
8181random_file: RandomFile = .{},
8282pipe_file: PipeFile = .{},
......@@ -90,6 +90,67 @@ const SystemBasicInformation = if (!is_windows) struct {} else struct {
9090 initialized: std.atomic.Value(bool) = .{ .raw = false },
9191};
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
93154pub const Csprng = struct {
94155 rng: std.Random.DefaultCsprng,
95156
......@@ -375,6 +436,17 @@ pub const UseFchmodat2 = if (have_fchmodat2 and !have_fchmodat_flags) enum {
375436 pub const default: UseFchmodat2 = .disabled;
376437};
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
378450const Runnable = struct {
379451 node: std.SinglyLinkedList.Node,
380452 startFn: *const fn (*Runnable, *Thread, *Threaded) void,
......@@ -1496,18 +1568,6 @@ const AlertableSyscall = struct {
14961568 s.finish();
14971569 return windows.unexpectedStatus(status);
14981570 }
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 }
15111571};
15121572
15131573pub fn waitForApcOrAlert() void {
......@@ -1667,13 +1727,11 @@ pub fn setAsyncLimit(t: *Threaded, new_limit: Io.Limit) void {
16671727
16681728pub fn deinit(t: *Threaded) void {
16691729 t.join();
1670 if (is_windows and t.wsa.status == .initialized) {
1671 if (ws2_32.WSACleanup() != 0) recoverableOsBugDetected();
1672 }
16731730 if (posix.Sigaction != void and t.have_signal_handler) {
16741731 if (have_sig_io) posix.sigaction(.IO, &t.old_sig_io, null);
16751732 if (have_sig_pipe) posix.sigaction(.PIPE, &t.old_sig_pipe, null);
16761733 }
1734 t.dl.deinit();
16771735 t.null_file.deinit();
16781736 t.random_file.deinit();
16791737 t.pipe_file.deinit();
......@@ -1717,6 +1775,7 @@ fn worker(t: *Threaded) void {
17171775 .SPECIFIC = .{
17181776 .THREAD = .{
17191777 .TERMINATE = true, // for `NtCancelSynchronousIoFile`
1778 .ALERT = true, // for `NtAlertThread`
17201779 },
17211780 },
17221781 },
......@@ -2914,7 +2973,7 @@ fn batchApc(
29142973 apc_context: ?*anyopaque,
29152974 iosb: *windows.IO_STATUS_BLOCK,
29162975 _: windows.ULONG,
2917) callconv(.winapi) void {
2976) align(apc_align) callconv(.winapi) void {
29182977 const b: *Io.Batch = @ptrCast(@alignCast(apc_context));
29192978 const operation_userdata: *WindowsBatchOperationUserdata = @fieldParentPtr("iosb", iosb);
29202979 const erased_userdata = operation_userdata.toErased();
......@@ -3278,7 +3337,7 @@ fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, pe
32783337 _ = t;
32793338 _ = 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, .{});
32823341 const attr: windows.OBJECT.ATTRIBUTES = .{
32833342 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
32843343 .Attributes = .{ .INHERIT = false },
......@@ -3446,7 +3505,7 @@ fn dirCreateDirPathOpenWindows(
34463505 };
34473506
34483507 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, .{});
34503509 const attr: windows.OBJECT.ATTRIBUTES = .{
34513510 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
34523511 .ObjectName = @constCast(&sub_path_w.string()),
......@@ -4144,7 +4203,7 @@ fn dirAccessWindows(
41444203 _ = options; // TODO
41454204
41464205 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, .{});
41484207 const attr: windows.OBJECT.ATTRIBUTES = .{
41494208 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
41504209 .ObjectName = @constCast(&sub_path_w.string()),
......@@ -4353,7 +4412,7 @@ fn dirCreateFileWindows(
43534412 if (std.mem.eql(u8, sub_path, ".")) return error.IsDir;
43544413 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, .{});
43574416 const attr: windows.OBJECT.ATTRIBUTES = .{
43584417 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
43594418 .ObjectName = @constCast(&sub_path_w.string()),
......@@ -4943,7 +5002,7 @@ fn dirOpenFileWindows(
49435002) File.OpenError!File {
49445003 const t: *Threaded = @ptrCast(@alignCast(userdata));
49455004 _ = 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, .{});
49475006 const sub_path_w = sub_path_w_array.span();
49485007 const dir_handle = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w)) null else dir.handle;
49495008 return dirOpenFileWtf16(dir_handle, sub_path_w, flags);
......@@ -5197,7 +5256,7 @@ fn dirOpenDirPosix(
51975256 _ = t;
51985257
51995258 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, .{});
52015260 return dirOpenDirWindows(dir, sub_path_w.span(), options);
52025261 }
52035262
......@@ -6027,7 +6086,7 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8,
60276086 const t: *Threaded = @ptrCast(@alignCast(userdata));
60286087 _ = 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
60326091 const h_file = handle: {
60336092 if (OpenFile(path_name_w.span(), .{
......@@ -6182,6 +6241,7 @@ pub fn GetFinalPathNameByHandle(
61826241 .out = &output_buf,
61836242 })).u.Status) {
61846243 .SUCCESS => {},
6244 .CANCELLED => unreachable,
61856245 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
61866246 else => |status| return windows.unexpectedStatus(status),
61876247 }
......@@ -6241,6 +6301,7 @@ pub fn GetFinalPathNameByHandle(
62416301 .out = &vol_output_buf,
62426302 })).u.Status) {
62436303 .SUCCESS => {},
6304 .CANCELLED => unreachable,
62446305 .UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,
62456306 else => |status| return windows.unexpectedStatus(status),
62466307 }
......@@ -6383,6 +6444,10 @@ const Wtf16ToPrefixedFileWError = error{
63836444 FileNotFound,
63846445} || Dir.PathNameError || Io.Cancelable || Io.UnexpectedError;
63856446
6447const Wtf16ToPrefixedFileWOptions = struct {
6448 allow_relative: bool = true,
6449};
6450
63866451/// Converts the `path` to WTF16, null-terminated. If the path contains any
63876452/// namespace prefix, or is anything but a relative path (rooted, drive relative,
63886453/// etc) the result will have the NT-style prefix `\??\`.
......@@ -6394,7 +6459,7 @@ const Wtf16ToPrefixedFileWError = error{
63946459/// is non-null, or the CWD if it is null.
63956460/// - Special case device names like COM1, NUL, etc are not handled specially (TODO)
63966461/// - . 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 {
63986463 const nt_prefix = [_]u16{ '\\', '?', '?', '\\' };
63996464 if (windows.hasCommonNtPrefix(u16, path)) {
64006465 // 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
64096474 } else {
64106475 const path_type = Dir.path.getWin32PathType(u16, path);
64116476 var path_space: WindowsPathSpace = undefined;
6412 if (path_type == .local_device) {
6413 switch (getLocalDevicePathType(u16, path)) {
6414 .verbatim => {
6415 path_space.data[0..nt_prefix.len].* = nt_prefix;
6416 const len_after_prefix = path.len - nt_prefix.len;
6417 @memcpy(path_space.data[nt_prefix.len..][0..len_after_prefix], path[nt_prefix.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 };
6477 if (path_type == .local_device) switch (getLocalDevicePathType(u16, path)) {
6478 .verbatim => {
6479 path_space.data[0..nt_prefix.len].* = nt_prefix;
6480 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..]);
6482 path_space.len = path.len;
64616483 path_space.data[path_space.len] = 0;
64626484 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;
64646525 }
64656526 // We now know we are going to return an absolute NT path, so
64666527 // we can unconditionally prefix it with the NT prefix.
......@@ -6591,13 +6652,13 @@ pub const Wtf8ToPrefixedFileWError = Wtf16ToPrefixedFileWError;
65916652
65926653/// Same as `wToPrefixedFileW` but accepts a WTF-8 encoded path.
65936654/// 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 {
65956656 var temp_path: WindowsPathSpace = undefined;
65966657 temp_path.len = std.unicode.wtf8ToWtf16Le(&temp_path.data, path) catch |err| switch (err) {
65976658 error.InvalidWtf8 => return error.BadPathName,
65986659 };
65996660 temp_path.data[temp_path.len] = 0;
6600 return wToPrefixedFileW(dir, temp_path.span());
6661 return wToPrefixedFileW(dir, temp_path.span(), options);
66016662}
66026663
66036664pub const WindowsPathSpace = struct {
......@@ -7068,7 +7129,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov
70687129 // Can't remove the parent directory with an open handle.
70697130 return error.FileBusy;
70707131 }
7071 var sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path);
7132 var sub_path_w = try sliceToPrefixedFileW(dir.handle, sub_path, .{});
70727133 if (std.mem.eql(u8, sub_path, ".")) {
70737134 // Windows does not recognize this, but it does work with empty string.
70747135 sub_path_w.len = 0;
......@@ -7336,9 +7397,9 @@ fn dirRenameWindowsInner(
73367397 replace_if_exists: bool,
73377398) Dir.RenamePreserveError!void {
73387399 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, .{});
73407401 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, .{});
73427403 const new_path_w = new_path_w_buf.span();
73437404
73447405 const src_fd = src_fd: {
......@@ -7673,7 +7734,7 @@ fn dirSymLinkWindows(
76737734 std.mem.nativeToLittle(u16, '\\'),
76747735 );
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
76787739 const SYMLINK_DATA = extern struct {
76797740 ReparseTag: w.IO_REPARSE_TAG,
......@@ -7738,7 +7799,7 @@ fn dirSymLinkWindows(
77387799 break :target_path target_path_w.span(),
77397800 }
77407801 }
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(), .{});
77427803 // We do this after prefixing to ensure that drive-relative paths are treated as absolute
77437804 is_target_absolute = Dir.path.isAbsoluteWindowsWtf16(prefixed_target_path.span());
77447805 break :target_path prefixed_target_path.span();
......@@ -7770,6 +7831,8 @@ fn dirSymLinkWindows(
77707831 .in = buffer[0..buf_len],
77717832 })).u.Status) {
77727833 .SUCCESS => {},
7834 .CANCELLED => unreachable,
7835 .INSUFFICIENT_RESOURCES => return error.SystemResources,
77737836 .PRIVILEGE_NOT_HELD => return error.PermissionDenied,
77747837 .ACCESS_DENIED => return error.AccessDenied,
77757838 .INVALID_DEVICE_REQUEST => return error.FileSystem,
......@@ -7887,7 +7950,7 @@ fn dirReadLink(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []
78877950fn dirReadLinkWindows(dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
78887951 // This gets used once for `sub_path` and then reused again temporarily
78897952 // 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, .{});
78917954 const attr: windows.OBJECT.ATTRIBUTES = .{
78927955 .RootDirectory = if (Dir.path.isAbsoluteWindowsWtf16(sub_path_w.span())) null else dir.handle,
78937956 .ObjectName = @constCast(&sub_path_w.string()),
......@@ -8532,6 +8595,7 @@ fn isTty(file: File) Io.Cancelable!bool {
85328595 .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})),
85338596 })).u.Status) {
85348597 .SUCCESS => return true,
8598 .CANCELLED => unreachable,
85358599 .INVALID_HANDLE => return isCygwinPty(file),
85368600 else => return false,
85378601 }
......@@ -8618,6 +8682,7 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE
86188682 .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})),
86198683 })).u.Status) {
86208684 .SUCCESS => {},
8685 .CANCELLED => unreachable,
86218686 .INVALID_HANDLE => return if (!try isCygwinPty(file)) error.NotTerminalDevice,
86228687 else => return error.NotTerminalDevice,
86238688 }
......@@ -8644,6 +8709,7 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE
86448709 .in = @ptrCast(&set_console_mode.request(file, 0, .{}, 0, .{})),
86458710 })).u.Status) {
86468711 .SUCCESS => {},
8712 .CANCELLED => unreachable,
86478713 else => |status| return windows.unexpectedStatus(status),
86488714 }
86498715}
......@@ -8667,6 +8733,7 @@ fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool {
86678733 })).u.Status) {
86688734 .SUCCESS => if (get_console_mode.Data & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0)
86698735 return true,
8736 .CANCELLED => unreachable,
86708737 .INVALID_HANDLE => return isCygwinPty(file),
86718738 else => return false,
86728739 }
......@@ -9673,7 +9740,7 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingEr
96739740 return ntReadFileResult(&iosb);
96749741}
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 {
96779744 const flag: *bool = @ptrCast(userdata);
96789745 flag.* = true;
96799746}
......@@ -10157,7 +10224,7 @@ fn processExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) process.O
1015710224 // not the path that the symlink points to. However, because we are opening
1015810225 // the file, we can let the openFileW call follow the symlink for us.
1015910226 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, .{});
1016110228 return dirOpenFileWtf16(null, prefixed_path_w.span(), flags);
1016210229 },
1016310230 .driverkit,
......@@ -10364,6 +10431,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) process.Execut
1036410431 var path_name_w_buf = try wToPrefixedFileW(
1036510432 null,
1036610433 windows.peb().ProcessParameters.ImagePathName.sliceZ(),
10434 .{},
1036710435 );
1036810436
1036910437 const h_file = handle: {
......@@ -11177,22 +11245,6 @@ fn netWriteFile(
1117711245 @panic("TODO implement netWriteFile");
1117811246}
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
1119611248fn fileWriteFilePositional(
1119711249 userdata: ?*anyopaque,
1119811250 file: File,
......@@ -11635,27 +11687,24 @@ fn sleepNanosleep(t: *Threaded, timeout: Io.Timeout) Io.Cancelable!void {
1163511687
1163611688fn netListenIpPosix(
1163711689 userdata: ?*anyopaque,
11638 address: IpAddress,
11690 address: *const IpAddress,
1163911691 options: IpAddress.ListenOptions,
11640) IpAddress.ListenError!net.Server {
11692) IpAddress.ListenError!net.Socket {
1164111693 if (!have_networking) return error.NetworkDown;
1164211694 const t: *Threaded = @ptrCast(@alignCast(userdata));
1164311695 _ = t;
11644 const family = posixAddressFamily(&address);
11645 const socket_fd = try openSocketPosix(family, .{
11646 .mode = options.mode,
11647 .protocol = options.protocol,
11648 });
11696 const family = posixAddressFamily(address);
11697 const socket_fd = try openSocketPosix(family, .{ .mode = options.mode, .protocol = options.protocol });
1164911698 errdefer closeFd(socket_fd);
1165011699
1165111700 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);
1165311702 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);
1165511704 }
1165611705
1165711706 var storage: PosixAddress = undefined;
11658 var addr_len = addressToPosix(&address, &storage);
11707 var addr_len = addressToPosix(address, &storage);
1165911708 try posixBind(socket_fd, &storage.any, addr_len);
1166011709
1166111710 const syscall: Syscall = try .start();
......@@ -11676,112 +11725,37 @@ fn netListenIpPosix(
1167611725 }
1167711726
1167811727 try posixGetSockName(socket_fd, &storage.any, &addr_len);
11679 return .{
11680 .socket = .{
11681 .handle = socket_fd,
11682 .address = addressFromPosix(&storage),
11683 },
11684 };
11728 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
1168511729}
1168611730
1168711731fn netListenIpWindows(
1168811732 userdata: ?*anyopaque,
11689 address: IpAddress,
11733 address: *const IpAddress,
1169011734 options: IpAddress.ListenOptions,
11691) IpAddress.ListenError!net.Server {
11735) IpAddress.ListenError!net.Socket {
1169211736 if (!have_networking) return error.NetworkDown;
1169311737 const t: *Threaded = @ptrCast(@alignCast(userdata));
11694 const family = posixAddressFamily(&address);
11695 const socket_handle = try openSocketWsa(t, family, .{
11696 .mode = options.mode,
11697 .protocol = options.protocol,
11698 });
11699 errdefer closeSocketWindows(socket_handle);
11700
11701 if (options.reuse_address)
11702 try setSocketOptionWsa(t, socket_handle, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);
11703
11704 var storage: WsaAddress = undefined;
11705 var addr_len = addressToWsa(&address, &storage);
11706
11707 var syscall: AlertableSyscall = try .start();
11708 while (true) {
11709 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
11710 if (rc != ws2_32.SOCKET_ERROR) {
11711 syscall.finish();
11712 break;
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 }
11738 _ = t;
11739 const family = posixAddressFamily(address);
11740 const socket_handle = try openSocketAfd(family, .{ .mode = options.mode, .protocol = options.protocol });
11741 errdefer windows.CloseHandle(socket_handle);
11742 if (options.reuse_address) try setSocketOptionAfd(socket_handle, ws2_32.SOL.SOCKET, ws2_32.SO.REUSEADDR, true);
11743 const bound_address = try bindSocketIpAfd(socket_handle, address, .Passive);
11744 switch ((try deviceIoControl(&.{
11745 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
11746 .code = windows.IOCTL.AFD.START_LISTEN,
11747 .in = @ptrCast(&windows.AFD.LISTEN_INFO{
11748 .UseSAN = windows.FALSE,
11749 .MaximumConnectionQueue = options.kernel_backlog,
11750 .UseDelayedAcceptance = windows.FALSE,
11751 }),
11752 })).u.Status) {
11753 .SUCCESS => {},
11754 .CANCELLED => unreachable,
11755 .INSUFFICIENT_RESOURCES => return error.SystemResources,
11756 else => |status| return windows.unexpectedStatus(status),
1176411757 }
11765
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;
11758 return .{ .handle = socket_handle, .address = bound_address };
1178511759}
1178611760
1178711761fn netListenUnixPosix(
......@@ -11833,85 +11807,40 @@ fn netListenUnixWindows(
1183311807 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
1183411808 if (!have_networking) return error.NetworkDown;
1183511809 const t: *Threaded = @ptrCast(@alignCast(userdata));
11836
11837 const socket_handle = openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
11810 _ = t;
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) {
1183811819 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
1183911820 else => |e| return e,
1184011821 };
11841 errdefer closeSocketWindows(socket_handle);
11842
11843 var storage: WsaAddress = undefined;
11844 const addr_len = addressUnixToWsa(address, &storage);
11845
11846 var syscall: AlertableSyscall = try .start();
11847 while (true) {
11848 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
11849 if (rc != ws2_32.SOCKET_ERROR) {
11850 syscall.finish();
11851 break;
11852 }
11853 switch (ws2_32.WSAGetLastError()) {
11854 .NOTINITIALISED => {
11855 syscall.finish();
11856 try initializeWsa(t);
11857 syscall = try .start();
11858 continue;
11859 },
11860 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
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 }
11822 errdefer windows.CloseHandle(socket_handle);
11823 if (!is_abstract) try socketOptionAfd(socket_handle, .special, 0, ws2_32.SO.UNIX_PATH, @constCast(
11824 @as([]const u8, @ptrCast(&windows.AFD.SOCKOPT_INFO.UNIX_PATH{
11825 .Path = wps.data,
11826 }))[0 .. @offsetOf(windows.AFD.SOCKOPT_INFO.UNIX_PATH, "Path") + @sizeOf(windows.WCHAR) * wps.len],
11827 ));
11828 try bindSocketUnixAfd(socket_handle, address);
11829 switch ((try deviceIoControl(&.{
11830 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
11831 .code = windows.IOCTL.AFD.START_LISTEN,
11832 .in = @ptrCast(&windows.AFD.LISTEN_INFO{
11833 .UseSAN = windows.FALSE,
11834 .MaximumConnectionQueue = options.kernel_backlog,
11835 .UseDelayedAcceptance = windows.FALSE,
11836 }),
11837 })).u.Status) {
11838 .SUCCESS => {},
11839 .CANCELLED => unreachable,
11840 .INSUFFICIENT_RESOURCES => return error.SystemResources,
11841 else => |status| return windows.unexpectedStatus(status),
1190311842 }
11904}
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;
11843 return socket_handle;
1191511844}
1191611845
1191711846fn posixBindUnix(
......@@ -12103,40 +12032,7 @@ fn posixGetSockName(
1210312032 }
1210412033}
1210512034
12106fn wsaGetSockName(
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 {
12035fn setSocketOptionPosix(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {
1214012036 const o: []const u8 = @ptrCast(&option);
1214112037 const syscall: Syscall = try .start();
1214212038 while (true) {
......@@ -12163,32 +12059,26 @@ fn setSocketOption(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void
1216312059 }
1216412060}
1216512061
12166fn setSocketOptionWsa(t: *Threaded, socket: Io.net.Socket.Handle, level: i32, opt_name: u32, option: u32) !void {
12167 const o: []const u8 = @ptrCast(&option);
12168 var syscall: AlertableSyscall = try .start();
12169 while (true) {
12170 const rc = ws2_32.setsockopt(socket, level, @bitCast(opt_name), o.ptr, @intCast(o.len));
12171 if (rc != ws2_32.SOCKET_ERROR) {
12172 syscall.finish();
12173 return;
12174 }
12175 switch (ws2_32.WSAGetLastError()) {
12176 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12177 try syscall.checkCancel();
12178 continue;
12179 },
12180 .NOTINITIALISED => {
12181 syscall.finish();
12182 try initializeWsa(t);
12183 syscall = try .start();
12184 continue;
12185 },
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 }
12062fn setSocketOptionAfd(socket: net.Socket.Handle, level: i32, opt_name: u32, opt_val: anytype) !void {
12063 try socketOptionAfd(socket, .set, level, opt_name, @ptrCast(@constCast(&opt_val)));
12064}
12065
12066fn socketOptionAfd(socket: net.Socket.Handle, mode: windows.AFD.SOCKOPT_INFO.Mode, level: i32, opt_name: u32, opt_val: []u8) !void {
12067 switch ((try deviceIoControl(&.{
12068 .file = .{ .handle = socket, .flags = .{ .nonblocking = true } },
12069 .code = windows.IOCTL.AFD.SOCKOPT,
12070 .in = @ptrCast(&windows.AFD.SOCKOPT_INFO{
12071 .mode = mode,
12072 .level = level,
12073 .optname = opt_name,
12074 .optval = opt_val.ptr,
12075 .optlen = opt_val.len,
12076 }),
12077 })).u.Status) {
12078 .SUCCESS => return,
12079 .CANCELLED => unreachable,
12080 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12081 else => |status| return windows.unexpectedStatus(status),
1219212082 }
1219312083}
1219412084
......@@ -12196,98 +12086,55 @@ fn netConnectIpPosix(
1219612086 userdata: ?*anyopaque,
1219712087 address: *const IpAddress,
1219812088 options: IpAddress.ConnectOptions,
12199) IpAddress.ConnectError!net.Stream {
12089) IpAddress.ConnectError!net.Socket {
1220012090 if (!have_networking) return error.NetworkDown;
1220112091 if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");
1220212092 const t: *Threaded = @ptrCast(@alignCast(userdata));
1220312093 _ = t;
1220412094 const family = posixAddressFamily(address);
12205 const socket_fd = try openSocketPosix(family, .{
12206 .mode = options.mode,
12207 .protocol = options.protocol,
12208 });
12095 const socket_fd = try openSocketPosix(family, .{ .mode = options.mode, .protocol = options.protocol });
1220912096 errdefer closeFd(socket_fd);
1221012097 var storage: PosixAddress = undefined;
1221112098 var addr_len = addressToPosix(address, &storage);
1221212099 try posixConnect(socket_fd, &storage.any, addr_len);
1221312100 try posixGetSockName(socket_fd, &storage.any, &addr_len);
12214 return .{ .socket = .{
12215 .handle = socket_fd,
12216 .address = addressFromPosix(&storage),
12217 } };
12101 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
1221812102}
1221912103
1222012104fn netConnectIpWindows(
1222112105 userdata: ?*anyopaque,
1222212106 address: *const IpAddress,
1222312107 options: IpAddress.ConnectOptions,
12224) IpAddress.ConnectError!net.Stream {
12108) IpAddress.ConnectError!net.Socket {
1222512109 if (!have_networking) return error.NetworkDown;
1222612110 if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");
1222712111 const t: *Threaded = @ptrCast(@alignCast(userdata));
12112 _ = t;
1222812113 const family = posixAddressFamily(address);
12229 const socket_handle = try openSocketWsa(t, family, .{
12230 .mode = options.mode,
12231 .protocol = options.protocol,
12232 });
12233 errdefer closeSocketWindows(socket_handle);
12234
12235 var storage: WsaAddress = undefined;
12236 var addr_len = addressToWsa(address, &storage);
12237
12238 var syscall: AlertableSyscall = try .start();
12239 while (true) {
12240 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);
12241 if (rc != ws2_32.SOCKET_ERROR) {
12242 syscall.finish();
12243 break;
12244 }
12245 switch (ws2_32.WSAGetLastError()) {
12246 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12247 try syscall.checkCancel();
12248 continue;
12249 },
12250 .NOTINITIALISED => {
12251 syscall.finish();
12252 try initializeWsa(t);
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;
12114 const socket_handle = try openSocketAfd(family, .{ .mode = options.mode, .protocol = options.protocol });
12115 errdefer windows.CloseHandle(socket_handle);
12116 try setSocketOptionAfd(socket_handle, ws2_32.SOL.SOCKET, ws2_32.SO.REUSE_UNICASTPORT, true);
12117 const bound_address = bindSocketIpAfd(socket_handle, &switch (address.*) {
12118 .ip4 => .{ .ip4 = .unspecified(0) },
12119 .ip6 => .{ .ip6 = .unspecified(0) },
12120 }, .Active) catch |err| switch (err) {
12121 error.AddressInUse => return error.Unexpected,
12122 else => |e| return e,
12123 };
12124 const Storage = extern struct { Reserved0: [3]usize = @splat(0), Address: PosixAddress };
12125 var storage: Storage = .{ .Address = undefined };
12126 const addr_len = addressToPosix(address, &storage.Address);
12127 switch ((try deviceIoControl(&.{
12128 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12129 .code = windows.IOCTL.AFD.CONNECT,
12130 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12131 })).u.Status) {
12132 .SUCCESS => {},
12133 .CANCELLED => unreachable,
12134 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12135 else => |status| return windows.unexpectedStatus(status),
12136 }
12137 return .{ .handle = socket_handle, .address = bound_address };
1229112138}
1229212139
1229312140fn netConnectUnixPosix(
......@@ -12298,6 +12145,7 @@ fn netConnectUnixPosix(
1229812145 const t: *Threaded = @ptrCast(@alignCast(userdata));
1229912146 _ = t;
1230012147 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
12148 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
1230112149 error.OptionUnsupported => return error.Unexpected,
1230212150 else => |e| return e,
1230312151 };
......@@ -12315,54 +12163,45 @@ fn netConnectUnixWindows(
1231512163 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
1231612164 if (!have_networking) return error.NetworkDown;
1231712165 const t: *Threaded = @ptrCast(@alignCast(userdata));
12318
12319 const socket_handle = try openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream });
12320 errdefer closeSocketWindows(socket_handle);
12321 var storage: WsaAddress = undefined;
12322 const addr_len = addressUnixToWsa(address, &storage);
12323
12324 var syscall: AlertableSyscall = try .start();
12325 while (true) {
12326 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);
12327 if (rc != ws2_32.SOCKET_ERROR) {
12328 syscall.finish();
12329 break;
12330 }
12331 switch (ws2_32.WSAGetLastError()) {
12332 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12333 try syscall.checkCancel();
12334 continue;
12335 },
12336 .NOTINITIALISED => {
12337 syscall.finish();
12338 try initializeWsa(t);
12339 syscall = try .start();
12340 continue;
12341 },
12342 .ECONNREFUSED => return syscall.fail(error.FileNotFound),
12343 .EWOULDBLOCK => return syscall.fail(error.WouldBlock),
12344 .EACCES => return syscall.fail(error.AccessDenied),
12345 .ENOBUFS => return syscall.fail(error.SystemResources),
12346 .EAFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported),
12347 .EFAULT => |err| return syscall.wsaErrorBug(err),
12348 .EINVAL => |err| return syscall.wsaErrorBug(err),
12349 .EISCONN => |err| return syscall.wsaErrorBug(err),
12350 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
12351 else => |err| return syscall.unexpectedWsaError(err),
12352 }
12353 }
12354
12355 return socket_handle;
12356}
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}
12166 _ = t;
12167 const is_abstract = address.isAbstract();
12168 const wps = if (!is_abstract) sliceToPrefixedFileW(null, address.path, .{
12169 .allow_relative = false,
12170 }) catch |err| switch (err) {
12171 error.NameTooLong, error.BadPathName => return error.FileNotFound,
12172 else => |e| return e,
12173 } else undefined;
12174 const socket_handle = openSocketAfd(ws2_32.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
12175 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
12176 else => |e| return e,
12177 };
12178 errdefer windows.CloseHandle(socket_handle);
12179 if (!is_abstract) try socketOptionAfd(socket_handle, .special, 0, ws2_32.SO.UNIX_PATH, @constCast(
12180 @as([]const u8, @ptrCast(&windows.AFD.SOCKOPT_INFO.UNIX_PATH{
12181 .Path = wps.data,
12182 }))[0 .. @offsetOf(windows.AFD.SOCKOPT_INFO.UNIX_PATH, "Path") + @sizeOf(windows.WCHAR) * wps.len],
12183 ));
12184 bindSocketUnixAfd(socket_handle, &(net.UnixAddress.init("") catch |err| switch (err) {
12185 error.NameTooLong => unreachable,
12186 })) catch |err| switch (err) {
12187 error.AddressInUse => return error.Unexpected,
12188 else => |e| return e,
12189 };
12190 const Storage = extern struct { Reserved0: [3]usize = @splat(0), Address: UnixAddress };
12191 var storage: Storage = .{ .Address = undefined };
12192 const addr_len = addressUnixToPosix(address, &storage.Address);
12193 switch ((try deviceIoControl(&.{
12194 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12195 .code = windows.IOCTL.AFD.CONNECT,
12196 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12197 })).u.Status) {
12198 .SUCCESS => {},
12199 .CANCELLED => unreachable,
12200 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12201 else => |status| return windows.unexpectedStatus(status),
12202 }
12203 return socket_handle;
12204}
1236612205
1236712206fn netBindIpPosix(
1236812207 userdata: ?*anyopaque,
......@@ -12379,10 +12218,7 @@ fn netBindIpPosix(
1237912218 var addr_len = addressToPosix(address, &storage);
1238012219 try posixBind(socket_fd, &storage.any, addr_len);
1238112220 try posixGetSockName(socket_fd, &storage.any, &addr_len);
12382 return .{
12383 .handle = socket_fd,
12384 .address = addressFromPosix(&storage),
12385 };
12221 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
1238612222}
1238712223
1238812224fn netBindIpWindows(
......@@ -12392,62 +12228,12 @@ fn netBindIpWindows(
1239212228) IpAddress.BindError!net.Socket {
1239312229 if (!have_networking) return error.NetworkDown;
1239412230 const t: *Threaded = @ptrCast(@alignCast(userdata));
12231 _ = t;
1239512232 const family = posixAddressFamily(address);
12396 const socket_handle = try openSocketWsa(t, family, .{
12397 .mode = options.mode,
12398 .protocol = options.protocol,
12399 });
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;
12233 const socket_handle = try openSocketAfd(family, options);
12234 errdefer windows.CloseHandle(socket_handle);
12235 const bound_address = try bindSocketIpAfd(socket_handle, address, .Active);
12236 return .{ .handle = socket_handle, .address = bound_address };
1245112237}
1245212238
1245312239fn openSocketPosix(
......@@ -12465,8 +12251,7 @@ fn openSocketPosix(
1246512251 Unexpected,
1246612252 Canceled,
1246712253}!posix.socket_t {
12468 const mode = posixSocketMode(options.mode);
12469 const protocol = posixProtocol(options.protocol);
12254 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
1247012255 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
1247112256 const syscall: Syscall = try .start();
1247212257 const socket_fd = while (true) {
......@@ -12498,7 +12283,7 @@ fn openSocketPosix(
1249812283
1249912284 if (options.ip6_only) {
1250012285 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);
1250212287 }
1250312288
1250412289 return socket_fd;
......@@ -12530,8 +12315,7 @@ fn netSocketCreatePair(
1253012315 .ip4 => posix.AF.INET,
1253112316 .ip6 => posix.AF.INET6,
1253212317 };
12533 const mode = posixSocketMode(options.mode);
12534 const protocol = posixProtocol(options.protocol);
12318 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
1253512319 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
1253612320
1253712321 var sockets: [2]posix.socket_t = undefined;
......@@ -12573,56 +12357,102 @@ fn netSocketCreatePair(
1257312357 };
1257412358}
1257512359
12576fn netSocketCreatePairUnavailable(
12577 userdata: ?*anyopaque,
12578 options: net.Socket.CreatePairOptions,
12579) net.Socket.CreatePairError![2]net.Socket {
12580 _ = userdata;
12581 _ = options;
12582 return error.OperationUnsupported;
12360fn openSocketAfd(family: ws2_32.ADDRESS_FAMILY, options: IpAddress.BindOptions) !net.Socket.Handle {
12361 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
12362 var handle: windows.HANDLE = undefined;
12363 var iosb: windows.IO_STATUS_BLOCK = undefined;
12364 var syscall: Syscall = try .start();
12365 while (true) switch (windows.ntdll.NtCreateFile(
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 };
1258312412}
1258412413
12585fn openSocketWsa(
12586 t: *Threaded,
12587 family: posix.sa_family_t,
12588 options: IpAddress.BindOptions,
12589) !ws2_32.SOCKET {
12590 const mode = posixSocketMode(options.mode);
12591 const protocol = posixProtocol(options.protocol);
12592 // WSA_FLAG_OVERLAPPED is chosen here because without this different
12593 // threads cannot use the same open socket handle.
12594 const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
12595 var syscall: AlertableSyscall = try .start();
12596 while (true) {
12597 const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);
12598 if (rc != ws2_32.INVALID_SOCKET) {
12599 syscall.finish();
12600 return rc;
12601 }
12602 switch (ws2_32.WSAGetLastError()) {
12603 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12604 try syscall.checkCancel();
12605 continue;
12606 },
12607 .NOTINITIALISED => {
12608 syscall.finish();
12609 try initializeWsa(t);
12610 syscall = try .start();
12611 continue;
12612 },
12613 .EAFNOSUPPORT => return syscall.fail(error.AddressFamilyUnsupported),
12614 .EMFILE => return syscall.fail(error.ProcessFdQuotaExceeded),
12615 .ENOBUFS => return syscall.fail(error.SystemResources),
12616 .EPROTONOSUPPORT => return syscall.fail(error.ProtocolUnsupportedByAddressFamily),
12617 else => |err| return syscall.unexpectedWsaError(err),
12618 }
12414fn bindSocketIpAfd(socket_handle: net.Socket.Handle, address: *const IpAddress, mode: windows.AFD.BIND_INFO.MODE) !IpAddress {
12415 const Storage = extern struct { Info: windows.AFD.BIND_INFO, Address: PosixAddress };
12416 var storage: Storage = .{ .Info = .{ .Mode = mode }, .Address = undefined };
12417 const addr_len = addressToPosix(address, &storage.Address);
12418 switch ((try deviceIoControl(&.{
12419 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12420 .code = windows.IOCTL.AFD.BIND,
12421 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12422 .out = @as([]u8, @ptrCast(&storage.Address))[0..addr_len],
12423 })).u.Status) {
12424 .SUCCESS => {},
12425 .CANCELLED => unreachable,
12426 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12427 .SHARING_VIOLATION => return error.AddressInUse,
12428 else => |status| return windows.unexpectedStatus(status),
12429 }
12430 return addressFromPosix(&storage.Address);
12431}
12432
12433fn bindSocketUnixAfd(socket_handle: net.Socket.Handle, address: *const net.UnixAddress) !void {
12434 const Storage = extern struct { Info: windows.AFD.BIND_INFO, Address: UnixAddress };
12435 var storage: Storage = .{ .Info = .{ .Mode = .Unix }, .Address = undefined };
12436 const addr_len = addressUnixToPosix(address, &storage.Address);
12437 switch ((try deviceIoControl(&.{
12438 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12439 .code = windows.IOCTL.AFD.BIND,
12440 .in = @as([]const u8, @ptrCast(&storage))[0 .. @offsetOf(Storage, "Address") + addr_len],
12441 .out = @ptrCast(&storage.Address),
12442 })).u.Status) {
12443 .SUCCESS => {},
12444 .CANCELLED => unreachable,
12445 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12446 .ADDRESS_ALREADY_EXISTS => return error.AddressInUse,
12447 else => |status| return windows.unexpectedStatus(status),
1261912448 }
1262012449}
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 {
1262312452 if (!have_networking) return error.NetworkDown;
1262412453 const t: *Threaded = @ptrCast(@alignCast(userdata));
1262512454 _ = t;
12455 options;
1262612456 var storage: PosixAddress = undefined;
1262712457 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
1262812458 const syscall: Syscall = try .start();
......@@ -12664,55 +12494,71 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
1266412494 },
1266512495 }
1266612496 };
12667 return .{ .socket = .{
12668 .handle = fd,
12669 .address = addressFromPosix(&storage),
12670 } };
12497 return .{ .handle = fd, .address = addressFromPosix(&storage) };
1267112498}
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 {
1267412501 if (!have_networking) return error.NetworkDown;
1267512502 const t: *Threaded = @ptrCast(@alignCast(userdata));
12676 var storage: WsaAddress = undefined;
12677 var addr_len: i32 = @sizeOf(WsaAddress);
12678 var syscall: AlertableSyscall = try .start();
12679 while (true) {
12680 const rc = ws2_32.accept(listen_handle, &storage.any, &addr_len);
12681 if (rc != ws2_32.INVALID_SOCKET) {
12682 syscall.finish();
12683 return .{ .socket = .{
12684 .handle = rc,
12685 .address = addressFromWsa(&storage),
12686 } };
12687 }
12688 switch (ws2_32.WSAGetLastError()) {
12689 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
12690 try syscall.checkCancel();
12691 continue;
12692 },
12693 .NOTINITIALISED => {
12694 syscall.finish();
12695 try initializeWsa(t);
12696 syscall = try .start();
12697 continue;
12698 },
12699 .ECONNRESET => return syscall.fail(error.ConnectionAborted),
12700 .EMFILE => return syscall.fail(error.ProcessFdQuotaExceeded),
12701 .ENETDOWN => return syscall.fail(error.NetworkDown),
12702 .ENOBUFS => return syscall.fail(error.SystemResources),
12703 .EFAULT => |err| return syscall.wsaErrorBug(err),
12704 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
12705 .EINVAL => |err| return syscall.wsaErrorBug(err),
12706 .EOPNOTSUPP => |err| return syscall.wsaErrorBug(err),
12707 else => |err| return syscall.unexpectedWsaError(err),
12708 }
12503 const Storage = extern struct {
12504 Info: windows.AFD.LISTEN_RESPONSE_INFO,
12505 RemoteAddress: extern union { posix: PosixAddress, unix: UnixAddress },
12506 };
12507 var storage: Storage = undefined;
12508 switch ((try deviceIoControl(&.{
12509 .file = .{ .handle = listen_handle, .flags = .{ .nonblocking = true } },
12510 .code = windows.IOCTL.AFD.WAIT_FOR_LISTEN,
12511 .out = @ptrCast(&storage),
12512 })).u.Status) {
12513 .SUCCESS => {},
12514 .CANCELLED => unreachable,
12515 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12516 else => |status| return windows.unexpectedStatus(status),
12517 }
12518 errdefer t.deferAcceptAfd(listen_handle, storage.Info);
12519 const accept_handle = openSocketAfd(
12520 storage.RemoteAddress.posix.any.family,
12521 .{ .mode = options.mode, .protocol = options.protocol },
12522 ) catch |err| switch (err) {
12523 error.AddressFamilyUnsupported => return error.Unexpected,
12524 error.ProtocolUnsupportedByAddressFamily => return error.Unexpected,
12525 else => |e| return e,
12526 };
12527 errdefer windows.CloseHandle(accept_handle);
12528 switch ((try deviceIoControl(&.{
12529 .file = .{ .handle = listen_handle, .flags = .{ .nonblocking = true } },
12530 .code = windows.IOCTL.AFD.ACCEPT,
12531 .in = @ptrCast(&windows.AFD.ACCEPT_INFO{
12532 .UseSAN = windows.FALSE,
12533 .Sequence = storage.Info.Sequence,
12534 .AcceptHandle = accept_handle,
12535 }),
12536 })).u.Status) {
12537 .SUCCESS => {},
12538 .CANCELLED => unreachable,
12539 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12540 else => |status| return windows.unexpectedStatus(status),
1270912541 }
12542 return .{ .handle = accept_handle, .address = addressFromPosix(&storage.RemoteAddress.posix) };
1271012543}
1271112544
12712fn netAcceptUnavailable(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {
12713 _ = userdata;
12714 _ = listen_handle;
12715 return error.NetworkDown;
12545fn deferAcceptAfd(t: *Threaded, listen_handle: net.Socket.Handle, info: windows.AFD.LISTEN_RESPONSE_INFO) void {
12546 const cancel_protection = swapCancelProtection(t, .blocked);
12547 defer _ = swapCancelProtection(t, cancel_protection);
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 }
1271612562}
1271712563
1271812564fn 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.
1279812644 }
1279912645}
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 {
1280212648 if (!have_networking) return error.NetworkDown;
1280312649 const t: *Threaded = @ptrCast(@alignCast(userdata));
12650 _ = t;
1280412651
12805 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;
12806 const bufs = b: {
12807 var i: usize = 0;
12808 var n: usize = 0;
12809 for (data) |buf| {
12810 if (iovec_buffer.len - i == 0) break;
12811 if (buf.len == 0) continue;
12812 if (std.math.cast(u32, buf.len)) |len| {
12813 iovec_buffer[i] = .{ .buf = buf.ptr, .len = len };
12814 i += 1;
12815 n += len;
12816 continue;
12817 }
12818 iovec_buffer[i] = .{ .buf = buf.ptr, .len = std.math.maxInt(u32) };
12819 i += 1;
12820 n += std.math.maxInt(u32);
12821 break;
12822 }
12823
12824 const bufs = iovec_buffer[0..i];
12825 assert(bufs[0].len != 0);
12826
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 }
12652 var iovecs: [max_iovecs_len]windows.AFD.WSABUF(.@"var") = undefined;
12653 var len: u32 = 0;
12654 for (data) |buf| {
12655 if (iovecs.len - len == 0) break;
12656 addAfdBuf(.@"var", &iovecs, &len, buf);
12657 }
12658
12659 const iosb = try deviceIoControl(&.{
12660 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12661 .code = windows.IOCTL.AFD.RECEIVE,
12662 .in = @ptrCast(&windows.AFD.RECV_INFO{
12663 .BufferArray = &iovecs,
12664 .BufferCount = len,
12665 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
12666 .TdiFlags = .{ .NORMAL = true },
12667 }),
12668 });
12669 switch (iosb.u.Status) {
12670 .SUCCESS => return iosb.Information,
12671 .CANCELLED => unreachable,
12672 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12673 else => |status| return windows.unexpectedStatus(status),
1286012674 }
1286112675}
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
1287012677fn netSendPosix(
1287112678 userdata: ?*anyopaque,
12872 handle: net.Socket.Handle,
12679 socket_handle: net.Socket.Handle,
1287312680 messages: []net.OutgoingMessage,
1287412681 flags: net.SendFlags,
1287512682) struct { ?net.Socket.SendError, usize } {
......@@ -12887,10 +12694,10 @@ fn netSendPosix(
1288712694 var i: usize = 0;
1288812695 while (messages.len - i != 0) {
1288912696 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 };
1289112698 continue;
1289212699 }
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 };
1289412701 i += 1;
1289512702 }
1289612703 return .{ null, i };
......@@ -12898,97 +12705,65 @@ fn netSendPosix(
1289812705
1289912706fn netSendWindows(
1290012707 userdata: ?*anyopaque,
12901 handle: net.Socket.Handle,
12708 socket_handle: net.Socket.Handle,
1290212709 messages: []net.OutgoingMessage,
1290312710 flags: net.SendFlags,
1290412711) struct { ?net.Socket.SendError, usize } {
1290512712 if (!have_networking) return .{ error.NetworkDown, 0 };
1290612713 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
1291312714 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 };
1291512716 }
1291612717 return .{ null, messages.len };
1291712718}
1291812719
12919fn netSendWindowsOne(
12720fn netSendOneWindows(
1292012721 t: *Threaded,
12921 handle: net.Socket.Handle,
12722 socket_handle: net.Socket.Handle,
1292212723 message: *net.OutgoingMessage,
12923 flags: u32,
12724 flags: net.SendFlags,
1292412725) net.Socket.SendError!void {
12925 var buf: ws2_32.WSABUF = .{
12926 .buf = @constCast(message.data_ptr),
12927 .len = std.math.cast(u32, message.data_len) orelse return error.MessageOversize,
12928 };
12929 var n: u32 = undefined;
12930 var address: WsaAddress = undefined;
12931 const address_size = addressToWsa(message.address, &address);
12932 var syscall: AlertableSyscall = try .start();
12933 while (true) {
12934 const rc = ws2_32.WSASendTo(
12935 handle,
12936 (&buf)[0..1],
12937 1,
12938 &n,
12939 flags,
12940 &address.any,
12941 address_size,
12942 null,
12943 null,
12944 );
12945 if (rc != ws2_32.SOCKET_ERROR) {
12946 syscall.finish();
12947 return;
12948 }
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;
12726 _ = t;
12727 _ = flags;
12728 const iovecs: [1]windows.AFD.WSABUF(.@"const") = .{.{
12729 .buf = message.data_ptr,
12730 .len = std.math.cast(std.os.windows.ULONG, message.data_len) orelse
12731 return error.MessageOversize,
12732 }};
12733 var storage: PosixAddress = undefined;
12734 const addr_len = addressToPosix(message.address, &storage);
12735 switch ((try deviceIoControl(&.{
12736 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12737 .code = windows.IOCTL.AFD.SEND_DATAGRAM,
12738 .in = @ptrCast(&windows.AFD.SEND_DATAGRAM_INFO{
12739 .BufferArray = &iovecs,
12740 .BufferCount = iovecs.len,
12741 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
12742 .TdiRequest = undefined,
12743 .TdiConnInfo = .{
12744 .UserDataLength = undefined,
12745 .UserData = undefined,
12746 .OptionsLength = undefined,
12747 .Options = undefined,
12748 .RemoteAddressLength = @bitCast(addr_len),
12749 .RemoteAddress = &storage,
1295912750 },
12960
12961 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
12962 .ENETDOWN => return syscall.fail(error.NetworkDown),
12963 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),
12964 .ENOTCONN => return syscall.fail(error.SocketUnconnected),
12965 .EFAULT => unreachable, // a pointer is not completely contained in user address space.
12966 .EINVAL => |err| return syscall.wsaErrorBug(err),
12967 .EMSGSIZE => |err| return syscall.wsaErrorBug(err),
12968 else => |err| return syscall.unexpectedWsaError(err),
12969 }
12751 }),
12752 })).u.Status) {
12753 .SUCCESS => return,
12754 .CANCELLED => unreachable,
12755 .INSUFFICIENT_RESOURCES => return error.SystemResources,
12756 else => |status| return windows.unexpectedStatus(status),
1297012757 }
1297112758}
1297212759
12973fn netSendUnavailable(
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(
12760fn netSendOnePosix(
1298712761 t: *Threaded,
12988 handle: net.Socket.Handle,
12762 socket_handle: net.Socket.Handle,
1298912763 message: *net.OutgoingMessage,
1299012764 flags: u32,
1299112765) net.Socket.SendError!void {
12766 _ = t;
1299212767 var addr: PosixAddress = undefined;
1299312768 var iovec: posix.iovec_const = .{ .base = @constCast(message.data_ptr), .len = message.data_len };
1299412769 const msg: posix.msghdr_const = .{
......@@ -13003,43 +12778,7 @@ fn netSendOne(
1300312778 };
1300412779 var syscall: if (is_windows) AlertableSyscall else Syscall = try .start();
1300512780 while (true) {
13006 const rc = posix.system.sendmsg(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 }
12781 const rc = posix.system.sendmsg(socket_handle, &msg, flags);
1304312782 switch (posix.errno(rc)) {
1304412783 .SUCCESS => {
1304512784 syscall.finish();
......@@ -13074,8 +12813,8 @@ fn netSendOne(
1307412813 }
1307512814}
1307612815
13077fn netSendMany(
13078 handle: net.Socket.Handle,
12816fn netSendManyPosix(
12817 socket_handle: net.Socket.Handle,
1307912818 messages: []net.OutgoingMessage,
1308012819 flags: u32,
1308112820) net.Socket.SendError!usize {
......@@ -13106,7 +12845,7 @@ fn netSendMany(
1310612845
1310712846 const syscall: Syscall = try .start();
1310812847 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);
1311012849 switch (posix.errno(rc)) {
1311112850 .SUCCESS => {
1311212851 syscall.finish();
......@@ -13231,11 +12970,12 @@ fn netReceiveWindows(
1323112970 data_buffer: []u8,
1323212971 flags: net.ReceiveFlags,
1323312972) 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 };
1323512975 return .{ null, 1 };
1323612976}
1323712977
13238fn netReceiveWindowsOne(
12978fn netReceiveOneWindows(
1323912979 t: *Threaded,
1324012980 socket_handle: net.Socket.Handle,
1324112981 message: *net.IncomingMessage,
......@@ -13243,69 +12983,49 @@ fn netReceiveWindowsOne(
1324312983 flags: net.ReceiveFlags,
1324412984) net.Socket.ReceiveError!void {
1324512985 if (!have_networking) return error.NetworkDown;
13246
13247 var windows_flags: u32 =
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 = .{
12986 _ = t;
12987 const iovecs: [1]windows.AFD.WSABUF(.@"var") = .{.{
1325312988 .buf = data_buffer.ptr,
13254 .len = std.math.cast(u32, data_buffer.len) orelse return error.MessageOversize,
13255 };
13256 var n: u32 = undefined;
13257 var from_storage: WsaAddress = undefined;
13258 var from_storage_len: i32 = @sizeOf(WsaAddress);
13259 var syscall: AlertableSyscall = try .start();
13260
13261 while (true) {
13262 const rc = ws2_32.WSARecvFrom(
13263 socket_handle,
13264 (&buf)[0..1],
13265 1,
13266 &n,
13267 &windows_flags,
13268 &from_storage.any,
13269 &from_storage_len,
13270 null,
13271 null,
13272 );
13273 if (rc != ws2_32.SOCKET_ERROR) {
13274 syscall.finish();
13275 message.* = .{
13276 .from = addressFromWsa(&from_storage),
13277 .data = data_buffer[0..n],
13278 .control = &.{},
13279 .flags = .{
13280 .eor = false,
13281 .trunc = (windows_flags & ws2_32.MSG.TRUNC) != 0,
13282 .ctrunc = (windows_flags & ws2_32.MSG.CTRUNC) != 0,
13283 .oob = false,
13284 .errqueue = false,
12989 .len = std.math.cast(std.os.windows.ULONG, data_buffer.len) orelse return error.MessageOversize,
12990 }};
12991 var storage: PosixAddress = undefined;
12992 var addr_len: windows.ULONG = @sizeOf(PosixAddress);
12993 const iosb = try deviceIoControl(&.{
12994 .file = .{ .handle = socket_handle, .flags = .{ .nonblocking = true } },
12995 .code = windows.IOCTL.AFD.RECEIVE_DATAGRAM,
12996 .in = @ptrCast(&windows.AFD.RECV_DATAGRAM_INFO{
12997 .BufferArray = &iovecs,
12998 .BufferCount = iovecs.len,
12999 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
13000 .TdiFlags = .{ .NORMAL = !flags.oob, .EXPEDITED = flags.oob, .PEEK = flags.peek },
13001 .Address = &storage,
13002 .AddressLength = &addr_len,
13003 }),
13004 });
13005 switch (iosb.u.Status) {
13006 .SUCCESS, .RECEIVE_PARTIAL => |status| message.* = .{
13007 .from = addressFromPosix(&storage),
13008 .data = data_buffer[0..iosb.Information],
13009 .control = &.{},
13010 .flags = .{
13011 .eor = false,
13012 .trunc = false,
13013 .ctrunc = false,
13014 .oob = switch (status) {
13015 else => unreachable,
13016 .SUCCESS, .RECEIVE_PARTIAL, .BUFFER_OVERFLOW => false,
13017 .RECEIVE_EXPEDITED, .RECEIVE_PARTIAL_EXPEDITED => true,
1328513018 },
13286 };
13287 return;
13288 }
13289 switch (ws2_32.WSAGetLastError()) {
13290 .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => {
13291 try syscall.checkCancel();
13292 continue;
13019 .errqueue = false,
1329313020 },
13294 .NOTINITIALISED => {
13295 syscall.finish();
13296 try initializeWsa(t);
13297 syscall = try .start();
13298 continue;
13299 },
13300 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
13301 .ENETDOWN => return syscall.fail(error.NetworkDown),
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 }
13021 },
13022 .RECEIVE_EXPEDITED,
13023 .RECEIVE_PARTIAL_EXPEDITED,
13024 .BUFFER_OVERFLOW,
13025 => |status| return windows.unexpectedStatus(status), // TdiFlags.PARTIAL = false
13026 .CANCELLED => unreachable,
13027 .INSUFFICIENT_RESOURCES => return error.SystemResources,
13028 else => |status| return windows.unexpectedStatus(status),
1330913029 }
1331013030}
1331113031
......@@ -13412,17 +13132,17 @@ fn netWriteWindows(
1341213132) net.Stream.Writer.Error!usize {
1341313133 if (!have_networking) return error.NetworkDown;
1341413134 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;
1341813138 var len: u32 = 0;
13419 addWsaBuf(&iovecs, &len, header);
13420 for (data[0 .. data.len - 1]) |bytes| addWsaBuf(&iovecs, &len, bytes);
13139 addAfdBuf(.@"const", &iovecs, &len, header);
13140 for (data[0 .. data.len - 1]) |bytes| addAfdBuf(.@"const", &iovecs, &len, bytes);
1342113141 const pattern = data[data.len - 1];
1342213142 var backup_buffer: [64]u8 = undefined;
1342313143 if (iovecs.len - len != 0) switch (splat) {
1342413144 0 => {},
13425 1 => addWsaBuf(&iovecs, &len, pattern),
13145 1 => addAfdBuf(.@"const", &iovecs, &len, pattern),
1342613146 else => switch (pattern.len) {
1342713147 0 => {},
1342813148 1 => {
......@@ -13430,87 +13150,63 @@ fn netWriteWindows(
1343013150 const memset_len = @min(splat_buffer.len, splat);
1343113151 const buf = splat_buffer[0..memset_len];
1343213152 @memset(buf, pattern[0]);
13433 addWsaBuf(&iovecs, &len, buf);
13434 var remaining_splat = splat - buf.len;
13435 while (remaining_splat > splat_buffer.len and len < iovecs.len) {
13436 addWsaBuf(&iovecs, &len, splat_buffer);
13437 remaining_splat -= splat_buffer.len;
13438 }
13439 addWsaBuf(&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;
13153 addAfdBuf(.@"const", &iovecs, &len, buf);
13154 var remaining_splat = splat - buf.len;
13155 while (remaining_splat > splat_buffer.len and len < iovecs.len) {
13156 addAfdBuf(.@"const", &iovecs, &len, splat_buffer);
13157 remaining_splat -= splat_buffer.len;
13158 }
13159 addAfdBuf(.@"const", &iovecs, &len, splat_buffer[0..@min(remaining_splat, splat_buffer.len)]);
1345913160 },
13460 .NOTINITIALISED => {
13461 syscall.finish();
13462 try initializeWsa(t);
13463 syscall = try .start();
13464 continue;
13161 else => for (0..@min(splat, iovecs.len - len)) |_| {
13162 addAfdBuf(.@"const", &iovecs, &len, pattern);
1346513163 },
13164 },
13165 };
1346613166
13467 .ECONNABORTED => return syscall.fail(error.ConnectionResetByPeer),
13468 .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer),
13469 .EINVAL => return syscall.fail(error.SocketUnconnected),
13470 .ENETDOWN => return syscall.fail(error.NetworkDown),
13471 .ENETRESET => return syscall.fail(error.ConnectionResetByPeer),
13472 .ENOBUFS => return syscall.fail(error.SystemResources),
13473 .ENOTCONN => return syscall.fail(error.SocketUnconnected),
13474 .ENOTSOCK => |err| return syscall.wsaErrorBug(err),
13475 .EOPNOTSUPP => |err| return syscall.wsaErrorBug(err),
13476 .ESHUTDOWN => |err| return syscall.wsaErrorBug(err),
13477 .IO_PENDING => |err| return syscall.wsaErrorBug(err),
13478 else => |err| return syscall.unexpectedWsaError(err),
13479 }
13167 const iosb = try deviceIoControl(&.{
13168 .file = .{ .handle = handle, .flags = .{ .nonblocking = true } },
13169 .code = windows.IOCTL.AFD.SEND,
13170 .in = @ptrCast(&windows.AFD.SEND_INFO{
13171 .BufferArray = &iovecs,
13172 .BufferCount = len,
13173 .AfdFlags = .{ .NO_FAST_IO = true, .OVERLAPPED = true },
13174 .TdiFlags = .{},
13175 }),
13176 });
13177 switch (iosb.u.Status) {
13178 .SUCCESS => return iosb.Information,
13179 .CANCELLED => unreachable,
13180 .INSUFFICIENT_RESOURCES => return error.SystemResources,
13181 else => |status| return windows.unexpectedStatus(status),
1348013182 }
1348113183}
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;
1348413195 const cap = std.math.maxInt(u32);
1348513196 var remaining = bytes;
1348613197 while (remaining.len > cap) {
13487 if (v.len - i.* == 0) return;
13488 v[i.*] = .{ .buf = @constCast(remaining.ptr), .len = cap };
13489 i.* += 1;
13198 if (iovecs.len - len.* == 0) return;
13199 iovecs[len.*] = .{ .buf = remaining.ptr, .len = cap };
13200 len.* += 1;
1349013201 remaining = remaining[cap..];
1349113202 } else {
1349213203 @branchHint(.likely);
13493 if (v.len - i.* == 0) return;
13494 v[i.*] = .{ .buf = @constCast(remaining.ptr), .len = @intCast(remaining.len) };
13495 i.* += 1;
13204 if (iovecs.len - len.* == 0) return;
13205 iovecs[len.*] = .{ .buf = remaining.ptr, .len = @intCast(remaining.len) };
13206 len.* += 1;
1349613207 }
1349713208}
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
1351413210/// This is either usize or u32. Since, either is fine, let's use the same
1351513211/// `addBuf` function for both writing to a file and sending network messages.
1351613212const iovlen_t = switch (native_os) {
......@@ -13530,16 +13226,10 @@ fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void {
1353013226 if (!have_networking) unreachable;
1353113227 const t: *Threaded = @ptrCast(@alignCast(userdata));
1353213228 _ = t;
13533 switch (native_os) {
13534 .windows => for (handles) |handle| closeSocketWindows(handle),
13535 else => for (handles) |handle| closeFd(handle),
13536 }
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?
13229 for (handles) |handle| switch (native_os) {
13230 .windows => windows.CloseHandle(handle),
13231 else => closeFd(handle),
13232 };
1354313233}
1354413234
1354513235fn 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
1357713267fn netShutdownWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
1357813268 if (!have_networking) return error.NetworkDown;
1357913269 const t: *Threaded = @ptrCast(@alignCast(userdata));
13270 _ = t;
1358013271
13581 const wsa_how: i32 = switch (how) {
13582 .recv => ws2_32.SD_RECEIVE,
13583 .send => ws2_32.SD_SEND,
13584 .both => ws2_32.SD_BOTH,
13585 };
13586
13587 var syscall: AlertableSyscall = try .start();
13588 while (true) {
13589 const rc = ws2_32.shutdown(handle, wsa_how);
13590 if (rc != ws2_32.SOCKET_ERROR) {
13591 syscall.finish();
13592 return;
13593 }
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 }
13272 // shutdown does not support apcs at all
13273 switch ((try deviceIoControl(&.{
13274 .file = .{ .handle = handle, .flags = .{ .nonblocking = false } },
13275 .code = windows.IOCTL.AFD.PARTIAL_DISCONNECT,
13276 .in = @ptrCast(&windows.AFD.PARTIAL_DISCONNECT_INFO{
13277 .DisconnectMode = .{ .SEND = how != .recv, .RECEIVE = how != .send },
13278 .Timeout = -1,
13279 }),
13280 })).u.Status) {
13281 .SUCCESS => {},
13282 .CANCELLED => unreachable,
13283 .INSUFFICIENT_RESOURCES => return error.SystemResources,
13284 else => |status| return windows.unexpectedStatus(status),
1361213285 }
1361313286}
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
1361913288fn netInterfaceNameResolve(
1362013289 userdata: ?*anyopaque,
1362113290 name: *const net.Interface.Name,
1362213291) net.Interface.Name.ResolveError!net.Interface {
1362313292 if (!have_networking) return error.InterfaceNotFound;
1362413293 const t: *Threaded = @ptrCast(@alignCast(userdata));
13625 _ = t;
1362613294
1362713295 if (native_os == .linux) {
1362813296 const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {
......@@ -13658,8 +13326,66 @@ fn netInterfaceNameResolve(
1365813326 }
1365913327
1366013328 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 }
1366113368 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) };
1366313389 }
1366413390
1366513391 if (builtin.link_libc) {
......@@ -13672,42 +13398,81 @@ fn netInterfaceNameResolve(
1367213398 @panic("unimplemented");
1367313399}
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
1368413401fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
1368513402 const t: *Threaded = @ptrCast(@alignCast(userdata));
13686 _ = t;
13687 try Thread.checkCancel();
1368813403
1368913404 if (native_os == .linux) {
13690 _ = interface;
13405 try Thread.checkCancel();
1369113406 @panic("TODO implement netInterfaceName for linux");
1369213407 }
1369313408
1369413409 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))]);
1369613466 }
1369713467
1369813468 if (builtin.link_libc) {
13469 try Thread.checkCancel();
1369913470 @panic("TODO implement netInterfaceName for libc");
1370013471 }
1370113472
1370213473 @panic("unimplemented");
1370313474}
1370413475
13705fn netInterfaceNameUnavailable(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
13706 _ = userdata;
13707 _ = interface;
13708 return error.Unexpected;
13709}
13710
1371113476fn netLookup(
1371213477 userdata: ?*anyopaque,
1371313478 host_name: HostName,
......@@ -13716,25 +13481,12 @@ fn netLookup(
1371613481) net.HostName.LookupError!void {
1371713482 const t: *Threaded = @ptrCast(@alignCast(userdata));
1371813483 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) {
1372013485 error.Closed => unreachable, // `resolved` must not be closed until `netLookup` returns
1372113486 else => |e| return e,
1372213487 };
1372313488}
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
1373813490fn netLookupFallible(
1373913491 t: *Threaded,
1374013492 host_name: HostName,
......@@ -13743,88 +13495,128 @@ fn netLookupFallible(
1374313495) (net.HostName.LookupError || Io.QueueClosedError)!void {
1374413496 if (!have_networking) return error.NetworkDown;
1374513497
13746 const t_io = io(t);
13498 const t_io = t.io();
1374713499 const name = host_name.bytes;
1374813500 assert(name.len <= HostName.max_len);
1374913501
1375013502 if (is_windows) {
13751 var name_buffer: [HostName.max_len + 1]u16 = undefined;
13752 const name_len = std.unicode.wtf8ToWtf16Le(&name_buffer, host_name.bytes) catch
13753 unreachable; // HostName is prevalidated.
13754 name_buffer[name_len] = 0;
13755 const name_w = name_buffer[0..name_len :0];
13756
13757 var port_buffer: [8]u8 = undefined;
13758 var port_buffer_wide: [8]u16 = undefined;
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 }
13503 if (options.family == null) {
13504 if (IpAddress.parseIp4(name, options.port)) |addr| {
13505 try resolved.putAll(t_io, &.{
13506 .{ .address = addr },
13507 .{ .canonical_name = copyCanon(options.canonical_name_buffer, name) },
13508 });
13509 return;
13510 } else |_| {}
1380613511 }
13807 defer ws2_32.FreeAddrInfoExW(res);
1380813512
13809 var it: ?*ws2_32.ADDRINFOEXW = res;
13810 var canon_name: ?[*:0]const u16 = null;
13811 while (it) |info| : (it = info.next) {
13812 const addr = info.addr orelse continue;
13813 try resolved.putOne(t_io, .{ .address = addressFromWsa(@alignCast(@fieldParentPtr("any", addr))) });
13814
13815 if (info.canonname) |n| {
13816 if (canon_name == null) {
13817 canon_name = n;
13513 var DnsQueryEx = t.dl.DnsQueryEx.load(.acquire);
13514 //var DnsCancelQuery = t.dl.DnsCancelQuery.load(.acquire);
13515 var DnsFree = t.dl.DnsFree.load(.acquire);
13516 if (DnsQueryEx == null or
13517 //DnsCancelQuery == null or
13518 DnsFree == null)
13519 {
13520 const dnsapi_dll = t.dl.dnsapi_dll.load(.acquire) orelse dnsapi_dll: {
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),
1381813535 }
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),
1381913554 }
1382013555 }
13821 if (canon_name) |n| {
13822 const len = std.unicode.wtf16LeToWtf8(options.canonical_name_buffer, std.mem.sliceTo(n, 0));
13823 try resolved.putOne(t_io, .{ .canonical_name = .{
13824 .bytes = options.canonical_name_buffer[0..len],
13825 } });
13556 const current_thread = Thread.current;
13557 var lookup_dns: LookupDnsWindows = .{
13558 .threaded = t,
13559 .thread = if (current_thread) |thread| thread.handle else undefined,
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))),
1382613619 }
13827 return;
1382813620 }
1382913621
1383013622 // On Linux, glibc provides getaddrinfo_a which is capable of supporting our semantics.
......@@ -13855,7 +13647,7 @@ fn netLookupFallible(
1385513647 } else |_| {}
1385613648 }
1385713649
13858 lookupHosts(t, host_name, resolved, options) catch |err| switch (err) {
13650 t.lookupHosts(host_name, resolved, options) catch |err| switch (err) {
1385913651 error.UnknownHostName => {},
1386013652 else => |e| return e,
1386113653 };
......@@ -13890,7 +13682,7 @@ fn netLookupFallible(
1389013682 return;
1389113683 }
1389213684
13893 return lookupDnsSearch(t, host_name, resolved, options);
13685 return t.lookupDnsSearch(host_name, resolved, options);
1389413686 }
1389513687
1389613688 if (native_os == .openbsd) {
......@@ -13908,16 +13700,16 @@ fn netLookupFallible(
1390813700 if (builtin.link_libc) {
1390913701 // This operating system lacks a way to resolve asynchronously. We are
1391013702 // stuck with getaddrinfo.
13911 var name_buffer: [HostName.max_len + 1]u8 = undefined;
13912 @memcpy(name_buffer[0..host_name.bytes.len], host_name.bytes);
13913 name_buffer[host_name.bytes.len] = 0;
13914 const name_c = name_buffer[0..host_name.bytes.len :0];
13703 var name_buffer: [HostName.max_len:0]u8 = undefined;
13704 @memcpy(name_buffer[0..name.len], name);
13705 name_buffer[name.len] = 0;
13706 const name_c = name_buffer[0..name.len :0];
1391513707
1391613708 var port_buffer: [8]u8 = undefined;
1391713709 const port_c = std.fmt.bufPrintZ(&port_buffer, "{d}", .{options.port}) catch unreachable;
1391813710
1391913711 const hints: posix.addrinfo = .{
13920 .flags = .{ .NUMERICSERV = true },
13712 .flags = .{ .CANONNAME = options.request_canonical_name, .NUMERICSERV = true },
1392113713 .family = posix.AF.UNSPEC,
1392213714 .socktype = posix.SOCK.STREAM,
1392313715 .protocol = posix.IPPROTO.TCP,
......@@ -14168,13 +13960,6 @@ const UnixAddress = extern union {
1416813960 un: posix.sockaddr.un,
1416913961};
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
1417813963pub fn posixAddressFamily(a: *const IpAddress) posix.sa_family_t {
1417913964 return switch (a.*) {
1418013965 .ip4 => posix.AF.INET,
......@@ -14190,14 +13975,6 @@ pub fn addressFromPosix(posix_address: *const PosixAddress) IpAddress {
1419013975 };
1419113976}
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
1420113978pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen_t {
1420213979 return switch (a.*) {
1420313980 .ip4 => |ip4| {
......@@ -14211,31 +13988,27 @@ pub fn addressToPosix(a: *const IpAddress, storage: *PosixAddress) posix.socklen
1421113988 };
1421213989}
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
1422713991fn addressUnixToPosix(a: *const net.UnixAddress, storage: *UnixAddress) posix.socklen_t {
14228 @memcpy(storage.un.path[0..a.path.len], a.path);
1422913992 storage.un.family = posix.AF.UNIX;
14230 storage.un.path[a.path.len] = 0;
14231 return @sizeOf(posix.sockaddr.un);
14232}
14233
14234fn addressUnixToWsa(a: *const net.UnixAddress, storage: *WsaAddress) i32 {
14235 @memcpy(storage.un.path[0..a.path.len], a.path);
14236 storage.un.family = posix.AF.UNIX;
14237 storage.un.path[a.path.len] = 0;
14238 return @sizeOf(posix.sockaddr.un);
13993 var path_len = switch (native_os) {
13994 .windows => @min(a.path.len, storage.un.path.len),
13995 else => a.path.len,
13996 };
13997 // With the AFD API, `sockaddr.un` is purely informational, so
13998 // use a suffix which is usually the most relevant part of a path.
13999 @memcpy(storage.un.path[0..path_len], a.path[a.path.len - path_len ..]);
14000 if (storage.un.path.len - path_len > 0) {
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 }
1423914012}
1424014013
1424114014fn address4FromPosix(in: *const posix.sockaddr.in) net.Ip4Address {
......@@ -14254,22 +14027,6 @@ fn address6FromPosix(in6: *const posix.sockaddr.in6) net.Ip6Address {
1425414027 };
1425514028}
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
1427314030fn address4ToPosix(a: net.Ip4Address) posix.sockaddr.in {
1427414031 return .{
1427514032 .port = std.mem.nativeToBig(u16, a.port),
......@@ -14291,20 +14048,30 @@ pub fn errnoBug(err: posix.E) Io.UnexpectedError {
1429114048 return error.Unexpected;
1429214049}
1429314050
14294pub fn posixSocketMode(mode: net.Socket.Mode) u32 {
14295 return switch (mode) {
14296 .stream => posix.SOCK.STREAM,
14297 .dgram => posix.SOCK.DGRAM,
14298 .seqpacket => posix.SOCK.SEQPACKET,
14299 .raw => posix.SOCK.RAW,
14300 .rdm => posix.SOCK.RDM,
14051pub fn posixSocketModeProtocol(family: posix.sa_family_t, mode: net.Socket.Mode, protocol: ?net.Protocol) !struct { u32, u32 } {
14052 return .{
14053 switch (mode) {
14054 .stream => posix.SOCK.STREAM,
14055 .dgram => posix.SOCK.DGRAM,
14056 .seqpacket => posix.SOCK.SEQPACKET,
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,
1430114072 };
1430214073}
1430314074
14304pub fn posixProtocol(protocol: ?net.Protocol) u32 {
14305 return @intFromEnum(protocol orelse return 0);
14306}
14307
1430814075pub fn recoverableOsBugDetected() void {
1430914076 if (is_debug) unreachable;
1431014077}
......@@ -14528,7 +14295,7 @@ fn lookupDnsSearch(
1452814295 while (it.next()) |token| {
1452914296 @memcpy(options.canonical_name_buffer[canon_name.len + 1 ..][0..token.len], token);
1453014297 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| {
1453214299 return result;
1453314300 } else |err| switch (err) {
1453414301 error.UnknownHostName, error.NoAddressReturned => continue,
......@@ -14537,7 +14304,7 @@ fn lookupDnsSearch(
1453714304 }
1453814305
1453914306 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);
1454114308}
1454214309
1454314310fn lookupDns(
......@@ -14610,7 +14377,7 @@ fn lookupDns(
1461014377 send: while (now_ts.nanoseconds < final_ts.nanoseconds) : (now_ts = clock.now(t_io)) {
1461114378 const max_messages = queries_buffer.len * HostName.ResolvConf.max_nameservers;
1461214379 {
14613 var message_buffer: [max_messages]Io.net.OutgoingMessage = undefined;
14380 var message_buffer: [max_messages]net.OutgoingMessage = undefined;
1461414381 var message_i: usize = 0;
1461514382 for (queries, answers) |query, *answer| {
1461614383 if (answer.len != 0) continue;
......@@ -14632,7 +14399,7 @@ fn lookupDns(
1463214399 } };
1463314400
1463414401 while (true) {
14635 var message_buffer: [max_messages]Io.net.IncomingMessage = @splat(.init);
14402 var message_buffer: [max_messages]net.IncomingMessage = @splat(.init);
1463614403 const buf = answer_buffer[answer_buffer_i..];
1463714404 const recv_err, const recv_n = socket.receiveManyTimeout(t_io, &message_buffer, buf, .{}, timeout);
1463814405 for (message_buffer[0..recv_n]) |*received_message| {
......@@ -14666,7 +14433,7 @@ fn lookupDns(
1466614433 if (answers_remaining == 0) break :send;
1466714434 },
1466814435 2 => {
14669 var retry_message: Io.net.OutgoingMessage = .{
14436 var retry_message: net.OutgoingMessage = .{
1467014437 .address = ns,
1467114438 .data_ptr = query.ptr,
1467214439 .data_len = query.len,
......@@ -14753,7 +14520,7 @@ fn lookupHosts(
1475314520
1475414521 var line_buf: [512]u8 = undefined;
1475514522 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) {
1475714524 error.ReadFailed => switch (file_reader.err.?) {
1475814525 error.Canceled => |e| return e,
1475914526 else => {
......@@ -14863,6 +14630,58 @@ fn writeResolutionQuery(q: *[280]u8, op: u4, dname: []const u8, class: u8, ty: H
1486314630 return n;
1486414631}
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
1486614685fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) HostName {
1486714686 const dest = canonical_name_buffer[0..name.len];
1486814687 @memcpy(dest, name);
......@@ -14879,64 +14698,6 @@ fn copyCanon(canonical_name_buffer: *[HostName.max_len]u8, name: []const u8) Hos
1487914698/// ulock_wait2() uses 64-bit nano-second timeouts (with the same convention)
1488014699const 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
1494014701fn doNothingSignalHandler(_: posix.SIG) callconv(.c) void {}
1494114702
1494214703const WindowsEnvironStrings = struct {
......@@ -16196,7 +15957,7 @@ fn windowsCreateProcessPathExt(
1619615957 try dir_buf.append(arena, 0);
1619715958 defer dir_buf.shrinkRetainingCapacity(dir_path_len);
1619815959 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, .{});
1620015961 break :dir dirOpenDirWindows(.cwd(), prefixed_path.span(), .{
1620115962 .iterate = true,
1620215963 }) catch |err| switch (err) {
lib/std/Io/Threaded/test.zig+3-3
......@@ -282,7 +282,7 @@ test "memory mapping fallback" {
282282/// Wrapper around RtlDosPathNameToNtPathName_U for use in comparing
283283/// the behavior of RtlDosPathNameToNtPathName_U with wToPrefixedFileW
284284/// Note: RtlDosPathNameToNtPathName_U is not used in the Zig implementation
285// because it allocates.
285/// because it allocates.
286286fn RtlDosPathNameToNtPathName_U(path: [:0]const u16) !Io.Threaded.WindowsPathSpace {
287287 var out: windows.UNICODE_STRING = undefined;
288288 const rc = windows.ntdll.RtlDosPathNameToNtPathName_U(path, &out, null, null);
......@@ -303,7 +303,7 @@ fn RtlDosPathNameToNtPathName_U(path: [:0]const u16) !Io.Threaded.WindowsPathSpa
303303fn testToPrefixedFileNoOracle(comptime path: []const u8, comptime expected_path: []const u8) !void {
304304 const path_utf16 = std.unicode.utf8ToUtf16LeStringLiteral(path);
305305 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, .{});
307307 std.testing.expectEqualSlices(u16, expected_path_utf16, actual_path.span()) catch |e| {
308308 std.debug.print("got '{f}', expected '{f}'\n", .{ std.unicode.fmtUtf16Le(actual_path.span()), std.unicode.fmtUtf16Le(expected_path_utf16) });
309309 return e;
......@@ -320,7 +320,7 @@ fn testToPrefixedFileWithOracle(comptime path: []const u8, comptime expected_pat
320320/// Test that the Zig conversion matches the conversion that RtlDosPathNameToNtPathName_U does.
321321fn testToPrefixedFileOnlyOracle(comptime path: []const u8) !void {
322322 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, .{});
324324 const win32_api_result = try RtlDosPathNameToNtPathName_U(path_utf16);
325325 std.testing.expectEqualSlices(u16, win32_api_result.span(), zig_result.span()) catch |e| {
326326 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;
3232const pid_t = linux.pid_t;
3333const PosixAddress = Io.Threaded.PosixAddress;
3434const posixAddressFamily = Io.Threaded.posixAddressFamily;
35const posixProtocol = Io.Threaded.posixProtocol;
36const posixSocketMode = Io.Threaded.posixSocketMode;
35const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;
3736const process = std.process;
3837const recoverableOsBugDetected = Io.Threaded.recoverableOsBugDetected;
3938const setTimestampToPosix = Io.Threaded.setTimestampToPosix;
......@@ -4952,9 +4951,9 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
49524951
49534952fn netListenIpUnavailable(
49544953 userdata: ?*anyopaque,
4955 address: net.IpAddress,
4954 address: *const net.IpAddress,
49564955 options: net.IpAddress.ListenOptions,
4957) net.IpAddress.ListenError!net.Server {
4956) net.IpAddress.ListenError!net.Socket {
49584957 const ev: *Evented = @ptrCast(@alignCast(userdata));
49594958 _ = ev;
49604959 _ = address;
......@@ -4965,10 +4964,12 @@ fn netListenIpUnavailable(
49654964fn netAcceptUnavailable(
49664965 userdata: ?*anyopaque,
49674966 listen_handle: net.Socket.Handle,
4968) net.Server.AcceptError!net.Stream {
4967 options: net.Server.AcceptOptions,
4968) net.Server.AcceptError!net.Socket {
49694969 const ev: *Evented = @ptrCast(@alignCast(userdata));
49704970 _ = ev;
49714971 _ = listen_handle;
4972 _ = options;
49724973 return error.NetworkDown;
49734974}
49744975
......@@ -4987,17 +4988,14 @@ fn netBindIp(
49874988 var addr_len = addressToPosix(address, &storage);
49884989 try ev.bind(&maybe_sync.cancel_region, socket_fd, &storage.any, addr_len);
49894990 try ev.getsockname(try maybe_sync.enterSync(ev), socket_fd, &storage.any, &addr_len);
4990 return .{
4991 .handle = socket_fd,
4992 .address = addressFromPosix(&storage),
4993 };
4991 return .{ .handle = socket_fd, .address = addressFromPosix(&storage) };
49944992}
49954993
49964994fn netConnectIpUnavailable(
49974995 userdata: ?*anyopaque,
49984996 address: *const net.IpAddress,
49994997 options: net.IpAddress.ConnectOptions,
5000) net.IpAddress.ConnectError!net.Stream {
4998) net.IpAddress.ConnectError!net.Socket {
50014999 const ev: *Evented = @ptrCast(@alignCast(userdata));
50025000 _ = ev;
50035001 _ = address;
......@@ -5941,8 +5939,7 @@ fn socket(
59415939 Unexpected,
59425940 Canceled,
59435941}!fd_t {
5944 const mode = posixSocketMode(options.mode);
5945 const protocol = posixProtocol(options.protocol);
5942 const mode, const protocol = try posixSocketModeProtocol(family, options.mode, options.protocol);
59465943 const socket_fd = while (true) {
59475944 const thread = try cancel_region.awaitIoUring();
59485945 thread.enqueue().* = .{
lib/std/Io/net.zig+74-48
......@@ -41,6 +41,7 @@ pub const Protocol = enum(u32) {
4141 ethernet = 143,
4242 raw = 255,
4343 mptcp = 262,
44 _,
4445};
4546
4647/// Windows 10 added support for unix sockets in build 17063, redstone 4 is the
......@@ -159,6 +160,11 @@ pub const IpAddress = union(enum) {
159160 }
160161 }
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
162168 /// Includes the optional scope ("%foo" at the end) in IPv6 addresses.
163169 ///
164170 /// See `format` for an alternative that omits scopes and does
......@@ -237,8 +243,14 @@ pub const IpAddress = union(enum) {
237243
238244 /// Waits for a TCP connection. When using this API, `bind` does not need
239245 /// to be called. The returned `Server` has an open `stream`.
240 pub fn listen(address: IpAddress, io: Io, options: ListenOptions) ListenError!Server {
241 return io.vtable.netListenIp(io.userdata, address, options);
246 pub fn listen(address: *const IpAddress, io: Io, options: ListenOptions) ListenError!Server {
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 };
242254 }
243255
244256 pub const BindError = error{
......@@ -320,8 +332,8 @@ pub const IpAddress = union(enum) {
320332 };
321333
322334 /// Initiates a connection-oriented network stream.
323 pub fn connect(address: IpAddress, io: Io, options: ConnectOptions) ConnectError!Stream {
324 return io.vtable.netConnectIp(io.userdata, &address, options);
335 pub fn connect(address: *const IpAddress, io: Io, options: ConnectOptions) ConnectError!Stream {
336 return .{ .socket = try io.vtable.netConnectIp(io.userdata, address, options) };
325337 }
326338};
327339
......@@ -344,6 +356,23 @@ pub const Ip4Address = struct {
344356 };
345357 }
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
347376 pub const ParseError = error{
348377 Overflow,
349378 InvalidEnd,
......@@ -429,9 +458,8 @@ pub const Ip6Address = struct {
429458
430459 /// Constructs an IPv4-mapped IPv6 address.
431460 pub fn fromIp4(ip4: Ip4Address) Ip6Address {
432 const b = &ip4.bytes;
433461 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,
435463 .port = ip4.port,
436464 };
437465 }
......@@ -572,19 +600,6 @@ pub const Ip6Address = struct {
572600 }
573601 }
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
588603 pub fn format(u: *const Unresolved, w: *Io.Writer) Io.Writer.Error!void {
589604 const bytes = &u.bytes;
590605 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 {
629644 }
630645
631646 var i: usize = 0;
632 var abbrv = false;
633 while (i < parts.len) : (i += 1) {
647 while (parts.len - i != 0) : (i += 1) {
634648 if (i == longest_start) {
635649 // Emit "::" for the longest zero run
636 if (!abbrv) {
637 try w.writeAll(if (i == 0) "::" else ":");
638 abbrv = true;
639 }
650 try w.writeAll(if (i == 0) "::" else ":");
640651 i += longest_len - 1; // Skip the compressed range
641652 continue;
642653 }
643 if (abbrv) {
644 abbrv = false;
645 }
646654 try w.print("{x}", .{parts[i]});
647655 if (i != parts.len - 1) {
648656 try w.writeAll(":");
......@@ -704,24 +712,25 @@ pub const Ip6Address = struct {
704712 };
705713 }
706714
707 pub const FormatError = Io.Writer.Error || Unresolved.FromAddressError;
715 pub const FormatError = Io.Writer.Error || Interface.NameError;
708716
709717 /// Includes the optional scope ("%foo" at the end).
710718 ///
711719 /// See `format` for an alternative that omits scopes and does
712720 /// not require an `Io` parameter.
713 pub fn formatResolved(a: Ip6Address, io: Io, w: *Io.Writer) FormatError!void {
714 const u: Unresolved = try .fromAddress(io);
721 pub fn formatResolved(a: *const Ip6Address, io: Io, w: *Io.Writer) FormatError!void {
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 };
715727 try w.print("[{f}]:{d}", .{ u, a.port });
716728 }
717729
718730 /// See `formatResolved` for an alternative that additionally prints the optional
719731 /// scope at the end of addresses and requires an `Io` parameter.
720 pub fn format(a: Ip6Address, w: *Io.Writer) Io.Writer.Error!void {
721 const u: Unresolved = .{
722 .bytes = a.bytes,
723 .interface_name = null,
724 };
732 pub fn format(a: *const Ip6Address, w: *Io.Writer) Io.Writer.Error!void {
733 const u: Unresolved = .{ .bytes = a.bytes, .interface_name = null };
725734 try w.print("[{f}]:{d}", .{ u, a.port });
726735 }
727736
......@@ -825,7 +834,10 @@ pub const Ip6Address = struct {
825834pub const UnixAddress = struct {
826835 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
830842 pub const InitError = error{NameTooLong};
831843
......@@ -834,6 +846,10 @@ pub const UnixAddress = struct {
834846 return .{ .path = p };
835847 }
836848
849 pub fn isAbstract(ua: *const UnixAddress) bool {
850 return ua.path.len == 0 or ua.path[0] == 0;
851 }
852
837853 pub const ListenError = error{
838854 AddressFamilyUnsupported,
839855 AddressInUse,
......@@ -859,10 +875,13 @@ pub const UnixAddress = struct {
859875
860876 pub fn listen(ua: *const UnixAddress, io: Io, options: ListenOptions) ListenError!Server {
861877 assert(ua.path.len <= max_len);
862 return .{ .socket = .{
863 .handle = try io.vtable.netListenUnix(io.userdata, ua, options),
864 .address = .{ .ip4 = .loopback(0) },
865 } };
878 return .{
879 .socket = .{
880 .handle = try io.vtable.netListenUnix(io.userdata, ua, options),
881 .address = .{ .ip4 = .loopback(0) },
882 },
883 .options = if (Server.AcceptOptions != void) .{ .mode = .stream, .protocol = null },
884 };
866885 }
867886
868887 pub const ConnectError = error{
......@@ -871,7 +890,6 @@ pub const UnixAddress = struct {
871890 SystemFdQuotaExceeded,
872891 AddressFamilyUnsupported,
873892 ProtocolUnsupportedBySystem,
874 ProtocolUnsupportedByAddressFamily,
875893 SocketModeUnsupported,
876894 AccessDenied,
877895 PermissionDenied,
......@@ -1006,7 +1024,12 @@ pub const Interface = struct {
10061024 }
10071025 };
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
10111034 /// Asserts not `none`.
10121035 ///
......@@ -1047,10 +1070,7 @@ pub const Socket = struct {
10471070
10481071 /// Underlying platform-defined type which may or may not be
10491072 /// interchangeable with a file system file descriptor.
1050 pub const Handle = switch (native_os) {
1051 .windows => std.os.windows.ws2_32.SOCKET,
1052 else => std.posix.fd_t,
1053 };
1073 pub const Handle = std.posix.fd_t;
10541074
10551075 /// Leaves `address` in a valid state.
10561076 pub fn close(s: *const Socket, io: Io) void {
......@@ -1377,6 +1397,7 @@ pub const Stream = struct {
13771397
13781398pub const Server = struct {
13791399 socket: Socket,
1400 options: AcceptOptions,
13801401
13811402 pub fn deinit(s: *Server, io: Io) void {
13821403 s.socket.close(io);
......@@ -1408,9 +1429,14 @@ pub const Server = struct {
14081429 ProtocolFailure,
14091430 } || 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
14111437 /// Blocks until a client connects to the server.
14121438 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) };
14141440 }
14151441};
14161442
lib/std/Io/net/HostName.zig+1
......@@ -125,6 +125,7 @@ pub fn eql(a: HostName, b: HostName) bool {
125125
126126pub const LookupOptions = struct {
127127 port: u16,
128 request_canonical_name: bool = false,
128129 canonical_name_buffer: *[max_len]u8,
129130 /// `null` means either.
130131 family: ?IpAddress.Family = null,
lib/std/Io/net/test.zig+4-12
......@@ -85,7 +85,7 @@ test "IPv6 address parse failures" {
8585}
8686
8787test "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
9090 const io = testing.io;
9191
......@@ -129,6 +129,7 @@ test "resolve DNS" {
129129
130130 net.HostName.lookup(try .init("localhost"), io, &results, .{
131131 .port = 80,
132 .request_canonical_name = true,
132133 .canonical_name_buffer = &canonical_name_buffer,
133134 }) catch |err| switch (err) {
134135 error.NetworkDown => return error.SkipZigTest,
......@@ -142,7 +143,8 @@ test "resolve DNS" {
142143 if (address.eql(&localhost_v4) or address.eql(&localhost_v6))
143144 addresses_found += 1;
144145 },
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),
146148 } else |err| switch (err) {
147149 error.Closed => {},
148150 error.Canceled => |e| return e,
......@@ -234,11 +236,6 @@ test "listen on an in use port" {
234236}
235237
236238test "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
242239 const io = testing.io;
243240 const gpa = testing.allocator;
244241
......@@ -345,11 +342,6 @@ test "decompress compressed DNS name" {
345342}
346343
347344test "cancel accept" {
348 if (builtin.os.tag == .windows) {
349 // https://codeberg.org/ziglang/zig/issues/30865
350 return error.SkipZigTest;
351 }
352
353345 const io = testing.io;
354346 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };
355347
lib/std/Progress.zig+2
......@@ -743,6 +743,7 @@ fn windowsApiWriteMarker(io: Io) WindowsApiError!void {
743743 }, 0, .{})),
744744 } })).device_io_control.u.Status) {
745745 .SUCCESS => {},
746 .CANCELLED => unreachable,
746747 else => |status| return windows.unexpectedStatus(status),
747748 }
748749}
......@@ -970,6 +971,7 @@ fn windowsApiMoveToMarker(io: Io, nl_n: usize) WindowsApiError!void {
970971 })),
971972 } })).device_io_control.u.Status) {
972973 .SUCCESS => {},
974 .CANCELLED => unreachable,
973975 else => |status| return windows.unexpectedStatus(status),
974976 }
975977 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 {
560560 },
561561 };
562562
563 // Windows appears to only support SYSTEM_INFO.dwAllocationGranularity minimum stack size.
564 // Going lower makes it default to that specified in the executable (~1mb).
565 // Its also fine if the limit here is incorrect as stack size is only a hint.
563 // Windows appears to only support SYSTEM.BASIC_INFORMATION.AllocationGranularity
564 // minimum stack size. Going lower makes it default to that specified in the executable
565 // (~1mb). Its also fine if the limit here is incorrect as stack size is only a hint.
566566 const stack_size = @max(64 * 1024, std.math.lossyCast(u32, config.stack_size));
567567
568568 // Intended to be equivalent to a kernel32.CreateThread call with no flags set.
......@@ -1741,6 +1741,6 @@ pub fn maybeAttachSignalStack() void {
17411741 }, null) catch |err| switch (err) {
17421742 error.SizeTooSmall => unreachable, // `std.options.signal_stack_size` must be sufficient for the target
17431743 error.PermissionDenied => unreachable, // called `maybeAttachSignalStack` from a signal handler
1744 error.Unexpected => @panic("unexpected error attaching signal stack"),
1744 error.Unexpected => unreachable,
17451745 };
17461746}
lib/std/c.zig-3
......@@ -10807,9 +10807,6 @@ pub extern "c" fn recvfrom(
1080710807) if (native_os == .windows) c_int else isize;
1080810808
1080910809pub 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
1081310810 .windows => {},
1081410811 else => private.recvmsg,
1081510812};
lib/std/debug/SelfInfo/Windows.zig+1
......@@ -576,6 +576,7 @@ fn loadNtdllProc(si: *SelfInfo, name: []const u8) Io.UnexpectedError!*anyopaque
576576 &.{ 'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l' },
577577 ), &ntdll_handle)) {
578578 .SUCCESS => {},
579 .DLL_NOT_FOUND => return error.Unexpected,
579580 else => |status| return windows.unexpectedStatus(status),
580581 }
581582 si.ntdll_handle = ntdll_handle;
lib/std/os/windows.zig+938-53
......@@ -598,6 +598,14 @@ pub const FILE = struct {
598598 CurrentByteOffset: LARGE_INTEGER,
599599 };
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
601609 pub const FS_DEVICE_INFORMATION = extern struct {
602610 DeviceType: DEVICE_TYPE,
603611 Characteristics: ULONG,
......@@ -864,8 +872,6 @@ pub const FILE = struct {
864872 Mode: MODE,
865873 };
866874 };
867
868 // ref: km/
869875};
870876
871877pub const DIRECTORY = struct {
......@@ -1108,6 +1114,865 @@ pub const CONSOLE = struct {
11081114 };
11091115};
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
11111976// ref: km/ntddk.h
11121977
11131978pub const SYSTEM = struct {
......@@ -1725,6 +2590,68 @@ pub const CTL_CODE = packed struct(ULONG) {
17252590};
17262591
17272592pub 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 };
17282655 pub const CONDRV = struct {
17292656 pub const READ_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 1, .Method = .OUT_DIRECT, .Access = .ANY };
17302657 pub const COMPLETE_IO: CTL_CODE = .{ .DeviceType = .CONSOLE, .Function = 2, .Method = .NEITHER, .Access = .ANY };
......@@ -3306,15 +4233,6 @@ pub fn unexpectedError(err: Win32Error) UnexpectedError {
33064233 return error.Unexpected;
33074234}
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
33184236/// Call this when you made a windows NtDll call
33194237/// and you get an unexpected status.
33204238pub fn unexpectedStatus(status: NTSTATUS) UnexpectedError {
......@@ -3432,6 +4350,15 @@ fn STRING(comptime C: type) type {
34324350 };
34334351 }
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
34354362 pub fn isEmpty(string: *const @This()) bool {
34364363 return string.Length == 0;
34374364 }
......@@ -3465,19 +4392,6 @@ pub const IO_STATUS_BLOCK = extern struct {
34654392 Information: ULONG_PTR,
34664393};
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
34814395pub const MAX_PATH = 260;
34824396
34834397pub const SECURITY_ATTRIBUTES = extern struct {
......@@ -3525,27 +4439,6 @@ pub const STARTF_USESTDHANDLES = 0x00000100;
35254439pub const THREAD_START_ROUTINE = fn (LPVOID) callconv(.winapi) DWORD;
35264440pub 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
35494442pub const GUID = extern struct {
35504443 Data1: u32,
35514444 Data2: u16,
......@@ -3914,14 +4807,6 @@ pub const PATH_MAX_WIDE = 32767;
39144807/// TODO: More verification of this assumption.
39154808pub 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
39254810pub const EXCEPTION_DATATYPE_MISALIGNMENT = 0x80000002;
39264811pub const EXCEPTION_ACCESS_VIOLATION = 0xc0000005;
39274812pub const EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d;
lib/std/os/windows/ntdll.zig+8-8
......@@ -114,14 +114,14 @@ pub extern "ntdll" fn NtCreateFile(
114114 ShareAccess: FILE.SHARE,
115115 CreateDisposition: FILE.CREATE_DISPOSITION,
116116 CreateOptions: FILE.MODE,
117 EaBuffer: ?*anyopaque,
117 EaBuffer: ?*const anyopaque,
118118 EaLength: ULONG,
119119) callconv(.winapi) NTSTATUS;
120120
121121pub extern "ntdll" fn NtDeviceIoControlFile(
122122 FileHandle: HANDLE,
123123 Event: ?HANDLE,
124 ApcRoutine: ?*const IO_APC_ROUTINE,
124 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
125125 ApcContext: ?*anyopaque,
126126 IoStatusBlock: *IO_STATUS_BLOCK,
127127 IoControlCode: CTL_CODE,
......@@ -134,7 +134,7 @@ pub extern "ntdll" fn NtDeviceIoControlFile(
134134pub extern "ntdll" fn NtFsControlFile(
135135 FileHandle: HANDLE,
136136 Event: ?HANDLE,
137 ApcRoutine: ?*const IO_APC_ROUTINE,
137 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
138138 ApcContext: ?*anyopaque,
139139 IoStatusBlock: *IO_STATUS_BLOCK,
140140 FsControlCode: CTL_CODE,
......@@ -147,7 +147,7 @@ pub extern "ntdll" fn NtFsControlFile(
147147pub extern "ntdll" fn NtLockFile(
148148 FileHandle: HANDLE,
149149 Event: ?HANDLE,
150 ApcRoutine: ?*const IO_APC_ROUTINE,
150 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
151151 ApcContext: ?*anyopaque,
152152 IoStatusBlock: *IO_STATUS_BLOCK,
153153 ByteOffset: *const LARGE_INTEGER,
......@@ -169,7 +169,7 @@ pub extern "ntdll" fn NtOpenFile(
169169pub extern "ntdll" fn NtQueryDirectoryFile(
170170 FileHandle: HANDLE,
171171 Event: ?HANDLE,
172 ApcRoutine: ?*const IO_APC_ROUTINE,
172 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
173173 ApcContext: ?*anyopaque,
174174 IoStatusBlock: *IO_STATUS_BLOCK,
175175 FileInformation: *anyopaque,
......@@ -199,7 +199,7 @@ pub extern "ntdll" fn NtQueryVolumeInformationFile(
199199pub extern "ntdll" fn NtReadFile(
200200 FileHandle: HANDLE,
201201 Event: ?HANDLE,
202 ApcRoutine: ?*const IO_APC_ROUTINE,
202 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
203203 ApcContext: ?*anyopaque,
204204 IoStatusBlock: *IO_STATUS_BLOCK,
205205 Buffer: *anyopaque,
......@@ -222,7 +222,7 @@ pub extern "ntdll" fn NtSetInformationFile(
222222pub extern "ntdll" fn NtWriteFile(
223223 FileHandle: HANDLE,
224224 Event: ?HANDLE,
225 ApcRoutine: ?*const IO_APC_ROUTINE,
225 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
226226 ApcContext: ?*anyopaque,
227227 IoStatusBlock: *IO_STATUS_BLOCK,
228228 Buffer: *const anyopaque,
......@@ -527,7 +527,7 @@ pub extern "ntdll" fn NtDelayExecution(
527527pub extern "ntdll" fn NtNotifyChangeDirectoryFileEx(
528528 FileHandle: HANDLE,
529529 Event: ?HANDLE,
530 ApcRoutine: ?*const IO_APC_ROUTINE,
530 ApcRoutine: ?*align(2) const IO_APC_ROUTINE,
531531 ApcContext: ?*anyopaque,
532532 IoStatusBlock: *IO_STATUS_BLOCK,
533533 Buffer: *anyopaque,
lib/std/os/windows/win32error.zig+266
......@@ -2503,5 +2503,271 @@ pub const Win32Error = enum(u32) {
25032503 REQUEST_PAUSED = 3050,
25042504 /// Reissue the given operation as a cached IO operation.
25052505 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,
25062772 _,
25072773};
lib/std/os/windows/ws2_32.zig+3-1922
......@@ -2,447 +2,15 @@ const std = @import("../../std.zig");
22const assert = std.debug.assert;
33const windows = std.os.windows;
44
5const OVERLAPPED = windows.OVERLAPPED;
6const WORD = windows.WORD;
7const DWORD = windows.DWORD;
8const GUID = windows.GUID;
95const 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;
176const 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
258pub const GROUP = u32;
269pub const ADDRESS_FAMILY = u16;
27pub const WSAEVENT = HANDLE;
2810
2911// Microsoft use the signed c_int for this, but it should never be negative
3012pub 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
44614pub const TCP = struct {
44715 pub const NODELAY = 1;
44816 pub const EXPEDITED_1122 = 2;
......@@ -469,10 +37,6 @@ pub const TCP = struct {
46937 pub const BSDURGENT = 28672;
47038};
47139
472pub const UDP_SEND_MSG_SIZE = 2;
473pub const UDP_RECV_MAX_COALESCED_SIZE = 3;
474pub const UDP_COALESCED_INFO = 3;
475
47640pub const AF = struct {
47741 pub const UNSPEC = 0;
47842 pub const UNIX = 1;
......@@ -507,6 +71,7 @@ pub const AF = struct {
50771 pub const TCNPROCESS = 29;
50872 pub const TCNMESSAGE = 30;
50973 pub const ICLFXBM = 31;
74 pub const BTH = 32;
51075 pub const LINK = 33;
51176 pub const HYPERV = 34;
51277};
......@@ -517,15 +82,6 @@ pub const SOCK = struct {
51782 pub const RAW = 3;
51883 pub const RDM = 4;
51984 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;
52985};
53086
53187pub const SOL = struct {
......@@ -581,84 +137,9 @@ pub const SO = struct {
581137 pub const UPDATE_ACCEPT_CONTEXT = 28683;
582138 pub const CONNECT_TIME = 28684;
583139 pub const UPDATE_CONNECT_CONTEXT = 28688;
584};
585140
586pub const WSK_SO_BASE = 16384;
587pub const IOC_UNIX = 0;
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;
141 pub const UNIX_PATH = 0x98000000;
142};
662143
663144pub const MSG = struct {
664145 pub const OOB = 0x1;
......@@ -678,215 +159,6 @@ pub const MSG = struct {
678159 pub const MAXIOVLEN = 16;
679160};
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
890162pub const IPPROTO = struct {
891163 pub const IP = 0;
892164 pub const ICMP = 1;
......@@ -902,77 +174,6 @@ pub const IPPROTO = struct {
902174 pub const MAX = 256;
903175};
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
976177pub const FLOWSPEC = extern struct {
977178 TokenRate: u32,
978179 TokenBucketSize: u32,
......@@ -984,94 +185,6 @@ pub const FLOWSPEC = extern struct {
984185 MinimumPolicedSize: u32,
985186};
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
1075188pub const sockproto = extern struct {
1076189 sp_family: u16,
1077190 sp_protocol: u16,
......@@ -1082,25 +195,6 @@ pub const linger = extern struct {
1082195 linger: u16,
1083196};
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
1104198pub const sockaddr = extern struct {
1105199 family: ADDRESS_FAMILY,
1106200 data: [14]u8,
......@@ -1140,118 +234,6 @@ pub const sockaddr = extern struct {
1140234 };
1141235};
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
1255237pub const hostent = extern struct {
1256238 h_name: [*]u8,
1257239 h_aliases: **i8,
......@@ -1264,904 +246,3 @@ pub const timeval = extern struct {
1264246 sec: LONG,
1265247 usec: LONG,
1266248};
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 {
268268 pub const DEBUG = 7;
269269};
270270
271pub const socket_t = if (native_os == .windows) windows.ws2_32.SOCKET else fd_t;
271pub const socket_t = fd_t;
272272
273273/// Obtains errno from the return value of a system function call.
274274///
......@@ -500,18 +500,7 @@ pub const GetSockNameError = error{
500500
501501pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {
502502 if (native_os == .windows) {
503 const rc = windows.getpeername(sock, addr, addrlen);
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;
503 @compileError("use std.Io instead");
515504 } else {
516505 const rc = system.getpeername(sock, addr, addrlen);
517506 switch (errno(rc)) {
......@@ -992,16 +981,7 @@ pub const PollError = error{
992981
993982pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
994983 if (native_os == .windows) {
995 switch (windows.poll(fds.ptr, @intCast(fds.len), timeout)) {
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 }
984 @compileError("use std.Io instead");
1005985 }
1006986 while (true) {
1007987 const fds_count = cast(nfds_t, fds.len) orelse return error.SystemResources;
......@@ -1071,18 +1051,7 @@ pub const SetSockOptError = error{
10711051/// Set a socket's options.
10721052pub fn setsockopt(fd: socket_t, level: i32, optname: u32, opt: []const u8) SetSockOptError!void {
10731053 if (native_os == .windows) {
1074 const rc = windows.ws2_32.setsockopt(fd, level, @intCast(optname), opt.ptr, @intCast(opt.len));
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;
1054 @compileError("use std.Io instead");
10861055 } else {
10871056 switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(opt.len)))) {
10881057 .SUCCESS => {},
test/standalone/coff_dwarf/build.zig-3
......@@ -46,9 +46,6 @@ pub fn build(b: *std.Build) void {
4646 lib.root_module.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-gdwarf"} });
4747 exe.root_module.linkLibrary(lib);
4848
49 if (target.result.os.tag == .windows)
50 exe.root_module.linkSystemLibrary("ws2_32", .{});
51
5249 const run = b.addRunArtifact(exe);
5350 run.expectExitCode(0);
5451 run.skip_foreign_checks = true;
test/standalone/issue_5825/build.zig-1
......@@ -34,7 +34,6 @@ pub fn build(b: *std.Build) void {
3434 exe.subsystem = .console;
3535 exe.root_module.linkSystemLibrary("kernel32", .{});
3636 exe.root_module.linkSystemLibrary("ntdll", .{});
37 exe.root_module.linkSystemLibrary("ws2_32", .{});
3837 exe.root_module.addObject(obj);
3938
4039 // TODO: actually check the output
test/standalone/mix_o_files/build.zig-3
......@@ -16,9 +16,6 @@ pub fn build(b: *std.Build) void {
1616 }),
1717 });
1818
19 if (target.result.os.tag == .windows)
20 obj.root_module.linkSystemLibrary("ws2_32", .{});
21
2219 const exe = b.addExecutable(.{
2320 .name = "test",
2421 .root_module = b.createModule(.{
test/standalone/shared_library/build.zig-3
......@@ -24,9 +24,6 @@ pub fn build(b: *std.Build) void {
2424 }),
2525 });
2626
27 if (target.result.os.tag == .windows)
28 lib.root_module.linkSystemLibrary("ws2_32", .{});
29
3027 const exe = b.addExecutable(.{
3128 .name = exe_name,
3229 .root_module = b.createModule(.{
test/standalone/test_obj_link_run/build.zig-1
......@@ -11,7 +11,6 @@ pub fn build(b: *std.Build) void {
1111 if (is_windows) {
1212 test_obj.root_module.linkSystemLibrary("ntdll", .{});
1313 test_obj.root_module.linkSystemLibrary("kernel32", .{});
14 test_obj.root_module.linkSystemLibrary("ws2_32", .{});
1514 }
1615
1716 const test_exe_mod = b.createModule(.{
test/standalone/windows_argv/build.zig-2
......@@ -20,7 +20,6 @@ pub fn build(b: *std.Build) !void {
2020 .optimize = optimize,
2121 }),
2222 });
23 lib_gnu.root_module.linkSystemLibrary("ws2_32", .{});
2423
2524 const verify_gnu = b.addExecutable(.{
2625 .name = "verify-gnu",
......@@ -103,7 +102,6 @@ pub fn build(b: *std.Build) !void {
103102 .flags = &.{ "-DUNICODE", "-D_UNICODE" },
104103 });
105104 verify_msvc.root_module.linkLibrary(lib_msvc);
106 verify_msvc.root_module.linkSystemLibrary("ws2_32", .{});
107105 verify_msvc.root_module.link_libc = true;
108106
109107 const run_msvc = b.addRunArtifact(fuzz);
test/tests.zig-1
......@@ -2587,7 +2587,6 @@ fn addOneModuleTest(
25872587 compile_c.linkSystemLibrary("advapi32", .{});
25882588 }
25892589 compile_c.linkSystemLibrary("crypt32", .{});
2590 compile_c.linkSystemLibrary("ws2_32", .{});
25912590 compile_c.linkSystemLibrary("ole32", .{});
25922591 }
25932592 }
tools/incr-check.zig-4
......@@ -148,7 +148,6 @@ pub fn main(init: std.process.Init) !void {
148148 "--global-cache-dir",
149149 ".global-cache",
150150 });
151 if (target.resolved.os.tag == .windows) try child_args.append(arena, "-lws2_32");
152151 try child_args.append(arena, "--listen=-");
153152
154153 if (opt_resolved_lib_dir) |resolved_lib_dir| {
......@@ -190,9 +189,6 @@ pub fn main(init: std.process.Init) !void {
190189 opt_resolved_lib_dir.?, // verified earlier
191190 });
192191
193 if (target.resolved.os.tag == .windows)
194 try cc_child_args.append(arena, "-lws2_32");
195
196192 try cc_child_args.append(arena, "-o");
197193 }
198194