From d3b2554b20da00bed8c2994c4f3a4303f21e5f1e Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Sun, 20 Feb 2022 16:07:42 +0100 Subject: [PATCH] Use a separate array for the native handles in NtWaitForMultipleObjectsEx --- src/core/kernel/common/nt.h | 2 ++ src/core/kernel/exports/EmuKrnlNt.cpp | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/core/kernel/common/nt.h b/src/core/kernel/common/nt.h index 531f20eae..01095adc9 100644 --- a/src/core/kernel/common/nt.h +++ b/src/core/kernel/common/nt.h @@ -19,6 +19,8 @@ namespace xbox #define NtCurrentThread() ((HANDLE)-2) +#define X_MAXIMUM_WAIT_OBJECTS 64 + // ****************************************************************** // * NtAllocateVirtualMemory // ****************************************************************** diff --git a/src/core/kernel/exports/EmuKrnlNt.cpp b/src/core/kernel/exports/EmuKrnlNt.cpp index 02935c80f..0c9e78e1b 100644 --- a/src/core/kernel/exports/EmuKrnlNt.cpp +++ b/src/core/kernel/exports/EmuKrnlNt.cpp @@ -2190,12 +2190,20 @@ XBSYSAPI EXPORTNUM(235) xbox::ntstatus_xt NTAPI xbox::NtWaitForMultipleObjectsEx LOG_FUNC_ARG(Timeout) LOG_FUNC_END; + if (!Count || (Count > X_MAXIMUM_WAIT_OBJECTS)) { + RETURN(X_STATUS_INVALID_PARAMETER); + } + // This function can wait on thread handles, which are currently created by ob, // so we need to check their presence in the handle array + ::HANDLE nativeHandles[X_MAXIMUM_WAIT_OBJECTS]; for (ulong_xt i = 0; i < Count; ++i) { if (const auto &nativeHandle = GetNativeHandle(Handles[i])) { // This is a ob handle, so replace it with its native counterpart - Handles[i] = *nativeHandle; + nativeHandles[i] = *nativeHandle; + } + else { + nativeHandles[i] = Handles[i]; } } @@ -2212,12 +2220,12 @@ XBSYSAPI EXPORTNUM(235) xbox::ntstatus_xt NTAPI xbox::NtWaitForMultipleObjectsEx pNewTime = &NewTime; } - xbox::ntstatus_xt ret = WaitApc([Count, Handles, WaitType, Alertable]() -> std::optional { + xbox::ntstatus_xt ret = WaitApc([Count, &nativeHandles, WaitType, Alertable]() -> std::optional { NtDll::LARGE_INTEGER ExpireTime; ExpireTime.QuadPart = 0; NTSTATUS Status = NtDll::NtWaitForMultipleObjects( Count, - Handles, + nativeHandles, (NtDll::OBJECT_WAIT_TYPE)WaitType, Alertable, &ExpireTime);