mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-20 12:13:57 +00:00
Better event support
This commit is contained in:
@@ -68,16 +68,35 @@ constexpr handle make_pseudo_handle(const uint32_t id, const handle_types::type
|
||||
return make_handle(id, type, true);
|
||||
}
|
||||
|
||||
namespace handle_detail
|
||||
{
|
||||
template <typename, typename = void>
|
||||
struct has_deleter_function : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_deleter_function<T, std::void_t<decltype(T::deleter(std::declval<T&>()))>>
|
||||
: std::is_same<decltype(T::deleter(std::declval<T&>())), bool> {};
|
||||
}
|
||||
|
||||
template <handle_types::type Type, typename T>
|
||||
requires(utils::Serializable<T>)
|
||||
class handle_store
|
||||
{
|
||||
public:
|
||||
using value_map = std::map<uint32_t, T>;
|
||||
|
||||
handle store(T value)
|
||||
{
|
||||
auto index = this->find_free_index();
|
||||
this->store_[index] = std::move(value);
|
||||
|
||||
return make_handle(index);
|
||||
}
|
||||
|
||||
handle make_handle(const uint32_t index)
|
||||
{
|
||||
handle h{};
|
||||
h.bits = 0;
|
||||
h.value.is_pseudo = false;
|
||||
@@ -119,6 +138,14 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if constexpr (handle_detail::has_deleter_function<T>())
|
||||
{
|
||||
if (!T::deleter(entry->second))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
this->store_.erase(entry);
|
||||
return true;
|
||||
}
|
||||
@@ -146,8 +173,26 @@ public:
|
||||
buffer.read_map(this->store_);
|
||||
}
|
||||
|
||||
value_map::iterator begin() {
|
||||
return this->store_.begin();
|
||||
}
|
||||
|
||||
value_map::const_iterator begin() const
|
||||
{
|
||||
return this->store_.begin();
|
||||
}
|
||||
|
||||
value_map::iterator end()
|
||||
{
|
||||
return this->store_.end();
|
||||
}
|
||||
|
||||
value_map::const_iterator end() const
|
||||
{
|
||||
return this->store_.end();
|
||||
}
|
||||
|
||||
private:
|
||||
using value_map = std::map<uint32_t, T>;
|
||||
|
||||
typename value_map::iterator get_iterator(const handle_value h)
|
||||
{
|
||||
|
||||
@@ -90,8 +90,8 @@ namespace
|
||||
void run()
|
||||
{
|
||||
const std::filesystem::path application =
|
||||
R"(C:\Users\mauri\source\repos\ConsoleApplication6\x64\Release\ConsoleApplication6.exe)";
|
||||
//R"(C:\Program Files (x86)\Steam\steamapps\common\Hogwarts Legacy\Phoenix\Binaries\Win64\HogwartsLegacy.exe)";
|
||||
//R"(C:\Users\mauri\source\repos\ConsoleApplication6\x64\Release\ConsoleApplication6.exe)";
|
||||
R"(C:\Program Files (x86)\Steam\steamapps\common\Hogwarts Legacy\Phoenix\Binaries\Win64\HogwartsLegacy.exe)";
|
||||
|
||||
windows_emulator win_emu{application, {L"Hello", L"World"}};
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ struct event
|
||||
{
|
||||
bool signaled{};
|
||||
EVENT_TYPE type{};
|
||||
std::wstring name{};
|
||||
uint32_t ref_count{0};
|
||||
|
||||
bool is_signaled()
|
||||
{
|
||||
@@ -28,12 +30,21 @@ struct event
|
||||
{
|
||||
buffer.write(this->signaled);
|
||||
buffer.write(this->type);
|
||||
buffer.write(this->name);
|
||||
buffer.write(this->ref_count);
|
||||
}
|
||||
|
||||
void deserialize(utils::buffer_deserializer& buffer)
|
||||
{
|
||||
buffer.read(this->signaled);
|
||||
buffer.read(this->type);
|
||||
buffer.read(this->name);
|
||||
buffer.read(this->ref_count);
|
||||
}
|
||||
|
||||
static bool deleter(event& e)
|
||||
{
|
||||
return --e.ref_count == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -308,18 +308,21 @@ namespace
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes,
|
||||
const EVENT_TYPE event_type, const BOOLEAN initial_state)
|
||||
{
|
||||
std::wstring name{};
|
||||
if (object_attributes)
|
||||
{
|
||||
//const auto attributes = object_attributes.read();
|
||||
|
||||
puts("Unsupported object attributes");
|
||||
//c.emu.stop();
|
||||
//return STATUS_NOT_SUPPORTED;
|
||||
const auto attributes = object_attributes.read();
|
||||
if (attributes.ObjectName)
|
||||
{
|
||||
name = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
}
|
||||
}
|
||||
|
||||
event e{};
|
||||
e.type = event_type;
|
||||
e.signaled = initial_state != FALSE;
|
||||
e.ref_count = 1;
|
||||
e.name = std::move(name);
|
||||
|
||||
const auto handle = c.proc.events.store(std::move(e));
|
||||
event_handle.write(handle.bits);
|
||||
@@ -330,6 +333,26 @@ namespace
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtOpenEvent(const syscall_context& c, const emulator_object<uint64_t> event_handle,
|
||||
const ACCESS_MASK /*desired_access*/,
|
||||
const emulator_object<OBJECT_ATTRIBUTES> object_attributes)
|
||||
{
|
||||
const auto attributes = object_attributes.read();
|
||||
const auto name = read_unicode_string(c.emu, attributes.ObjectName);
|
||||
|
||||
for (auto& entry : c.proc.events)
|
||||
{
|
||||
if (entry.second.name == name)
|
||||
{
|
||||
++entry.second.ref_count;
|
||||
event_handle.write(c.proc.events.make_handle(entry.first).bits);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
NTSTATUS handle_NtQueryVolumeInformationFile(const syscall_context& c, uint64_t /*file_handle*/,
|
||||
uint64_t /*io_status_block*/, uint64_t fs_information,
|
||||
ULONG /*length*/,
|
||||
@@ -1696,8 +1719,6 @@ void syscall_dispatcher::add_handlers()
|
||||
std::unordered_map<std::string, syscall_handler> handler_mapping{};
|
||||
handler_mapping.reserve(this->handlers_.size());
|
||||
|
||||
make_syscall_handler<handle_NtCreateEvent>();
|
||||
|
||||
#define add_handler(syscall) \
|
||||
do \
|
||||
{ \
|
||||
@@ -1761,6 +1782,7 @@ void syscall_dispatcher::add_handlers()
|
||||
add_handler(NtUserGetThreadState);
|
||||
add_handler(NtOpenKeyEx);
|
||||
add_handler(NtUserDisplayConfigGetDeviceInfo);
|
||||
add_handler(NtOpenEvent);
|
||||
|
||||
#undef add_handler
|
||||
|
||||
|
||||
Reference in New Issue
Block a user