Skip to content

Commit

Permalink
Support afd endpoint serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Nov 17, 2024
1 parent d05ccdd commit a87bb85
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 17 deletions.
21 changes: 20 additions & 1 deletion src/emulator/serialization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <functional>
#include <typeindex>

void serialize();
void deserialize();

namespace utils
{
class buffer_serializer;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {};
}
Expand Down
35 changes: 28 additions & 7 deletions src/windows-emulator/devices/afd_endpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_{};
Expand All @@ -204,17 +205,29 @@ 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!");
}

network::socket::set_blocking(sock, false);

s_ = sock;
this->s_ = sock;
}

void delay_ioctrl(const io_device_context& c,
Expand Down Expand Up @@ -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
Expand Down
28 changes: 27 additions & 1 deletion src/windows-emulator/emulator_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
50 changes: 42 additions & 8 deletions src/windows-emulator/io_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/windows-emulator/windows_emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit a87bb85

Please sign in to comment.