From 469ea9451df71921bea533d1710c549d8ca121a7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 6 Jan 2014 23:23:27 -0800 Subject: [PATCH] NtSuspendThread. --- src/xenia/kernel/objects/xthread.cc | 12 ++++++++ src/xenia/kernel/objects/xthread.h | 1 + src/xenia/kernel/xboxkrnl_threading.cc | 41 ++++++++++++++++++++++++++ src/xenia/kernel/xboxkrnl_threading.h | 1 + 4 files changed, 55 insertions(+) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index f0539b4eb..e5e36fe1c 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -353,6 +353,18 @@ X_STATUS XThread::Resume(uint32_t* out_suspend_count) { } } +X_STATUS XThread::Suspend(uint32_t* out_suspend_count) { + DWORD result = SuspendThread(thread_handle_); + if (result >= 0) { + if (out_suspend_count) { + *out_suspend_count = result; + } + return X_STATUS_SUCCESS; + } else { + return X_STATUS_UNSUCCESSFUL; + } +} + X_STATUS XThread::Delay( uint32_t processor_mode, uint32_t alertable, uint64_t interval) { int64_t timeout_ticks = interval; diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index a5c160666..029001d33 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -58,6 +58,7 @@ public: void LowerIrql(uint32_t new_irql); X_STATUS Resume(uint32_t* out_suspend_count); + X_STATUS Suspend(uint32_t* out_suspend_count); X_STATUS Delay( uint32_t processor_mode, uint32_t alertable, uint64_t interval); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index a176709ba..4dda918f1 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -230,6 +230,46 @@ SHIM_CALL KeResumeThread_shim( } +X_STATUS xeNtSuspendThread(uint32_t handle, uint32_t* out_suspend_count) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + + X_STATUS result = X_STATUS_SUCCESS; + + XThread* thread = NULL; + result = state->object_table()->GetObject( + handle, (XObject**)&thread); + if (XSUCCEEDED(result)) { + result = thread->Suspend(out_suspend_count); + thread->Release(); + } + + return result; +} + + +SHIM_CALL NtSuspendThread_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t handle = SHIM_GET_ARG_32(0); + uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); + + XELOGD( + "NtSuspendThread(%.8X, %.8X)", + handle, + suspend_count_ptr); + + uint32_t suspend_count; + X_STATUS result = xeNtSuspendThread(handle, &suspend_count); + if (XSUCCEEDED(result)) { + if (suspend_count_ptr) { + SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); + } + } + + SHIM_SET_RETURN(result); +} + + uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { KernelState* state = shared_kernel_state_; XEASSERTNOTNULL(state); @@ -987,6 +1027,7 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports( SHIM_SET_MAPPING("xboxkrnl.exe", ExTerminateThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtResumeThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeResumeThread, state); + SHIM_SET_MAPPING("xboxkrnl.exe", NtSuspendThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeSetAffinityThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeSetBasePriorityThread, state); diff --git a/src/xenia/kernel/xboxkrnl_threading.h b/src/xenia/kernel/xboxkrnl_threading.h index dac0db9bc..9b33964f9 100644 --- a/src/xenia/kernel/xboxkrnl_threading.h +++ b/src/xenia/kernel/xboxkrnl_threading.h @@ -26,6 +26,7 @@ X_STATUS xeExCreateThread( uint32_t start_address, uint32_t start_context, uint32_t creation_flags); X_STATUS xeNtResumeThread(uint32_t handle, uint32_t* out_suspend_count); +X_STATUS xeNtSuspendThread(uint32_t handle, uint32_t* out_suspend_count); uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity);