Support afd endpoint serialization

This commit is contained in:
momo5502
2024-11-17 09:23:45 +01:00
parent d05ccdd04c
commit a87bb85858
5 changed files with 124 additions and 17 deletions

View File

@@ -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 {};
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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());