Replace DeviceIoControl with FsControlFile
This commit replaces `windows.DeviceIoControl` with `windows.FsControlFile` which is a wrapper around the NT-based syscall `ntdll.NtFsControlFile`.master
parent
d1755e7f16
commit
f0ed2ed67f
|
@ -215,31 +215,35 @@ pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn DeviceIoControl(
|
pub const FsControlFileError = error{Unexpected};
|
||||||
|
|
||||||
|
// TODO work out if we need to expose other arguments to the underlying
|
||||||
|
// NtFsControlFile syscall
|
||||||
|
pub fn FsControlFile(
|
||||||
h: HANDLE,
|
h: HANDLE,
|
||||||
ioControlCode: DWORD,
|
fsControlCode: ULONG,
|
||||||
in: ?[]const u8,
|
in: ?[]const u8,
|
||||||
out: ?[]u8,
|
out: ?[]u8,
|
||||||
overlapped: ?*OVERLAPPED,
|
) FsControlFileError!void {
|
||||||
) !DWORD {
|
var io: IO_STATUS_BLOCK = undefined;
|
||||||
var bytes: DWORD = undefined;
|
const rc = ntdll.NtFsControlFile(
|
||||||
if (kernel32.DeviceIoControl(
|
|
||||||
h,
|
h,
|
||||||
ioControlCode,
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
&io,
|
||||||
|
fsControlCode,
|
||||||
if (in) |i| i.ptr else null,
|
if (in) |i| i.ptr else null,
|
||||||
if (in) |i| @intCast(u32, i.len) else 0,
|
if (in) |i| @intCast(ULONG, i.len) else 0,
|
||||||
if (out) |o| o.ptr else null,
|
if (out) |o| o.ptr else null,
|
||||||
if (out) |o| @intCast(u32, o.len) else 0,
|
if (out) |o| @intCast(ULONG, o.len) else 0,
|
||||||
&bytes,
|
);
|
||||||
overlapped,
|
switch (rc) {
|
||||||
) == 0) {
|
.SUCCESS => {},
|
||||||
switch (kernel32.GetLastError()) {
|
.INVALID_PARAMETER => unreachable,
|
||||||
.IO_PENDING => if (overlapped == null) unreachable,
|
else => return unexpectedStatus(rc),
|
||||||
else => |err| return unexpectedError(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
|
pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
|
||||||
var bytes: DWORD = undefined;
|
var bytes: DWORD = undefined;
|
||||||
|
@ -727,8 +731,7 @@ pub fn CreateSymbolicLinkW(
|
||||||
@memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2);
|
@memcpy(buffer[@sizeOf(SYMLINK_DATA)..], @ptrCast([*]const u8, target_path), target_path.len * 2);
|
||||||
const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2;
|
const paths_start = @sizeOf(SYMLINK_DATA) + target_path.len * 2;
|
||||||
@memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2);
|
@memcpy(buffer[paths_start..].ptr, @ptrCast([*]const u8, target_path), target_path.len * 2);
|
||||||
// TODO replace with NtDeviceIoControl
|
_ = try FsControlFile(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null);
|
||||||
_ = try DeviceIoControl(symlink_handle, FSCTL_SET_REPARSE_POINT, buffer[0..buf_len], null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ReadLinkError = error{
|
pub const ReadLinkError = error{
|
||||||
|
@ -806,7 +809,7 @@ pub fn ReadLinkW(dir: ?HANDLE, sub_path_w: [*:0]const u16, out_buffer: []u8) Rea
|
||||||
defer CloseHandle(result_handle);
|
defer CloseHandle(result_handle);
|
||||||
|
|
||||||
var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;
|
var reparse_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]u8 = undefined;
|
||||||
_ = try DeviceIoControl(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..], null);
|
_ = try FsControlFile(result_handle, FSCTL_GET_REPARSE_POINT, null, reparse_buf[0..]);
|
||||||
|
|
||||||
const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0]));
|
const reparse_struct = @ptrCast(*const REPARSE_DATA_BUFFER, @alignCast(@alignOf(REPARSE_DATA_BUFFER), &reparse_buf[0]));
|
||||||
switch (reparse_struct.ReparseTag) {
|
switch (reparse_struct.ReparseTag) {
|
||||||
|
|
|
@ -54,6 +54,18 @@ pub extern "NtDll" fn NtDeviceIoControlFile(
|
||||||
OutputBuffer: ?PVOID,
|
OutputBuffer: ?PVOID,
|
||||||
OutputBufferLength: ULONG,
|
OutputBufferLength: ULONG,
|
||||||
) callconv(.Stdcall) NTSTATUS;
|
) callconv(.Stdcall) NTSTATUS;
|
||||||
|
pub extern "NtDll" fn NtFsControlFile(
|
||||||
|
FileHandle: HANDLE,
|
||||||
|
Event: ?HANDLE,
|
||||||
|
ApcRoutine: ?IO_APC_ROUTINE,
|
||||||
|
ApcContext: ?*c_void,
|
||||||
|
IoStatusBlock: *IO_STATUS_BLOCK,
|
||||||
|
FsControlCode: ULONG,
|
||||||
|
InputBuffer: ?*const c_void,
|
||||||
|
InputBufferLength: ULONG,
|
||||||
|
OutputBuffer: ?PVOID,
|
||||||
|
OutputBufferLength: ULONG,
|
||||||
|
) callconv(.Stdcall) NTSTATUS;
|
||||||
pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;
|
pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;
|
||||||
pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(
|
pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(
|
||||||
DosPathName: [*:0]const u16,
|
DosPathName: [*:0]const u16,
|
||||||
|
|
Loading…
Reference in New Issue