From 7595df4876389a55bd70572efec6e93c499469b4 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 17 Jul 2015 19:50:04 -0500 Subject: [PATCH 1/6] We don't need to be the calling thread to set a thread name. --- src/xenia/base/threading_win.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/xenia/base/threading_win.cc b/src/xenia/base/threading_win.cc index 9d37ba5c4..da3034bb2 100644 --- a/src/xenia/base/threading_win.cc +++ b/src/xenia/base/threading_win.cc @@ -315,8 +315,7 @@ class Win32Thread : public Win32Handle { ~Win32Thread() = default; void set_name(std::string name) override { - AssertCallingThread(); - xe::threading::set_name(name); + xe::threading::set_name(handle_, name); Thread::set_name(name); } From e54477d0e4c787e567b4f7ac41b85ca69e59cf04 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 17 Jul 2015 19:52:29 -0500 Subject: [PATCH 2/6] XObject::StashNative --- src/xenia/kernel/xobject.cc | 10 ++-------- src/xenia/kernel/xobject.h | 13 +++++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 1b2735625..2fb798dcd 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -273,10 +273,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { // Stash pointer in struct. // FIXME: This assumes the object has a dispatch header (some don't!) - uint64_t object_ptr = reinterpret_cast(this); - object_ptr |= 0x1; - header->wait_list_flink = (uint32_t)(object_ptr >> 32); - header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); + StashNative(header, this); guest_object_ptr_ = native_ptr; } @@ -354,10 +351,7 @@ object_ref XObject::GetNativeObject(KernelState* kernel_state, // Stash pointer in struct. // FIXME: This assumes the object contains a dispatch header (some don't!) - uint64_t object_ptr = reinterpret_cast(object); - object_ptr |= 0x1; - header->wait_list_flink = (uint32_t)(object_ptr >> 32); - header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); + StashNative(header, object); // NOTE: we are double-retaining, as the object is implicitly created and // can never be released. diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 18cdaa71c..c9ddfd54c 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -156,6 +156,19 @@ class XObject { uint8_t* CreateNative(uint32_t size); void SetNativePointer(uint32_t native_ptr, bool uninitialized = false); + template + T* CreateNative(uint32_t size) { + return reinterpret_cast(CreateNative(size)); + } + + // Stash native pointer into X_DISPATCH_HEADER + static void StashNative(X_DISPATCH_HEADER* header, void* native_ptr) { + uint64_t object_ptr = reinterpret_cast(native_ptr); + object_ptr |= 0x1; + header->wait_list_flink = (uint32_t)(object_ptr >> 32); + header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); + } + static uint32_t TimeoutTicksToMs(int64_t timeout_ticks); KernelState* kernel_state_; From 1ea5a4b7b419cd5fac42d1c721eab3ef7033a94f Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 17 Jul 2015 19:55:09 -0500 Subject: [PATCH 3/6] XThread initialize the dispatch header --- src/xenia/kernel/objects/xthread.cc | 15 ++++++--------- src/xenia/kernel/objects/xthread.h | 11 +++-------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index e56448bb4..61e864671 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -150,12 +150,15 @@ uint8_t GetFakeCpuNumber(uint8_t proc_mask) { X_STATUS XThread::Create() { // Thread kernel object // This call will also setup the native pointer for us. - uint8_t* guest_object = CreateNative(sizeof(X_THREAD)); + auto guest_object = CreateNative(sizeof(X_KTHREAD)); if (!guest_object) { XELOGW("Unable to allocate thread object"); return X_STATUS_NO_MEMORY; } + guest_object->header.type = 6; + StashNative(&guest_object->header, this); + auto module = kernel_state()->GetExecutableModule(); // Allocate thread scratch. @@ -268,15 +271,9 @@ X_STATUS XThread::Create() { pcr->current_cpu = GetFakeCpuNumber(proc_mask); // Current CPU(?) pcr->dpc_active = 0; // DPC active bool? - // Thread state block - struct XTEB { - xe::be unk_00; // 0x0 - xe::be unk_04; // 0x4 - X_LIST_ENTRY unk_08; // 0x8 - X_LIST_ENTRY unk_10; // 0x10 - }; - // Setup the thread state block (last error/etc). + // TODO: This is actually a KTHREAD object. Use the one from CreateNative + // instead. uint8_t* p = memory()->TranslateVirtual(thread_state_address_); xe::store_and_swap(p + 0x000, 6); xe::store_and_swap(p + 0x008, thread_state_address_ + 0x008); diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 95b3719cf..1365a3091 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -66,14 +66,9 @@ struct XAPC { }; // http://www.nirsoft.net/kernel_struct/vista/KTHREAD.html -struct X_THREAD { - X_DISPATCH_HEADER header; - xe::be cycle_time; - xe::be high_cycle_time; // FIXME: Needed? - xe::be quantum_target; - xe::be initial_stack_ptr; - xe::be stack_limit_ptr; - xe::be kernel_stack_ptr; +struct X_KTHREAD { + X_DISPATCH_HEADER header; // 0x0 + char unk_04[0xAA0]; // 0x4 // This struct is actually quite long... so uh, not filling this out! }; From c3189a68371ae6f5ff18393988b521615cf25725 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 17 Jul 2015 19:56:54 -0500 Subject: [PATCH 4/6] ObLookupThreadByThreadId / ObOpenObjectByPointer --- src/xenia/kernel/xboxkrnl_ob.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index b428fd9e2..df6b1f858 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -136,6 +136,35 @@ SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(0); } +dword_result_t ObLookupThreadByThreadId(dword_t thread_id, lpdword_t out_object_ptr) { + auto thread = kernel_state()->GetThreadByID(thread_id); + if (!thread) { + return X_STATUS_NOT_FOUND; + } + + // Retain the object. Will be released in ObDereferenceObject. + thread->Retain(); + *out_object_ptr = thread->guest_object(); + auto hdr = kernel_memory()->TranslateVirtual(thread->guest_object()); + assert_true(hdr->type == 6); + + return X_STATUS_SUCCESS; +} +DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kStub); + +dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr, lpdword_t out_handle_ptr) { + auto object = XObject::GetNativeObject(kernel_state(), object_ptr); + if (!object) { + return X_STATUS_UNSUCCESSFUL; + } + + // Retain the handle. Will be released in NtClose. + object->RetainHandle(); + *out_handle_ptr = object->handle(); + return X_STATUS_SUCCESS; +} +DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByPointer, ExportTag::kStub); + dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr, dword_t options) { // NOTE: new_handle_ptr can be zero to just close a handle. @@ -162,6 +191,7 @@ dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr, DECLARE_XBOXKRNL_EXPORT(NtDuplicateObject, ExportTag::kImplemented); dword_result_t NtClose(dword_t handle) { + // FIXME: This needs to be removed once handle count reaches 0! return kernel_state()->object_table()->RemoveHandle(handle); } DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented); From c60d30a311a06899eed62e6300aac1996c1396a1 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 17 Jul 2015 19:57:35 -0500 Subject: [PATCH 5/6] Add a few more xam exports --- src/xenia/kernel/xam_table.inc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/xenia/kernel/xam_table.inc b/src/xenia/kernel/xam_table.inc index d732679d3..e6d215245 100644 --- a/src/xenia/kernel/xam_table.inc +++ b/src/xenia/kernel/xam_table.inc @@ -150,7 +150,10 @@ XE_EXPORT(xam, 0x000000D7, NetDll_XHttpSetOption, XE_EXPORT(xam, 0x000000D8, NetDll_XHttpDoWork, kFunction), XE_EXPORT(xam, 0x000000D9, NetDll_XHttpSetCredentials, kFunction), XE_EXPORT(xam, 0x000000DA, NetDll_XHttpQueryAuthSchemes, kFunction), -XE_EXPORT(xam, 0x000000DB, NetDll_XHttpCrackUrl, kFunction), +XE_EXPORT(xam, 0x000000DB, NetDll_XHttpCrackUrlW, kFunction), +XE_EXPORT(xam, 0x000000DC, NetDll_XHttpCrackUrl, kFunction), +XE_EXPORT(xam, 0x000000DD, NetDll_XHttpCreateUrl, kFunction), +XE_EXPORT(xam, 0x000000DE, NetDll_XHttpCreateUrlW, kFunction), XE_EXPORT(xam, 0x000000FB, NetDll_UpnpStartup, kFunction), XE_EXPORT(xam, 0x000000FC, NetDll_UpnpCleanup, kFunction), XE_EXPORT(xam, 0x000000FD, NetDll_UpnpSearchCreate, kFunction), @@ -957,7 +960,13 @@ XE_EXPORT(xam, 0x00000490, XamVoiceGetMicArrayAudioEx, XE_EXPORT(xam, 0x00000491, XamVoiceDisableMicArray, kFunction), XE_EXPORT(xam, 0x00000497, XamVoiceIsActiveProcess, kFunction), XE_EXPORT(xam, 0x0000049E, XGetVideoCapabilities, kFunction), +XE_EXPORT(xam, 0x000004A5, XamUserGetAgeGroup, kFunction), XE_EXPORT(xam, 0x000004B0, XMPRegisterCodec, kFunction), +XE_EXPORT(xam, 0x000004BC, XampXAuthStartup, kFunction), +XE_EXPORT(xam, 0x000004BD, XampXAuthShutdown, kFunction), +XE_EXPORT(xam, 0x000004BE, XamGetToken, kFunction), +XE_EXPORT(xam, 0x000004BF, XamFreeToken, kFunction), +XE_EXPORT(xam, 0x000004EE, XampXAuthGetTitleBuffer, kFunction), XE_EXPORT(xam, 0x00000514, XamIsCurrentTitleIptv, kFunction), XE_EXPORT(xam, 0x00000515, XamIsIptvEnabled, kFunction), XE_EXPORT(xam, 0x00000516, XamIsDvrRecording, kFunction), @@ -1046,6 +1055,7 @@ XE_EXPORT(xam, 0x000006A8, XamShowPaymentOptionsUI, XE_EXPORT(xam, 0x00000708, XamGetLiveHiveValueA, kFunction), XE_EXPORT(xam, 0x00000709, XamGetLiveHiveValueW, kFunction), XE_EXPORT(xam, 0x0000070A, XamGetLiveHiveValueDuringLogonAttemptA, kFunction), +XE_EXPORT(xam, 0x0000070C, XamQueryLiveHiveA, kFunction), XE_EXPORT(xam, 0x0000076C, XamDownloadMarketplaceStoresList, kFunction), XE_EXPORT(xam, 0x0000076D, XamGetStoreFront, kFunction), XE_EXPORT(xam, 0x0000076E, XamSetStagingMode, kFunction), From 55f5b956709ccd7244f0cd7837d7b3fd8c54718a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 17 Jul 2015 19:58:56 -0500 Subject: [PATCH 6/6] These are implemented (and formatting) --- src/xenia/kernel/xboxkrnl_ob.cc | 57 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index df6b1f858..7bf99bdb5 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -49,6 +49,34 @@ SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(result); } +dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr, + lpdword_t out_handle_ptr) { + auto object = XObject::GetNativeObject(kernel_state(), object_ptr); + if (!object) { + return X_STATUS_UNSUCCESSFUL; + } + + // Retain the handle. Will be released in NtClose. + object->RetainHandle(); + *out_handle_ptr = object->handle(); + return X_STATUS_SUCCESS; +} +DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByPointer, ExportTag::kImplemented); + +dword_result_t ObLookupThreadByThreadId(dword_t thread_id, + lpdword_t out_object_ptr) { + auto thread = kernel_state()->GetThreadByID(thread_id); + if (!thread) { + return X_STATUS_NOT_FOUND; + } + + // Retain the object. Will be released in ObDereferenceObject. + thread->Retain(); + *out_object_ptr = thread->guest_object(); + return X_STATUS_SUCCESS; +} +DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kImplemented); + SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, KernelState* kernel_state) { uint32_t handle = SHIM_GET_ARG_32(0); @@ -136,35 +164,6 @@ SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context, SHIM_SET_RETURN_32(0); } -dword_result_t ObLookupThreadByThreadId(dword_t thread_id, lpdword_t out_object_ptr) { - auto thread = kernel_state()->GetThreadByID(thread_id); - if (!thread) { - return X_STATUS_NOT_FOUND; - } - - // Retain the object. Will be released in ObDereferenceObject. - thread->Retain(); - *out_object_ptr = thread->guest_object(); - auto hdr = kernel_memory()->TranslateVirtual(thread->guest_object()); - assert_true(hdr->type == 6); - - return X_STATUS_SUCCESS; -} -DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kStub); - -dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr, lpdword_t out_handle_ptr) { - auto object = XObject::GetNativeObject(kernel_state(), object_ptr); - if (!object) { - return X_STATUS_UNSUCCESSFUL; - } - - // Retain the handle. Will be released in NtClose. - object->RetainHandle(); - *out_handle_ptr = object->handle(); - return X_STATUS_SUCCESS; -} -DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByPointer, ExportTag::kStub); - dword_result_t NtDuplicateObject(dword_t handle, lpdword_t new_handle_ptr, dword_t options) { // NOTE: new_handle_ptr can be zero to just close a handle.