From 6a23f1457be0aeab4bd8fc8d7f39ca2458eee04e Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Mon, 8 May 2023 17:31:06 +0100 Subject: [PATCH] [XAM] Plugin Functions --- src/xenia/app/emulator_window.cc | 2 +- src/xenia/kernel/xam/xam_info.cc | 171 ++++++++++++++++-- src/xenia/kernel/xam/xam_ui.cc | 38 ++++ src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc | 23 ++- src/xenia/kernel/xboxkrnl/xboxkrnl_modules.h | 26 +++ src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc | 4 +- .../kernel/xboxkrnl/xboxkrnl_threading.cc | 69 ++++--- .../kernel/xboxkrnl/xboxkrnl_threading.h | 21 ++- 8 files changed, 310 insertions(+), 44 deletions(-) create mode 100644 src/xenia/kernel/xboxkrnl/xboxkrnl_modules.h diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 2d6c11b92..d71c903ba 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -1191,7 +1191,7 @@ const std::map controller_hotkey_map = { {X_INPUT_GAMEPAD_BACK | X_INPUT_GAMEPAD_START, EmulatorWindow::ControllerHotKey( EmulatorWindow::ButtonFunctions::ToggleLogging, - "Back + Start = Close Window", false, false)}, + "Back + Start = Toggle between loglevel set in config and the 'Disabled' loglevel.", false, false)}, {X_INPUT_GAMEPAD_DPAD_DOWN, EmulatorWindow::ControllerHotKey( EmulatorWindow::ButtonFunctions::IncTitleSelect, diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc index 6ffaccc2e..c3ff87c33 100644 --- a/src/xenia/kernel/xam/xam_info.cc +++ b/src/xenia/kernel/xam/xam_info.cc @@ -7,6 +7,8 @@ ****************************************************************************** */ +#include +#include #include "xenia/base/cvar.h" #include "xenia/base/logging.h" #include "xenia/base/string_util.h" @@ -290,17 +292,165 @@ DECLARE_XAM_EXPORT1(Sleep, kNone, kImplemented); dword_result_t GetTickCount_entry() { return Clock::QueryGuestUptimeMillis(); } DECLARE_XAM_EXPORT1(GetTickCount, kNone, kImplemented); -dword_result_t GetModuleHandleA_entry(lpstring_t moduleName) { - auto module = kernel_state()->GetModule(moduleName.value(), false); - return module ? module->hmodule_ptr() : NULL; -} -DECLARE_XAM_EXPORT1(GetModuleHandleA, kNone, kImplemented); - dword_result_t XamGetCurrentTitleId_entry() { return kernel_state()->emulator()->title_id(); } DECLARE_XAM_EXPORT1(XamGetCurrentTitleId, kNone, kImplemented); +dword_result_t RtlSetLastNTError_entry(dword_t error_code) { + const uint32_t result = + xe::kernel::xboxkrnl::xeRtlNtStatusToDosError(error_code); + XThread::SetLastError(result); + + return result; +} +DECLARE_XAM_EXPORT1(RtlSetLastNTError, kNone, kImplemented); + +dword_result_t RtlGetLastError_entry() { return XThread::GetLastError(); } +DECLARE_XAM_EXPORT1(RtlGetLastError, kNone, kImplemented); + +dword_result_t GetLastError_entry() { return RtlGetLastError_entry(); } +DECLARE_XAM_EXPORT1(GetLastError, kNone, kImplemented); + +dword_result_t GetModuleHandleA_entry(lpstring_t module_name) { + xe::be module_ptr = 0; + const X_STATUS error_code = xe::kernel::xboxkrnl::XexGetModuleHandle( + module_name.value(), &module_ptr); + + if (XFAILED(error_code)) { + RtlSetLastNTError_entry(error_code); + + return NULL; + } + + return (uint32_t)module_ptr; +} +DECLARE_XAM_EXPORT1(GetModuleHandleA, kNone, kImplemented); + +dword_result_t XapipCreateThread_entry(lpdword_t lpThreadAttributes, + dword_t dwStackSize, + lpvoid_t lpStartAddress, + lpvoid_t lpParameter, + dword_t dwCreationFlags, dword_t unkn, + lpdword_t lpThreadId) { + uint32_t flags = (dwCreationFlags >> 2) & 1; + + if (unkn != -1) { + flags |= 1 << unkn << 24; + } + + xe::be result = 0; + + const X_STATUS error_code = xe::kernel::xboxkrnl::ExCreateThread( + &result, dwStackSize, lpThreadId, lpStartAddress, lpParameter, 0, flags); + + if (XFAILED(error_code)) { + RtlSetLastNTError_entry(error_code); + + return NULL; + } + + return (uint32_t)result; +} +DECLARE_XAM_EXPORT1(XapipCreateThread, kNone, kImplemented); + +dword_result_t CreateThread_entry(lpdword_t lpThreadAttributes, + dword_t dwStackSize, lpvoid_t lpStartAddress, + lpvoid_t lpParameter, dword_t dwCreationFlags, + lpdword_t lpThreadId) { + return XapipCreateThread_entry(lpThreadAttributes, dwStackSize, + lpStartAddress, lpParameter, dwCreationFlags, + -1, lpThreadId); +} +DECLARE_XAM_EXPORT1(CreateThread, kNone, kImplemented); + +dword_result_t CloseHandle_entry(dword_t hObject) { + const X_STATUS error_code = xe::kernel::xboxkrnl::NtClose(hObject); + + if (XFAILED(error_code)) { + RtlSetLastNTError_entry(error_code); + + return false; + } + + return true; +} +DECLARE_XAM_EXPORT1(CloseHandle, kNone, kImplemented); + +dword_result_t ResumeThread_entry(dword_t hThread) { + uint32_t suspend_count; + const X_STATUS error_code = + xe::kernel::xboxkrnl::NtResumeThread(hThread, &suspend_count); + + if (XFAILED(error_code)) { + RtlSetLastNTError_entry(error_code); + + return -1; + } + + return suspend_count; +} +DECLARE_XAM_EXPORT1(ResumeThread, kNone, kImplemented); + +void ExitThread_entry(dword_t exit_code) { + xe::kernel::xboxkrnl::ExTerminateThread(exit_code); +} +DECLARE_XAM_EXPORT1(ExitThread, kNone, kImplemented); + +dword_result_t GetCurrentThreadId_entry() { + return XThread::GetCurrentThread()->GetCurrentThreadId(); +} +DECLARE_XAM_EXPORT1(GetCurrentThreadId, kNone, kImplemented); + +qword_result_t XapiFormatTimeOut_entry(lpqword_t result, + dword_t dwMilliseconds) { + LARGE_INTEGER delay{}; + + // Convert the delay time to 100-nanosecond intervals + delay.QuadPart = + dwMilliseconds == -1 ? 0 : static_cast(-10000) * dwMilliseconds; + + return (uint64_t)&delay; +} +DECLARE_XAM_EXPORT1(XapiFormatTimeOut, kNone, kImplemented); + +dword_result_t WaitForSingleObjectEx_entry(dword_t hHandle, + dword_t dwMilliseconds, + dword_t bAlertable) { + uint64_t* timeout = nullptr; + uint64_t timeout_ptr = XapiFormatTimeOut_entry(timeout, dwMilliseconds); + + X_STATUS result = xe::kernel::xboxkrnl::NtWaitForSingleObjectEx( + hHandle, 1, bAlertable, &timeout_ptr); + + while (bAlertable && result == X_STATUS_ALERTED) { + result = xe::kernel::xboxkrnl::NtWaitForSingleObjectEx( + hHandle, 1, bAlertable, &timeout_ptr); + } + + RtlSetLastNTError_entry(result); + result = -1; + + return result; +} +DECLARE_XAM_EXPORT1(WaitForSingleObjectEx, kNone, kImplemented); + +dword_result_t WaitForSingleObject_entry(dword_t hHandle, + dword_t dwMilliseconds) { + return WaitForSingleObjectEx_entry(hHandle, dwMilliseconds, 0); +} +DECLARE_XAM_EXPORT1(WaitForSingleObject, kNone, kImplemented); + +dword_result_t lstrlenW_entry(lpu16string_t string) { + // wcslen? + if (string) { + return (uint32_t)string.value().length(); + } + + return NULL; +} +DECLARE_XAM_EXPORT1(lstrlenW, kNone, kImplemented); + dword_result_t XamGetExecutionId_entry(lpdword_t info_ptr) { auto module = kernel_state()->GetExecutableModule(); assert_not_null(module); @@ -419,11 +569,8 @@ dword_result_t XamAlloc_entry(dword_t flags, dword_t size, lpdword_t out_ptr) { DECLARE_XAM_EXPORT1(XamAlloc, kMemory, kImplemented); static const unsigned short XamPhysicalProtTable[4] = { - X_PAGE_READONLY, - X_PAGE_READWRITE | X_PAGE_NOCACHE, - X_PAGE_READWRITE, - X_PAGE_WRITECOMBINE | X_PAGE_READWRITE -}; + X_PAGE_READONLY, X_PAGE_READWRITE | X_PAGE_NOCACHE, X_PAGE_READWRITE, + X_PAGE_WRITECOMBINE | X_PAGE_READWRITE}; dword_result_t XamAllocEx_entry(dword_t phys_flags, dword_t flags, dword_t size, lpdword_t out_ptr, const ppc_context_t& ctx) { @@ -433,7 +580,7 @@ dword_result_t XamAllocEx_entry(dword_t phys_flags, dword_t flags, dword_t size, uint32_t flags_remapped = phys_flags; if ((phys_flags & 0xF000000) == 0) { - // setting default alignment + // setting default alignment flags_remapped = 0xC000000 | phys_flags & 0xF0FFFFFF; } diff --git a/src/xenia/kernel/xam/xam_ui.cc b/src/xenia/kernel/xam/xam_ui.cc index 30fb57bc6..7f274920c 100644 --- a/src/xenia/kernel/xam/xam_ui.cc +++ b/src/xenia/kernel/xam/xam_ui.cc @@ -344,6 +344,44 @@ dword_result_t XamShowMessageBoxUIEx_entry( overlapped); } DECLARE_XAM_EXPORT1(XamShowMessageBoxUIEx, kUI, kImplemented); + +dword_result_t XNotifyQueueUI_entry(dword_t exnq, dword_t dwUserIndex, + qword_t qwAreas, + lpu16string_t displayText_ptr, + lpvoid_t contextData) { + std::string displayText = ""; + + if (displayText_ptr) { + displayText = xe::to_utf8(displayText_ptr.value()); + } + + XELOGI("XNotifyQueueUI: {}", displayText); + + if (cvars::headless) { + return X_ERROR_SUCCESS; + } + + auto close = [](MessageBoxDialog* dialog) -> X_RESULT { + dialog->chosen_button(); + return X_ERROR_SUCCESS; + }; + + std::vector buttons(1, "OK"); + + const Emulator* emulator = kernel_state()->emulator(); + ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); + + xeXamDispatchDialog( + new MessageBoxDialog(imgui_drawer, "XNotifyQueueUI", displayText, buttons, + 0), + close, false); + + // XNotifyQueueUI -> XNotifyQueueUIEx -> XMsgProcessRequest -> + // XMsgStartIORequestEx & XMsgInProcessCall + return X_ERROR_SUCCESS; +} +DECLARE_XAM_EXPORT1(XNotifyQueueUI, kUI, kSketchy); + class KeyboardInputDialog : public XamDialog { public: KeyboardInputDialog(xe::ui::ImGuiDrawer* imgui_drawer, std::string title, diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc index 42d2584f6..061d44cb1 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.cc @@ -7,6 +7,7 @@ ****************************************************************************** */ +#include "xboxkrnl_modules.h" #include "xenia/base/logging.h" #include "xenia/cpu/processor.h" #include "xenia/kernel/kernel_state.h" @@ -39,14 +40,14 @@ dword_result_t XexCheckExecutablePrivilege_entry(dword_t privilege) { } DECLARE_XBOXKRNL_EXPORT1(XexCheckExecutablePrivilege, kModules, kImplemented); -dword_result_t XexGetModuleHandle_entry(lpstring_t module_name, - lpdword_t hmodule_ptr) { +dword_result_t XexGetModuleHandle(std::string module_name, + xe::be* hmodule_ptr) { object_ref module; - if (!module_name) { + if (module_name.empty()) { module = kernel_state()->GetExecutableModule(); } else { - module = kernel_state()->GetModule(module_name.value()); + module = kernel_state()->GetModule(module_name); } if (!module) { @@ -59,6 +60,11 @@ dword_result_t XexGetModuleHandle_entry(lpstring_t module_name, return X_ERROR_SUCCESS; } + +dword_result_t XexGetModuleHandle_entry(lpstring_t module_name, + lpdword_t hmodule_ptr) { + return XexGetModuleHandle(module_name.value(), hmodule_ptr); +} DECLARE_XBOXKRNL_EXPORT1(XexGetModuleHandle, kModules, kImplemented); dword_result_t XexGetModuleSection_entry(lpvoid_t hmodule, lpstring_t name, @@ -119,6 +125,15 @@ dword_result_t XexLoadImage_entry(lpstring_t module_name, dword_t module_flags, } DECLARE_XBOXKRNL_EXPORT1(XexLoadImage, kModules, kImplemented); +dword_result_t XexLoadExecutable_entry(lpstring_t module_name, + dword_t module_flags, + dword_t min_version, + lpdword_t hmodule_ptr) { + return XexLoadImage_entry(module_name, module_flags, min_version, + hmodule_ptr); +} +DECLARE_XBOXKRNL_EXPORT1(XexLoadExecutable, kModules, kSketchy); + dword_result_t XexUnloadImage_entry(lpvoid_t hmodule) { auto module = XModule::GetFromHModule(kernel_state(), hmodule); if (!module) { diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.h b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.h new file mode 100644 index 000000000..e6c9f9f53 --- /dev/null +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_modules.h @@ -0,0 +1,26 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_XBOXKRNL_MODULES_H_ +#define XENIA_KERNEL_XBOXKRNL_XBOXKRNL_MODULES_H_ + +#include "xenia/kernel/util/shim_utils.h" + +namespace xe { +namespace kernel { +namespace xboxkrnl { + +dword_result_t XexGetModuleHandle(std::string module_name, + xe::be* hmodule_ptr); + +} // namespace xboxkrnl +} // namespace kernel +} // namespace xe + +#endif // XENIA_KERNEL_XBOXKRNL_XBOXKRNL_MODULES_H_ diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc index 6ab7a035a..3dbef4046 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc @@ -256,9 +256,11 @@ dword_result_t NtDuplicateObject_entry(dword_t handle, lpdword_t new_handle_ptr, } DECLARE_XBOXKRNL_EXPORT1(NtDuplicateObject, kNone, kImplemented); -dword_result_t NtClose_entry(dword_t handle) { +uint32_t NtClose(uint32_t handle) { return kernel_state()->object_table()->ReleaseHandle(handle); } + +dword_result_t NtClose_entry(dword_t handle) { return NtClose(handle); } DECLARE_XBOXKRNL_EXPORT1(NtClose, kNone, kImplemented); } // namespace xboxkrnl diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index 591848907..45ce52633 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -96,12 +96,10 @@ object_ref LookupNamedObject(KernelState* kernel_state, return nullptr; } -dword_result_t ExCreateThread_entry(lpdword_t handle_ptr, dword_t stack_size, - lpdword_t thread_id_ptr, - dword_t xapi_thread_startup, - lpvoid_t start_address, - lpvoid_t start_context, - dword_t creation_flags) { +uint32_t ExCreateThread(xe::be* handle_ptr, uint32_t stack_size, + xe::be* thread_id_ptr, + uint32_t xapi_thread_startup, uint32_t start_address, + uint32_t start_context, uint32_t creation_flags) { // Invalid Link // http://jafile.com/uploads/scoop/main.cpp.txt // DWORD @@ -126,8 +124,7 @@ dword_result_t ExCreateThread_entry(lpdword_t handle_ptr, dword_t stack_size, auto thread = object_ref( new XThread(kernel_state(), actual_stack_size, xapi_thread_startup, - start_address.guest_address(), start_context.guest_address(), - creation_flags, true)); + start_address, start_context, creation_flags, true)); X_STATUS result = thread->Create(); if (XFAILED(result)) { @@ -150,18 +147,32 @@ dword_result_t ExCreateThread_entry(lpdword_t handle_ptr, dword_t stack_size, } return result; } + +dword_result_t ExCreateThread_entry(lpdword_t handle_ptr, dword_t stack_size, + lpdword_t thread_id_ptr, + dword_t xapi_thread_startup, + lpvoid_t start_address, + lpvoid_t start_context, + dword_t creation_flags) { + return ExCreateThread(handle_ptr, stack_size, thread_id_ptr, + xapi_thread_startup, start_address, start_context, + creation_flags); +} DECLARE_XBOXKRNL_EXPORT1(ExCreateThread, kThreading, kImplemented); -dword_result_t ExTerminateThread_entry(dword_t exit_code) { +uint32_t ExTerminateThread(uint32_t exit_code) { XThread* thread = XThread::GetCurrentThread(); // NOTE: this kills us right now. We won't return from it. return thread->Exit(exit_code); } + +dword_result_t ExTerminateThread_entry(dword_t exit_code) { + return ExTerminateThread(exit_code); +} DECLARE_XBOXKRNL_EXPORT1(ExTerminateThread, kThreading, kImplemented); -dword_result_t NtResumeThread_entry(dword_t handle, - lpdword_t suspend_count_ptr) { +uint32_t NtResumeThread(uint32_t handle, uint32_t* suspend_count_ptr) { X_RESULT result = X_STATUS_INVALID_HANDLE; uint32_t suspend_count = 0; @@ -170,7 +181,6 @@ dword_result_t NtResumeThread_entry(dword_t handle, if (thread) { if (thread->type() == XObject::Type::Thread) { result = thread->Resume(&suspend_count); - } else { return X_STATUS_OBJECT_TYPE_MISMATCH; } @@ -183,6 +193,13 @@ dword_result_t NtResumeThread_entry(dword_t handle, return result; } + +dword_result_t NtResumeThread_entry(dword_t handle, + lpdword_t suspend_count_ptr) { + uint32_t suspend_count = + suspend_count_ptr ? static_cast(*suspend_count_ptr) : 0u; + return NtResumeThread(handle, suspend_count_ptr ? &suspend_count : nullptr); +} DECLARE_XBOXKRNL_EXPORT1(NtResumeThread, kThreading, kImplemented); dword_result_t KeResumeThread_entry(pointer_t thread_ptr) { @@ -232,7 +249,8 @@ DECLARE_XBOXKRNL_EXPORT1(NtSuspendThread, kThreading, kImplemented); dword_result_t KeSuspendThread_entry(pointer_t kthread, const ppc_context_t& context) { - auto thread = XObject::GetNativeObject(context->kernel_state, kthread); + auto thread = + XObject::GetNativeObject(context->kernel_state, kthread); uint32_t suspend_count_out = 0; if (thread) { @@ -254,7 +272,7 @@ void KeSetCurrentStackPointers_entry(lpvoid_t stack_ptr, auto current_thread = XThread::GetCurrentThread(); auto pcr = context->TranslateVirtualGPR(context->r[13]); - //also supposed to load msr mask, and the current msr with that, and store + // also supposed to load msr mask, and the current msr with that, and store thread->stack_alloc_base = stack_alloc_base.value(); thread->stack_base = stack_base.value(); thread->stack_limit = stack_limit.value(); @@ -352,8 +370,7 @@ dword_result_t KeQueryPerformanceFrequency_entry() { DECLARE_XBOXKRNL_EXPORT2(KeQueryPerformanceFrequency, kThreading, kImplemented, kHighFrequency); -uint32_t KeDelayExecutionThread(uint32_t processor_mode, - uint32_t alertable, +uint32_t KeDelayExecutionThread(uint32_t processor_mode, uint32_t alertable, uint64_t* interval_ptr) { XThread* thread = XThread::GetCurrentThread(); X_STATUS result = thread->Delay(processor_mode, alertable, *interval_ptr); @@ -387,7 +404,7 @@ void KeQuerySystemTime_entry(lpqword_t time_ptr, const ppc_context_t& ctx) { // something uses this function, but also reads it directly uint32_t ts_bundle = ctx->kernel_state->GetKeTimestampBundle(); uint64_t time = Clock::QueryGuestSystemTime(); - //todo: cmpxchg? + // todo: cmpxchg? xe::store_and_swap( &ctx->TranslateVirtual(ts_bundle)->system_time, time); @@ -534,7 +551,7 @@ uint32_t xeNtSetEvent(uint32_t handle, xe::be* previous_state_ptr) { auto ev = kernel_state()->object_table()->LookupObject(handle); if (ev) { - //d3 ros does this + // d3 ros does this if (ev->type() != XObject::Type::Event) { return X_STATUS_OBJECT_TYPE_MISMATCH; } @@ -583,7 +600,6 @@ dword_result_t NtQueryEvent_entry(dword_t handle, lpdword_t out_struc) { out_struc[0] = type_tmp; out_struc[1] = state_tmp; - } else { result = X_STATUS_INVALID_HANDLE; } @@ -881,10 +897,8 @@ dword_result_t KeWaitForSingleObject_entry(lpvoid_t object_ptr, DECLARE_XBOXKRNL_EXPORT3(KeWaitForSingleObject, kThreading, kImplemented, kBlocking, kHighFrequency); -dword_result_t NtWaitForSingleObjectEx_entry(dword_t object_handle, - dword_t wait_mode, - dword_t alertable, - lpqword_t timeout_ptr) { +uint32_t NtWaitForSingleObjectEx(uint32_t object_handle, uint32_t wait_mode, + uint32_t alertable, uint64_t* timeout_ptr) { X_STATUS result = X_STATUS_SUCCESS; auto object = @@ -899,6 +913,15 @@ dword_result_t NtWaitForSingleObjectEx_entry(dword_t object_handle, return result; } + +dword_result_t NtWaitForSingleObjectEx_entry(dword_t object_handle, + dword_t wait_mode, + dword_t alertable, + lpqword_t timeout_ptr) { + uint64_t timeout = timeout_ptr ? static_cast(*timeout_ptr) : 0u; + return NtWaitForSingleObjectEx(object_handle, wait_mode, alertable, + timeout_ptr ? &timeout : nullptr); +} DECLARE_XBOXKRNL_EXPORT3(NtWaitForSingleObjectEx, kThreading, kImplemented, kBlocking, kHighFrequency); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h index 76ddf9c83..b4aee7071 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.h @@ -20,6 +20,7 @@ struct X_KEVENT; namespace xboxkrnl { uint32_t xeNtSetEvent(uint32_t handle, xe::be* previous_state_ptr); + uint32_t xeNtClearEvent(uint32_t handle); uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, xe::be* handles, @@ -30,11 +31,25 @@ uint32_t xeNtWaitForMultipleObjectsEx(uint32_t count, xe::be* handles, uint32_t xeKeWaitForSingleObject(void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* timeout_ptr); + +uint32_t NtWaitForSingleObjectEx(uint32_t object_handle, uint32_t wait_mode, + uint32_t alertable, uint64_t* timeout_ptr); + uint32_t xeKeSetEvent(X_KEVENT* event_ptr, uint32_t increment, uint32_t wait); -uint32_t KeDelayExecutionThread(uint32_t processor_mode, - uint32_t alertable, - uint64_t* interval_ptr); +uint32_t KeDelayExecutionThread(uint32_t processor_mode, uint32_t alertable, + uint64_t* interval_ptr); + +uint32_t ExCreateThread(xe::be* handle_ptr, uint32_t stack_size, + xe::be* thread_id_ptr, + uint32_t xapi_thread_startup, uint32_t start_address, + uint32_t start_context, uint32_t creation_flags); + +uint32_t ExTerminateThread(uint32_t exit_code); + +uint32_t NtResumeThread(uint32_t handle, uint32_t* suspend_count_ptr); + +uint32_t NtClose(uint32_t handle); } // namespace xboxkrnl } // namespace kernel