diff --git a/src/windows_emulator/handles.hpp b/src/windows_emulator/handles.hpp index c28661a8..c557a8cd 100644 --- a/src/windows_emulator/handles.hpp +++ b/src/windows_emulator/handles.hpp @@ -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 + struct has_deleter_function : std::false_type + { + }; + + template + struct has_deleter_function()))>> + : std::is_same())), bool> {}; +} + template requires(utils::Serializable) class handle_store { public: + using value_map = std::map; + 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()) + { + 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; typename value_map::iterator get_iterator(const handle_value h) { diff --git a/src/windows_emulator/main.cpp b/src/windows_emulator/main.cpp index 116a2708..b17b56cc 100644 --- a/src/windows_emulator/main.cpp +++ b/src/windows_emulator/main.cpp @@ -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"}}; diff --git a/src/windows_emulator/process_context.hpp b/src/windows_emulator/process_context.hpp index b2e590fa..7825fd90 100644 --- a/src/windows_emulator/process_context.hpp +++ b/src/windows_emulator/process_context.hpp @@ -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; } }; diff --git a/src/windows_emulator/syscalls.cpp b/src/windows_emulator/syscalls.cpp index d570d15c..4ec6b2cc 100644 --- a/src/windows_emulator/syscalls.cpp +++ b/src/windows_emulator/syscalls.cpp @@ -308,18 +308,21 @@ namespace const emulator_object 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 event_handle, + const ACCESS_MASK /*desired_access*/, + const emulator_object 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 handler_mapping{}; handler_mapping.reserve(this->handlers_.size()); - make_syscall_handler(); - #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