#define NDEBUG
#include <debug.h>
-/* FUNCTIONS *****************************************************************/
+/* GLOBALS *******************************************************************/
-_SEH_DEFINE_LOCALS(KiCopyInfo)
+/* DR Registers in the CONTEXT structure */
+UCHAR KiDebugRegisterContextOffsets[9] =
{
- volatile EXCEPTION_RECORD SehExceptRecord;
+ FIELD_OFFSET(CONTEXT, Dr0),
+ FIELD_OFFSET(CONTEXT, Dr1),
+ FIELD_OFFSET(CONTEXT, Dr2),
+ FIELD_OFFSET(CONTEXT, Dr3),
+ 0,
+ 0,
+ FIELD_OFFSET(CONTEXT, Dr6),
+ FIELD_OFFSET(CONTEXT, Dr7),
+ 0,
};
-_SEH_FILTER(KiCopyInformation)
+/* DR Registers in the KTRAP_FRAME structure */
+UCHAR KiDebugRegisterTrapOffsets[9] =
{
- _SEH_ACCESS_LOCALS(KiCopyInfo);
+ FIELD_OFFSET(KTRAP_FRAME, Dr0),
+ FIELD_OFFSET(KTRAP_FRAME, Dr1),
+ FIELD_OFFSET(KTRAP_FRAME, Dr2),
+ FIELD_OFFSET(KTRAP_FRAME, Dr3),
+ 0,
+ 0,
+ FIELD_OFFSET(KTRAP_FRAME, Dr6),
+ FIELD_OFFSET(KTRAP_FRAME, Dr7),
+ 0,
+};
- /* Copy the exception records and return to the handler */
- RtlCopyMemory((PVOID)&_SEH_VAR(SehExceptRecord),
- _SEH_GetExceptionPointers()->ExceptionRecord,
- sizeof(EXCEPTION_RECORD));
- return EXCEPTION_EXECUTE_HANDLER;
-}
+/* FUNCTIONS *****************************************************************/
VOID
INIT_FUNCTION
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;
}
}
+ULONG
+FASTCALL
+KiUpdateDr7(IN ULONG Dr7)
+{
+ ULONG DebugMask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
+
+ /* Check if debugging is enabled */
+ if (DebugMask & DR_MASK(DR7_OVERRIDE_V))
+ {
+ /* Sanity checks */
+ ASSERT((DebugMask & DR_REG_MASK) != 0);
+ ASSERT((Dr7 & ~DR7_RESERVED_MASK) == DR7_OVERRIDE_MASK);
+ return 0;
+ }
+
+ /* Return DR7 itself */
+ return Dr7;
+}
+
+BOOLEAN
+FASTCALL
+KiRecordDr7(OUT PULONG Dr7Ptr,
+ OUT PULONG DrMask)
+{
+ ULONG NewMask, Mask;
+ UCHAR Result;
+
+ /* Check if the caller gave us a mask */
+ if (!DrMask)
+ {
+ /* He didn't, use the one from the thread */
+ Mask = KeGetCurrentThread()->DispatcherHeader.DebugActive;
+ }
+ else
+ {
+ /* He did, read it */
+ Mask = *DrMask;
+ }
+
+ /* Sanity check */
+ ASSERT((*Dr7Ptr & DR7_RESERVED_MASK) == 0);
+
+ /* Check if DR7 is empty */
+ NewMask = Mask;
+ if (!(*Dr7Ptr))
+ {
+ /* Assume failure */
+ Result = FALSE;
+
+ /* Check the DR mask */
+ NewMask &= ~(DR_MASK(7));
+ if (NewMask & DR_REG_MASK)
+ {
+ /* Set the active mask */
+ NewMask |= DR_MASK(DR7_OVERRIDE_V);
+
+ /* Set DR7 override */
+ *Dr7Ptr |= DR7_OVERRIDE_MASK;
+ }
+ else
+ {
+ /* Sanity check */
+ ASSERT(NewMask == 0);
+ }
+ }
+ else
+ {
+ /* Check if we have a mask or not */
+ Result = NewMask ? TRUE: FALSE;
+
+ /* Update the mask to disable debugging */
+ NewMask &= ~(DR_MASK(DR7_OVERRIDE_V));
+ NewMask |= DR_MASK(7);
+ }
+
+ /* Check if caller wants the new mask */
+ if (DrMask)
+ {
+ /* Update it */
+ *DrMask = NewMask;
+ }
+ else
+ {
+ /* Check if the mask changed */
+ if (Mask != NewMask)
+ {
+ /* Update it */
+ KeGetCurrentThread()->DispatcherHeader.DebugActive =
+ (BOOLEAN)NewMask;
+ }
+ }
+
+ /* Return the result */
+ return Result;
+}
+
ULONG
NTAPI
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
IN ULONG Esp)
{
- ULONG Previous = KiEspFromTrapFrame(TrapFrame);
+ KIRQL OldIrql;
+ ULONG Previous;
+
+ /* Raise to APC_LEVEL if needed */
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
+
+ /* Get the old ESP */
+ Previous = KiEspFromTrapFrame(TrapFrame);
/* Check if this is user-mode or V86 */
- if ((TrapFrame->SegCs & MODE_MASK) || (TrapFrame->EFlags & EFLAGS_V86_MASK))
+ if ((TrapFrame->SegCs & MODE_MASK) ||
+ (TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Write it directly */
TrapFrame->HardwareEsp = Esp;
else
{
/* Don't allow ESP to be lowered, this is illegal */
- if (Esp < Previous) KeBugCheck(SET_OF_INVALID_CONTEXT);
+ if (Esp < Previous) KeBugCheckEx(SET_OF_INVALID_CONTEXT,
+ Esp,
+ Previous,
+ (ULONG_PTR)TrapFrame,
+ 0);
/* Create an edit frame, check if it was alrady */
if (!(TrapFrame->SegCs & FRAME_EDITED))
}
}
}
+
+ /* Restore IRQL */
+ if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}
ULONG
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)
*/
PFX_SAVE_AREA FxSaveArea;
ULONG i;
BOOLEAN V86Switch = FALSE;
- KIRQL OldIrql = APC_LEVEL;
+ KIRQL OldIrql;
+ ULONG DrMask = 0;
+ PVOID SafeDr;
/* Do this at APC_LEVEL */
- if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Start with the basic Registers */
if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
V86Switch = TRUE;
}
- /* Copy EFLAGS. FIXME: Needs to be sanitized */
- TrapFrame->EFlags = Context->EFlags;
+ /* Copy EFLAGS and sanitize them*/
+ TrapFrame->EFlags = Ke386SanitizeFlags(Context->EFlags, PreviousMode);
/* Copy EBP and EIP */
TrapFrame->Ebp = Context->Ebp;
}
else
{
- /* We weren't in V86, so sanitize the CS (FIXME!) */
- TrapFrame->SegCs = Context->SegCs;
+ /* We weren't in V86, so sanitize the CS */
+ TrapFrame->SegCs = Ke386SanitizeSeg(Context->SegCs, PreviousMode);
/* Don't let it under 8, that's invalid */
if ((PreviousMode != KernelMode) && (TrapFrame->SegCs < 8))
{
/* Force it to User CS */
- TrapFrame->SegCs = (KGDT_R3_CODE | RPL_MASK);
+ TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
}
}
/* Check if we were in V86 Mode */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
- /* Copy the V86 Segments directlry */
+ /* Copy the V86 Segments directly */
TrapFrame->V86Ds = Context->SegDs;
TrapFrame->V86Es = Context->SegEs;
TrapFrame->V86Fs = Context->SegFs;
/* For kernel mode, write the standard values */
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegFs = Context->SegFs;
+ TrapFrame->SegFs = Ke386SanitizeSeg(Context->SegFs, PreviousMode);
TrapFrame->SegGs = 0;
}
else
{
- /* For user mode, return the values directlry */
+ /* For user mode, return the values directly */
TrapFrame->SegDs = Context->SegDs;
TrapFrame->SegEs = Context->SegEs;
TrapFrame->SegFs = Context->SegFs;
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);
- /* FIXME: Check if this is a VDM app */
+ /* Check if this is a VDM app */
+ if (PsGetCurrentProcess()->VdmObjects)
+ {
+ /* Allow the EM flag */
+ FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
+ (CR0_EM | CR0_MP);
+ }
}
}
}
else
{
- /* Just dump the Fn state in */
- RtlCopyMemory(&FxSaveArea->U.FnArea,
- &Context->FloatSave,
- sizeof(FNSAVE_FORMAT));
+ /* Copy the structure */
+ FxSaveArea->U.FnArea.ControlWord = Context->FloatSave.
+ ControlWord;
+ FxSaveArea->U.FnArea.StatusWord = Context->FloatSave.
+ StatusWord;
+ FxSaveArea->U.FnArea.TagWord = Context->FloatSave.TagWord;
+ FxSaveArea->U.FnArea.ErrorOffset = Context->FloatSave.
+ ErrorOffset;
+ FxSaveArea->U.FnArea.ErrorSelector = Context->FloatSave.
+ ErrorSelector;
+ FxSaveArea->U.FnArea.DataOffset = Context->FloatSave.
+ DataOffset;
+ FxSaveArea->U.FnArea.DataSelector = Context->FloatSave.
+ DataSelector;
+
+ /* Loop registers */
+ for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
+ {
+ /* Copy registers */
+ FxSaveArea->U.FnArea.RegisterArea[i] =
+ Context->FloatSave.RegisterArea[i];
+ }
}
/* Mask out any invalid flags */
FxSaveArea->Cr0NpxState &= ~(CR0_EM | CR0_MP | CR0_TS);
- /* FIXME: Check if this is a VDM app */
+ /* Check if this is a VDM app */
+ if (PsGetCurrentProcess()->VdmObjects)
+ {
+ /* Allow the EM flag */
+ FxSaveArea->Cr0NpxState |= Context->FloatSave.Cr0NpxState &
+ (CR0_EM | CR0_MP);
+ }
}
else
{
/* FIXME: Handle FPU Emulation */
- ASSERT(FALSE);
+ //ASSERT(FALSE);
}
}
/* Handle the Debug Registers */
if ((ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
- /* FIXME: All these should be sanitized */
- TrapFrame->Dr0 = Context->Dr0;
- TrapFrame->Dr1 = Context->Dr1;
- TrapFrame->Dr2 = Context->Dr2;
- TrapFrame->Dr3 = Context->Dr3;
- TrapFrame->Dr6 = Context->Dr6;
- TrapFrame->Dr7 = Context->Dr7;
+ /* Loop DR registers */
+ for (i = 0; i < 4; i++)
+ {
+ /* Sanitize the context DR Address */
+ SafeDr = Ke386SanitizeDr(KiDrFromContext(i, Context), PreviousMode);
+
+ /* Save it in the trap frame */
+ *KiDrFromTrapFrame(i, TrapFrame) = SafeDr;
+
+ /* Check if this DR address is active and add it in the DR mask */
+ if (SafeDr) DrMask |= DR_MASK(i);
+ }
+
+ /* Now save and sanitize DR6 */
+ TrapFrame->Dr6 = Context->Dr6 & DR6_LEGAL;
+ if (TrapFrame->Dr6) DrMask |= DR_MASK(6);
- /* Check if usermode */
+ /* Save and sanitize DR7 */
+ TrapFrame->Dr7 = Context->Dr7 & DR7_LEGAL;
+ KiRecordDr7(&TrapFrame->Dr7, &DrMask);
+
+ /* If we're in user-mode */
if (PreviousMode != KernelMode)
{
- /* Set the Debug Flag */
- KeGetCurrentThread()->DispatcherHeader.DebugActive =
- (Context->Dr7 & DR7_ACTIVE) ? TRUE: FALSE;
+ /* Save the mask */
+ KeGetCurrentThread()->DispatcherHeader.DebugActive = DrMask;
}
}
+ /* Check if thread has IOPL and force it enabled if so */
+ if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
+
/* Restore IRQL */
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}
FLOATING_SAVE_AREA UnalignedArea;
} FloatSaveBuffer;
FLOATING_SAVE_AREA *FloatSaveArea;
- KIRQL OldIrql = APC_LEVEL;
+ KIRQL OldIrql;
+ ULONG i;
/* Do this at APC_LEVEL */
- if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
/* Start with the Control flags */
if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
KiFlushNPXState(NULL);
}
- /* Copy into the Context */
- RtlCopyMemory(&Context->FloatSave,
- FloatSaveArea,
- sizeof(FNSAVE_FORMAT));
+ /* Copy structure */
+ Context->FloatSave.ControlWord = FloatSaveArea->ControlWord;
+ Context->FloatSave.StatusWord = FloatSaveArea->StatusWord;
+ Context->FloatSave.TagWord = FloatSaveArea->TagWord;
+ Context->FloatSave.ErrorOffset = FloatSaveArea->ErrorOffset;
+ Context->FloatSave.ErrorSelector = FloatSaveArea->ErrorSelector;
+ Context->FloatSave.DataOffset = FloatSaveArea->DataOffset;
+ Context->FloatSave.DataSelector = FloatSaveArea->DataSelector;
+ Context->FloatSave.Cr0NpxState = FxSaveArea->Cr0NpxState;
+
+ /* Loop registers */
+ for (i = 0; i < SIZE_OF_80387_REGISTERS; i++)
+ {
+ /* Copy them */
+ Context->FloatSave.RegisterArea[i] =
+ FloatSaveArea->RegisterArea[i];
+ }
}
else
{
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
CONTEXT_DEBUG_REGISTERS)
{
- /* Copy the debug registers */
- Context->Dr0 = TrapFrame->Dr0;
- Context->Dr1 = TrapFrame->Dr1;
- Context->Dr2 = TrapFrame->Dr2;
- Context->Dr3 = TrapFrame->Dr3;
- Context->Dr6 = TrapFrame->Dr6;
-
- /* For user-mode, only set DR7 if a debugger is active */
- if (((TrapFrame->SegCs & MODE_MASK) ||
- (TrapFrame->EFlags & EFLAGS_V86_MASK)) &&
- (KeGetCurrentThread()->DispatcherHeader.DebugActive))
+ /* Make sure DR7 is valid */
+ if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
{
- /* Copy it over */
- Context->Dr7 = TrapFrame->Dr7;
+ /* Copy the debug registers */
+ Context->Dr0 = TrapFrame->Dr0;
+ Context->Dr1 = TrapFrame->Dr1;
+ Context->Dr2 = TrapFrame->Dr2;
+ Context->Dr3 = TrapFrame->Dr3;
+ Context->Dr6 = TrapFrame->Dr6;
+
+ /* Update DR7 */
+ Context->Dr7 = KiUpdateDr7(TrapFrame->Dr7);
}
else
{
- /* Clear it */
+ /* Otherwise clear DR registers */
+ Context->Dr0 =
+ Context->Dr1 =
+ 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 isenabled */
+ /* Check if User Mode or if the debugger is enabled */
if ((PreviousMode == UserMode) || (KdDebuggerEnabled))
{
/* Add the FPU Flag */
/* Get a Context */
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
- /* Fix up EIP */
- if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
+ /* Look at our exception code */
+ switch (ExceptionRecord->ExceptionCode)
{
- /* Decrement EIP by one */
- Context.Eip--;
+ /* Breakpoint */
+ case STATUS_BREAKPOINT:
+
+ /* Decrement EIP by one */
+ Context.Eip--;
+ break;
+
+ /* Internal exception */
+ case KI_EXCEPTION_ACCESS_VIOLATION:
+
+ /* Set correct code */
+ ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
+ if (PreviousMode == UserMode)
+ {
+ /* FIXME: Handle no execute */
+ }
+ break;
}
/* Sanity check */
goto Handled;
}
- /* HACK: GDB Entry */
- if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled;
-
/* If the Debugger couldn't handle it, dispatch the exception */
if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
}
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode,
(ULONG_PTR)ExceptionRecord->ExceptionAddress,
- ExceptionRecord->ExceptionInformation[0],
- ExceptionRecord->ExceptionInformation[1]);
+ (ULONG_PTR)TrapFrame,
+ 0);
}
else
{
/* User mode exception, was it first-chance? */
if (FirstChance)
{
- /* Enter Debugger if available */
- if (PsGetCurrentProcess()->DebugPort)
- {
- /* FIXME : TODO */
- ASSERT(FALSE);
- }
- else if (KiDebugRoutine(TrapFrame,
- ExceptionFrame,
- ExceptionRecord,
- &Context,
- PreviousMode,
- FALSE))
+ /* Make sure a debugger is present, and ignore user-mode if requested */
+ if ((KiDebugRoutine) &&
+ (!(PsGetCurrentProcess()->DebugPort)))
{
- /* Exception was handled */
- goto Handled;
+ /* Call the debugger */
+ if (KiDebugRoutine(TrapFrame,
+ ExceptionFrame,
+ ExceptionRecord,
+ &Context,
+ PreviousMode,
+ FALSE))
+ {
+ /* Exception was handled */
+ goto Handled;
+ }
}
- /* HACK: GDB Entry */
- if (KdpCallGdb(TrapFrame, ExceptionRecord, &Context)) goto Handled;
-
/* Forward exception to user mode debugger */
if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit;
/* 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))
KiEspToTrapFrame(TrapFrame, NewStack - 2 * sizeof(ULONG_PTR));
/* Force correct segments */
- TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
- TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegEs = KGDT_R3_DATA | RPL_MASK;
- TrapFrame->SegFs = KGDT_R3_TEB | RPL_MASK;
+ TrapFrame->SegCs = Ke386SanitizeSeg(KGDT_R3_CODE, PreviousMode);
+ TrapFrame->SegDs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
+ TrapFrame->SegEs = Ke386SanitizeSeg(KGDT_R3_DATA, PreviousMode);
+ TrapFrame->SegFs = Ke386SanitizeSeg(KGDT_R3_TEB, PreviousMode);
TrapFrame->SegGs = 0;
- /* Set EIP to the User-mode Dispathcer */
+ /* Set EIP to the User-mode Dispatcher */
TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
- _SEH_LEAVE;
+
+ /* Dispatch exception to user-mode */
+ _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 */
- goto DispatchToUser;
+ _SEH2_YIELD(goto DispatchToUser);
}
}
- _SEH_END;
-
- /* Dispatch exception to user-mode */
- return;
+ _SEH2_END;
}
/* Try second chance */
- if (DbgkForwardException(ExceptionRecord, TRUE, FALSE))
+ if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
{
/* Handled, get out */
goto Exit;
}
/* 3rd strike, kill the process */
+ DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx\n",
+ PsGetCurrentProcess()->ImageFileName,
+ ExceptionRecord->ExceptionCode,
+ ExceptionRecord->ExceptionAddress);
+
ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
ExceptionRecord->ExceptionCode,
(ULONG_PTR)ExceptionRecord->ExceptionAddress,
- ExceptionRecord->ExceptionInformation[0],
- ExceptionRecord->ExceptionInformation[1]);
+ (ULONG_PTR)TrapFrame,
+ 0);
}
Handled:
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;
/* Return the old EIP */
return (NTSTATUS)OldEip;
}
-