Definition at line 1170 of file traphdlr.c. {
PKTHREAD Thread;
ULONG_PTR Cr2;
NTSTATUS Status;
/* Save trap frame */
KiEnterTrap(TrapFrame);
/* Check if this is the base frame */
Thread = KeGetCurrentThread();
if (KeGetTrapFrame(Thread) != TrapFrame)
{
/* It isn't, check if this is a second nested frame */
if (((ULONG_PTR)KeGetTrapFrame(Thread) - (ULONG_PTR)TrapFrame) <=
FIELD_OFFSET(KTRAP_FRAME, EFlags))
{
/* The stack is somewhere in between frames, we need to fix it */
UNIMPLEMENTED_FATAL();
}
}
/* Save CR2 */
Cr2 = __readcr2();
/* Enable interupts */
_enable();
/* Check if we came in with interrupts disabled */
if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
{
/* This is completely illegal, bugcheck the system */
KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
Cr2,
-1,
TrapFrame->ErrCode & 2 ? TRUE : FALSE,
TrapFrame->Eip,
TrapFrame);
}
/* Check for S-LIST fault in kernel mode */
if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
{
PSLIST_HEADER SListHeader;
/* Sanity check that the assembly is correct:
This must be mov ebx, [eax]
Followed by cmpxchg8b [ebp] */
ASSERT((((UCHAR*)TrapFrame->Eip)[0] == 0x8B) &&
(((UCHAR*)TrapFrame->Eip)[1] == 0x18) &&
(((UCHAR*)TrapFrame->Eip)[2] == 0x0F) &&
(((UCHAR*)TrapFrame->Eip)[3] == 0xC7) &&
(((UCHAR*)TrapFrame->Eip)[4] == 0x4D) &&
(((UCHAR*)TrapFrame->Eip)[5] == 0x00));
/* Get the pointer to the SLIST_HEADER */
SListHeader = (PSLIST_HEADER)TrapFrame->Ebp;
/* Check if the Next member of the SLIST_HEADER was changed */
if (SListHeader->Next.Next != (PSLIST_ENTRY)TrapFrame->Eax)
{
/* Restart the operation */
TrapFrame->Eip = (ULONG_PTR)ExpInterlockedPopEntrySListResume;
/* Continue execution */
KiEoiHelper(TrapFrame);
}
}
/* Call the access fault handler */
Status = MmAccessFault(TrapFrame->ErrCode & 1,
(PVOID)Cr2,
TrapFrame->SegCs & MODE_MASK,
TrapFrame);
if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame);
/* Check for syscall fault */
#if 0
if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
(TrapFrame->Eip == (ULONG_PTR)ReadBatch))
{
/* Not yet implemented */
UNIMPLEMENTED_FATAL();
}
#endif
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
/* Either kernel or user trap (non VDM) so dispatch exception */
if (Status == STATUS_ACCESS_VIOLATION)
{
/* This status code is repurposed so we can recognize it later */
KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
TrapFrame->Eip,
TrapFrame->ErrCode & 2 ? TRUE : FALSE,
Cr2,
TrapFrame);
}
else if ((Status == STATUS_GUARD_PAGE_VIOLATION) ||
(Status == STATUS_STACK_OVERFLOW))
{
/* These faults only have two parameters */
KiDispatchException2Args(Status,
TrapFrame->Eip,
TrapFrame->ErrCode & 2 ? TRUE : FALSE,
Cr2,
TrapFrame);
}
/* Only other choice is an in-page error, with 3 parameters */
KiDispatchExceptionFromTrapFrame(STATUS_IN_PAGE_ERROR,
TrapFrame->Eip,
3,
TrapFrame->ErrCode & 2 ? TRUE : FALSE,
Cr2,
Status,
TrapFrame);
}
|