fix thread calls issue from GetNativeHandle to keep special handle return

This commit is contained in:
RadWolfie 2022-01-16 16:12:56 -06:00 committed by ergo720
parent 7e5f9a7cb7
commit e208c73586
3 changed files with 22 additions and 5 deletions

View File

@ -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<true>(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<true>(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<true>(PspGetCurrentThread()->UniqueThread);
boolean_xt prevDisableBoost = Thread->DisableBoost;
Thread->DisableBoost = (CHAR)Disable;

View File

@ -51,12 +51,27 @@ void RemoveXboxHandle(xbox::HANDLE xhandle)
assert(ret == 1);
}
template<bool NoConversion>
std::optional<HANDLE> 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<std::shared_mutex> lck(g_MapMtx);
@ -68,3 +83,5 @@ std::optional<HANDLE> GetNativeHandle(xbox::HANDLE xhandle)
return it->second;
}
}
template std::optional<HANDLE> GetNativeHandle<true>(xbox::HANDLE xhandle);
template std::optional<HANDLE> GetNativeHandle<false>(xbox::HANDLE xhandle);

View File

@ -31,4 +31,4 @@
void RegisterXboxHandle(xbox::HANDLE xhandle, HANDLE nhandle);
void RemoveXboxHandle(xbox::HANDLE xhandle);
std::optional<HANDLE> GetNativeHandle(xbox::HANDLE xhandle);
template<bool NoConversion = false> std::optional<HANDLE> GetNativeHandle(xbox::HANDLE xhandle);