VOID NTAPI HalpSwitchToRealModeTrapHandlers(VOID) { // // Save the current Invalid Opcode and General Protection Fault Handlers // HalpGpfHandler = KeQueryInterruptHandler(13); HalpBopHandler = KeQueryInterruptHandler(6); // // Now set our own GPF handler to handle exceptions while in real mode // KeRegisterInterruptHandler(13, HalpTrap0D); // // And our own invalid opcode handler to detect the BOP to get us out // KeRegisterInterruptHandler(6, HalpTrap06); }
BOOLEAN NTAPI KeConnectInterrupt(IN PKINTERRUPT Interrupt) { PVOID CurrentHandler; ASSERT(Interrupt->Vector <= MAXIMUM_IDTVECTOR); ASSERT(Interrupt->Number < KeNumberProcessors); ASSERT(Interrupt->Irql <= HIGH_LEVEL); /* Check if its already connected */ if (Interrupt->Connected) return TRUE; /* Query the current handler */ CurrentHandler = KeQueryInterruptHandler(Interrupt->Vector); /* Check if the vector is already unused */ if ((CurrentHandler >= (PVOID)KiUnexpectedRange) && (CurrentHandler <= (PVOID)KiUnexpectedRangeEnd)) { /* Initialize the list for chained interrupts */ InitializeListHead(&Interrupt->InterruptListEntry); /* Set normal dispatch address */ Interrupt->DispatchAddress = KiInterruptDispatch; /* Set the new handler */ KeRegisterInterruptHandler(Interrupt->Vector, Interrupt->DispatchCode); if (!HalEnableSystemInterrupt(Interrupt->Vector, Interrupt->Irql, Interrupt->Mode)) { /* Didn't work, restore old handler */ DPRINT1("HalEnableSystemInterrupt failed\n"); KeRegisterInterruptHandler(Interrupt->Vector, CurrentHandler); return FALSE; } /* Mark as connected */ Interrupt->Connected = TRUE; } else { // later __debugbreak(); } return TRUE; }
VOID NTAPI KiGetVectorDispatch(IN ULONG Vector, IN PDISPATCH_INFO Dispatch) { PKINTERRUPT_ROUTINE Handler; PVOID Current; UCHAR Type; UCHAR Entry; /* Check if this is a primary or 2nd-level dispatch */ Type = HalSystemVectorDispatchEntry(Vector, &Dispatch->FlatDispatch, &Dispatch->NoDispatch); ASSERT(Type == 0); /* Get the IDT entry for this vector */ Entry = HalVectorToIDTEntry(Vector); /* Setup the unhandled dispatch */ Dispatch->NoDispatch = (PVOID)(((ULONG_PTR)&KiStartUnexpectedRange) + (Entry - PRIMARY_VECTOR_BASE) * KiUnexpectedEntrySize); /* Setup the handlers */ Dispatch->InterruptDispatch = (PVOID)KiInterruptDispatch; Dispatch->FloatingDispatch = NULL; // Floating Interrupts are not supported Dispatch->ChainedDispatch = (PVOID)KiChainedDispatch; Dispatch->FlatDispatch = NULL; /* Get the current handler */ Current = KeQueryInterruptHandler(Vector); /* Set the interrupt */ Dispatch->Interrupt = CONTAINING_RECORD(Current, KINTERRUPT, DispatchCode); /* Check what this interrupt is connected to */ if ((PKINTERRUPT_ROUTINE)Current == Dispatch->NoDispatch) { /* Not connected */ Dispatch->Type = NoConnect; } else { /* Get the handler */ Handler = Dispatch->Interrupt->DispatchAddress; if (Handler == Dispatch->ChainedDispatch) { /* It's a chained interrupt */ Dispatch->Type = ChainConnect; } else if ((Handler == Dispatch->InterruptDispatch) || (Handler == Dispatch->FloatingDispatch)) { /* It's unchained */ Dispatch->Type = NormalConnect; } else { /* Unknown */ Dispatch->Type = UnknownConnect; } } }