/* FUNCTIONS *****************************************************************/
-_SEH_DEFINE_LOCALS(KiCopyInfo)
-{
- volatile EXCEPTION_RECORD SehExceptRecord;
-};
-
-_SEH_FILTER(KiCopyInformation)
-{
- _SEH_ACCESS_LOCALS(KiCopyInfo);
-
- /* Copy the exception records and return to the handler */
- RtlCopyMemory((PVOID)&_SEH_VAR(SehExceptRecord),
- _SEH_GetExceptionPointers()->ExceptionRecord,
- sizeof(EXCEPTION_RECORD));
- return EXCEPTION_EXECUTE_HANDLER;
-}
-
VOID
INIT_FUNCTION
NTAPI
{
ULONG i;
USHORT FlippedSelector;
- extern KIDTENTRY KiIdt[MAXIMUM_IDTVECTOR];
/* Loop the IDT */
- for (i = 0; i <= MAXIMUM_IDTVECTOR; i ++)
+ for (i = 0; i <= MAXIMUM_IDTVECTOR; i++)
{
/* Save the current Selector */
FlippedSelector = KiIdt[i].Selector;
/* Check if the caller gave us a mask */
if (!DrMask)
{
- /* He didn't use the one from the thread */
+ /* He didn't, use the one from the thread */
Mask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
}
else
NewMask |= DR_MASK(DR7_OVERRIDE_V);
/* Set DR7 override */
- *DrMask |= DR7_OVERRIDE_MASK;
+ *Dr7Ptr |= DR7_OVERRIDE_MASK;
}
else
{
if (Mask != NewMask)
{
/* Update it */
- KeGetCurrentThread()->DispatcherHeader.DebugActive = NewMask;
+ KeGetCurrentThread()->DispatcherHeader.DebugActive =
+ (BOOLEAN)NewMask;
}
}
NTAPI
KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
{
- /* If this was V86 Mode */
+ /* Check if this was V86 Mode */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
/* Just return it */
}
else if (TrapFrame->SegCs & MODE_MASK)
{
- /* Usermode, return the User SS */
+ /* User mode, return the User SS */
return TrapFrame->HardwareSegSs | RPL_MASK;
}
else
NTAPI
KiTagWordFnsaveToFxsave(USHORT TagWord)
{
- INT FxTagWord = ~TagWord;
+ INT FxTagWord = ~TagWord;
- /*
+ /*
* Empty is now 00, any 2 bits containing 1 mean valid
* Now convert the rest (11->0 and the rest to 1)
*/
return FxTagWord;
}
+VOID
+NTAPI
+Ki386AdjustEsp0(IN PKTRAP_FRAME TrapFrame)
+{
+ PKTHREAD Thread;
+ ULONG_PTR Stack;
+ ULONG EFlags;
+
+ /* Get the current thread's stack */
+ Thread = KeGetCurrentThread();
+ Stack = (ULONG_PTR)Thread->InitialStack;
+
+ /* Check if we are in V8086 mode */
+ if (!(TrapFrame->EFlags & EFLAGS_V86_MASK))
+ {
+ /* Bias the stack for the V86 segments */
+ Stack -= (FIELD_OFFSET(KTRAP_FRAME, V86Gs) -
+ FIELD_OFFSET(KTRAP_FRAME, HardwareSegSs));
+ }
+
+ /* Bias the stack for the FPU area */
+ Stack -= sizeof(FX_SAVE_AREA);
+
+ /* Disable interrupts */
+ EFlags = __readeflags();
+ _disable();
+
+ /* Set new ESP0 value in the TSS */
+ KeGetPcr()->TSS->Esp0 = Stack;
+
+ /* Restore old interrupt state */
+ __writeeflags(EFlags);
+}
+
VOID
NTAPI
KeContextToTrapFrame(IN PCONTEXT Context,
MAXIMUM_SUPPORTED_EXTENSION);
/* Remove reserved bits from MXCSR */
- FxSaveArea->U.FxArea.MXCsr &= ~0xFFBF;
+ FxSaveArea->U.FxArea.MXCsr &= KiMXCsrMask;
/* Mask out any invalid flags */
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
}
/* Handle the Debug Registers */
- if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+ if (0 && (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
/* Loop DR registers */
for (i = 0; i < 4; i++)
/* If we're in user-mode */
if (PreviousMode != KernelMode)
{
- /* FIXME: Save the mask */
- //KeGetCurrentThread()->DispatcherHeader.DebugActive = DrMask;
+ /* Save the mask */
+ KeGetCurrentThread()->DispatcherHeader.DebugActive = DrMask;
}
}
/* Check if thread has IOPL and force it enabled if so */
- if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= 0x3000;
+ if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
/* Restore IRQL */
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
Context->Dr6 = TrapFrame->Dr6;
/* Update DR7 */
- //Context->Dr7 = KiUpdateDr7(TrapFrame->Dr7);
+ Context->Dr7 = KiUpdateDr7(TrapFrame->Dr7);
}
else
{
/* Otherwise clear DR registers */
Context->Dr0 =
Context->Dr1 =
+ Context->Dr2 =
Context->Dr3 =
Context->Dr6 =
Context->Dr7 = 0;
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}
+BOOLEAN
+FASTCALL
+KeInvalidAccessAllowed(IN PVOID TrapInformation OPTIONAL)
+{
+ ULONG Eip;
+ PKTRAP_FRAME TrapFrame = TrapInformation;
+ VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
+
+ /* Don't do anything if we didn't get a trap frame */
+ if (!TrapInformation) return FALSE;
+
+ /* Check where we came from */
+ switch (TrapFrame->SegCs)
+ {
+ /* Kernel mode */
+ case KGDT_R0_CODE:
+
+ /* Allow S-LIST Routine to fail */
+ Eip = (ULONG)&ExpInterlockedPopEntrySListFault;
+ break;
+
+ /* User code */
+ case KGDT_R3_CODE | RPL_MASK:
+
+ /* Allow S-LIST Routine to fail */
+ //Eip = (ULONG)KeUserPopEntrySListFault;
+ Eip = 0;
+ break;
+
+ default:
+
+ /* Anything else gets a bugcheck */
+ Eip = 0;
+ }
+
+ /* Return TRUE if we want to keep the system up */
+ return (TrapFrame->Eip == Eip) ? TRUE : FALSE;
+}
+
VOID
NTAPI
KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN BOOLEAN FirstChance)
{
CONTEXT Context;
- ULONG_PTR Stack, NewStack;
- ULONG Size;
EXCEPTION_RECORD LocalExceptRecord;
- _SEH_DECLARE_LOCALS(KiCopyInfo);
/* Increase number of Exception Dispatches */
KeGetCurrentPrcb()->KeExceptionDispatchCount++;
/* Set the context flags */
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
- /* Check if User Mode or if the debugger is enabled */
- if ((PreviousMode == UserMode) || (KdDebuggerEnabled))
+ /* Check if User Mode or if the kernel debugger is enabled */
+ if ((PreviousMode == UserMode) || (KeGetPcr()->KdVersionBlock))
{
/* Add the FPU Flag */
Context.ContextFlags |= CONTEXT_FLOATING_POINT;
/* Look at our exception code */
switch (ExceptionRecord->ExceptionCode)
{
- /* Breapoint */
+ /* Breakpoint */
case STATUS_BREAKPOINT:
/* Decrement EIP by one */
/* User mode exception, was it first-chance? */
if (FirstChance)
{
- /* Enter Debugger if available */
- if (PsGetCurrentProcess()->DebugPort)
+ /*
+ * Break into the kernel debugger unless a user mode debugger
+ * is present or user mode exceptions are ignored, except if this
+ * is a debug service which we must always pass to KD
+ */
+ if ((!(PsGetCurrentProcess()->DebugPort) &&
+ !(KdIgnoreUmExceptions)) ||
+ (KdIsThisAKdTrap(ExceptionRecord,
+ &Context,
+ PreviousMode)))
{
- /* FIXME : TODO */
- //KEBUGCHECK(0);
- }
- else if (KiDebugRoutine(TrapFrame,
- ExceptionFrame,
- ExceptionRecord,
- &Context,
- PreviousMode,
- FALSE))
- {
- /* Exception was handled */
- goto Handled;
+ /* Call the kernel debugger */
+ if (KiDebugRoutine(TrapFrame,
+ ExceptionFrame,
+ ExceptionRecord,
+ &Context,
+ PreviousMode,
+ FALSE))
+ {
+ /* Exception was handled */
+ goto Handled;
+ }
}
/* Forward exception to user mode debugger */
- if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit;
+ if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
/* Set up the user-stack */
DispatchToUser:
- _SEH_TRY
+ _SEH2_TRY
{
+ ULONG Size;
+ ULONG_PTR Stack, NewStack;
+
/* Make sure we have a valid SS and that this isn't V86 mode */
if ((TrapFrame->HardwareSegSs != (KGDT_R3_DATA | RPL_MASK)) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
/* Dispatch exception to user-mode */
- _SEH_YIELD(return);
+ _SEH2_YIELD(return);
}
- _SEH_EXCEPT(KiCopyInformation)
+ _SEH2_EXCEPT((RtlCopyMemory(&LocalExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
{
/* Check if we got a stack overflow and raise that instead */
- if (_SEH_VAR(SehExceptRecord).ExceptionCode ==
+ if ((NTSTATUS)LocalExceptRecord.ExceptionCode ==
STATUS_STACK_OVERFLOW)
{
/* Copy the exception address and record */
- _SEH_VAR(SehExceptRecord).ExceptionAddress =
+ LocalExceptRecord.ExceptionAddress =
ExceptionRecord->ExceptionAddress;
RtlCopyMemory(ExceptionRecord,
- (PVOID)&_SEH_VAR(SehExceptRecord),
+ (PVOID)&LocalExceptRecord,
sizeof(EXCEPTION_RECORD));
/* Do the exception again */
- _SEH_YIELD(goto DispatchToUser);
+ _SEH2_YIELD(goto DispatchToUser);
}
}
- _SEH_END;
+ _SEH2_END;
}
/* Try second chance */
- if (DbgkForwardException(ExceptionRecord, TRUE, FALSE))
+ if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
{
/* Handled, get out */
- goto Exit;
+ return;
}
else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
{
/* Handled, get out */
- goto Exit;
+ return;
}
/* 3rd strike, kill the process */
- DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n",
+ DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n",
PsGetCurrentProcess()->ImageFileName,
ExceptionRecord->ExceptionCode,
- ExceptionRecord->ExceptionAddress);
+ ExceptionRecord->ExceptionAddress,
+ PsGetCurrentProcess()->SectionBaseAddress);
ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
TrapFrame,
Context.ContextFlags,
PreviousMode);
-Exit:
return;
}
+VOID
+NTAPI
+DECLSPEC_NORETURN
+KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
+ IN ULONG_PTR Address,
+ IN ULONG ParameterCount,
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN PKTRAP_FRAME TrapFrame)
+{
+ EXCEPTION_RECORD ExceptionRecord;
+
+ /* Build the exception record */
+ ExceptionRecord.ExceptionCode = Code;
+ ExceptionRecord.ExceptionFlags = 0;
+ ExceptionRecord.ExceptionRecord = NULL;
+ ExceptionRecord.ExceptionAddress = (PVOID)Address;
+ ExceptionRecord.NumberParameters = ParameterCount;
+ if (ParameterCount)
+ {
+ /* Copy extra parameters */
+ ExceptionRecord.ExceptionInformation[0] = Parameter1;
+ ExceptionRecord.ExceptionInformation[1] = Parameter2;
+ ExceptionRecord.ExceptionInformation[2] = Parameter3;
+ }
+
+ /* Now go dispatch the exception */
+ KiDispatchException(&ExceptionRecord,
+ NULL,
+ TrapFrame,
+ TrapFrame->EFlags & EFLAGS_V86_MASK ?
+ -1 : KiUserTrap(TrapFrame),
+ TRUE);
+
+ /* Return from this trap */
+ KiEoiHelper(TrapFrame);
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+KiSystemFatalException(IN ULONG ExceptionCode,
+ IN PKTRAP_FRAME TrapFrame)
+{
+ /* Bugcheck the system */
+ KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
+ ExceptionCode,
+ 0,
+ 0,
+ 0,
+ TrapFrame);
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
/*
* @implemented
*/
NTAPI
KeRaiseUserException(IN NTSTATUS ExceptionCode)
{
- NTSTATUS Status = STATUS_SUCCESS;
ULONG OldEip;
PTEB Teb = KeGetCurrentThread()->Teb;
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
/* Make sure we can access the TEB */
- _SEH_TRY
+ _SEH2_TRY
{
/* Set the exception code */
Teb->ExceptionCode = ExceptionCode;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- /* Save exception code */
- Status = ExceptionCode;
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
- _SEH_END;
- if (!NT_SUCCESS(Status)) return Status;
+ _SEH2_END;
/* Get the old EIP */
OldEip = TrapFrame->Eip;