From 547e520359b983d301670b8a3b37df67d4ab1a53 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 29 Jul 2020 09:02:21 +0200 Subject: [PATCH] Split DeviceIoControl path into two fn call paths As discussed in the previous commit, it would be better to avoid function pointers to syscalls and explicitly split the control path into two function calls instead. This commit addresses that for `std.os.windows.DeviceIoControl`. --- lib/std/os/windows.zig | 49 +++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 20ca28d318..b0b70139fd 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -228,20 +228,43 @@ pub fn DeviceIoControl( out: ?[]u8, ) DeviceIoControlError!void { // Logic from: https://doxygen.reactos.org/d3/d74/deviceio_8c.html - const syscall = if ((ioControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM) ntdll.NtFsControlFile else ntdll.NtDeviceIoControlFile; + const is_fsctl = (ioControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM; + var io: IO_STATUS_BLOCK = undefined; - const rc = syscall( - h, - null, - null, - null, - &io, - ioControlCode, - if (in) |i| i.ptr else null, - if (in) |i| @intCast(ULONG, i.len) else 0, - if (out) |o| o.ptr else null, - if (out) |o| @intCast(ULONG, o.len) else 0, - ); + const in_ptr = if (in) |i| i.ptr else null; + const in_len = if (in) |i| @intCast(ULONG, i.len) else 0; + const out_ptr = if (out) |o| o.ptr else null; + const out_len = if (out) |o| @intCast(ULONG, o.len) else 0; + + const rc = blk: { + if (is_fsctl) { + break :blk ntdll.NtFsControlFile( + h, + null, + null, + null, + &io, + ioControlCode, + in_ptr, + in_len, + out_ptr, + out_len, + ); + } else { + break :blk ntdll.NtDeviceIoControlFile( + h, + null, + null, + null, + &io, + ioControlCode, + in_ptr, + in_len, + out_ptr, + out_len, + ); + } + }; switch (rc) { .SUCCESS => {}, .INVALID_PARAMETER => unreachable,