Skip to content

Commit

Permalink
More threading support
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Oct 21, 2024
1 parent 9692e15 commit 72bcac1
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/windows-emulator/process_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class emulator_thread : ref_counted_object

std::optional<uint32_t> exit_status{};
std::optional<handle> await_object{};
std::optional<bool> alerted{};
std::optional<std::chrono::steady_clock::time_point> await_time{};

std::optional<emulator_allocator> gs_segment;
Expand Down
90 changes: 80 additions & 10 deletions src/windows-emulator/syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2074,35 +2074,46 @@ namespace
const BOOLEAN alertable,
const emulator_object<LARGE_INTEGER> timeout)
{
if (timeout.value())
{
puts("NtWaitForSingleObject timeout not supported yet!");
return STATUS_NOT_SUPPORTED;
}

if (alertable)
{
puts("Alertable NtWaitForSingleObject not supported yet!");
c.emu.stop();
return STATUS_NOT_SUPPORTED;
}

handle h{};
h.bits = handle_value;

if (h.value.type != handle_types::thread)
auto& t = c.win_emu.current_thread();

if (h.value.type != handle_types::thread && h.value.type != handle_types::event)
{
puts("NtWaitForSingleObject only supported with thread handles yet!");
puts("Unsupported handle type for NtWaitForSingleObject!");
c.emu.stop();
return STATUS_NOT_SUPPORTED;
}

if (timeout.value() && !t.await_time.has_value())
{
t.await_time = convert_delay_interval_to_time_point(timeout.read());
}

if (is_object_signaled(c.proc, h))
{
t.await_time = {};
t.await_object = {};
return STATUS_WAIT_0;
}

c.retrigger_syscall = true;
if (t.await_time.has_value() && *t.await_time < std::chrono::steady_clock::now())
{
t.await_time = {};
t.await_object = {};
return STATUS_TIMEOUT;
}

c.win_emu.current_thread().await_object = h;
t.await_object = h;
c.retrigger_syscall = true;
c.win_emu.switch_thread = true;
c.emu.stop();

Expand Down Expand Up @@ -2137,6 +2148,7 @@ namespace
if (alertable)
{
puts("Alertable NtDelayExecution not supported yet!");
c.emu.stop();
return STATUS_NOT_SUPPORTED;
}

Expand All @@ -2158,6 +2170,62 @@ namespace

return STATUS_SUCCESS;
}

NTSTATUS handle_NtAlertThreadByThreadIdEx(const syscall_context& c, const uint64_t thread_id,
const emulator_object<RTL_SRWLOCK> lock)
{
if (lock.value())
{
puts("NtAlertThreadByThreadIdEx with lock not supported yet!");
//c.emu.stop();
//return STATUS_NOT_SUPPORTED;
}

for (auto& t : c.proc.threads)
{
if (t.second.id == thread_id)
{
t.second.alerted = true;
return STATUS_SUCCESS;
}
}

return STATUS_INVALID_HANDLE;
}

NTSTATUS handle_NtWaitForAlertByThreadId(const syscall_context& c, const uint64_t,
const emulator_object<LARGE_INTEGER> timeout)
{
auto& t = c.win_emu.current_thread();

if (timeout.value() && !t.await_time.has_value())
{
t.await_time = convert_delay_interval_to_time_point(timeout.read());
}

if (!t.alerted.has_value())
{
t.alerted = false;
}
else if (*t.alerted)
{
t.alerted = {};
t.await_time = {};
return STATUS_ALERTED;
}
else if (t.await_time.has_value() && *t.await_time < std::chrono::steady_clock::now())
{
t.alerted = {};
t.await_time = {};
return STATUS_TIMEOUT;
}

c.retrigger_syscall = true;
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)
Expand Down Expand Up @@ -2261,6 +2329,8 @@ void syscall_dispatcher::add_handlers()
add_handler(NtWaitForSingleObject);
add_handler(NtTerminateThread);
add_handler(NtDelayExecution);
add_handler(NtWaitForAlertByThreadId);
add_handler(NtAlertThreadByThreadIdEx);

#undef add_handler

Expand Down

0 comments on commit 72bcac1

Please sign in to comment.