Function DeviceIoControl [src]
A Zig wrapper around NtDeviceIoControlFile and NtFsControlFile syscalls.
It implements similar behavior to DeviceIoControl and is meant to serve
as a direct substitute for that call.
TODO work out if we need to expose other arguments to the underlying syscalls.
Prototype
pub fn DeviceIoControl( h: HANDLE, ioControlCode: ULONG, in: ?[]const u8, out: ?[]u8, ) DeviceIoControlError!void
Parameters
h: HANDLE
ioControlCode: ULONG
in: ?[]const u8
out: ?[]u8
Possible Errors
The volume does not contain a recognized file system. File system drivers might not be loaded, or the volume may be corrupt.
Source
pub fn DeviceIoControl(
h: HANDLE,
ioControlCode: ULONG,
in: ?[]const u8,
out: ?[]u8,
) DeviceIoControlError!void {
// Logic from: https://doxygen.reactos.org/d3/d74/deviceio_8c.html
const is_fsctl = (ioControlCode >> 16) == FILE_DEVICE_FILE_SYSTEM;
var io: IO_STATUS_BLOCK = undefined;
const in_ptr = if (in) |i| i.ptr else null;
const in_len = if (in) |i| @as(ULONG, @intCast(i.len)) else 0;
const out_ptr = if (out) |o| o.ptr else null;
const out_len = if (out) |o| @as(ULONG, @intCast(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 => {},
.PRIVILEGE_NOT_HELD => return error.AccessDenied,
.ACCESS_DENIED => return error.AccessDenied,
.INVALID_DEVICE_REQUEST => return error.AccessDenied, // Not supported by the underlying filesystem
.INVALID_PARAMETER => unreachable,
.UNRECOGNIZED_VOLUME => return error.UnrecognizedVolume,
else => return unexpectedStatus(rc),
}
}