From ef6cec983c71b65058c54d98e7482b9926e7ddbf Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 14:59:21 +1100 Subject: [PATCH 01/11] std: add windows FILE_DEVICE_ defines --- lib/std/os/windows/bits.zig | 87 +++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 951edf2d67..bf71ca22aa 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -67,6 +67,93 @@ pub const va_list = *@OpaqueType(); pub const TRUE = 1; pub const FALSE = 0; +pub const DEVICE_TYPE = ULONG; +pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001; +pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002; +pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003; +pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004; +pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005; +pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006; +pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007; +pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008; +pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009; +pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a; +pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b; +pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c; +pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d; +pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e; +pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f; +pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010; +pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011; +pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012; +pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013; +pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014; +pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015; +pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016; +pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017; +pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018; +pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019; +pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a; +pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b; +pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c; +pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d; +pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e; +pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f; +pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020; +pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021; +pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022; +pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023; +pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024; +pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025; +pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026; +pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027; +pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028; +pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029; +pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a; +pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b; +pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c; +pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d; +pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e; +pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f; +pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030; +pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031; +pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032; +pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033; +pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034; +pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035; +pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036; +pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037; +pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038; +pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039; +pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a; +pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b; +// TODO: missing values? +pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e; +pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f; +pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040; +pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041; +pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042; +pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043; +pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044; +pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045; +pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046; +pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047; +pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048; +pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049; +pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050; +pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051; +pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052; +pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053; +pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054; +pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055; +pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056; +pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057; +pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058; +pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059; +pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a; +pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b; +pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c; + pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize)); pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD)); From 0270545edb8db7f51e6b0581fad0bad5b783a7e0 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 15:00:32 +1100 Subject: [PATCH 02/11] std: add windows ioctl transfer types --- lib/std/os/windows/bits.zig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index bf71ca22aa..eb37a7e396 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -154,6 +154,14 @@ pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a; pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b; pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c; +/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes +pub const TransferType = enum(u2) { + METHOD_BUFFERED = 0, + METHOD_IN_DIRECT = 1, + METHOD_OUT_DIRECT = 2, + METHOD_NEITHER = 3, +}; + pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize)); pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD)); From 4830415071c3d62e4e2c19e5f5342151632e72bb Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 15:59:03 +1100 Subject: [PATCH 03/11] std: add FILE_ANY_ constants for windows --- lib/std/os/windows/bits.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index eb37a7e396..3dc772a7c3 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -162,6 +162,10 @@ pub const TransferType = enum(u2) { METHOD_NEITHER = 3, }; +pub const FILE_ANY_ACCESS = 0; +pub const FILE_READ_ACCESS = 1; +pub const FILE_WRITE_ACCESS = 2; + pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize)); pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD)); From be86e41d975325d30145e30369912a409012b76b Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 15:37:21 +1100 Subject: [PATCH 04/11] std: add CTL_CODE function for windows --- lib/std/os/windows/bits.zig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 3dc772a7c3..2f65c27e47 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -166,6 +166,14 @@ pub const FILE_ANY_ACCESS = 0; pub const FILE_READ_ACCESS = 1; pub const FILE_WRITE_ACCESS = 2; +/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes +pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD { + return (@as(DWORD, deviceType) << 16) | + (@as(DWORD, access) << 14) | + (@as(DWORD, function) << 2) | + @enumToInt(method); +} + pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize)); pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD)); From a832b35c19801b02f97103bce9e86afd389a01dd Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 16:27:33 +1100 Subject: [PATCH 05/11] std: add windows socket constants Taken from https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw --- lib/std/os/bits/windows.zig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/std/os/bits/windows.zig b/lib/std/os/bits/windows.zig index b5b8a9c2d4..a1ceb8ff5c 100644 --- a/lib/std/os/bits/windows.zig +++ b/lib/std/os/bits/windows.zig @@ -226,3 +226,17 @@ pub const AF_TCNMESSAGE = 30; pub const AF_ICLFXBM = 31; pub const AF_BTH = 32; pub const AF_MAX = 33; + +pub const SOCK_STREAM = 1; +pub const SOCK_DGRAM = 2; +pub const SOCK_RAW = 3; +pub const SOCK_RDM = 4; +pub const SOCK_SEQPACKET = 5; + +pub const IPPROTO_ICMP = 1; +pub const IPPROTO_IGMP = 2; +pub const BTHPROTO_RFCOMM = 3; +pub const IPPROTO_TCP = 6; +pub const IPPROTO_UDP = 17; +pub const IPPROTO_ICMPV6 = 58; +pub const IPPROTO_RM = 113; From f4c6cc3270db8f3557b3e7191eccc02098b4b2da Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 17:30:26 +1100 Subject: [PATCH 06/11] std: add winsock some definitions --- lib/std/os/windows.zig | 1 + lib/std/os/windows/ws2_32.zig | 186 ++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 lib/std/os/windows/ws2_32.zig diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 9cdf8e9317..bc360e7e70 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -16,6 +16,7 @@ pub const kernel32 = @import("windows/kernel32.zig"); pub const ntdll = @import("windows/ntdll.zig"); pub const ole32 = @import("windows/ole32.zig"); pub const shell32 = @import("windows/shell32.zig"); +pub const ws2_32 = @import("windows/ws2_32.zig"); pub usingnamespace @import("windows/bits.zig"); diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig new file mode 100644 index 0000000000..1fe5d87496 --- /dev/null +++ b/lib/std/os/windows/ws2_32.zig @@ -0,0 +1,186 @@ +usingnamespace @import("bits.zig"); + +pub const SOCKET = *@OpaqueType(); +pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0)); + +pub const MAX_PROTOCOL_CHAIN = 7; + +pub const WSAPROTOCOLCHAIN = extern struct { + ChainLen: c_int, + ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD, +}; + +pub const WSAPROTOCOL_LEN = 255; + +pub const WSAPROTOCOL_INFOA = extern struct { + dwServiceFlags1: DWORD, + dwServiceFlags2: DWORD, + dwServiceFlags3: DWORD, + dwServiceFlags4: DWORD, + dwProviderFlags: DWORD, + ProviderId: GUID, + dwCatalogEntryId: DWORD, + ProtocolChain: WSAPROTOCOLCHAIN, + iVersion: c_int, + iAddressFamily: c_int, + iMaxSockAddr: c_int, + iMinSockAddr: c_int, + iSocketType: c_int, + iProtocol: c_int, + iProtocolMaxOffset: c_int, + iNetworkByteOrder: c_int, + iSecurityScheme: c_int, + dwMessageSize: DWORD, + dwProviderReserved: DWORD, + szProtocol: [WSAPROTOCOL_LEN + 1]CHAR, +}; + +pub const WSAPROTOCOL_INFOW = extern struct { + dwServiceFlags1: DWORD, + dwServiceFlags2: DWORD, + dwServiceFlags3: DWORD, + dwServiceFlags4: DWORD, + dwProviderFlags: DWORD, + ProviderId: GUID, + dwCatalogEntryId: DWORD, + ProtocolChain: WSAPROTOCOLCHAIN, + iVersion: c_int, + iAddressFamily: c_int, + iMaxSockAddr: c_int, + iMinSockAddr: c_int, + iSocketType: c_int, + iProtocol: c_int, + iProtocolMaxOffset: c_int, + iNetworkByteOrder: c_int, + iSecurityScheme: c_int, + dwMessageSize: DWORD, + dwProviderReserved: DWORD, + szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR, +}; + +pub const GROUP = u32; + +pub const SG_UNCONSTRAINED_GROUP = 0x1; +pub const SG_CONSTRAINED_GROUP = 0x2; + +pub const WSA_FLAG_OVERLAPPED = 0x01; +pub const WSA_FLAG_MULTIPOINT_C_ROOT = 0x02; +pub const WSA_FLAG_MULTIPOINT_C_LEAF = 0x04; +pub const WSA_FLAG_MULTIPOINT_D_ROOT = 0x08; +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 WSA_INVALID_HANDLE = 6; +pub const WSA_NOT_ENOUGH_MEMORY = 8; +pub const WSA_INVALID_PARAMETER = 87; +pub const WSA_OPERATION_ABORTED = 995; +pub const WSA_IO_INCOMPLETE = 996; +pub const WSA_IO_PENDING = 997; +pub const WSAEINTR = 10004; +pub const WSAEBADF = 10009; +pub const WSAEACCES = 10013; +pub const WSAEFAULT = 10014; +pub const WSAEINVAL = 10022; +pub const WSAEMFILE = 10024; +pub const WSAEWOULDBLOCK = 10035; +pub const WSAEINPROGRESS = 10036; +pub const WSAEALREADY = 10037; +pub const WSAENOTSOCK = 10038; +pub const WSAEDESTADDRREQ = 10039; +pub const WSAEMSGSIZE = 10040; +pub const WSAEPROTOTYPE = 10041; +pub const WSAENOPROTOOPT = 10042; +pub const WSAEPROTONOSUPPORT = 10043; +pub const WSAESOCKTNOSUPPORT = 10044; +pub const WSAEOPNOTSUPP = 10045; +pub const WSAEPFNOSUPPORT = 10046; +pub const WSAEAFNOSUPPORT = 10047; +pub const WSAEADDRINUSE = 10048; +pub const WSAEADDRNOTAVAIL = 10049; +pub const WSAENETDOWN = 10050; +pub const WSAENETUNREACH = 10051; +pub const WSAENETRESET = 10052; +pub const WSAECONNABORTED = 10053; +pub const WSAECONNRESET = 10054; +pub const WSAENOBUFS = 10055; +pub const WSAEISCONN = 10056; +pub const WSAENOTCONN = 10057; +pub const WSAESHUTDOWN = 10058; +pub const WSAETOOMANYREFS = 10059; +pub const WSAETIMEDOUT = 10060; +pub const WSAECONNREFUSED = 10061; +pub const WSAELOOP = 10062; +pub const WSAENAMETOOLONG = 10063; +pub const WSAEHOSTDOWN = 10064; +pub const WSAEHOSTUNREACH = 10065; +pub const WSAENOTEMPTY = 10066; +pub const WSAEPROCLIM = 10067; +pub const WSAEUSERS = 10068; +pub const WSAEDQUOT = 10069; +pub const WSAESTALE = 10070; +pub const WSAEREMOTE = 10071; +pub const WSASYSNOTREADY = 10091; +pub const WSAVERNOTSUPPORTED = 10092; +pub const WSANOTINITIALISED = 10093; +pub const WSAEDISCON = 10101; +pub const WSAENOMORE = 10102; +pub const WSAECANCELLED = 10103; +pub const WSAEINVALIDPROCTABLE = 10104; +pub const WSAEINVALIDPROVIDER = 10105; +pub const WSAEPROVIDERFAILEDINIT = 10106; +pub const WSASYSCALLFAILURE = 10107; +pub const WSASERVICE_NOT_FOUND = 10108; +pub const WSATYPE_NOT_FOUND = 10109; +pub const WSA_E_NO_MORE = 10110; +pub const WSA_E_CANCELLED = 10111; +pub const WSAEREFUSED = 10112; +pub const WSAHOST_NOT_FOUND = 11001; +pub const WSATRY_AGAIN = 11002; +pub const WSANO_RECOVERY = 11003; +pub const WSANO_DATA = 11004; +pub const WSA_QOS_RECEIVERS = 11005; +pub const WSA_QOS_SENDERS = 11006; +pub const WSA_QOS_NO_SENDERS = 11007; +pub const WSA_QOS_NO_RECEIVERS = 11008; +pub const WSA_QOS_REQUEST_CONFIRMED = 11009; +pub const WSA_QOS_ADMISSION_FAILURE = 11010; +pub const WSA_QOS_POLICY_FAILURE = 11011; +pub const WSA_QOS_BAD_STYLE = 11012; +pub const WSA_QOS_BAD_OBJECT = 11013; +pub const WSA_QOS_TRAFFIC_CTRL_ERROR = 11014; +pub const WSA_QOS_GENERIC_ERROR = 11015; +pub const WSA_QOS_ESERVICETYPE = 11016; +pub const WSA_QOS_EFLOWSPEC = 11017; +pub const WSA_QOS_EPROVSPECBUF = 11018; +pub const WSA_QOS_EFILTERSTYLE = 11019; +pub const WSA_QOS_EFILTERTYPE = 11020; +pub const WSA_QOS_EFILTERCOUNT = 11021; +pub const WSA_QOS_EOBJLENGTH = 11022; +pub const WSA_QOS_EFLOWCOUNT = 11023; +pub const WSA_QOS_EUNKOWNPSOBJ = 11024; +pub const WSA_QOS_EPOLICYOBJ = 11025; +pub const WSA_QOS_EFLOWDESC = 11026; +pub const WSA_QOS_EPSFLOWSPEC = 11027; +pub const WSA_QOS_EPSFILTERSPEC = 11028; +pub const WSA_QOS_ESDMODEOBJ = 11029; +pub const WSA_QOS_ESHAPERATEOBJ = 11030; +pub const WSA_QOS_RESERVED_PETYPE = 11031; + +pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int; +pub extern "ws2_32" stdcallcc fn WSASocketA( + af: c_int, + type: c_int, + protocol: c_int, + lpProtocolInfo: ?*WSAPROTOCOL_INFOA, + g: GROUP, + dwFlags: DWORD, +) SOCKET; +pub extern "ws2_32" stdcallcc fn WSASocketW( + af: c_int, + type: c_int, + protocol: c_int, + lpProtocolInfo: ?*WSAPROTOCOL_INFOW, + g: GROUP, + dwFlags: DWORD, +) SOCKET; From d9d3268cc1fe6b581ccb44606346cb6847d557a5 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 18:22:33 +1100 Subject: [PATCH 07/11] std: add DeviceIoControl and GetOverlappedResult for windows --- lib/std/os/windows.zig | 36 +++++++++++++++++++++++++++++++++ lib/std/os/windows/kernel32.zig | 11 ++++++++++ 2 files changed, 47 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index bc360e7e70..4d2944b563 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -97,6 +97,42 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C } } +pub fn DeviceIoControl( + h: HANDLE, + ioControlCode: DWORD, + in: ?[]const u8, + out: ?[]u8, + overlapped: ?*OVERLAPPED, +) !DWORD { + var bytes: DWORD = undefined; + if (kernel32.DeviceIoControl( + h, + ioControlCode, + if (in) |i| i.ptr else null, + if (in) |i| @intCast(u32, i.len) else 0, + if (out) |o| o.ptr else null, + if (out) |o| @intCast(u32, o.len) else 0, + &bytes, + overlapped, + ) == 0) { + switch (kernel32.GetLastError()) { + else => |err| return unexpectedError(err), + } + } + return bytes; +} + +pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD { + var bytes: DWORD = undefined; + if (kernel32.GetOverlappedResult(h, overlapped, &bytes, wait) == 0) { + switch (kernel32.GetLastError()) { + ERROR_IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable, + else => |err| return unexpectedError(err), + } + } + return bytes; +} + pub const SetHandleInformationError = error{Unexpected}; pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInformationError!void { diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index d466f9946d..30c4cf4785 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -45,6 +45,17 @@ pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, Ex pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE; +pub extern "kernel32" stdcallcc fn DeviceIoControl( + h: HANDLE, + dwIoControlCode: DWORD, + lpInBuffer: ?*const c_void, + nInBufferSize: DWORD, + lpOutBuffer: ?LPVOID, + nOutBufferSize: DWORD, + lpBytesReturned: LPDWORD, + lpOverlapped: ?*OVERLAPPED, +) BOOL; + pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL; pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL; From 4cf535a01b06c301239fb888dbdf87831c568867 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 13 Nov 2019 18:23:21 +1100 Subject: [PATCH 08/11] std: add WSASocketW for windows --- lib/std/os/windows.zig | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 4d2944b563..e8011b7534 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -608,6 +608,27 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD return rc; } +pub fn WSASocketW( + af: i32, + socket_type: i32, + protocol: i32, + protocolInfo: ?*ws2_32.WSAPROTOCOL_INFOW, + g: ws2_32.GROUP, + dwFlags: DWORD, +) !ws2_32.SOCKET { + const rc = ws2_32.WSASocketW(af, socket_type, protocol, protocolInfo, g, dwFlags); + if (rc == ws2_32.INVALID_SOCKET) { + switch (ws2_32.WSAGetLastError()) { + ws2_32.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported, + ws2_32.WSAEMFILE => return error.ProcessFdQuotaExceeded, + ws2_32.WSAENOBUFS => return error.SystemResources, + ws2_32.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported, + else => |err| return unexpectedWSAError(err), + } + } + return rc; +} + const GetModuleFileNameError = error{Unexpected}; pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 { @@ -905,6 +926,10 @@ pub fn unexpectedError(err: DWORD) std.os.UnexpectedError { return error.Unexpected; } +pub fn unexpectedWSAError(err: c_int) std.os.UnexpectedError { + return unexpectedError(@intCast(DWORD, err)); +} + /// Call this when you made a windows NtDll call /// and you get an unexpected status. pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError { From 6469900e79369f5ff7539501767842dc6922f887 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 14 Nov 2019 14:37:08 +1100 Subject: [PATCH 09/11] std: add WSAStartup and WSACleanup for windows --- lib/std/os/windows.zig | 18 ++++++++++++++++++ lib/std/os/windows/ws2_32.zig | 30 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index e8011b7534..e55ac3fe8f 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -608,6 +608,24 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD return rc; } +pub fn WSAStartup(majorVersion: u8, minorVersion: u8) !ws2_32.WSADATA { + var wsadata: ws2_32.WSADATA = undefined; + return switch (ws2_32.WSAStartup((@as(WORD, minorVersion) << 8) | majorVersion, &wsadata)) { + 0 => wsadata, + else => |err| unexpectedWSAError(err), + }; +} + +pub fn WSACleanup() !void { + return switch (ws2_32.WSACleanup()) { + 0 => {}, + ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) { + else => |err| return unexpectedWSAError(err), + }, + else => unreachable, + }; +} + pub fn WSASocketW( af: i32, socket_type: i32, diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index 1fe5d87496..d47c5a3d1d 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -2,6 +2,31 @@ usingnamespace @import("bits.zig"); pub const SOCKET = *@OpaqueType(); pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0)); +pub const SOCKET_ERROR = -1; + +pub const WSADESCRIPTION_LEN = 256; +pub const WSASYS_STATUS_LEN = 128; + +pub const WSADATA = if (usize.bit_count == u64.bit_count) + extern struct { + wVersion: WORD, + wHighVersion: WORD, + iMaxSockets: u16, + iMaxUdpDg: u16, + lpVendorInfo: *u8, + szDescription: [WSADESCRIPTION_LEN + 1]u8, + szSystemStatus: [WSASYS_STATUS_LEN + 1]u8, + } +else + extern struct { + wVersion: WORD, + wHighVersion: WORD, + szDescription: [WSADESCRIPTION_LEN + 1]u8, + szSystemStatus: [WSASYS_STATUS_LEN + 1]u8, + iMaxSockets: u16, + iMaxUdpDg: u16, + lpVendorInfo: *u8, + }; pub const MAX_PROTOCOL_CHAIN = 7; @@ -167,6 +192,11 @@ pub const WSA_QOS_ESDMODEOBJ = 11029; pub const WSA_QOS_ESHAPERATEOBJ = 11030; pub const WSA_QOS_RESERVED_PETYPE = 11031; +pub extern "ws2_32" stdcallcc fn WSAStartup( + wVersionRequired: WORD, + lpWSAData: *WSADATA, +) c_int; +pub extern "ws2_32" stdcallcc fn WSACleanup() c_int; pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int; pub extern "ws2_32" stdcallcc fn WSASocketA( af: c_int, From 3b8afe31a0c4cc1f6febb5f83566a897f765c98e Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 14 Nov 2019 15:33:47 +1100 Subject: [PATCH 10/11] std: add NtDeviceIoControlFile definition for windows --- lib/std/os/windows/ntdll.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 293891123e..d70b1cfefa 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -21,6 +21,18 @@ pub extern "NtDll" stdcallcc fn NtCreateFile( EaBuffer: ?*c_void, EaLength: ULONG, ) NTSTATUS; +pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( + FileHandle: HANDLE, + Event: ?HANDLE, + ApcRoutine: ?*IO_APC_ROUTINE, + ApcContext: usize, + IoStatusBlock: *IO_STATUS_BLOCK, + IoControlCode: ULONG, + InputBuffer: ?*const c_void, + InputBufferLength: ULONG, + OutputBuffer: ?PVOID, + OutputBufferLength: ULONG, +) NTSTATUS; pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS; pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U( DosPathName: [*]const u16, From 431eeb5e20d20584688235078c9f5d730e59a5b9 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 14 Nov 2019 16:34:13 +1100 Subject: [PATCH 11/11] 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;