From e80b3e588c1fe77df3baf8f2a03b1dbf9f051d98 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Wed, 6 Nov 2024 19:55:28 +0100 Subject: [PATCH] Prepare I/O control support --- src/windows-emulator/io_device.cpp | 7 +--- src/windows-emulator/io_device.hpp | 38 ++++++++++++------ src/windows-emulator/syscall_dispatcher.hpp | 2 +- src/windows-emulator/syscalls.cpp | 44 +++++++++++++++------ 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index 17f6264..9b29979 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -4,12 +4,9 @@ namespace { struct dummy_device : stateless_device { - void read() override - { - } - - void write() override + NTSTATUS io_control(const io_device_context&) override { + return STATUS_SUCCESS; } }; } diff --git a/src/windows-emulator/io_device.hpp b/src/windows-emulator/io_device.hpp index f58ad97..fa3f11e 100644 --- a/src/windows-emulator/io_device.hpp +++ b/src/windows-emulator/io_device.hpp @@ -1,8 +1,32 @@ #pragma once #include +#include #include +#include "emulator_utils.hpp" +#include "handles.hpp" + +class windows_emulator; +struct process_context; + +struct io_device_context +{ + windows_emulator& win_emu; + x64_emulator& emu; + process_context& proc; + + handle event; + emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine; + emulator_pointer apc_context; + emulator_object io_status_block; + ULONG io_control_code; + emulator_pointer input_buffer; + ULONG input_buffer_length; + emulator_pointer output_buffer; + ULONG output_buffer_length; +}; + struct io_device { io_device() = default; @@ -14,9 +38,7 @@ struct io_device io_device(const io_device&) = delete; io_device& operator=(const io_device&) = delete; - // TODO - virtual void read() = 0; - virtual void write() = 0; + virtual NTSTATUS io_control(const io_device_context& context) = 0; virtual void serialize(utils::buffer_serializer& buffer) const = 0; virtual void deserialize(utils::buffer_deserializer& buffer) = 0; @@ -46,16 +68,10 @@ class io_device_container : public io_device this->setup(); } - void read() override - { - this->assert_validity(); - this->device_->read(); - } - - void write() override + NTSTATUS io_control(const io_device_context& context) override { this->assert_validity(); - this->device_->write(); + return this->device_->io_control(context); } void serialize(utils::buffer_serializer& buffer) const override diff --git a/src/windows-emulator/syscall_dispatcher.hpp b/src/windows-emulator/syscall_dispatcher.hpp index 398b64a..ac5fc43 100644 --- a/src/windows-emulator/syscall_dispatcher.hpp +++ b/src/windows-emulator/syscall_dispatcher.hpp @@ -34,6 +34,6 @@ class syscall_dispatcher private: std::map handlers_{}; - void add_handlers(std::map& handler_mapping); + static void add_handlers(std::map& handler_mapping); void add_handlers(); }; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 3478895..1e3e5e6 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -1649,18 +1649,38 @@ namespace return STATUS_SUCCESS; } - NTSTATUS handle_NtDeviceIoControlFile(const syscall_context&, const handle /*file_handle*/, - const handle /*event*/, - const emulator_pointer /*PIO_APC_ROUTINE*/ /*apc_routine*/, - const emulator_pointer /*apc_context*/, - const emulator_object /*io_status_block*/, - const ULONG /*io_control_code*/, - const emulator_pointer /*input_buffer*/, - const ULONG /*input_buffer_length*/, const emulator_pointer /*output_buffer*/, - const ULONG /*output_buffer_length*/) - { - //puts("NtDeviceIoControlFile not supported"); - return STATUS_SUCCESS; + NTSTATUS handle_NtDeviceIoControlFile(const syscall_context& c, const handle file_handle, + const handle event, + const emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine, + const emulator_pointer apc_context, + const emulator_object io_status_block, + const ULONG io_control_code, + const emulator_pointer input_buffer, + const ULONG input_buffer_length, const emulator_pointer output_buffer, + const ULONG output_buffer_length) + { + auto* device = c.proc.devices.get(file_handle); + if (!device) + { + return STATUS_INVALID_HANDLE; + } + + const io_device_context context{ + .win_emu = c.win_emu, + .emu = c.emu, + .proc = c.proc, + .event = event, + .apc_routine = apc_routine, + .apc_context = apc_context, + .io_status_block = io_status_block, + .io_control_code = io_control_code, + .input_buffer = input_buffer, + .input_buffer_length = input_buffer_length, + .output_buffer = output_buffer, + .output_buffer_length = output_buffer_length, + }; + + return device->io_control(context); } NTSTATUS handle_NtQueryWnfStateData()