EmuKrnl Files Update
This commit is contained in:
parent
8379cdad10
commit
1cbde6f7e8
|
@ -132,6 +132,23 @@ xboxkrnl::PLIST_ENTRY RemoveTailList(xboxkrnl::PLIST_ENTRY pListHead)
|
|||
// ******************************************************************
|
||||
xboxkrnl::KPCR* KeGetPcr();
|
||||
|
||||
// ******************************************************************
|
||||
// * KiLockDispatcherDatabase()
|
||||
// ******************************************************************
|
||||
// * Not exported in kernel thunk table
|
||||
// * NOTE: This is a macro on the Xbox, however we implement it
|
||||
// * as a function because a macro doesn't compile this: *(&OldIrql)
|
||||
// ******************************************************************
|
||||
void xboxkrnl::KiLockDispatcherDatabase
|
||||
(
|
||||
OUT KIRQL* OldIrql
|
||||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG_OUT(OldIrql);
|
||||
|
||||
*(OldIrql) = KeRaiseIrqlToDpcLevel();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * 0x0033 - InterlockedCompareExchange()
|
||||
// ******************************************************************
|
||||
|
@ -282,27 +299,28 @@ XBSYSAPI EXPORTNUM(58) xboxkrnl::PSLIST_ENTRY FASTCALL xboxkrnl::KRNL(Interlocke
|
|||
// ******************************************************************
|
||||
// * 0x00A0 - KfRaiseIrql()
|
||||
// ******************************************************************
|
||||
// Raises the hardware priority (irql)
|
||||
// NewIrql = Irql to raise to
|
||||
// Raises the hardware priority (irq level)
|
||||
// NewIrql = Irq level to raise to
|
||||
// RETURN VALUE previous irq level
|
||||
XBSYSAPI EXPORTNUM(160) xboxkrnl::UCHAR FASTCALL xboxkrnl::KfRaiseIrql
|
||||
XBSYSAPI EXPORTNUM(160) xboxkrnl::KIRQL FASTCALL xboxkrnl::KfRaiseIrql
|
||||
(
|
||||
IN UCHAR NewIrql
|
||||
IN KIRQL NewIrql
|
||||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(NewIrql);
|
||||
|
||||
UCHAR OldIrql;
|
||||
// Inlined KeGetCurrentIrql() :
|
||||
PKPCR Pcr = KeGetPcr();
|
||||
KIRQL OldIrql = (KIRQL)Pcr->Irql;
|
||||
|
||||
KPCR* Pcr = KeGetPcr();
|
||||
|
||||
if (NewIrql < Pcr->Irql) {
|
||||
if (NewIrql < OldIrql) {
|
||||
KeBugCheck(0x00000009); // IRQL_NOT_GREATER_OR_EQUAL
|
||||
}
|
||||
|
||||
OldIrql = Pcr->Irql;
|
||||
Pcr->Irql = NewIrql;
|
||||
|
||||
|
||||
LOG_INCOMPLETE();
|
||||
|
||||
RETURN(OldIrql);
|
||||
}
|
||||
|
||||
|
@ -313,7 +331,7 @@ XBSYSAPI EXPORTNUM(160) xboxkrnl::UCHAR FASTCALL xboxkrnl::KfRaiseIrql
|
|||
// ARGUMENTS NewIrql = Irql to lower to
|
||||
XBSYSAPI EXPORTNUM(161) xboxkrnl::VOID FASTCALL xboxkrnl::KfLowerIrql
|
||||
(
|
||||
IN UCHAR NewIrql
|
||||
IN KIRQL NewIrql
|
||||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(NewIrql);
|
||||
|
@ -336,6 +354,8 @@ XBSYSAPI EXPORTNUM(161) xboxkrnl::VOID FASTCALL xboxkrnl::KfLowerIrql
|
|||
// Source:ReactOS
|
||||
XBSYSAPI EXPORTNUM(162) xboxkrnl::ULONG_PTR xboxkrnl::KiBugCheckData[5] = { NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
extern xboxkrnl::KPRCB *KeGetCurrentPrcb();
|
||||
|
||||
// ******************************************************************
|
||||
// * 0x00A3 - KiUnlockDispatcherDatabase()
|
||||
// ******************************************************************
|
||||
|
@ -346,7 +366,12 @@ XBSYSAPI EXPORTNUM(163) xboxkrnl::VOID FASTCALL xboxkrnl::KiUnlockDispatcherData
|
|||
{
|
||||
LOG_FUNC_ONE_ARG(OldIrql);
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
if (!(KeGetCurrentPrcb()->DpcRoutineActive)) // Avoid KeIsExecutingDpc(), as that logs
|
||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||
|
||||
LOG_INCOMPLETE(); // TODO : Thread-switch?
|
||||
|
||||
KfLowerIrql(OldIrql);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -358,8 +383,10 @@ XBSYSAPI EXPORTNUM(252) xboxkrnl::DWORD NTAPI xboxkrnl::PhyGetLinkState
|
|||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(Mode);
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
return 0;
|
||||
|
||||
return 0; // Was XNET_ETHERNET_LINK_ACTIVE | XNET_ETHERNET_LINK_100MBPS | XNET_ETHERNET_LINK_FULL_DUPLEX;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
}
|
||||
|
||||
void Trigger(xboxkrnl::PKINTERRUPT Interrupt) {
|
||||
// If interrupt was level sensitive, we clear the pending flag, oreventing the interrupt from being triggered
|
||||
// If interrupt was level sensitive, we clear the pending flag, preventing the interrupt from being triggered
|
||||
// until it is deasserted then asserted again. Latched interrupts are triggered until the line is Deasserted!
|
||||
if (m_InterruptMode == xboxkrnl::KINTERRUPT_MODE::LevelSensitive) {
|
||||
m_Pending = false;
|
||||
|
|
|
@ -65,6 +65,7 @@ namespace NtDll
|
|||
#include "EmuNtDll.h"
|
||||
};
|
||||
|
||||
static DWORD EmuSoftwareInterrupRequestRegister = 0;
|
||||
HalSystemInterrupt HalSystemInterrupts[MAX_BUS_INTERRUPT_LEVEL + 1];
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -109,7 +110,9 @@ XBSYSAPI EXPORTNUM(38) xboxkrnl::VOID FASTCALL xboxkrnl::HalClearSoftwareInterru
|
|||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(Request);
|
||||
LOG_UNIMPLEMENTED();
|
||||
|
||||
// Mask out this interrupt request
|
||||
EmuSoftwareInterrupRequestRegister &= ~(1 << Request);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -224,7 +227,7 @@ XBSYSAPI EXPORTNUM(44) xboxkrnl::ULONG NTAPI xboxkrnl::HalGetInterruptVector
|
|||
*Irql = (KIRQL)VECTOR2IRQL(dwVector);
|
||||
|
||||
#ifdef _DEBUG_TRACE
|
||||
DbgPrintf("HalGetInterruptVector(): Interrupt vector requested for %d (%s)!\n",
|
||||
DbgPrintf("KRNL: HalGetInterruptVector(): Interrupt vector requested for %d (%s)\n",
|
||||
BusInterruptLevel, IRQNames[BusInterruptLevel]);
|
||||
#endif
|
||||
}
|
||||
|
@ -408,7 +411,10 @@ XBSYSAPI EXPORTNUM(48) xboxkrnl::VOID FASTCALL xboxkrnl::HalRequestSoftwareInter
|
|||
{
|
||||
LOG_FUNC_ONE_ARG(Request);
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
// Set this software interrupt request :
|
||||
EmuSoftwareInterrupRequestRegister |= (1 << Request);
|
||||
|
||||
LOG_INCOMPLETE();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -279,7 +279,7 @@ XBSYSAPI EXPORTNUM(66) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateFile
|
|||
// Force ShareAccess to all
|
||||
ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
|
||||
if (!FAILED(ret))
|
||||
if (SUCCEEDED(ret))
|
||||
// redirect to NtCreateFile
|
||||
ret = NtDll::NtCreateFile(
|
||||
FileHandle,
|
||||
|
@ -296,11 +296,11 @@ XBSYSAPI EXPORTNUM(66) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateFile
|
|||
|
||||
if (FAILED(ret))
|
||||
{
|
||||
EmuWarning("EmuKrnl: IoCreateFile Failed! (%s)\n", NtStatusToString(ret));
|
||||
EmuWarning("KRNL: IoCreateFile Failed! (%s)\n", NtStatusToString(ret));
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrintf("EmuKrnl: IoCreateFile = 0x%.08X\n", *FileHandle);
|
||||
DbgPrintf("KRNL: IoCreateFile = 0x%.8X\n", *FileHandle);
|
||||
}
|
||||
|
||||
RETURN(ret);
|
||||
|
@ -330,10 +330,10 @@ XBSYSAPI EXPORTNUM(67) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateSymbolicLink
|
|||
// ******************************************************************
|
||||
XBSYSAPI EXPORTNUM(68) xboxkrnl::VOID NTAPI xboxkrnl::IoDeleteDevice
|
||||
(
|
||||
IN PDEVICE_OBJECT irql
|
||||
IN PDEVICE_OBJECT Irql
|
||||
)
|
||||
{
|
||||
LOG_FUNC_ONE_ARG(irql);
|
||||
LOG_FUNC_ONE_ARG(Irql);
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ xboxkrnl::KPRCB *KeGetCurrentPrcb()
|
|||
|
||||
// Forward KeRaiseIrql() to KfRaiseIrql()
|
||||
#define KeRaiseIrql(NewIrql, OldIrql) \
|
||||
*OldIrql = KfRaiseIrql(NewIrql)
|
||||
*(OldIrql) = KfRaiseIrql(NewIrql)
|
||||
|
||||
ULONGLONG BootTickCount = 0;
|
||||
|
||||
|
@ -176,7 +176,7 @@ DWORD CxbxXboxGetTickCount()
|
|||
return (DWORD)(GetTickCount64() - BootTickCount);
|
||||
}
|
||||
|
||||
DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
|
||||
DWORD ExecuteDpcQueue()
|
||||
{
|
||||
xboxkrnl::PKDPC pkdpc;
|
||||
DWORD dwWait;
|
||||
|
@ -184,16 +184,8 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
|
|||
LONG lWait;
|
||||
xboxkrnl::PKTIMER pktimer;
|
||||
|
||||
// since callbacks come from here
|
||||
// Note : This function runs on the Xbox core to somewhat approximate
|
||||
// CPU locking (the prevention of interrupts to avoid thread-switches)
|
||||
// so that callbacks don't get preempted. This needs more work.
|
||||
InitXboxThread(g_CPUXbox);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// While we're working with the DpcQueue, we need to be thread-safe :
|
||||
EnterCriticalSection(&(g_DpcData.Lock));
|
||||
// While we're working with the DpcQueue, we need to be thread-safe :
|
||||
EnterCriticalSection(&(g_DpcData.Lock));
|
||||
|
||||
// if (g_DpcData._fShutdown)
|
||||
// break; // while
|
||||
|
@ -203,18 +195,61 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
|
|||
// g_DpcData._dwDpcThreadId = g_DpcData._dwThreadId;
|
||||
// Assert(g_DpcData._dwDpcThreadId != 0);
|
||||
|
||||
// Are there entries in the DpqQueue?
|
||||
while (!IsListEmpty(&(g_DpcData.DpcQueue)))
|
||||
// Are there entries in the DpqQueue?
|
||||
while (!IsListEmpty(&(g_DpcData.DpcQueue)))
|
||||
{
|
||||
// Extract the head entry and retrieve the containing KDPC pointer for it:
|
||||
pkdpc = CONTAINING_RECORD(RemoveHeadList(&(g_DpcData.DpcQueue)), xboxkrnl::KDPC, DpcListEntry);
|
||||
// Mark it as no longer linked into the DpcQueue
|
||||
pkdpc->Inserted = FALSE;
|
||||
// Set DpcRoutineActive to support KeIsExecutingDpc:
|
||||
KeGetCurrentPrcb()->DpcRoutineActive = TRUE; // Experimental
|
||||
DbgPrintf("KRNL: Global DpcQueue, calling DPC at 0x%.8X\n", pkdpc->DeferredRoutine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
pkdpc->DeferredRoutine(
|
||||
pkdpc,
|
||||
pkdpc->DeferredContext,
|
||||
pkdpc->SystemArgument1,
|
||||
pkdpc->SystemArgument2);
|
||||
} __except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
// Extract the head entry and retrieve the containing KDPC pointer for it:
|
||||
pkdpc = CONTAINING_RECORD(RemoveHeadList(&(g_DpcData.DpcQueue)), xboxkrnl::KDPC, DpcListEntry);
|
||||
// Mark it as no longer linked into the DpcQueue
|
||||
pkdpc->Inserted = FALSE;
|
||||
// Set DpcRoutineActive to support KeIsExecutingDpc:
|
||||
KeGetCurrentPrcb()->DpcRoutineActive = TRUE; // Experimental
|
||||
EmuWarning("Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental
|
||||
}
|
||||
|
||||
dwWait = INFINITE;
|
||||
if (!IsListEmpty(&(g_DpcData.TimerQueue)))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
dwNow = CxbxXboxGetTickCount();
|
||||
dwWait = INFINITE;
|
||||
pktimer = (xboxkrnl::PKTIMER)g_DpcData.TimerQueue.Flink;
|
||||
pkdpc = nullptr;
|
||||
while (pktimer != (xboxkrnl::PKTIMER)&(g_DpcData.TimerQueue))
|
||||
{
|
||||
lWait = (LONG)pktimer->DueTime.u.LowPart - dwNow;
|
||||
if (lWait <= 0)
|
||||
{
|
||||
pktimer->DueTime.u.LowPart = pktimer->Period + dwNow;
|
||||
pkdpc = pktimer->Dpc;
|
||||
break; // while
|
||||
}
|
||||
|
||||
if (dwWait > (DWORD)lWait)
|
||||
dwWait = (DWORD)lWait;
|
||||
|
||||
pktimer = (xboxkrnl::PKTIMER)pktimer->TimerListEntry.Flink;
|
||||
}
|
||||
|
||||
if (pkdpc == nullptr)
|
||||
break; // while
|
||||
|
||||
DbgPrintf("KRNL: Global TimerQueue, calling DPC at 0x%.8X\n", pkdpc->DeferredRoutine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
pkdpc->DeferredRoutine(
|
||||
pkdpc,
|
||||
pkdpc->DeferredContext,
|
||||
|
@ -224,55 +259,30 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
|
|||
{
|
||||
EmuWarning("Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental
|
||||
}
|
||||
|
||||
dwWait = INFINITE;
|
||||
if (!IsListEmpty(&(g_DpcData.TimerQueue)))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
dwNow = CxbxXboxGetTickCount();
|
||||
dwWait = INFINITE;
|
||||
pktimer = (xboxkrnl::PKTIMER)g_DpcData.TimerQueue.Flink;
|
||||
pkdpc = nullptr;
|
||||
while (pktimer != (xboxkrnl::PKTIMER)&(g_DpcData.TimerQueue))
|
||||
{
|
||||
lWait = (LONG)pktimer->DueTime.u.LowPart - dwNow;
|
||||
if (lWait <= 0)
|
||||
{
|
||||
pktimer->DueTime.u.LowPart = pktimer->Period + dwNow;
|
||||
pkdpc = pktimer->Dpc;
|
||||
break; // while
|
||||
}
|
||||
|
||||
if (dwWait > (DWORD)lWait)
|
||||
dwWait = (DWORD)lWait;
|
||||
|
||||
pktimer = (xboxkrnl::PKTIMER)pktimer->TimerListEntry.Flink;
|
||||
}
|
||||
|
||||
if (pkdpc == nullptr)
|
||||
break; // while
|
||||
|
||||
__try {
|
||||
pkdpc->DeferredRoutine(
|
||||
pkdpc,
|
||||
pkdpc->DeferredContext,
|
||||
pkdpc->SystemArgument1,
|
||||
pkdpc->SystemArgument2);
|
||||
} __except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuWarning("Problem with ExceptionFilter!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assert(g_DpcData._dwThreadId == GetCurrentThreadId());
|
||||
// Assert(g_DpcData._dwDpcThreadId == g_DpcData._dwThreadId);
|
||||
// g_DpcData._dwDpcThreadId = 0;
|
||||
LeaveCriticalSection(&(g_DpcData.Lock));
|
||||
LeaveCriticalSection(&(g_DpcData.Lock));
|
||||
|
||||
return dwWait;
|
||||
}
|
||||
|
||||
DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
|
||||
{
|
||||
DbgPrintf("KRNL: DPC thread is running\n");
|
||||
|
||||
// Make sure DPC callbacks run on the same core as the one that runs Xbox1 code :
|
||||
// Note : This function runs on the Xbox core to somewhat approximate
|
||||
// CPU locking (the prevention of interrupts to avoid thread-switches)
|
||||
// so that callbacks don't get preempted. This needs more work.
|
||||
InitXboxThread(g_CPUXbox);
|
||||
|
||||
while (true)
|
||||
{
|
||||
DWORD dwWait = ExecuteDpcQueue();
|
||||
|
||||
// TODO : Wait for shutdown too here
|
||||
WaitForSingleObject(g_DpcData.DpcEvent, dwWait);
|
||||
|
@ -280,19 +290,24 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid)
|
|||
SwitchToThread();
|
||||
} // while
|
||||
|
||||
DbgPrintf("KRNL: DPC thread is finished\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void InitDpcAndTimerThread()
|
||||
{
|
||||
DWORD dwThreadId;
|
||||
DWORD dwThreadId = 0;
|
||||
|
||||
InitializeCriticalSection(&(g_DpcData.Lock));
|
||||
InitializeListHead(&(g_DpcData.DpcQueue));
|
||||
InitializeListHead(&(g_DpcData.TimerQueue));
|
||||
|
||||
DbgPrintf("INIT: Creating DPC event\n");
|
||||
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);
|
||||
DbgPrintf("INIT: Created DPC thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", g_DpcData.DpcThread, dwThreadId);
|
||||
SetThreadPriority(g_DpcData.DpcThread, THREAD_PRIORITY_HIGHEST);
|
||||
}
|
||||
|
||||
|
@ -426,11 +441,11 @@ XBSYSAPI EXPORTNUM(96) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeBugCheckEx
|
|||
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "The running software triggered KeBugCheck with the following information\n"
|
||||
"BugCheckCode: 0x%08X\n"
|
||||
"BugCheckParameter1: 0x%08X\n"
|
||||
"BugCheckParameter2: 0x%08X\n"
|
||||
"BugCheckParameter3: 0x%08X\n"
|
||||
"BugCheckParameter4: 0x%08X\n"
|
||||
"BugCheckCode: 0x%.8X\n"
|
||||
"BugCheckParameter1: 0x%p\n"
|
||||
"BugCheckParameter2: 0x%p\n"
|
||||
"BugCheckParameter3: 0x%p\n"
|
||||
"BugCheckParameter4: 0x%p\n"
|
||||
"\nThis is the Xbox equivalent to a BSOD and would cause the console to automatically reboot\n"
|
||||
"\nContinue Execution (Not Recommended)?\n",
|
||||
BugCheckCode, BugCheckParameter1, BugCheckParameter2, BugCheckParameter3, BugCheckParameter4);
|
||||
|
@ -480,6 +495,9 @@ XBSYSAPI EXPORTNUM(98) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeConnectInterrupt
|
|||
LOG_FUNC_ONE_ARG(InterruptObject);
|
||||
|
||||
BOOLEAN ret = FALSE;
|
||||
KIRQL OldIrql;
|
||||
|
||||
KiLockDispatcherDatabase(&OldIrql);
|
||||
|
||||
// here we have to connect the interrupt object to the vector
|
||||
if (!InterruptObject->Connected)
|
||||
|
@ -495,6 +513,8 @@ XBSYSAPI EXPORTNUM(98) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeConnectInterrupt
|
|||
}
|
||||
// else do nothing
|
||||
|
||||
KiUnlockDispatcherDatabase(OldIrql);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
|
@ -529,15 +549,19 @@ XBSYSAPI EXPORTNUM(100) xboxkrnl::VOID NTAPI xboxkrnl::KeDisconnectInterrupt
|
|||
{
|
||||
LOG_FUNC_ONE_ARG(InterruptObject);
|
||||
|
||||
KIRQL OldIrql;
|
||||
|
||||
KiLockDispatcherDatabase(&OldIrql);
|
||||
|
||||
// Do the reverse of KeConnectInterrupt
|
||||
// Untested (no known test cases) and not thread safe :
|
||||
if (InterruptObject->Connected)
|
||||
{
|
||||
if (InterruptObject->Connected) { // Text case : d3dbvt.xbe
|
||||
// Mark InterruptObject as not connected anymore
|
||||
HalDisableSystemInterrupt(InterruptObject->BusInterruptLevel);
|
||||
EmuInterruptList[InterruptObject->BusInterruptLevel] = NULL;
|
||||
InterruptObject->Connected = FALSE;
|
||||
}
|
||||
|
||||
KiUnlockDispatcherDatabase(OldIrql);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -560,9 +584,10 @@ XBSYSAPI EXPORTNUM(101) xboxkrnl::VOID NTAPI xboxkrnl::KeEnterCriticalRegion
|
|||
// ******************************************************************
|
||||
XBSYSAPI EXPORTNUM(103) xboxkrnl::KIRQL NTAPI xboxkrnl::KeGetCurrentIrql(void)
|
||||
{
|
||||
LOG_FUNC();
|
||||
LOG_FUNC(); // TODO : Remove nested logging on this somehow, so we can call this (instead of inlining)
|
||||
|
||||
KIRQL Irql = KeGetPcr()->Irql;
|
||||
KPCR* Pcr = KeGetPcr();
|
||||
KIRQL Irql = (KIRQL)Pcr->Irql;
|
||||
|
||||
RETURN(Irql);
|
||||
}
|
||||
|
@ -722,6 +747,7 @@ XBSYSAPI EXPORTNUM(109) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeInterrupt
|
|||
// Interrupt->DispatchCode = []?; //TODO : Populate this interrupt dispatch
|
||||
// code block, patch it up so it works with the address of this Interrupt
|
||||
// struct and calls the right dispatch routine (depending on InterruptMode).
|
||||
LOG_INCOMPLETE();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -953,7 +979,7 @@ XBSYSAPI EXPORTNUM(119) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeInsertQueueDpc
|
|||
|
||||
// Thread-safety is no longer required anymore
|
||||
LeaveCriticalSection(&(g_DpcData.Lock));
|
||||
// TODO : Instead, enable interrupts - use KeLowerIrql(&OldIrql) ?
|
||||
// TODO : Instead, enable interrupts - use KeLowerIrql(OldIrql) ?
|
||||
|
||||
RETURN(NeedsInsertion);
|
||||
}
|
||||
|
@ -1135,23 +1161,24 @@ XBSYSAPI EXPORTNUM(129) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToDpcLevel()
|
|||
{
|
||||
LOG_FUNC();
|
||||
|
||||
if(KeGetCurrentIrql() > DISPATCH_LEVEL)
|
||||
// Inlined KeGetCurrentIrql() :
|
||||
KPCR* Pcr = KeGetPcr();
|
||||
KIRQL OldIrql = (KIRQL)Pcr->Irql;
|
||||
|
||||
if(OldIrql > DISPATCH_LEVEL)
|
||||
CxbxKrnlCleanup("Bugcheck: Caller of KeRaiseIrqlToDpcLevel is higher than DISPATCH_LEVEL!");
|
||||
|
||||
KIRQL kRet = NULL;
|
||||
|
||||
KPCR* Pcr = KeGetPcr();
|
||||
Pcr->Irql = DISPATCH_LEVEL;
|
||||
|
||||
#ifdef _DEBUG_TRACE
|
||||
DbgPrintf("Raised IRQL to DISPATCH_LEVEL (2).\n");
|
||||
DbgPrintf("Old IRQL is %d.\n", kRet);
|
||||
DbgPrintf("KRNL: Raised IRQL to DISPATCH_LEVEL (2).\n");
|
||||
DbgPrintf("Old IRQL is %d.\n", OldIrql);
|
||||
#endif
|
||||
|
||||
// We reached the DISPATCH_LEVEL, so the queue can be processed now :
|
||||
// TODO : ExecuteDpcQueue();
|
||||
// We reached the DISPATCH_LEVEL, so the queue can be processed now
|
||||
ExecuteDpcQueue();
|
||||
|
||||
RETURN(kRet);
|
||||
RETURN(OldIrql);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -50,8 +50,6 @@ namespace xboxkrnl
|
|||
#include "EmuKrnlLogging.h"
|
||||
#include "CxbxKrnl.h" // For CxbxKrnlCleanup
|
||||
#include "Emu.h" // For EmuWarning()
|
||||
#include "EmuAlloc.h" // For CxbxFree(), g_MemoryManager.Allocate(), etc.
|
||||
#include "ResourceTracker.h" // For g_AlignCache
|
||||
#include "MemoryManager.h"
|
||||
|
||||
// prevent name collisions
|
||||
|
@ -181,7 +179,7 @@ XBSYSAPI EXPORTNUM(168) xboxkrnl::PVOID NTAPI xboxkrnl::MmClaimGpuInstanceMemory
|
|||
*NumberOfPaddingBytes = MI_CONVERT_PFN_TO_PHYSICAL(MM_64M_PHYSICAL_PAGE) -
|
||||
MI_CONVERT_PFN_TO_PHYSICAL(MM_INSTANCE_PHYSICAL_PAGE + MM_INSTANCE_PAGE_COUNT);
|
||||
|
||||
DbgPrintf("MmClaimGpuInstanceMemory : *NumberOfPaddingBytes = 0x%08X\n", *NumberOfPaddingBytes);
|
||||
DbgPrintf("KNRL: MmClaimGpuInstanceMemory : *NumberOfPaddingBytes = 0x%.8X\n", *NumberOfPaddingBytes);
|
||||
|
||||
#ifdef _DEBUG_TRACE
|
||||
if (NumberOfBytes != MAXULONG_PTR)
|
||||
|
@ -288,7 +286,7 @@ XBSYSAPI EXPORTNUM(171) xboxkrnl::VOID NTAPI xboxkrnl::MmFreeContiguousMemory
|
|||
LOG_FUNC_ONE_ARG(BaseAddress);
|
||||
|
||||
if (BaseAddress == &DefaultLaunchDataPage) {
|
||||
DbgPrintf("Ignored MmFreeContiguousMemory(&DefaultLaunchDataPage)\n");
|
||||
DbgPrintf("KNRL: Ignored MmFreeContiguousMemory(&DefaultLaunchDataPage)\n");
|
||||
LOG_IGNORED();
|
||||
return;
|
||||
}
|
||||
|
@ -455,17 +453,17 @@ XBSYSAPI EXPORTNUM(178) xboxkrnl::VOID NTAPI xboxkrnl::MmPersistContiguousMemory
|
|||
FILE* fp = fopen(szFilePath_LaunchDataPage_bin, "wb"); // TODO : Support wide char paths using _wfopen
|
||||
if (fp)
|
||||
{
|
||||
DbgPrintf("Persisting LaunchDataPage\n");
|
||||
DbgPrintf("KNRL: Persisting LaunchDataPage\n");
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fwrite(LaunchDataPage, sizeof(LAUNCH_DATA_PAGE), 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
DbgPrintf("Can't persist LaunchDataPage to %s!\n", szFilePath_LaunchDataPage_bin);
|
||||
DbgPrintf("KNRL: Can't persist LaunchDataPage to %s!\n", szFilePath_LaunchDataPage_bin);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrintf("Forgetting LaunchDataPage\n");
|
||||
DbgPrintf("KNRL: Forgetting LaunchDataPage\n");
|
||||
remove(szFilePath_LaunchDataPage_bin);
|
||||
}
|
||||
}
|
||||
|
@ -574,7 +572,7 @@ XBSYSAPI EXPORTNUM(181) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmQueryStatistics
|
|||
}
|
||||
else
|
||||
{
|
||||
EmuWarning("EmuKrnl: MmQueryStatistics with unusual size -> 0x%.08X", MemoryStatistics->Length);
|
||||
EmuWarning("KRNL: MmQueryStatistics with unusual size -> 0x%.8X", MemoryStatistics->Length);
|
||||
ret = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -602,7 +600,7 @@ XBSYSAPI EXPORTNUM(182) xboxkrnl::VOID NTAPI xboxkrnl::MmSetAddressProtect
|
|||
if (!VirtualProtect(BaseAddress, NumberOfBytes, NewProtect & (~PAGE_WRITECOMBINE), &dwOldProtect))
|
||||
EmuWarning("VirtualProtect Failed!");
|
||||
|
||||
DbgPrintf("EmuKrnl: VirtualProtect was 0x%.08X -> 0x%.08X\n", dwOldProtect, NewProtect & (~PAGE_WRITECOMBINE));
|
||||
DbgPrintf("KRNL: VirtualProtect was 0x%.8X -> 0x%.8X\n", dwOldProtect, NewProtect & (~PAGE_WRITECOMBINE));
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -96,7 +96,7 @@ XBSYSAPI EXPORTNUM(184) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtAllocateVirtualMemo
|
|||
ULONG_PTR RequestedBaseAddress = (ULONG_PTR)*BaseAddress;
|
||||
ULONG RequestedAllocationSize = *AllocationSize;
|
||||
|
||||
DbgPrintf("NtAllocateVirtualMemory requested range : 0x%.08X - 0x%.08X\n", RequestedBaseAddress, RequestedBaseAddress + RequestedAllocationSize);
|
||||
DbgPrintf("KNRL: NtAllocateVirtualMemory requested range : 0x%.8X - 0x%.8X\n", RequestedBaseAddress, RequestedBaseAddress + RequestedAllocationSize);
|
||||
|
||||
// Don't allow base address to exceed highest virtual address
|
||||
if (RequestedBaseAddress > MM_HIGHEST_VAD_ADDRESS)
|
||||
|
@ -154,7 +154,7 @@ XBSYSAPI EXPORTNUM(184) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtAllocateVirtualMemo
|
|||
ULONG_PTR ResultingBaseAddress = (ULONG_PTR)*BaseAddress;
|
||||
ULONG ResultingAllocationSize = *AllocationSize;
|
||||
|
||||
DbgPrintf("NtAllocateVirtualMemory resulting range : 0x%.08X - 0x%.08X\n", ResultingBaseAddress, ResultingBaseAddress + ResultingAllocationSize);
|
||||
DbgPrintf("KNRL: NtAllocateVirtualMemory resulting range : 0x%.8X - 0x%.8X\n", ResultingBaseAddress, ResultingBaseAddress + ResultingAllocationSize);
|
||||
}
|
||||
else
|
||||
if (ret == STATUS_INVALID_PARAMETER_5) // = 0xC00000F3
|
||||
|
@ -269,7 +269,7 @@ XBSYSAPI EXPORTNUM(188) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateDirectoryObje
|
|||
if (FAILED(ret))
|
||||
EmuWarning("NtCreateDirectoryObject Failed!");
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateDirectoryObject DirectoryHandle = 0x%.08X\n", *DirectoryHandle);
|
||||
DbgPrintf("KRNL: NtCreateDirectoryObject DirectoryHandle = 0x%.8X\n", *DirectoryHandle);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -346,10 +346,10 @@ XBSYSAPI EXPORTNUM(189) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateEvent
|
|||
if(FAILED(ret))
|
||||
EmuWarning("NtCreateEvent Failed!");
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateEvent EventHandle = 0x%.08X\n", *EventHandle);
|
||||
DbgPrintf("KRNL: NtCreateEvent EventHandle = 0x%.8X\n", *EventHandle);
|
||||
}
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateEvent EventHandle = 0x%.08X\n", *EventHandle);
|
||||
DbgPrintf("KRNL: NtCreateEvent EventHandle = 0x%.8X\n", *EventHandle);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -471,10 +471,10 @@ XBSYSAPI EXPORTNUM(192) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateMutant
|
|||
if(FAILED(ret))
|
||||
EmuWarning("NtCreateMutant Failed!");
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateMutant MutantHandle = 0x%.08X\n", *MutantHandle);
|
||||
DbgPrintf("KRNL: NtCreateMutant MutantHandle = 0x%.8X\n", *MutantHandle);
|
||||
}
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateMutant MutantHandle = 0x%.08X\n", *MutantHandle);
|
||||
DbgPrintf("KRNL: NtCreateMutant MutantHandle = 0x%.8X\n", *MutantHandle);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -546,10 +546,10 @@ XBSYSAPI EXPORTNUM(193) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateSemaphore
|
|||
if(FAILED(ret))
|
||||
EmuWarning("NtCreateSemaphore failed!");
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateSemaphore SemaphoreHandle = 0x%.08X\n", *SemaphoreHandle);
|
||||
DbgPrintf("KRNL: NtCreateSemaphore SemaphoreHandle = 0x%.8X\n", *SemaphoreHandle);
|
||||
}
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateSemaphore SemaphoreHandle = 0x%.08X\n", *SemaphoreHandle);
|
||||
DbgPrintf("KRNL: NtCreateSemaphore SemaphoreHandle = 0x%.8X\n", *SemaphoreHandle);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ XBSYSAPI EXPORTNUM(194) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateTimer
|
|||
if (FAILED(ret))
|
||||
EmuWarning("NtCreateTimer failed!");
|
||||
else
|
||||
DbgPrintf("EmuKrnl: NtCreateTimer TimerHandle = 0x%.08X\n", *TimerHandle);
|
||||
DbgPrintf("KRNL: NtCreateTimer TimerHandle = 0x%.8X\n", *TimerHandle);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -925,7 +925,7 @@ XBSYSAPI EXPORTNUM(203) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtOpenSymbolicLinkObj
|
|||
if (ret != STATUS_SUCCESS)
|
||||
EmuWarning("NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(ret));
|
||||
else
|
||||
DbgPrintf("EmuKrnl : NtOpenSymbolicLinkObject LinkHandle^ = 0x%.08X", *LinkHandle);
|
||||
DbgPrintf("KRNL: NtOpenSymbolicLinkObject LinkHandle^ = 0x%.8X", *LinkHandle);
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -1423,7 +1423,7 @@ XBSYSAPI EXPORTNUM(217) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryVirtualMemory
|
|||
|
||||
ret = STATUS_SUCCESS;
|
||||
|
||||
DbgPrintf("EmuKrnl: NtQueryVirtualMemory: Applied fix for Forza Motorsport!\n");
|
||||
DbgPrintf("KRNL: NtQueryVirtualMemory: Applied fix for Forza Motorsport!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1575,6 +1575,8 @@ XBSYSAPI EXPORTNUM(219) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtReadFile
|
|||
|
||||
if (FAILED(ret))
|
||||
EmuWarning("NtReadFile Failed! (0x%.08X)", ret);
|
||||
else
|
||||
Sleep(10); // HACK : This prevents Turok from skipping it's intro-movie
|
||||
|
||||
RETURN(ret);
|
||||
}
|
||||
|
@ -1849,7 +1851,7 @@ XBSYSAPI EXPORTNUM(232) xboxkrnl::VOID NTAPI xboxkrnl::NtUserIoApcDispatcher
|
|||
|
||||
(CompletionRoutine)(dwErrorCode, dwTransferred, lpOverlapped);
|
||||
|
||||
DbgPrintf("EmuKrnl: NtUserIoApcDispatcher Completed\n");
|
||||
DbgPrintf("KRNL: NtUserIoApcDispatcher Completed\n");
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -151,7 +151,7 @@ static unsigned int WINAPI PCSTProxy
|
|||
if (pfnNotificationRoutine == NULL)
|
||||
continue;
|
||||
|
||||
DbgPrintf("EmuKrnl: Calling pfnNotificationRoutine[%d] (0x%.08X)\n", g_iThreadNotificationCount, pfnNotificationRoutine);
|
||||
DbgPrintf("KRNL: Calling pfnNotificationRoutine[%d] (0x%.8X)\n", g_iThreadNotificationCount, pfnNotificationRoutine);
|
||||
|
||||
pfnNotificationRoutine(TRUE);
|
||||
}
|
||||
|
@ -293,26 +293,50 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
|
|||
// else
|
||||
// KernelStackSize = round up;
|
||||
|
||||
static bool bFirstTime = false;
|
||||
static bool bFirstTime = false;
|
||||
|
||||
// create thread, using our special proxy technique
|
||||
{
|
||||
DWORD dwThreadId;
|
||||
// create thread, using our special proxy technique
|
||||
{
|
||||
DWORD dwThreadId = 0, dwThreadWait;
|
||||
bool bWait = true;
|
||||
|
||||
// PCSTProxy is responsible for cleaning up this pointer
|
||||
::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam();
|
||||
// PCSTProxy is responsible for cleaning up this pointer
|
||||
::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam();
|
||||
|
||||
iPCSTProxyParam->StartRoutine = StartRoutine;
|
||||
iPCSTProxyParam->StartContext = StartContext;
|
||||
iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown?
|
||||
iPCSTProxyParam->StartSuspended = CreateSuspended;
|
||||
iPCSTProxyParam->hStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
iPCSTProxyParam->StartRoutine = StartRoutine;
|
||||
iPCSTProxyParam->StartContext = StartContext;
|
||||
iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown?
|
||||
iPCSTProxyParam->StartSuspended = CreateSuspended;
|
||||
iPCSTProxyParam->hStartedEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("PCSTProxyEvent"));
|
||||
|
||||
*ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId);
|
||||
*ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId);
|
||||
|
||||
WaitForSingleObject(iPCSTProxyParam->hStartedEvent, 1000);
|
||||
DbgPrintf("KRNL: Waiting for Xbox proxy thread to start...\n");
|
||||
|
||||
DbgPrintf("EmuKrnl: ThreadHandle : 0x%X, ThreadId : 0x%.08X\n", *ThreadHandle, dwThreadId);
|
||||
while (bWait) {
|
||||
dwThreadWait = WaitForSingleObject(*ThreadHandle, 300);
|
||||
switch (dwThreadWait) {
|
||||
// Thread is running
|
||||
case WAIT_TIMEOUT:
|
||||
// Thread is complete
|
||||
case WAIT_OBJECT_0: {
|
||||
// if either of two above is true, don't need to wait.
|
||||
bWait = false;
|
||||
break;
|
||||
}
|
||||
// A problem has occurred, what should we do?
|
||||
case WAIT_FAILED: {
|
||||
break;
|
||||
}
|
||||
// Unknown wait
|
||||
default:
|
||||
bWait = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Log ThreadID identical to how GetCurrentThreadID() is rendered :
|
||||
DbgPrintf("KRNL: Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", *ThreadHandle, dwThreadId);
|
||||
|
||||
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread
|
||||
{
|
||||
|
@ -413,7 +437,7 @@ XBSYSAPI EXPORTNUM(258) xboxkrnl::VOID NTAPI xboxkrnl::PsTerminateSystemThread
|
|||
if (pfnNotificationRoutine == NULL)
|
||||
continue;
|
||||
|
||||
DbgPrintf("EmuKrnl: Calling pfnNotificationRoutine[%d] (0x%.08X)\n", g_iThreadNotificationCount, pfnNotificationRoutine);
|
||||
DbgPrintf("KRNL: Calling pfnNotificationRoutine[%d] (0x%.8X)\n", g_iThreadNotificationCount, pfnNotificationRoutine);
|
||||
|
||||
pfnNotificationRoutine(FALSE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue