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); } 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! }; 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), diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index b428fd9e2..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); @@ -162,6 +190,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); 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_;