From 009961620bd261135e28e494f4f376b3e31e8dc2 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 1 Jun 2025 13:57:14 +0200 Subject: [PATCH 1/2] Fix thread deletion --- src/windows-emulator/emulator_thread.hpp | 5 +++++ src/windows-emulator/handles.hpp | 5 +++++ src/windows-emulator/syscalls/object.cpp | 2 +- src/windows-emulator/windows_emulator.cpp | 21 +++++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/windows-emulator/emulator_thread.hpp b/src/windows-emulator/emulator_thread.hpp index e9907d08..c0b5b891 100644 --- a/src/windows-emulator/emulator_thread.hpp +++ b/src/windows-emulator/emulator_thread.hpp @@ -210,6 +210,11 @@ class emulator_thread : public ref_counted_object this->marker.mark_as_moved(); } + static bool deleter(emulator_thread& t) + { + return ref_counted_object::deleter(t) && t.is_terminated(); + } + private: void setup_registers(x86_64_emulator& emu, const process_context& context) const; diff --git a/src/windows-emulator/handles.hpp b/src/windows-emulator/handles.hpp index a5430973..d105fbc4 100644 --- a/src/windows-emulator/handles.hpp +++ b/src/windows-emulator/handles.hpp @@ -136,6 +136,11 @@ class ref_counted_object static bool deleter(ref_counted_object& e) { + if (e.ref_count == 0) + { + return true; + } + return --e.ref_count == 0; } diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index 024a04b9..ae7c134c 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -15,7 +15,7 @@ namespace syscalls if (h.value.type == handle_types::thread) { const auto* t = c.proc.threads.get(h); - if (t == c.proc.active_thread && t->ref_count == 1) + if (t && t->ref_count == 1) { // TODO: Better handle ref counting return STATUS_SUCCESS; diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 8911a48b..76cf20ba 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -50,6 +50,27 @@ namespace void perform_context_switch_work(windows_emulator& win_emu) { + auto& threads = win_emu.process.threads; + + for (auto it = threads.begin(); it != threads.end();) + { + if (!it->second.is_terminated() || it->second.ref_count > 0) + { + ++it; + continue; + } + + const auto [new_it, deleted] = threads.erase(it); + if (!deleted) + { + ++it; + } + else + { + it = new_it; + } + } + auto& devices = win_emu.process.devices; // Crappy mechanism to prevent mutation while iterating. From aa763c8392f3b943efc1afdeda617ba85ed7d474 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 1 Jun 2025 14:02:36 +0200 Subject: [PATCH 2/2] Prepare more timer syscalls --- src/windows-emulator/emulator_thread.cpp | 4 ++++ src/windows-emulator/syscalls.cpp | 3 +++ src/windows-emulator/syscalls/object.cpp | 1 + src/windows-emulator/syscalls/timer.cpp | 6 ++++++ 4 files changed, 14 insertions(+) diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index e3628706..8f1b3fd6 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -58,6 +58,10 @@ namespace return !e || e->try_lock(current_thread_id); } + case handle_types::timer: { + return true; // TODO + } + case handle_types::semaphore: { auto* s = c.semaphores.get(h); if (s) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index b8e5ec76..971fc5b0 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -361,6 +361,8 @@ namespace syscalls NTSTATUS handle_NtCreateTimer2(const syscall_context& c, emulator_object timer_handle, uint64_t reserved, emulator_object>> object_attributes, ULONG attributes, ACCESS_MASK desired_access); + NTSTATUS handle_NtSetTimerEx(const syscall_context& c, handle timer_handle, uint32_t timer_set_info_class, + uint64_t timer_set_information, ULONG timer_set_information_length); // syscalls/token.cpp: NTSTATUS @@ -1104,6 +1106,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtUserSetCursor); add_handler(NtOpenMutant); add_handler(NtCreateTimer2); + add_handler(NtSetTimerEx); #undef add_handler } diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index ae7c134c..db66de02 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -119,6 +119,7 @@ namespace syscalls return h.value.type == handle_types::thread // || h.value.type == handle_types::mutant // || h.value.type == handle_types::semaphore // + || h.value.type == handle_types::timer // || h.value.type == handle_types::event; } diff --git a/src/windows-emulator/syscalls/timer.cpp b/src/windows-emulator/syscalls/timer.cpp index 329a3ab2..2f683bed 100644 --- a/src/windows-emulator/syscalls/timer.cpp +++ b/src/windows-emulator/syscalls/timer.cpp @@ -69,4 +69,10 @@ namespace syscalls return STATUS_SUCCESS; } + NTSTATUS handle_NtSetTimerEx(const syscall_context& /*c*/, handle /*timer_handle*/, + uint32_t /*timer_set_info_class*/, uint64_t /*timer_set_information*/, + ULONG /*timer_set_information_length*/) + { + return STATUS_NOT_SUPPORTED; + } }