From 934945d04856a543c269c4e95a14ee6cced35ba8 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Wed, 9 Aug 2017 19:28:20 +0100 Subject: [PATCH] Fix DPC bugs: Wrong calling convention was used --- import/OpenXDK/include/xboxkrnl/xboxkrnl.h | 2 +- src/CxbxKrnl/EmuKrnlKe.cpp | 42 ++++++++++++++++------ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h index e3bdb94db5..1e4e982a9e 100644 --- a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h +++ b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h @@ -1527,7 +1527,7 @@ struct _KDPC; // ****************************************************************** // * PKDEFERRED_ROUTINE // ****************************************************************** -typedef VOID (*PKDEFERRED_ROUTINE) +typedef VOID (__stdcall *PKDEFERRED_ROUTINE) ( IN struct _KDPC *Dpc, IN PVOID DeferredContext, diff --git a/src/CxbxKrnl/EmuKrnlKe.cpp b/src/CxbxKrnl/EmuKrnlKe.cpp index fbe9f6e796..865e3545d6 100644 --- a/src/CxbxKrnl/EmuKrnlKe.cpp +++ b/src/CxbxKrnl/EmuKrnlKe.cpp @@ -54,6 +54,7 @@ namespace NtDll #include "CxbxKrnl.h" // For CxbxKrnlCleanup #include "Emu.h" // For EmuWarning() +#include "EmuFS.h" #include "EmuKrnl.h" // For InitializeListHead(), etc. #include "EmuFile.h" // For IsEmuHandle(), NtStatusToString() @@ -178,6 +179,11 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) LONG lWait; xboxkrnl::PKTIMER pktimer; + EmuGenerateFS(CxbxKrnl_TLS, CxbxKrnl_TLSData); + + _controlfp(_PC_53, _MCW_PC); // Set Precision control to 53 bits (verified setting) + _controlfp(_RC_NEAR, _MCW_RC); // Set Rounding control to near (unsure about this) + while (true) { // While we're working with the DpcQueue, we need to be thread-safe : @@ -200,12 +206,19 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) pkdpc->Inserted = FALSE; // Set DpcRoutineActive to support KeIsExecutingDpc: KeGetCurrentPrcb()->DpcRoutineActive = TRUE; // Experimental - // Call the Deferred Procedure : - pkdpc->DeferredRoutine( - pkdpc, - pkdpc->DeferredContext, - pkdpc->SystemArgument1, - pkdpc->SystemArgument2); + + __try { + // Call the Deferred Procedure : + pkdpc->DeferredRoutine( + pkdpc, + pkdpc->DeferredContext, + pkdpc->SystemArgument1, + pkdpc->SystemArgument2); + } __except (EmuException(GetExceptionInformation())) + { + EmuWarning("Problem with ExceptionFilter!"); + } + KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental } @@ -237,10 +250,16 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) if (pkdpc == nullptr) break; // while - pkdpc->DeferredRoutine(pkdpc, - pkdpc->DeferredContext, - pkdpc->SystemArgument1, - pkdpc->SystemArgument2); + __try { + pkdpc->DeferredRoutine( + pkdpc, + pkdpc->DeferredContext, + pkdpc->SystemArgument1, + pkdpc->SystemArgument2); + } __except (EmuException(GetExceptionInformation())) + { + EmuWarning("Problem with ExceptionFilter!"); + } } } @@ -251,6 +270,8 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) // TODO : Wait for shutdown too here WaitForSingleObject(g_DpcData.DpcEvent, dwWait); + + SwitchToThread(); } // while return S_OK; @@ -265,6 +286,7 @@ void InitDpcAndTimerThread() InitializeListHead(&(g_DpcData.TimerQueue)); g_DpcData.DpcEvent = CreateEvent(/*lpEventAttributes=*/nullptr, /*bManualReset=*/FALSE, /*bInitialState=*/FALSE, /*lpName=*/nullptr); g_DpcData.DpcThread = CreateThread(/*lpThreadAttributes=*/nullptr, /*dwStackSize=*/0, (LPTHREAD_START_ROUTINE)&EmuThreadDpcHandler, /*lpParameter=*/nullptr, /*dwCreationFlags=*/0, &dwThreadId); + SetThreadAffinityMask(g_DpcData.DpcThread, g_CPUXbox); SetThreadPriority(g_DpcData.DpcThread, THREAD_PRIORITY_HIGHEST); }