diff --git a/src/xenia/kernel/xboxkrnl/objects/xthread.cc b/src/xenia/kernel/xboxkrnl/objects/xthread.cc index 56595b7af..5fe545553 100644 --- a/src/xenia/kernel/xboxkrnl/objects/xthread.cc +++ b/src/xenia/kernel/xboxkrnl/objects/xthread.cc @@ -349,6 +349,18 @@ void XThread::LowerIrql(uint32_t new_irql) { irql_ = new_irql; } +X_STATUS XThread::Resume(uint32_t* out_suspend_count) { + DWORD result = ResumeThread(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/xboxkrnl/objects/xthread.h b/src/xenia/kernel/xboxkrnl/objects/xthread.h index 8d856458b..785387881 100644 --- a/src/xenia/kernel/xboxkrnl/objects/xthread.h +++ b/src/xenia/kernel/xboxkrnl/objects/xthread.h @@ -61,6 +61,7 @@ public: uint32_t RaiseIrql(uint32_t new_irql); void LowerIrql(uint32_t new_irql); + X_STATUS Resume(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/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index f224e0bba..8865d38ec 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -136,6 +136,46 @@ SHIM_CALL ExCreateThread_shim( } +X_STATUS xeNtResumeThread(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->Resume(out_suspend_count); + thread->Release(); + } + + return result; +} + + +SHIM_CALL NtResumeThread_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t handle = SHIM_GET_ARG_32(0); + uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); + + XELOGD( + "NtResumeThread(%.8X, %.8X)", + handle, + suspend_count_ptr); + + uint32_t suspend_count; + X_STATUS result = xeNtResumeThread(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); @@ -523,6 +563,28 @@ SHIM_CALL KeResetEvent_shim( } +SHIM_CALL NtClearEvent_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t event_handle = SHIM_GET_ARG_32(0); + + XELOGD( + "NtClearEvent(%.8X)", + event_handle); + + X_STATUS result = X_STATUS_SUCCESS; + + XEvent* ev = NULL; + result = state->object_table()->GetObject( + event_handle, (XObject**)&ev); + if (XSUCCEEDED(result)) { + ev->Reset(); + ev->Release(); + } + + SHIM_SET_RETURN(result); +} + + X_STATUS xeKeWaitForSingleObject( void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout) { @@ -674,6 +736,7 @@ SHIM_CALL KeLeaveCriticalRegion_shim( void xe::kernel::xboxkrnl::RegisterThreadingExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", ExCreateThread, state); + SHIM_SET_MAPPING("xboxkrnl.exe", NtResumeThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeSetAffinityThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeGetCurrentProcessType, state); @@ -691,6 +754,7 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports( SHIM_SET_MAPPING("xboxkrnl.exe", KeSetEvent, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtSetEvent, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeResetEvent, state); + SHIM_SET_MAPPING("xboxkrnl.exe", NtClearEvent, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeWaitForSingleObject, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtWaitForSingleObjectEx, state); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h index 45c908942..28d2c4bb8 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h @@ -26,6 +26,8 @@ X_STATUS xeExCreateThread( uint32_t xapi_thread_startup, uint32_t start_address, uint32_t start_context, uint32_t creation_flags); +X_STATUS xeNtResumeThread(uint32_t handle, uint32_t* out_suspend_count); + uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity); uint32_t xeKeGetCurrentProcessType();