Commit d9d3268cc1

daurnimator <quae@daurnimator.com>
2019-11-13 08:22:33
std: add DeviceIoControl and GetOverlappedResult for windows
1 parent f4c6cc3
Changed files (2)
lib
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;
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 {