diff --git a/src/CxbxKrnl/EmuFile.cpp b/src/CxbxKrnl/EmuFile.cpp index b94bcc234..f539ef54e 100644 --- a/src/CxbxKrnl/EmuFile.cpp +++ b/src/CxbxKrnl/EmuFile.cpp @@ -81,19 +81,6 @@ std::string DeviceHarddisk0Partition18 = "\\Device\\Harddisk0\\partition18"; std::string DeviceHarddisk0Partition19 = "\\Device\\Harddisk0\\partition19"; std::string DeviceHarddisk0Partition20 = "\\Device\\Harddisk0\\partition20"; // 20 = Largest possible partition number char CxbxDefaultXbeVolumeLetter = 'C'; - -// Array of EmuHandles in the system -EmuHandle EmuHandle::Handles[EMU_MAX_HANDLES]; - -// Pointer to first free handle in array, or NULL if none -volatile EmuHandle *EmuHandle::FirstFree; - -// Pointer to last free handle in array, or NULL if none -volatile EmuHandle *EmuHandle::LastFree; - -// Lock on the handle system -CRITICAL_SECTION EmuHandle::HandleLock; - EmuNtSymbolicLinkObject* NtSymbolicLinkObjects[26]; struct XboxDevice { @@ -103,6 +90,60 @@ struct XboxDevice { }; std::vector Devices; +EmuHandle::EmuHandle(EmuNtObject* ntObject) +{ + NtObject = ntObject; +} + +NTSTATUS EmuHandle::NtClose() +{ + return NtObject->NtClose(); +} + +NTSTATUS EmuHandle::NtDuplicateObject(PHANDLE TargetHandle, DWORD Options) +{ + *TargetHandle = NtObject->NtDuplicateObject(Options)->NewHandle(); + return STATUS_SUCCESS; +} + +EmuNtObject::EmuNtObject() +{ + RefCount = 1; +} + +HANDLE EmuNtObject::NewHandle() +{ + RefCount++; + return EmuHandleToHandle(new EmuHandle(this)); +} + +NTSTATUS EmuNtObject::NtClose() +{ + RefCount--; + + if (RefCount <= 0) { + delete this; + } + + return STATUS_SUCCESS; +} + +EmuNtObject* EmuNtObject::NtDuplicateObject(DWORD Options) +{ + RefCount++; + return this; +} + +bool IsEmuHandle(HANDLE Handle) +{ + return (uint32_t)Handle > 0x80000000; +} + +EmuHandle* HandleToEmuHandle(HANDLE Handle) { return (EmuHandle*)((uint32_t)Handle & 0x7FFFFFFF); } HANDLE EmuHandleToHandle(EmuHandle* emuHandle) +{ + return (HANDLE)((uint32_t)emuHandle | 0x80000000); +} + bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile) { bool result; @@ -147,82 +188,6 @@ NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPa return result; } -// ****************************************************************** -// * Initialize the handle database -// ****************************************************************** -bool EmuHandle::Initialize() -{ - size_t x; - - // Initialize the critical section - InitializeCriticalSection(&HandleLock); - - // Mark all handles as free. We also set up the linked list of - // free handles here. - for (x = 0; x < EMU_MAX_HANDLES; x++) - { - Handles[x].m_Type = EMUHANDLE_TYPE_EMPTY; - Handles[x].m_NextFree = &Handles[x + 1]; - } - - // The last entry should have a NULL next entry - Handles[EMU_MAX_HANDLES - 1].m_NextFree = NULL; - - // Set up the head and tail pointers - FirstFree = &Handles[0]; - LastFree = &Handles[EMU_MAX_HANDLES]; - - return true; -} - -// ****************************************************************** -// * func: EmuHandle::Lock -// * Locks the handle database -// ****************************************************************** -inline void EmuHandle::Lock(void) -{ - EnterCriticalSection(&HandleLock); -} - -// ****************************************************************** -// * func: EmuHandle::Unlock -// * Unlocks the handle database -// ****************************************************************** -inline void EmuHandle::Unlock(void) -{ - LeaveCriticalSection(&HandleLock); -} - -// ****************************************************************** -// * func: EmuHandle::Allocate -// * Allocates a new handle -// ****************************************************************** -EmuHandle volatile *EmuHandle::Allocate(void) -{ - volatile EmuHandle *Handle; - - // Lock the database - Lock(); - - // Get the first free entry - Handle = FirstFree; - - // Remove it from the list - FirstFree = Handle->m_NextFree; - - // If it was the last handle, clear LastFree - if (!Handle->m_NextFree) - LastFree = NULL; - - // Initialize the handle's fields - Handle->m_Type = EMUHANDLE_TYPE_ALLOCATED; - Handle->m_Object = NULL; - - // Unlock the database - Unlock(); - - return Handle; -} NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::string aFullPath) { @@ -295,7 +260,7 @@ NTSTATUS EmuNtSymbolicLinkObject::Init(std::string aSymbolicLinkName, std::strin return result; } -void EmuNtSymbolicLinkObject::Free() + EmuNtSymbolicLinkObject::~EmuNtSymbolicLinkObject() { if (DriveLetter >= 'A' && DriveLetter <= 'Z') { NtSymbolicLinkObjects[DriveLetter - 'A'] = NULL; @@ -388,21 +353,3 @@ EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(const HANDLE Handl return NULL; } - -NTSTATUS EmuNtObject::NtClose() -{ - NTSTATUS result = 0; - RefCount--; - if (RefCount <= 0) - Free(); - result = STATUS_SUCCESS; - return result; -} - -EmuNtObject* EmuNtObject::NtDuplicateObject(DWORD Options) -{ - EmuNtObject* result = NULL; - RefCount++; - result = this; - return result; -} \ No newline at end of file diff --git a/src/CxbxKrnl/EmuFile.h b/src/CxbxKrnl/EmuFile.h index 787fa598e..2d9e74c76 100644 --- a/src/CxbxKrnl/EmuFile.h +++ b/src/CxbxKrnl/EmuFile.h @@ -1,274 +1,165 @@ -// ****************************************************************** -// * -// * .,-::::: .,:: .::::::::. .,:: .: -// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; -// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' -// * $$$ Y$$$P $$""""Y$$ Y$$$P -// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, -// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, -// * -// * Cxbx->Win32->CxbxKrnl->EmuFile.h -// * -// * This file is part of the Cxbx project. -// * -// * Cxbx and Cxbe are free software; you can redistribute them -// * and/or modify them under the terms of the GNU General Public -// * License as published by the Free Software Foundation; either -// * version 2 of the license, or (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have recieved a copy of the GNU General Public License -// * along with this program; see the file COPYING. -// * If not, write to the Free Software Foundation, Inc., -// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. -// * -// * (c) 2002-2003 Aaron Robinson -// * -// * All rights reserved -// * -// ****************************************************************** -#ifndef EMUFILE_H -#define EMUFILE_H - -// ****************************************************************** -// * prevent name collisions -// ****************************************************************** -namespace xboxkrnl -{ - #include -}; - -#include -#include - -// ****************************************************************** -// * prevent name collisions -// ****************************************************************** -namespace NtDll -{ - #include "EmuNtDll.h" -}; - -#include "Emu.h" - -extern std::string DriveSerial; -extern std::string DriveCdRom0; -extern std::string DriveMbfs; -extern std::string DriveMbcom; -extern std::string DriveMbrom; -extern std::string DriveC; -extern std::string DriveD; -extern std::string DriveE; -extern std::string DriveF; -extern std::string DriveT; -extern std::string DriveU; -extern std::string DriveV; -extern std::string DriveW; -extern std::string DriveX; -extern std::string DriveY; -extern std::string DriveZ; -extern std::string DeviceCdrom0; -extern std::string DeviceHarddisk0; -extern std::string DeviceHarddisk0Partition0; -extern std::string DeviceHarddisk0Partition1; -extern std::string DeviceHarddisk0Partition2; -extern std::string DeviceHarddisk0Partition3; -extern std::string DeviceHarddisk0Partition4; -extern std::string DeviceHarddisk0Partition5; -extern std::string DeviceHarddisk0Partition6; -extern std::string DeviceHarddisk0Partition7; -extern std::string DeviceHarddisk0Partition8; -extern std::string DeviceHarddisk0Partition9; -extern std::string DeviceHarddisk0Partition10; -extern std::string DeviceHarddisk0Partition11; -extern std::string DeviceHarddisk0Partition12; -extern std::string DeviceHarddisk0Partition13; -extern std::string DeviceHarddisk0Partition14; -extern std::string DeviceHarddisk0Partition15; -extern std::string DeviceHarddisk0Partition16; -extern std::string DeviceHarddisk0Partition17; -extern std::string DeviceHarddisk0Partition18; -extern std::string DeviceHarddisk0Partition19; -extern std::string DeviceHarddisk0Partition20; -extern char CxbxDefaultXbeVolumeLetter; - -extern std::string CxbxBasePath; -extern HANDLE CxbxBasePathHandle; - -// ****************************************************************** -// * Maximum number of open handles in the system -// ****************************************************************** -#define EMU_MAX_HANDLES 1024 - - -// ****************************************************************** -// * Wrapper of a handle object -// ****************************************************************** -class EmuHandle -{ - public: - // Type of handle - volatile enum _EmuHandleType m_Type; - - // To keep the size 8 bytes, these 2 items are in a union - union - { - // Pointer to actual object (when handle is valid) - volatile class EmuNtObject *m_Object; - - // Pointer to next free handle - volatile EmuHandle *m_NextFree; - }; - - // Close this handle - NtDll::NTSTATUS Close(void); - - // Initialize the EmuHandle system - static bool Initialize(); - - // Close all open handles - static void CloseAll(void); - - // Allocate an empty handle - static volatile EmuHandle *Allocate(void); - - private: - // Array of EmuHandles in the system - static EmuHandle Handles[EMU_MAX_HANDLES]; - - // Pointer to first free handle in array, or NULL if none - volatile static EmuHandle *FirstFree; - - // Pointer to last free handle in array, or NULL if none - volatile static EmuHandle *LastFree; - - // Lock on the handle system - static CRITICAL_SECTION HandleLock; - - // Quick functions to lock/unlock - inline static void Lock(void); - inline static void Unlock(void); -}; - -// ****************************************************************** -// * Various "special" handle types -// ****************************************************************** -typedef enum _EmuHandleType -{ - // Unallocated handle - EMUHANDLE_TYPE_EMPTY = 0, - - // Allocated but so far unused handle - EMUHANDLE_TYPE_ALLOCATED, - - // File handle with no really special features - EMUHANDLE_TYPE_FILE, - - // Fake file/directory/directory object/partition handle - EMUHANDLE_TYPE_OBJECT -} -EmuHandleType; - -// ****************************************************************** -// * An NT fake object -// ****************************************************************** -class EmuNtObject -{ - public: - // Decrements the reference count of this object (never override) - NTSTATUS NtClose(void); - - // These functions mimic the Nt* calls - - // Increments the reference count of this object - // For file handles, a whole new EmuFile structure is returned. - // For other objects (the default implementation), "this" is returned. - EmuNtObject *NtDuplicateObject(DWORD options); - - protected: - // Object name (Unicode, because we handle after-conversion strings) - const WCHAR *Name; - ULONG NameLength; - // Permanent status - bool PermanentFlag; - - // Called by close() when the reference count reaches zero - virtual void Free(void) = 0; - - - private: - // Reference count - LONG RefCount; -}; - -// ****************************************************************** -// * Emulated file handle -// ****************************************************************** -class EmuNtFile : public EmuNtObject -{ - public: - // We need to override NtDuplicateObject in this case - - private: - // The Windows file handle - HANDLE File; - // Pointer to the volume from which this came - //EmuNtVolume *Volume; -}; - -// ****************************************************************** -// * Emulated symbolic link handle -// ****************************************************************** -class EmuNtSymbolicLinkObject : public EmuNtObject { -public: - char DriveLetter; - std::string SymbolicLinkName; - std::string XboxFullPath; - std::string NativePath; - HANDLE RootDirectoryHandle; - NTSTATUS Init(std::string aSymbolicLinkName, std::string aFullPath); - void Free(); -}; - -// ****************************************************************** -// * is hFile a 'special' emulated handle? -// ****************************************************************** -static inline bool IsEmuHandle(xboxkrnl::HANDLE hFile) -{ - bool ret = ((uint32)hFile > 0x80000000) && ((uint32)hFile != -1); - - return ret; -} - -// ****************************************************************** -// * convert from 'special' emulated handle to a pointer -// ****************************************************************** -static inline EmuHandle *EmuHandleToPtr(xboxkrnl::HANDLE hFile) -{ - return (EmuHandle*)((uint32)hFile - 0x80000000); -} - -// ****************************************************************** -// * convert from 'special' emulated handle to a pointer -// ****************************************************************** -static inline HANDLE PtrToEmuHandle(EmuHandle *pEmuHandle) -{ - return (HANDLE)((uint32)pEmuHandle + 0x80000000); -} - -char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName); -EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByVolumeLetter(const char VolumeLetter); -EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName); -EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName); -EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle); -void CleanupSymbolicLinks(); -bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile = false); -HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath); -NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath); -bool CxbxMountUtilityDrive(bool formatClean); - -#endif +// ****************************************************************** +// * +// * .,-::::: .,:: .::::::::. .,:: .: +// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;; +// * [[[ '[[,,[[' [[[__[[\. '[[,,[[' +// * $$$ Y$$$P $$""""Y$$ Y$$$P +// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo, +// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm, +// * +// * Cxbx->Win32->CxbxKrnl->EmuFile.h +// * +// * This file is part of the Cxbx project. +// * +// * Cxbx and Cxbe are free software; you can redistribute them +// * and/or modify them under the terms of the GNU General Public +// * License as published by the Free Software Foundation; either +// * version 2 of the license, or (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have recieved a copy of the GNU General Public License +// * along with this program; see the file COPYING. +// * If not, write to the Free Software Foundation, Inc., +// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. +// * +// * (c) 2002-2003 Aaron Robinson +// * +// * All rights reserved +// * +// ****************************************************************** +#ifndef EMUFILE_H +#define EMUFILE_H + +// ****************************************************************** +// * prevent name collisions +// ****************************************************************** +namespace xboxkrnl +{ + #include +}; + +#include +#include + +// ****************************************************************** +// * prevent name collisions +// ****************************************************************** +namespace NtDll +{ + #include "EmuNtDll.h" +}; + +#include "Emu.h" + +extern std::string DriveSerial; +extern std::string DriveCdRom0; +extern std::string DriveMbfs; +extern std::string DriveMbcom; +extern std::string DriveMbrom; +extern std::string DriveC; +extern std::string DriveD; +extern std::string DriveE; +extern std::string DriveF; +extern std::string DriveT; +extern std::string DriveU; +extern std::string DriveV; +extern std::string DriveW; +extern std::string DriveX; +extern std::string DriveY; +extern std::string DriveZ; +extern std::string DeviceCdrom0; +extern std::string DeviceHarddisk0; +extern std::string DeviceHarddisk0Partition0; +extern std::string DeviceHarddisk0Partition1; +extern std::string DeviceHarddisk0Partition2; +extern std::string DeviceHarddisk0Partition3; +extern std::string DeviceHarddisk0Partition4; +extern std::string DeviceHarddisk0Partition5; +extern std::string DeviceHarddisk0Partition6; +extern std::string DeviceHarddisk0Partition7; +extern std::string DeviceHarddisk0Partition8; +extern std::string DeviceHarddisk0Partition9; +extern std::string DeviceHarddisk0Partition10; +extern std::string DeviceHarddisk0Partition11; +extern std::string DeviceHarddisk0Partition12; +extern std::string DeviceHarddisk0Partition13; +extern std::string DeviceHarddisk0Partition14; +extern std::string DeviceHarddisk0Partition15; +extern std::string DeviceHarddisk0Partition16; +extern std::string DeviceHarddisk0Partition17; +extern std::string DeviceHarddisk0Partition18; +extern std::string DeviceHarddisk0Partition19; +extern std::string DeviceHarddisk0Partition20; +extern char CxbxDefaultXbeVolumeLetter; + +extern std::string CxbxBasePath; +extern HANDLE CxbxBasePathHandle; + +class EmuNtObject; + +// ****************************************************************** +// * Wrapper of a handle object +// ****************************************************************** +class EmuHandle +{ +public: + EmuHandle(EmuNtObject* ntObject); + NTSTATUS NtClose(); + NTSTATUS NtDuplicateObject(PHANDLE TargetHandle, DWORD Options); + EmuNtObject* NtObject; +}; + +// ****************************************************************** +// * An NT fake object +// ****************************************************************** +class EmuNtObject +{ +public: + EmuNtObject(); + HANDLE NewHandle(); + NTSTATUS NtClose(); + EmuNtObject* NtDuplicateObject(DWORD Options); +protected: + virtual ~EmuNtObject() {}; +private: + ULONG RefCount; + +}; + +// ****************************************************************** +// * Emulated symbolic link handle +// ****************************************************************** +class EmuNtSymbolicLinkObject : public EmuNtObject { +public: + char DriveLetter; + std::string SymbolicLinkName; + std::string XboxFullPath; + std::string NativePath; + HANDLE RootDirectoryHandle; + NTSTATUS Init(std::string aSymbolicLinkName, std::string aFullPath); + ~EmuNtSymbolicLinkObject(); +}; + +// ****************************************************************** +// * is hFile a 'special' emulated handle? +// ****************************************************************** +bool IsEmuHandle(HANDLE Handle); +EmuHandle* HandleToEmuHandle(HANDLE Handle); HANDLE EmuHandleToHandle(EmuHandle* emuHandle); + + +char SymbolicLinkToDriveLetter(std::string aSymbolicLinkName); +EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByVolumeLetter(const char VolumeLetter); +EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByName(std::string SymbolicLinkName); +EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByDevice(std::string DeviceName); +EmuNtSymbolicLinkObject* FindNtSymbolicLinkObjectByRootHandle(HANDLE Handle); +void CleanupSymbolicLinks(); +bool CxbxRegisterDeviceNativePath(std::string XboxFullPath, std::string NativePath, bool IsFile = false); +HANDLE CxbxGetDeviceNativeRootHandle(std::string XboxFullPath); +NTSTATUS CxbxCreateSymbolicLink(std::string SymbolicLinkName, std::string FullPath); +bool CxbxMountUtilityDrive(bool formatClean); + +#endif diff --git a/src/CxbxKrnl/EmuKrnl.cpp b/src/CxbxKrnl/EmuKrnl.cpp index d13adfe42..023c3c62d 100644 --- a/src/CxbxKrnl/EmuKrnl.cpp +++ b/src/CxbxKrnl/EmuKrnl.cpp @@ -2975,15 +2975,8 @@ XBSYSAPI EXPORTNUM(187) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtClose // delete 'special' handles if(IsEmuHandle(Handle)) { - EmuHandle *iEmuHandle = EmuHandleToPtr(Handle); - - // HACK: Do not delete emuhandle - // There is an issue with EmuHandle/EmuNtObject causing referencing counting to not function - // Consider translating the entirity of EmuFile & EmuKrnl from Dxbx - //delete iEmuHandle; - EmuWarning("EmuKrnl::NtClose : EmuHandle not deleted"); - - ret = STATUS_SUCCESS; + EmuHandle *iEmuHandle = HandleToEmuHandle(Handle); + ret = iEmuHandle->NtClose(); } // close normal handles else @@ -3260,15 +3253,24 @@ XBSYSAPI EXPORTNUM(197) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtDuplicateObject ");\n", GetCurrentThreadId(), SourceHandle, TargetHandle, Options); - // redirect to Win2k/XP - NTSTATUS ret = NtDll::NtDuplicateObject - ( - GetCurrentProcess(), - SourceHandle, - GetCurrentProcess(), - TargetHandle, - 0, 0, Options - ); + NTSTATUS ret; + + if (IsEmuHandle(SourceHandle)) { + EmuHandle* iEmuHandle = HandleToEmuHandle(SourceHandle); + ret = iEmuHandle->NtDuplicateObject(TargetHandle, Options); + } + else { + // redirect to Win2k/XP + ret = NtDll::NtDuplicateObject + ( + GetCurrentProcess(), + SourceHandle, + GetCurrentProcess(), + TargetHandle, + 0, 0, Options + ); + } + if(ret != STATUS_SUCCESS) EmuWarning("Object was not duplicated!"); @@ -3393,7 +3395,7 @@ XBSYSAPI EXPORTNUM(203) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtOpenSymbolicLinkObj if ((symbolicLinkObject != NULL)) { // Return a new handle - *LinkHandle = EmuHandleToPtr(symbolicLinkObject); + *LinkHandle = symbolicLinkObject->NewHandle(); ret = STATUS_SUCCESS; } else @@ -3664,9 +3666,10 @@ XBSYSAPI EXPORTNUM(215) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQuerySymbolicLinkOb // Check that we actually got an EmuHandle : result = STATUS_INVALID_HANDLE; + EmuHandle* iEmuHandle = HandleToEmuHandle(LinkHandle); // Retrieve the NtSymbolicLinkObject and populate the output arguments : result = STATUS_SUCCESS; - symbolicLinkObject = ((EmuNtSymbolicLinkObject*)PtrToEmuHandle((EmuHandle*)LinkHandle)); + symbolicLinkObject = (EmuNtSymbolicLinkObject*)iEmuHandle->NtObject; if ((LinkTarget != NULL)) { if (LinkTarget->Length > LinkTarget->MaximumLength) { result = STATUS_BUFFER_TOO_SMALL; @@ -4157,9 +4160,21 @@ XBSYSAPI EXPORTNUM(234) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtWaitForSingleObject ");\n", GetCurrentThreadId(), Handle, WaitMode, Alertable, Timeout, Timeout == 0 ? 0 : Timeout->QuadPart); - NTSTATUS ret = NtDll::NtWaitForSingleObject(Handle, Alertable, (NtDll::PLARGE_INTEGER)Timeout); + NTSTATUS ret; - DbgPrintf("Finished waiting for 0x%.08X\n", Handle); + if (IsEmuHandle(Handle)) + { + ret = WAIT_FAILED; + EmuWarning("WaitFor EmuHandle not supported!"); + } + else + { + ret = NtDll::NtWaitForSingleObject(Handle, Alertable, (NtDll::PLARGE_INTEGER)Timeout); + DbgPrintf("Finished waiting for 0x%.08X\n", Handle); + } + + if (ret == WAIT_FAILED) + EmuWarning("NtWaitForSingleObjectEx failed! (%s)", NtStatusToString(ret)); EmuSwapFS(); // Xbox FS @@ -4193,6 +4208,7 @@ XBSYSAPI EXPORTNUM(235) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtWaitForMultipleObje GetCurrentThreadId(), Count, Handles, WaitType, WaitMode, Alertable, Timeout, Timeout == 0 ? 0 : Timeout->QuadPart); + // TODO: Process EmuHandle NTSTATUS ret = NtDll::NtWaitForMultipleObjects(Count, Handles, (NtDll::OBJECT_WAIT_TYPE)WaitType, Alertable, (NtDll::PLARGE_INTEGER)Timeout); EmuSwapFS(); // Xbox FS