Commit 431eeb5e20

daurnimator <quae@daurnimator.com>
2019-11-14 06:34:13
std: add pieces for WSAIoctl on windows
1 parent 3b8afe3
Changed files (2)
lib
std
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;
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 {