mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
Support afd endpoint serialization
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
#include <functional>
|
||||
#include <typeindex>
|
||||
|
||||
void serialize();
|
||||
void deserialize();
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class buffer_serializer;
|
||||
@@ -57,6 +60,18 @@ namespace utils
|
||||
: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename, typename = void>
|
||||
struct has_construct_function : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_construct_function<T, std::void_t<decltype(T::construct(
|
||||
std::declval<buffer_deserializer&>()))>>
|
||||
: std::bool_constant<std::is_same_v<decltype(T::construct(std::declval<buffer_deserializer&>())), T>>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
class buffer_deserializer
|
||||
@@ -291,7 +306,11 @@ namespace utils
|
||||
template <typename T>
|
||||
T construct_object()
|
||||
{
|
||||
if constexpr (std::is_default_constructible_v<T>)
|
||||
if constexpr (detail::has_construct_function<T>::value)
|
||||
{
|
||||
return T::construct(*this);
|
||||
}
|
||||
else if constexpr (std::is_default_constructible_v<T>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -181,6 +181,7 @@ namespace
|
||||
struct afd_endpoint : io_device
|
||||
{
|
||||
bool executing_delayed_ioctl_{};
|
||||
std::optional<afd_creation_data> creation_data{};
|
||||
std::optional<SOCKET> s_{};
|
||||
std::optional<bool> require_poll_{};
|
||||
std::optional<io_device_context> delayed_ioctl_{};
|
||||
@@ -204,9 +205,21 @@ namespace
|
||||
|
||||
void create(windows_emulator& win_emu, const io_device_creation_data& data) override
|
||||
{
|
||||
const auto creation_data = get_creation_data(win_emu, data);
|
||||
this->creation_data = get_creation_data(win_emu, data);
|
||||
this->setup();
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
if (!this->creation_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& data = *this->creation_data;
|
||||
|
||||
// TODO: values map to windows values; might not be the case for other platforms
|
||||
const auto sock = socket(creation_data.address_family, creation_data.type, creation_data.protocol);
|
||||
const auto sock = socket(data.address_family, data.type, data.protocol);
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
throw std::runtime_error("Failed to create socket!");
|
||||
@@ -214,7 +227,7 @@ namespace
|
||||
|
||||
network::socket::set_blocking(sock, false);
|
||||
|
||||
s_ = sock;
|
||||
this->s_ = sock;
|
||||
}
|
||||
|
||||
void delay_ioctrl(const io_device_context& c,
|
||||
@@ -280,14 +293,22 @@ namespace
|
||||
this->clear_pending_state();
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer&) override
|
||||
void deserialize(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
// TODO
|
||||
buffer.read(this->creation_data);
|
||||
this->setup();
|
||||
|
||||
buffer.read(this->require_poll_);
|
||||
buffer.read(this->delayed_ioctl_);
|
||||
buffer.read(this->timeout_);
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer&) const override
|
||||
void serialize(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
// TODO
|
||||
buffer.write(this->creation_data);
|
||||
buffer.write(this->require_poll_);
|
||||
buffer.write(this->delayed_ioctl_);
|
||||
buffer.write(this->timeout_);
|
||||
}
|
||||
|
||||
NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override
|
||||
|
||||
@@ -4,13 +4,39 @@
|
||||
// TODO: Replace with pointer handling structure for future 32 bit support
|
||||
using emulator_pointer = uint64_t;
|
||||
|
||||
struct emulator_wrapper
|
||||
{
|
||||
emulator* emu;
|
||||
|
||||
emulator& get() const
|
||||
{
|
||||
return *this->emu;
|
||||
}
|
||||
|
||||
operator emulator&() const
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer&) const
|
||||
{
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class emulator_object
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
//emulator_object() = default;
|
||||
emulator_object(const emulator_wrapper& wrapper, const uint64_t address = 0)
|
||||
: emulator_object(wrapper.emu, address)
|
||||
{
|
||||
}
|
||||
|
||||
emulator_object(emulator& emu, const uint64_t address = 0)
|
||||
: emu_(&emu)
|
||||
|
||||
@@ -12,15 +12,49 @@ struct process_context;
|
||||
|
||||
struct io_device_context
|
||||
{
|
||||
handle event;
|
||||
emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine;
|
||||
emulator_pointer apc_context;
|
||||
handle event{};
|
||||
emulator_pointer /*PIO_APC_ROUTINE*/ apc_routine{};
|
||||
emulator_pointer apc_context{};
|
||||
emulator_object<IO_STATUS_BLOCK> io_status_block;
|
||||
ULONG io_control_code;
|
||||
emulator_pointer input_buffer;
|
||||
ULONG input_buffer_length;
|
||||
emulator_pointer output_buffer;
|
||||
ULONG output_buffer_length;
|
||||
ULONG io_control_code{};
|
||||
emulator_pointer input_buffer{};
|
||||
ULONG input_buffer_length{};
|
||||
emulator_pointer output_buffer{};
|
||||
ULONG output_buffer_length{};
|
||||
|
||||
static io_device_context construct(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
const auto wrapper = buffer.read<emulator_wrapper>();
|
||||
return io_device_context{
|
||||
.io_status_block = wrapper.get(),
|
||||
};
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(event);
|
||||
buffer.write(apc_routine);
|
||||
buffer.write(apc_context);
|
||||
buffer.write(io_status_block);
|
||||
buffer.write(io_control_code);
|
||||
buffer.write(input_buffer);
|
||||
buffer.write(input_buffer_length);
|
||||
buffer.write(output_buffer);
|
||||
buffer.write(output_buffer_length);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(event);
|
||||
buffer.read(apc_routine);
|
||||
buffer.read(apc_context);
|
||||
buffer.read(io_status_block);
|
||||
buffer.read(io_control_code);
|
||||
buffer.read(input_buffer);
|
||||
buffer.read(input_buffer_length);
|
||||
buffer.read(output_buffer);
|
||||
buffer.read(output_buffer_length);
|
||||
}
|
||||
};
|
||||
|
||||
struct io_device_creation_data
|
||||
|
||||
@@ -1046,6 +1046,13 @@ void windows_emulator::serialize(utils::buffer_serializer& buffer) const
|
||||
|
||||
void windows_emulator::deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.register_factory<emulator_wrapper>([this]
|
||||
{
|
||||
return emulator_wrapper{
|
||||
.emu = &this->emu(),
|
||||
};
|
||||
});
|
||||
|
||||
buffer.register_factory<emulator_thread>([this]
|
||||
{
|
||||
return emulator_thread(this->emu());
|
||||
|
||||
Reference in New Issue
Block a user