diff --git a/src/core/kernel/exports/EmuKrnlKe.cpp b/src/core/kernel/exports/EmuKrnlKe.cpp index de5421d59..9d3f22384 100644 --- a/src/core/kernel/exports/EmuKrnlKe.cpp +++ b/src/core/kernel/exports/EmuKrnlKe.cpp @@ -1225,7 +1225,7 @@ XBSYSAPI EXPORTNUM(124) xbox::long_xt NTAPI xbox::KeQueryBasePriorityThread KiLockDispatcherDatabase(&OldIrql); // It cannot fail because all thread handles are created by ob - const auto& nativeHandle = GetNativeHandle(PspGetCurrentThread()->UniqueThread); + const auto& nativeHandle = GetNativeHandle(PspGetCurrentThread()->UniqueThread); long_xt ret = GetThreadPriority(*nativeHandle); KiUnlockDispatcherDatabase(OldIrql); @@ -1652,7 +1652,7 @@ XBSYSAPI EXPORTNUM(143) xbox::long_xt NTAPI xbox::KeSetBasePriorityThread KiLockDispatcherDatabase(&oldIRQL); // It cannot fail because all thread handles are created by ob - const auto &nativeHandle = GetNativeHandle(PspGetCurrentThread()->UniqueThread); + const auto &nativeHandle = GetNativeHandle(PspGetCurrentThread()->UniqueThread); LONG ret = GetThreadPriority(*nativeHandle); // This would work normally, but it will slow down the emulation, @@ -1693,7 +1693,7 @@ XBSYSAPI EXPORTNUM(144) xbox::boolean_xt NTAPI xbox::KeSetDisableBoostThread KiLockDispatcherDatabase(&oldIRQL); // It cannot fail because all thread handles are created by ob - const auto &nativeHandle = GetNativeHandle(PspGetCurrentThread()->UniqueThread); + const auto &nativeHandle = GetNativeHandle(PspGetCurrentThread()->UniqueThread); boolean_xt prevDisableBoost = Thread->DisableBoost; Thread->DisableBoost = (CHAR)Disable; diff --git a/src/core/kernel/support/NativeHandle.cpp b/src/core/kernel/support/NativeHandle.cpp index fc870ef83..459e6cdfe 100644 --- a/src/core/kernel/support/NativeHandle.cpp +++ b/src/core/kernel/support/NativeHandle.cpp @@ -51,12 +51,27 @@ void RemoveXboxHandle(xbox::HANDLE xhandle) assert(ret == 1); } +template std::optional GetNativeHandle(xbox::HANDLE xhandle) { // If SourceHandle is -2 = NtCurrentThread, then we are searching the handle of this thread // Test case: Metal Slug 3 if (xhandle == NtCurrentThread()) { - xhandle = xbox::PspGetCurrentThread()->UniqueThread; + // Only used for threads as Windows doesn't allow non-special handle for same thread. + if (NoConversion) { + return xhandle; + } + else { + xhandle = xbox::PspGetCurrentThread()->UniqueThread; + } + } + // If xhandle is not special handle, check if it's the same as current thread. + // Only used for threads as Windows doesn't allow non-special handle for same thread. + // This will only triggered within kernel functions i.e. KeSetDisableBoostThread and KeSetBasePriorityThread. + else if (NoConversion) { + if (xhandle == xbox::PspGetCurrentThread()->UniqueThread) { + return NtCurrentThread(); + } } std::shared_lock lck(g_MapMtx); @@ -68,3 +83,5 @@ std::optional GetNativeHandle(xbox::HANDLE xhandle) return it->second; } } +template std::optional GetNativeHandle(xbox::HANDLE xhandle); +template std::optional GetNativeHandle(xbox::HANDLE xhandle); diff --git a/src/core/kernel/support/NativeHandle.h b/src/core/kernel/support/NativeHandle.h index 3ba46f9b8..b0ec16dcd 100644 --- a/src/core/kernel/support/NativeHandle.h +++ b/src/core/kernel/support/NativeHandle.h @@ -31,4 +31,4 @@ void RegisterXboxHandle(xbox::HANDLE xhandle, HANDLE nhandle); void RemoveXboxHandle(xbox::HANDLE xhandle); -std::optional GetNativeHandle(xbox::HANDLE xhandle); +template std::optional GetNativeHandle(xbox::HANDLE xhandle);