diff --git a/src/windows-emulator/emulator_thread.hpp b/src/windows-emulator/emulator_thread.hpp index b0cc364b..d3e34c3a 100644 --- a/src/windows-emulator/emulator_thread.hpp +++ b/src/windows-emulator/emulator_thread.hpp @@ -54,6 +54,7 @@ class emulator_thread : public ref_counted_object bool await_any{false}; bool waiting_for_alert{false}; bool alerted{false}; + bool apc_alertable{false}; uint32_t suspended{0}; std::optional await_time{}; @@ -123,6 +124,7 @@ class emulator_thread : public ref_counted_object buffer.write(this->waiting_for_alert); buffer.write(this->alerted); + buffer.write(this->apc_alertable); buffer.write(this->suspended); @@ -158,6 +160,7 @@ class emulator_thread : public ref_counted_object buffer.read(this->waiting_for_alert); buffer.read(this->alerted); + buffer.read(this->apc_alertable); buffer.read(this->suspended); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 5a40a921..2d285295 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -413,10 +413,10 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } - NTSTATUS handle_NtTestAlert() + NTSTATUS handle_NtTestAlert(const syscall_context& c) { - // puts("NtTestAlert not supported"); - return STATUS_NOT_SUPPORTED; + c.win_emu.yield_thread(true); + return STATUS_SUCCESS; } NTSTATUS handle_NtUserSystemParametersInfo() diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index 76ca46e4..7420e43e 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -116,11 +116,6 @@ namespace syscalls const emulator_object handles, const WAIT_TYPE wait_type, const BOOLEAN alertable, const emulator_object timeout) { - if (alertable) - { - c.win_emu.log.print(color::gray, "Alertable NtWaitForMultipleObjects not supported yet!\n"); - } - if (wait_type != WaitAny && wait_type != WaitAll) { c.win_emu.log.error("Wait type not supported!\n"); @@ -151,18 +146,13 @@ namespace syscalls t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), timeout.read()); } - c.win_emu.yield_thread(); + c.win_emu.yield_thread(alertable); return STATUS_SUCCESS; } NTSTATUS handle_NtWaitForSingleObject(const syscall_context& c, const handle h, const BOOLEAN alertable, const emulator_object timeout) { - if (alertable) - { - c.win_emu.log.print(color::gray, "Alertable NtWaitForSingleObject not supported yet!\n"); - } - if (!is_awaitable_object_type(h)) { c.win_emu.log.print(color::gray, "Unsupported handle type for NtWaitForSingleObject: %d!\n", h.value.type); @@ -178,7 +168,7 @@ namespace syscalls t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), timeout.read()); } - c.win_emu.yield_thread(); + c.win_emu.yield_thread(alertable); return STATUS_SUCCESS; } diff --git a/src/windows-emulator/syscalls/thread.cpp b/src/windows-emulator/syscalls/thread.cpp index 8c65a5a1..f9b98484 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -282,17 +282,9 @@ namespace syscalls NTSTATUS handle_NtDelayExecution(const syscall_context& c, const BOOLEAN alertable, const emulator_object delay_interval) { - if (alertable) - { - c.win_emu.log.error("Alertable NtDelayExecution not supported yet!\n"); - c.emu.stop(); - return STATUS_NOT_SUPPORTED; - } - auto& t = c.win_emu.current_thread(); t.await_time = utils::convert_delay_interval_to_time_point(c.win_emu.clock(), delay_interval.read()); - - c.win_emu.yield_thread(); + c.win_emu.yield_thread(alertable); return STATUS_SUCCESS; } @@ -370,10 +362,15 @@ namespace syscalls } NTSTATUS handle_NtContinue(const syscall_context& c, const emulator_object thread_context, - const BOOLEAN /*raise_alert*/) + const BOOLEAN raise_alert) { c.write_status = false; + if (raise_alert) + { + c.win_emu.current_thread().apc_alertable = false; + } + const auto context = thread_context.read(); cpu_context::restore(c.emu, context); diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 8bdb30bb..787afb16 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -298,9 +298,10 @@ void windows_emulator::setup_process(const application_settings& app_settings) switch_to_thread(*this, main_thread_id); } -void windows_emulator::yield_thread() +void windows_emulator::yield_thread(const bool alertable) { this->switch_thread_ = true; + this->current_thread().apc_alertable = alertable; this->emu().stop(); } diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 986f0be7..5a68f614 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -183,7 +183,7 @@ class windows_emulator bool buffer_stdout{false}; bool fuzzing{false}; - void yield_thread(); + void yield_thread(bool alertable = false); void perform_thread_switch(); bool activate_thread(uint32_t id);