From 20720f750d8d21c937b414e01d361ccd88b4530f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 17 Oct 2013 00:47:02 -0700 Subject: [PATCH] KeSetAffinityThread stub, Ob* fns added, current thread handled. --- src/xenia/kernel/modules/xboxkrnl/module.cc | 15 +-- .../kernel/modules/xboxkrnl/object_table.cc | 9 ++ .../modules/xboxkrnl/objects/xthread.cc | 8 ++ .../kernel/modules/xboxkrnl/objects/xthread.h | 1 + .../kernel/modules/xboxkrnl/sources.gypi | 2 + .../kernel/modules/xboxkrnl/xboxkrnl_ob.cc | 92 +++++++++++++++++++ .../kernel/modules/xboxkrnl/xboxkrnl_ob.h | 29 ++++++ .../modules/xboxkrnl/xboxkrnl_private.h | 1 + .../modules/xboxkrnl/xboxkrnl_threading.cc | 35 ++++--- .../modules/xboxkrnl/xboxkrnl_threading.h | 2 + 10 files changed, 175 insertions(+), 19 deletions(-) create mode 100644 src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc create mode 100644 src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.h diff --git a/src/xenia/kernel/modules/xboxkrnl/module.cc b/src/xenia/kernel/modules/xboxkrnl/module.cc index 245877057..23cd46d77 100644 --- a/src/xenia/kernel/modules/xboxkrnl/module.cc +++ b/src/xenia/kernel/modules/xboxkrnl/module.cc @@ -58,6 +58,7 @@ XboxkrnlModule::XboxkrnlModule(Runtime* runtime) : RegisterMiscExports(resolver, kernel_state_.get()); RegisterModuleExports(resolver, kernel_state_.get()); RegisterNtExports(resolver, kernel_state_.get()); + RegisterObExports(resolver, kernel_state_.get()); RegisterRtlExports(resolver, kernel_state_.get()); RegisterThreadingExports(resolver, kernel_state_.get()); RegisterVideoExports(resolver, kernel_state_.get()); @@ -138,13 +139,13 @@ XboxkrnlModule::XboxkrnlModule(Runtime* runtime) : XESETUINT16BE(mem + pXboxKrnlVersion + 4, 0xFFFF); XESETUINT16BE(mem + pXboxKrnlVersion + 6, 0xFFFF); - // KeTimeStampBundle (ad) - uint32_t pKeTimeStampBundle = xe_memory_heap_alloc(memory_, 0, 24, 0); - resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::KeTimeStampBundle, - pKeTimeStampBundle); - XESETUINT64BE(mem + pKeTimeStampBundle + 0, 0); - XESETUINT64BE(mem + pKeTimeStampBundle + 8, 0); + // KeTimeStampBundle (ad) + uint32_t pKeTimeStampBundle = xe_memory_heap_alloc(memory_, 0, 24, 0); + resolver->SetVariableMapping( + "xboxkrnl.exe", ordinals::KeTimeStampBundle, + pKeTimeStampBundle); + XESETUINT64BE(mem + pKeTimeStampBundle + 0, 0); + XESETUINT64BE(mem + pKeTimeStampBundle + 8, 0); XESETUINT32BE(mem + pKeTimeStampBundle + 12, 0); } diff --git a/src/xenia/kernel/modules/xboxkrnl/object_table.cc b/src/xenia/kernel/modules/xboxkrnl/object_table.cc index 2f70cbe84..ebb8ac9ac 100644 --- a/src/xenia/kernel/modules/xboxkrnl/object_table.cc +++ b/src/xenia/kernel/modules/xboxkrnl/object_table.cc @@ -10,6 +10,7 @@ #include #include +#include using namespace xe; @@ -155,6 +156,14 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) { X_STATUS result = X_STATUS_SUCCESS; + if (handle == 0xFFFFFFFF) { + // CurrentProcess + XEASSERTALWAYS(); + } else if (handle == 0xFFFFFFFE) { + // CurrentThread + handle = XThread::GetCurrentThreadHandle(); + } + xe_mutex_lock(table_mutex_); // Lower 2 bits are ignored. diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc index 2162732cb..3c69dec89 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -21,6 +22,7 @@ using namespace xe::kernel::xboxkrnl; namespace { static uint32_t next_xthread_id = 0; + static uint32_t current_thread_tls = xeKeTlsAlloc(); } @@ -71,6 +73,10 @@ XThread::~XThread() { } } +uint32_t XThread::GetCurrentThreadHandle() { + return xeKeTlsGetValue(current_thread_tls); +} + uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) { return XEGETUINT32BE(thread_state_block + 0x14C); } @@ -172,6 +178,7 @@ X_STATUS XThread::Exit(int exit_code) { static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { XThread* thread = reinterpret_cast(param); + xeKeTlsSetValue(current_thread_tls, thread->handle()); thread->Execute(); thread->Release(); return 0; @@ -210,6 +217,7 @@ X_STATUS XThread::PlatformExit(int exit_code) { static void* XThreadStartCallbackPthreads(void* param) { XThread* thread = reinterpret_cast(param); + xeKeTlsSetValue(current_thread_tls, thread->handle()); thread->Execute(); thread->Release(); return 0; diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h index baff6c077..f3ce52a5c 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xthread.h @@ -39,6 +39,7 @@ public: uint32_t creation_flags); virtual ~XThread(); + static uint32_t GetCurrentThreadHandle(); static uint32_t GetCurrentThreadId(const uint8_t* thread_state_block); uint32_t thread_id(); diff --git a/src/xenia/kernel/modules/xboxkrnl/sources.gypi b/src/xenia/kernel/modules/xboxkrnl/sources.gypi index c712d6163..8af61490f 100644 --- a/src/xenia/kernel/modules/xboxkrnl/sources.gypi +++ b/src/xenia/kernel/modules/xboxkrnl/sources.gypi @@ -23,6 +23,8 @@ 'xboxkrnl_module.h', 'xboxkrnl_nt.cc', 'xboxkrnl_nt.h', + 'xboxkrnl_ob.cc', + 'xboxkrnl_ob.h', 'xboxkrnl_ordinals.h', 'xboxkrnl_private.h', 'xboxkrnl_rtl.cc', diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc new file mode 100644 index 000000000..45b0b7086 --- /dev/null +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.cc @@ -0,0 +1,92 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include + + +using namespace xe; +using namespace xe::kernel; +using namespace xe::kernel::xboxkrnl; + + +namespace xe { +namespace kernel { +namespace xboxkrnl { + + +SHIM_CALL ObReferenceObjectByHandle_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t handle = SHIM_GET_ARG_32(0); + uint32_t object_type_ptr = SHIM_GET_ARG_32(1); + uint32_t out_object_ptr = SHIM_GET_ARG_32(2); + + XELOGD( + "ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", + handle, + object_type_ptr, + out_object_ptr); + + X_STATUS result = X_STATUS_INVALID_HANDLE; + + XObject* object = NULL; + result = state->object_table()->GetObject(handle, &object); + if (XSUCCEEDED(result)) { + // TODO(benvanik): verify type with object_type_ptr + + // TODO(benvanik): get native value, if supported. + uint32_t native_ptr = 0xDEADF00D; + + if (out_object_ptr) { + SHIM_SET_MEM_32(out_object_ptr, native_ptr); + } + } + + SHIM_SET_RETURN(result); +} + + +SHIM_CALL ObDereferenceObject_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t native_ptr = SHIM_GET_ARG_32(0); + + XELOGD( + "ObDereferenceObject(%.8X)", + native_ptr); + + // Check if a dummy value from ObReferenceObjectByHandle. + if (native_ptr == 0xDEADF00D) { + SHIM_SET_RETURN(0); + return; + } + + void* object_ptr = SHIM_MEM_ADDR(native_ptr); + XObject* object = XObject::GetObject(state, object_ptr); + if (object) { + object->Release(); + } + + SHIM_SET_RETURN(0); +} + + +} // namespace xboxkrnl +} // namespace kernel +} // namespace xe + + +void xe::kernel::xboxkrnl::RegisterObExports( + ExportResolver* export_resolver, KernelState* state) { + SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state); + SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state); +} diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.h new file mode 100644 index 000000000..04fa70a40 --- /dev/null +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_ob.h @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_MODULES_XBOXKRNL_OB_H_ +#define XENIA_KERNEL_MODULES_XBOXKRNL_OB_H_ + +#include +#include + +#include + + +namespace xe { +namespace kernel { +namespace xboxkrnl { + + +} // namespace xboxkrnl +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_MODULES_XBOXKRNL_OB_H_ diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h index 2513e7371..b730c05d5 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h @@ -36,6 +36,7 @@ void RegisterMemoryExports(ExportResolver* export_resolver, KernelState* state); void RegisterMiscExports(ExportResolver* export_resolver, KernelState* state); void RegisterModuleExports(ExportResolver* export_resolver, KernelState* state); void RegisterNtExports(ExportResolver* export_resolver, KernelState* state); +void RegisterObExports(ExportResolver* export_resolver, KernelState* state); void RegisterRtlExports(ExportResolver* export_resolver, KernelState* state); void RegisterThreadingExports(ExportResolver* export_resolver, KernelState* state); diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc index bb692a798..98e766e85 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.cc @@ -135,6 +135,28 @@ SHIM_CALL ExCreateThread_shim( } +uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { + // TODO(benvanik): implement. + return affinity; +} + + +SHIM_CALL KeSetAffinityThread_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t thread = SHIM_GET_ARG_32(0); + uint32_t affinity = SHIM_GET_ARG_32(1); + + XELOGD( + "KeSetAffinityThread(%.8X, %.8X)", + thread, + affinity); + + void* thread_ptr = SHIM_MEM_ADDR(thread); + uint32_t result = xeKeSetAffinityThread(thread_ptr, affinity); + SHIM_SET_RETURN(result); +} + + uint32_t xeKeGetCurrentProcessType() { KernelState* state = shared_kernel_state_; XEASSERTNOTNULL(state); @@ -207,9 +229,6 @@ SHIM_CALL KeQuerySystemTime_shim( // http://msdn.microsoft.com/en-us/library/ms686801 uint32_t xeKeTlsAlloc() { - KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); - // DWORD uint32_t tls_index; @@ -241,9 +260,6 @@ SHIM_CALL KeTlsAlloc_shim( // http://msdn.microsoft.com/en-us/library/ms686804 int KeTlsFree(uint32_t tls_index) { - KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); - // BOOL // _In_ DWORD dwTlsIndex @@ -278,9 +294,6 @@ SHIM_CALL KeTlsFree_shim( // http://msdn.microsoft.com/en-us/library/ms686812 uint32_t xeKeTlsGetValue(uint32_t tls_index) { - KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); - // LPVOID // _In_ DWORD dwTlsIndex @@ -316,9 +329,6 @@ SHIM_CALL KeTlsGetValue_shim( // http://msdn.microsoft.com/en-us/library/ms686818 int xeKeTlsSetValue(uint32_t tls_index, uint32_t tls_value) { - KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); - // BOOL // _In_ DWORD dwTlsIndex, // _In_opt_ LPVOID lpTlsValue @@ -554,6 +564,7 @@ SHIM_CALL NtWaitForSingleObjectEx_shim( void xe::kernel::xboxkrnl::RegisterThreadingExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", ExCreateThread, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeSetAffinityThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeGetCurrentProcessType, state); diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h index 23eb48de7..a7df57813 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_threading.h +++ b/src/xenia/kernel/modules/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); +uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity); + uint32_t xeKeGetCurrentProcessType(); uint64_t xeKeQueryPerformanceFrequency();