mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
Fix more handles
This commit is contained in:
@@ -474,7 +474,7 @@ namespace
|
||||
this->clear_pending_state();
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer) override
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read_optional(this->creation_data);
|
||||
this->setup();
|
||||
@@ -484,7 +484,7 @@ namespace
|
||||
buffer.read_optional(this->timeout_);
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const override
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write_optional(this->creation_data);
|
||||
buffer.write_optional(this->require_poll_);
|
||||
|
||||
@@ -111,14 +111,44 @@ namespace handle_detail
|
||||
};
|
||||
}
|
||||
|
||||
class ref_counted_object
|
||||
{
|
||||
public:
|
||||
virtual ~ref_counted_object() = default;
|
||||
|
||||
uint32_t ref_count{1};
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(this->ref_count);
|
||||
this->serialize_object(buffer);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(this->ref_count);
|
||||
this->deserialize_object(buffer);
|
||||
}
|
||||
|
||||
static bool deleter(ref_counted_object& e)
|
||||
{
|
||||
return --e.ref_count == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void serialize_object(utils::buffer_serializer& buffer) const = 0;
|
||||
virtual void deserialize_object(utils::buffer_deserializer& buffer) = 0;
|
||||
};
|
||||
|
||||
struct generic_handle_store
|
||||
{
|
||||
virtual ~generic_handle_store() = default;
|
||||
virtual bool erase(handle h) = 0;
|
||||
virtual std::optional<handle> duplicate(handle h) = 0;
|
||||
};
|
||||
|
||||
template <handle_types::type Type, typename T, uint32_t IndexShift = 0>
|
||||
requires(utils::Serializable<T>)
|
||||
requires(utils::Serializable<T> && std::is_base_of_v<ref_counted_object, T>)
|
||||
class handle_store : public generic_handle_store
|
||||
{
|
||||
public:
|
||||
@@ -189,6 +219,18 @@ class handle_store : public generic_handle_store
|
||||
return this->store_.size();
|
||||
}
|
||||
|
||||
std::optional<handle> duplicate(const handle h) override
|
||||
{
|
||||
auto* entry = this->get(h);
|
||||
if (!entry)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
++static_cast<ref_counted_object*>(entry)->ref_count;
|
||||
return h;
|
||||
}
|
||||
|
||||
bool erase(const typename value_map::iterator& entry)
|
||||
{
|
||||
if (this->block_mutation_)
|
||||
|
||||
@@ -76,10 +76,10 @@ inline void write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits
|
||||
}
|
||||
}
|
||||
|
||||
struct io_device
|
||||
struct io_device : ref_counted_object
|
||||
{
|
||||
io_device() = default;
|
||||
virtual ~io_device() = default;
|
||||
~io_device() override = default;
|
||||
|
||||
io_device(io_device&&) = default;
|
||||
io_device& operator=(io_device&&) = default;
|
||||
@@ -100,9 +100,6 @@ struct io_device
|
||||
(void)win_emu;
|
||||
}
|
||||
|
||||
virtual void serialize(utils::buffer_serializer& buffer) const = 0;
|
||||
virtual void deserialize(utils::buffer_deserializer& buffer) = 0;
|
||||
|
||||
NTSTATUS execute_ioctl(windows_emulator& win_emu, const io_device_context& c)
|
||||
{
|
||||
if (c.io_status_block)
|
||||
@@ -122,11 +119,11 @@ struct stateless_device : io_device
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer&) const override
|
||||
void serialize_object(utils::buffer_serializer&) const override
|
||||
{
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer&) override
|
||||
void deserialize_object(utils::buffer_deserializer&) override
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -157,7 +154,7 @@ class io_device_container : public io_device
|
||||
return this->device_->work(win_emu);
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const override
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
this->assert_validity();
|
||||
|
||||
@@ -165,7 +162,7 @@ class io_device_container : public io_device
|
||||
this->device_->serialize(buffer);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer) override
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read_string(this->device_name_);
|
||||
this->setup();
|
||||
|
||||
@@ -27,26 +27,6 @@
|
||||
|
||||
class windows_emulator;
|
||||
|
||||
struct ref_counted_object
|
||||
{
|
||||
uint32_t ref_count{1};
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(this->ref_count);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(this->ref_count);
|
||||
}
|
||||
|
||||
static bool deleter(ref_counted_object& e)
|
||||
{
|
||||
return --e.ref_count == 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct event : ref_counted_object
|
||||
{
|
||||
bool signaled{};
|
||||
@@ -65,22 +45,18 @@ struct event : ref_counted_object
|
||||
return res;
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write(this->signaled);
|
||||
buffer.write(this->type);
|
||||
buffer.write(this->name);
|
||||
|
||||
ref_counted_object::serialize(buffer);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->signaled);
|
||||
buffer.read(this->type);
|
||||
buffer.read(this->name);
|
||||
|
||||
ref_counted_object::deserialize(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -121,22 +97,18 @@ struct mutant : ref_counted_object
|
||||
return {old_count, true};
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write(this->locked_count);
|
||||
buffer.write(this->owning_thread_id);
|
||||
buffer.write(this->name);
|
||||
|
||||
ref_counted_object::serialize(buffer);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->locked_count);
|
||||
buffer.read(this->owning_thread_id);
|
||||
buffer.read(this->name);
|
||||
|
||||
ref_counted_object::deserialize(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -173,7 +145,7 @@ struct file_enumeration_state
|
||||
}
|
||||
};
|
||||
|
||||
struct file
|
||||
struct file : ref_counted_object
|
||||
{
|
||||
utils::file_handle handle{};
|
||||
std::u16string name{};
|
||||
@@ -189,14 +161,14 @@ struct file
|
||||
return !this->is_file();
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
// TODO: Serialize handle
|
||||
buffer.write(this->name);
|
||||
buffer.write_optional(this->enumeration_state);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->name);
|
||||
buffer.read_optional(this->enumeration_state);
|
||||
@@ -204,7 +176,7 @@ struct file
|
||||
}
|
||||
};
|
||||
|
||||
struct section
|
||||
struct section : ref_counted_object
|
||||
{
|
||||
std::u16string name{};
|
||||
std::u16string file_name{};
|
||||
@@ -217,7 +189,7 @@ struct section
|
||||
return this->allocation_attributes & SEC_IMAGE;
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write(this->name);
|
||||
buffer.write(this->file_name);
|
||||
@@ -226,7 +198,7 @@ struct section
|
||||
buffer.write(this->allocation_attributes);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->name);
|
||||
buffer.read(this->file_name);
|
||||
@@ -267,37 +239,33 @@ struct semaphore : ref_counted_object
|
||||
return {old_count, true};
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write(this->name);
|
||||
buffer.write(this->current_count);
|
||||
buffer.write(this->max_count);
|
||||
|
||||
ref_counted_object::serialize(buffer);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->name);
|
||||
buffer.read(this->current_count);
|
||||
buffer.read(this->max_count);
|
||||
|
||||
ref_counted_object::deserialize(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct port
|
||||
struct port : ref_counted_object
|
||||
{
|
||||
std::u16string name{};
|
||||
uint64_t view_base{};
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write(this->name);
|
||||
buffer.write(this->view_base);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->name);
|
||||
buffer.read(this->view_base);
|
||||
@@ -439,7 +407,7 @@ class emulator_thread : public ref_counted_object
|
||||
}
|
||||
}
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
if (this->marker.was_moved())
|
||||
{
|
||||
@@ -470,7 +438,7 @@ class emulator_thread : public ref_counted_object
|
||||
buffer.write_vector(this->last_registers);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
if (this->marker.was_moved())
|
||||
{
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
#include "../std_include.hpp"
|
||||
#include "hive_parser.hpp"
|
||||
#include "serialization_helper.hpp"
|
||||
#include "../handles.hpp"
|
||||
|
||||
struct registry_key
|
||||
struct registry_key : ref_counted_object
|
||||
{
|
||||
utils::path_key hive{};
|
||||
utils::path_key path{};
|
||||
|
||||
void serialize(utils::buffer_serializer& buffer) const
|
||||
void serialize_object(utils::buffer_serializer& buffer) const override
|
||||
{
|
||||
buffer.write(this->hive);
|
||||
buffer.write(this->path);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
void deserialize_object(utils::buffer_deserializer& buffer) override
|
||||
{
|
||||
buffer.read(this->hive);
|
||||
buffer.read(this->path);
|
||||
|
||||
@@ -1108,8 +1108,20 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
c.win_emu.log.error("Duplicating non-pseudo object not supported yet!\n");
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
auto* store = get_handle_store(c.proc, source_handle);
|
||||
if (!store)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const auto new_handle = store->duplicate(source_handle);
|
||||
if (!new_handle)
|
||||
{
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
target_handle.write(*new_handle);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQuerySystemInformationEx(const syscall_context& c, const uint32_t info_class,
|
||||
@@ -3302,6 +3314,11 @@ namespace
|
||||
return handle_NtUserGetDCEx();
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserGetWindowDC()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtUserReleaseDC()
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
@@ -3734,6 +3751,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
|
||||
add_handler(NtUserModifyUserStartupInfoFlags);
|
||||
add_handler(NtUserGetDCEx);
|
||||
add_handler(NtUserGetDC);
|
||||
add_handler(NtUserGetWindowDC);
|
||||
add_handler(NtUserGetDpiForCurrentProcess);
|
||||
add_handler(NtReleaseSemaphore);
|
||||
add_handler(NtEnumerateKey);
|
||||
|
||||
Reference in New Issue
Block a user