0xEE, /* OUT */
0xEF, /* OUT */
0x6E, /* OUTS */
- 0x6F, /* OUTS */
+ 0x6F, /* OUTS */
};
PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler;
+#if DBG && !defined(_WINKD_)
+PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
+PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
+#endif
+#if TRAP_DEBUG
+BOOLEAN StopChecking = FALSE;
+#endif
/* TRAP EXIT CODE *************************************************************/
VOID
FORCEINLINE
-KiCommonExit(IN PKTRAP_FRAME TrapFrame, const ULONG Flags)
+KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
{
/* Disable interrupts until we return */
_disable();
-
+
/* Check for APC delivery */
KiCheckForApcDelivery(TrapFrame);
-
- /* Debugging checks */
- KiExitTrapDebugChecks(TrapFrame, Flags);
/* Restore the SEH handler chain */
KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
/* Check if there are active debug registers */
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
{
- /* Not handled yet */
- DbgPrint("Need Hardware Breakpoint Support!\n");
- DbgBreakPoint();
- while (TRUE);
+ /* Check if the frame was from user mode or v86 mode */
+ if ((TrapFrame->SegCs & MODE_MASK) ||
+ (TrapFrame->EFlags & EFLAGS_V86_MASK))
+ {
+ /* Handle debug registers */
+ KiHandleDebugRegistersOnTrapExit(TrapFrame);
+ }
}
+
+ /* Debugging checks */
+ KiExitTrapDebugChecks(TrapFrame, SkipPreviousMode);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
{
/* Common trap exit code */
- KiCommonExit(TrapFrame, 0);
+ KiCommonExit(TrapFrame, TRUE);
/* Check if this was a V8086 trap */
if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
KiTrapReturnNoSegments(TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiServiceExit(IN PKTRAP_FRAME TrapFrame,
IN NTSTATUS Status)
{
TrapFrame->Eax = Status;
/* Common trap exit code */
- KiCommonExit(TrapFrame, 0);
+ KiCommonExit(TrapFrame, FALSE);
/* Restore previous mode */
- KeGetCurrentThread()->PreviousMode = TrapFrame->PreviousPreviousMode;
+ KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
/* Check for user mode exit */
if (TrapFrame->SegCs & MODE_MASK)
KiSystemCallReturn(TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiServiceExit2(IN PKTRAP_FRAME TrapFrame)
{
/* Common trap exit code */
- KiCommonExit(TrapFrame, 0);
+ KiCommonExit(TrapFrame, FALSE);
/* Restore previous mode */
- KeGetCurrentThread()->PreviousMode = TrapFrame->PreviousPreviousMode;
+ KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
/* Check if this was a V8086 trap */
if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
/* TRAP HANDLERS **************************************************************/
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiDebugHandler(IN PKTRAP_FRAME TrapFrame,
IN ULONG Parameter1,
IN ULONG Parameter2,
Parameter1,
Parameter2,
Parameter3,
- TrapFrame);
+ TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
IN PKTHREAD Thread,
IN PFX_SAVE_AREA SaveArea)
}
/* Get legal exceptions that software should handle */
- Error &= (FSW_INVALID_OPERATION |
- FSW_DENORMAL |
- FSW_ZERO_DIVIDE |
- FSW_OVERFLOW |
- FSW_UNDERFLOW |
- FSW_PRECISION);
+ /* We do this by first masking off from the Mask the bits we need, */
+ /* This is done so we can keep the FSW_STACK_FAULT bit in Error. */
+ Mask &= (FSW_INVALID_OPERATION |
+ FSW_DENORMAL |
+ FSW_ZERO_DIVIDE |
+ FSW_OVERFLOW |
+ FSW_UNDERFLOW |
+ FSW_PRECISION);
Error &= ~Mask;
-
- if (Error & FSW_STACK_FAULT)
- {
- /* Issue stack check fault */
- KiDispatchException2Args(STATUS_FLOAT_STACK_CHECK,
- ErrorOffset,
- 0,
- DataOffset,
- TrapFrame);
- }
/* Check for invalid operation */
if (Error & FSW_INVALID_OPERATION)
{
+ /* NOTE: Stack fault is handled differently than any other case. */
+ /* 1. It's only raised for invalid operation. */
+ /* 2. It's only raised if invalid operation is not masked. */
+ if (Error & FSW_STACK_FAULT)
+ {
+ /* Issue stack check fault */
+ KiDispatchException2Args(STATUS_FLOAT_STACK_CHECK,
+ ErrorOffset,
+ 0,
+ DataOffset,
+ TrapFrame);
+ }
+
/* Issue fault */
KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
ErrorOffset,
KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 1, Error, 0, 0, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap00Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
TrapFrame);
}
-VOID
DECLSPEC_NORETURN
+VOID
+__cdecl
KiTrap02(VOID)
{
PKTSS Tss, NmiTss;
//
// Note that in reality, we are already on the NMI tss -- we just need to
// update the PCR to reflect this
- //
+ //
PCR->TSS = NmiTss;
__writeeflags(__readeflags() &~ EFLAGS_NESTED_TASK);
TssGdt->HighWord.Bits.Dpl = 0;
// Although the CPU disabled NMIs, we just did a BIOS Call, which could've
// totally changed things.
//
- // We have to make sure we're still in our original NMI -- a nested NMI
+ // We have to make sure we're still in our original NMI -- a nested NMI
// will point back to the NMI TSS, and in that case we're hosed.
//
if (PCR->TSS->Backlink != KGDT_NMI_TSS)
KiSystemFatalException(EXCEPTION_NMI, NULL);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap03Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiDebugHandler(TrapFrame, BREAKPOINT_BREAK, 0, 0);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap04Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap05Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
{
PUCHAR Instruction;
if (!VdmDispatchBop(TrapFrame))
{
/* Should only happen in VDM mode */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
/* Bring IRQL back */
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap07Handler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread, NpxThread;
if (SaveArea->Cr0NpxState & CR0_EM)
{
/* Not implemented */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
/* Save CR0 and check NPX state */
NpxSaveArea = KiGetThreadNpxArea(NpxThread);
/* Save FPU state */
+ DPRINT("FIXME: Save FPU state: %p\n", NpxSaveArea);
//Ke386SaveFpuState(NpxSaveArea);
/* Update NPX state */
- Thread->NpxState = NPX_STATE_NOT_LOADED;
+ NpxThread->NpxState = NPX_STATE_NOT_LOADED;
}
/* Load FPU state */
KiNpxHandler(TrapFrame, Thread, SaveArea);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap08Handler(IN PKTRAP_FRAME TrapFrame)
{
/* FIXME: Not handled */
KiSystemFatalException(EXCEPTION_DOUBLE_FAULT, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap09Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiSystemFatalException(EXCEPTION_NPX_OVERRUN, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
/* Check for VDM trap */
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
-
+
/* Kill the system */
KiSystemFatalException(EXCEPTION_INVALID_TSS, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap0BHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiSystemFatalException(EXCEPTION_SEGMENT_NOT_PRESENT, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap0CHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiSystemFatalException(EXCEPTION_STACK_FAULT, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
{
ULONG i, j, Iopl;
if (__builtin_expect(Ki386HandleOpcodeV86(TrapFrame) == 0xFF, 0))
{
/* Should only happen in VDM mode */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
/* Bring IRQL back */
/* Enable interrupts and check error code */
_enable();
if (!TrapFrame->ErrCode)
- {
+ {
/* FIXME: Use SEH */
Instructions = (PUCHAR)TrapFrame->Eip;
}
/* Check for privileged instructions */
+ DPRINT("Instruction (%d) at fault: %lx %lx %lx %lx\n",
+ i,
+ Instructions[i],
+ Instructions[i + 1],
+ Instructions[i + 2],
+ Instructions[i + 3]);
if (Instruction == 0xF4) // HLT
{
/* HLT is privileged */
(Instructions[i + 1] == 0x08) || // INVD
(Instructions[i + 1] == 0x09) || // WBINVD
(Instructions[i + 1] == 0x35) || // SYSEXIT
- (Instructions[i + 1] == 0x26) || // MOV DR, XXX
+ (Instructions[i + 1] == 0x21) || // MOV DR, XXX
(Instructions[i + 1] == 0x06) || // CLTS
(Instructions[i + 1] == 0x20) || // MOV CR, XXX
- (Instructions[i + 1] == 0x24) || // MOV YYY, DR
+ (Instructions[i + 1] == 0x22) || // MOV XXX, CR
+ (Instructions[i + 1] == 0x23) || // MOV YYY, DR
(Instructions[i + 1] == 0x30) || // WRMSR
(Instructions[i + 1] == 0x33)) // RDPMC
// INVLPG, INVLPGA, SYSRET
TrapFrame);
}
- /*
+ /*
* Check for a fault during checking of the user instruction.
*
* Note that the SEH handler will catch invalid EIP, but we could be dealing
((PVOID)TrapFrame->Eip < (PVOID)KiTrap0DHandler))
{
/* Not implemented */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
-
+
/*
* NOTE: The ASM trap exit code would restore segment registers by doing
* a POP <SEG>, which could cause an invalid segment if someone had messed
if (Instructions[0] == 0xCF)
{
/*
- * Some evil shit is going on here -- this is not the SS:ESP you're
+ * Some evil shit is going on here -- this is not the SS:ESP you're
* looking for! Instead, this is actually CS:EIP you're looking at!
* Why? Because part of the trap frame actually corresponds to the IRET
* stack during the trap exit!
else
{
/* Otherwise, this is another kind of IRET fault */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
}
/* So since we're not dealing with the above case, check for RDMSR/WRMSR */
if ((Instructions[0] == 0xF) && // 2-byte opcode
- (((Instructions[1] >> 8) == 0x30) || // RDMSR
- ((Instructions[2] >> 8) == 0x32))) // WRMSR
+ ((Instructions[1] == 0x32) || // RDMSR
+ (Instructions[1] == 0x30))) // WRMSR
{
/* Unknown CPU MSR, so raise an access violation */
KiDispatchException0Args(STATUS_ACCESS_VIOLATION,
KiTrapReturn(TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
FIELD_OFFSET(KTRAP_FRAME, EFlags))
{
/* The stack is somewhere in between frames, we need to fix it */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
}
-
+
/* Save CR2 */
Cr2 = __readcr2();
-
- /* Check for Pentium LOCK errata */
- if (KiI386PentiumLockErrataPresent)
+
+ /* Enable interupts */
+ _enable();
+
+ /* Check if we came in with interrupts disabled */
+ if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
{
- /* Not yet implemented */
- UNIMPLEMENTED;
- while (TRUE);
+ /* This is completely illegal, bugcheck the system */
+ KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
+ Cr2,
+ -1,
+ TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ TrapFrame->Eip,
+ TrapFrame);
}
-
- /* HACK: Check if interrupts are disabled and enable them */
- if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
+
+ /* Check for S-LIST fault in kernel mode */
+ if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
{
- /* Enable interupts */
- _enable();
-#ifdef HACK_ABOVE_FIXED
- if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
+ 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)
{
- /* This is illegal */
- KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
- Cr2,
- -1,
- TrapFrame->ErrCode & 1,
- TrapFrame->Eip,
- TrapFrame);
+ /* Restart the operation */
+ TrapFrame->Eip = (ULONG_PTR)ExpInterlockedPopEntrySListResume;
+
+ /* Continue execution */
+ KiEoiHelper(TrapFrame);
}
-#endif
}
/* Call the access fault handler */
TrapFrame);
if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame);
- /* Check for S-LIST fault */
- if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
- {
- /* Not yet implemented */
- UNIMPLEMENTED;
- while (TRUE);
- }
-
/* Check for syscall fault */
#if 0
if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
(TrapFrame->Eip == (ULONG_PTR)ReadBatch))
{
/* Not yet implemented */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
#endif
/* Check for VDM trap */
/* This status code is repurposed so we can recognize it later */
KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
TrapFrame->Eip,
- TrapFrame->ErrCode & 1,
+ TrapFrame->ErrCode & 2 ? TRUE : FALSE,
Cr2,
TrapFrame);
}
/* These faults only have two parameters */
KiDispatchException2Args(Status,
TrapFrame->Eip,
- TrapFrame->ErrCode & 1,
+ TrapFrame->ErrCode & 2 ? TRUE : FALSE,
Cr2,
TrapFrame);
}
KiDispatchExceptionFromTrapFrame(STATUS_IN_PAGE_ERROR,
TrapFrame->Eip,
3,
- TrapFrame->ErrCode & 1,
+ TrapFrame->ErrCode & 2 ? TRUE : FALSE,
Cr2,
Status,
TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap0FHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiSystemFatalException(EXCEPTION_RESERVED_TRAP, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
KiNpxHandler(TrapFrame, Thread, SaveArea);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiSystemFatalException(EXCEPTION_ALIGNMENT_CHECK, TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
FASTCALL
KiGetTickCountHandler(IN PKTRAP_FRAME TrapFrame)
{
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
}
VOID
FASTCALL
KiCallbackReturnHandler(IN PKTRAP_FRAME TrapFrame)
{
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiRaiseAssertionHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
TrapFrame);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Save trap frame */
KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx);
}
+
+FORCEINLINE
VOID
+KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments)
+{
+#if DBG && !defined(_WINKD_)
+ if (SystemCallNumber >= 0x1000 && KeWin32PreServiceHook)
+ KeWin32PreServiceHook(SystemCallNumber, Arguments);
+#endif
+}
+
FORCEINLINE
+ULONG_PTR
+KiDbgPostServiceHook(ULONG SystemCallNumber, ULONG_PTR Result)
+{
+#if DBG && !defined(_WINKD_)
+ if (SystemCallNumber >= 0x1000 && KeWin32PostServiceHook)
+ return KeWin32PostServiceHook(SystemCallNumber, Result);
+#endif
+ return Result;
+}
+
DECLSPEC_NORETURN
+VOID
+FORCEINLINE
KiSystemCall(IN PKTRAP_FRAME TrapFrame,
IN PVOID Arguments)
{
/* Save previous mode */
TrapFrame->PreviousPreviousMode = Thread->PreviousMode;
- /* Save the SEH chain and terminate it for now */
+ /* Save the SEH chain and terminate it for now */
TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
- /* Clear DR7 and check for debugging */
+ /* Default to debugging disabled */
TrapFrame->Dr7 = 0;
- if (__builtin_expect(Thread->DispatcherHeader.DebugActive & 0xFF, 0))
+
+ /* Check if the frame was from user mode */
+ if (TrapFrame->SegCs & MODE_MASK)
{
- UNIMPLEMENTED;
- while (TRUE);
+ /* Check for active debugging */
+ if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
+ {
+ /* Handle debug registers */
+ KiHandleDebugRegistersOnTrapEntry(TrapFrame);
+ }
}
/* Set thread fields */
goto ExitCall;
}
- /* Convert us to a GUI thread -- must wrap in ASM to get new EBP */
+ /* Convert us to a GUI thread -- must wrap in ASM to get new EBP */
Result = KiConvertToGuiThread();
+
+ /* Reload trap frame and descriptor table pointer from new stack */
+ TrapFrame = *(volatile PVOID*)&Thread->TrapFrame;
+ DescriptorTable = (PVOID)(*(volatile ULONG_PTR*)&Thread->ServiceTable + Offset);
+
if (!NT_SUCCESS(Result))
{
/* Set the last error and fail */
//SetLastWin32Error(RtlNtStatusToDosError(Result));
goto ExitCall;
}
-
- /* Reload trap frame and descriptor table pointer from new stack */
- TrapFrame = *(volatile PVOID*)&Thread->TrapFrame;
- DescriptorTable = (PVOID)(*(volatile ULONG_PTR*)&Thread->ServiceTable + Offset);
-
+
/* Validate the system call number again */
if (Id >= DescriptorTable->Limit)
{
if (__builtin_expect((Arguments < (PVOID)MmUserProbeAddress) && !(KiUserTrap(TrapFrame)), 0))
{
/* Access violation */
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_FATAL();
}
+ /* Call pre-service debug hook */
+ KiDbgPreServiceHook(SystemCallNumber, Arguments);
+
/* Get the handler and make the system call */
Handler = (PVOID)DescriptorTable->Base[Id];
Result = KiSystemCallTrampoline(Handler, Arguments, StackBytes);
+ /* Call post-service debug hook */
+ Result = KiDbgPostServiceHook(SystemCallNumber, Result);
+
/* Make sure we're exiting correctly */
KiExitSystemCallDebugChecks(Id, TrapFrame);
KiServiceExit(TrapFrame, Result);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame,
IN PVOID Arguments)
{
KiSystemCall(TrapFrame, Arguments);
}
+DECLSPEC_NORETURN
VOID
FASTCALL
-DECLSPEC_NORETURN
KiFastCallEntryHandler(IN PKTRAP_FRAME TrapFrame,
IN PVOID Arguments)
{
Kei386EoiHelper(VOID)
{
/* We should never see this call happening */
- DPRINT1("Mismatched NT/HAL version");
- while (TRUE);
+ ERROR_FATAL("Mismatched NT/HAL version");
}
/* EOF */