From 431eeb5e20d20584688235078c9f5d730e59a5b9 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 14 Nov 2019 16:34:13 +1100 Subject: [PATCH] std: add pieces for WSAIoctl on windows --- lib/std/os/windows.zig | 29 +++++++++++++++++++++++++ lib/std/os/windows/ws2_32.zig | 41 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index e55ac3fe8f..06da223d5c 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -647,6 +647,35 @@ pub fn WSASocketW( return rc; } +pub fn WSAIoctl( + s: ws2_32.SOCKET, + dwIoControlCode: DWORD, + inBuffer: ?[]const u8, + outBuffer: []u8, + overlapped: ?*ws2_32.WSAOVERLAPPED, + completionRoutine: ?*ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE, +) !DWORD { + var bytes: DWORD = undefined; + switch (ws2_32.WSAIoctl( + s, + dwIoControlCode, + if (inBuffer) |i| i.ptr else null, + if (inBuffer) |i| @intCast(DWORD, i.len) else 0, + outBuffer.ptr, + @intCast(DWORD, outBuffer.len), + &bytes, + overlapped, + completionRoutine, + )) { + 0 => {}, + ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) { + else => |err| return unexpectedWSAError(err), + }, + else => unreachable, + } + return bytes; +} + const GetModuleFileNameError = error{Unexpected}; pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 { diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index d47c5a3d1d..c34077a9dc 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -96,6 +96,23 @@ pub const WSA_FLAG_MULTIPOINT_D_LEAF = 0x10; pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40; pub const WSA_FLAG_NO_HANDLE_INHERIT = 0x80; +pub const WSAEVENT = HANDLE; + +pub const WSAOVERLAPPED = extern struct { + Internal: DWORD, + InternalHigh: DWORD, + Offset: DWORD, + OffsetHigh: DWORD, + hEvent: ?WSAEVENT, +}; + +pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn ( + dwError: DWORD, + cbTransferred: DWORD, + lpOverlapped: *WSAOVERLAPPED, + dwFlags: DWORD +) void; + pub const WSA_INVALID_HANDLE = 6; pub const WSA_NOT_ENOUGH_MEMORY = 8; pub const WSA_INVALID_PARAMETER = 87; @@ -192,6 +209,19 @@ pub const WSA_QOS_ESDMODEOBJ = 11029; pub const WSA_QOS_ESHAPERATEOBJ = 11030; pub const WSA_QOS_RESERVED_PETYPE = 11031; + +/// no parameters +const IOC_VOID = 0x80000000; +/// copy out parameters +const IOC_OUT = 0x40000000; +/// copy in parameters +const IOC_IN = 0x80000000; + +/// The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1. +const IOC_WS2 = 0x08000000; + +pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34; + pub extern "ws2_32" stdcallcc fn WSAStartup( wVersionRequired: WORD, lpWSAData: *WSADATA, @@ -214,3 +244,14 @@ pub extern "ws2_32" stdcallcc fn WSASocketW( g: GROUP, dwFlags: DWORD, ) SOCKET; +pub extern "ws2_32" stdcallcc fn WSAIoctl( + s: SOCKET, + dwIoControlCode: DWORD, + lpvInBuffer: ?*const c_void, + cbInBuffer: DWORD, + lpvOutBuffer: ?LPVOID, + cbOutBuffer: DWORD, + lpcbBytesReturned: LPDWORD, + lpOverlapped: ?*WSAOVERLAPPED, + lpCompletionRoutine: ?*WSAOVERLAPPED_COMPLETION_ROUTINE, +) c_int;