Doxygen

DECLSPEC_NORETURN VOID FASTCALL KiTrap0EHandler ( IN PKTRAP_FRAME  TrapFrame)

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);
}