diff --git a/src/windows-emulator/handles.hpp b/src/windows-emulator/handles.hpp index a1a8b1ad..05f26a82 100644 --- a/src/windows-emulator/handles.hpp +++ b/src/windows-emulator/handles.hpp @@ -133,6 +133,11 @@ public: return this->get(hh); } + size_t size() const + { + return this->store_.size(); + } + bool erase(const handle_value h) { const auto entry = this->get_iterator(h); diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 84fceb1e..98c70ce6 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -201,6 +201,7 @@ public: uint32_t id{}; + std::optional exit_status{}; std::optional await_object{}; std::optional gs_segment; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 37bf6fd3..e08aa44b 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -1158,6 +1158,24 @@ namespace return STATUS_SUCCESS; } + if (info_class == ThreadAmILastThread) + { + if (return_length) + { + return_length.write(sizeof(ULONG)); + } + + if (thread_information_length != sizeof(ULONG)) + { + return STATUS_BUFFER_OVERFLOW; + } + + const emulator_object info{c.emu, thread_information}; + info.write(c.proc.threads.size() <= 1); + + return STATUS_SUCCESS; + } + printf("Unsupported thread info class: %X\n", info_class); c.emu.stop(); @@ -2013,6 +2031,25 @@ namespace return STATUS_WAIT_0; } + + NTSTATUS handle_NtTerminateThread(const syscall_context& c, const uint64_t thread_handle, + const NTSTATUS exit_status) + { + auto* thread = c.proc.threads.get(thread_handle); + if (!thread) + { + return STATUS_INVALID_HANDLE; + } + + thread->exit_status = exit_status; + if (thread == c.proc.active_thread) + { + c.win_emu.switch_thread = true; + c.emu.stop(); + } + + return STATUS_SUCCESS; + } } void syscall_dispatcher::setup(const exported_symbols& ntdll_exports, const exported_symbols& win32u_exports) @@ -2114,6 +2151,7 @@ void syscall_dispatcher::add_handlers() add_handler(NtCreateThreadEx); add_handler(NtQueryDebugFilterState); add_handler(NtWaitForSingleObject); + add_handler(NtTerminateThread); #undef add_handler