mirror of
https://github.com/reactos/reactos.git
synced 2024-09-19 17:21:14 +00:00
29fa274d6d
- TSVN choked repeatedly when attempting to merge ~9000 revs into the branch (tried 3 times on 2 different computers) - If someone wants to delete aicom-network-fixes, they are welcome to - Lesson learned: Letting a branch get thousands of revs out of date is a horrible idea svn path=/branches/aicom-network-branch/; revision=44353
168 lines
5.1 KiB
C
168 lines
5.1 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: ntoskrnl/ke/except.c
|
|
* PURPOSE: Platform independent exception handling
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
VOID
|
|
NTAPI
|
|
KiContinuePreviousModeUser(IN PCONTEXT Context,
|
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
IN PKTRAP_FRAME TrapFrame)
|
|
{
|
|
CONTEXT LocalContext;
|
|
|
|
/* We'll have to make a copy and probe it */
|
|
ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
|
|
RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
|
|
Context = &LocalContext;
|
|
|
|
/* Convert the context into Exception/Trap Frames */
|
|
KeContextToTrapFrame(&LocalContext,
|
|
ExceptionFrame,
|
|
TrapFrame,
|
|
LocalContext.ContextFlags,
|
|
UserMode);
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
KiContinue(IN PCONTEXT Context,
|
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
IN PKTRAP_FRAME TrapFrame)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
KIRQL OldIrql = APC_LEVEL;
|
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
|
|
|
/* Raise to APC_LEVEL, only if needed */
|
|
if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
|
|
|
|
/* Set up SEH to validate the context */
|
|
_SEH2_TRY
|
|
{
|
|
/* Check the previous mode */
|
|
if (PreviousMode != KernelMode)
|
|
{
|
|
/* Validate from user-mode */
|
|
KiContinuePreviousModeUser(Context,
|
|
ExceptionFrame,
|
|
TrapFrame);
|
|
}
|
|
else
|
|
{
|
|
/* Convert the context into Exception/Trap Frames */
|
|
KeContextToTrapFrame(Context,
|
|
ExceptionFrame,
|
|
TrapFrame,
|
|
Context->ContextFlags,
|
|
KernelMode);
|
|
}
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
/* Save the exception code */
|
|
Status = _SEH2_GetExceptionCode();
|
|
}
|
|
_SEH2_END;
|
|
|
|
/* Lower the IRQL if needed */
|
|
if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord,
|
|
IN PCONTEXT Context,
|
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
IN PKTRAP_FRAME TrapFrame,
|
|
IN BOOLEAN SearchFrames)
|
|
{
|
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
|
CONTEXT LocalContext;
|
|
EXCEPTION_RECORD LocalExceptionRecord;
|
|
ULONG ParameterCount, Size;
|
|
|
|
/* Check if we need to probe */
|
|
if (PreviousMode != KernelMode)
|
|
{
|
|
/* Set up SEH */
|
|
_SEH2_TRY
|
|
{
|
|
/* Probe the context */
|
|
ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
|
|
|
|
/* Probe the Exception Record */
|
|
ProbeForRead(ExceptionRecord,
|
|
FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +
|
|
sizeof(ULONG),
|
|
sizeof(ULONG));
|
|
|
|
/* Validate the maximum parameters */
|
|
if ((ParameterCount = ExceptionRecord->NumberParameters) >
|
|
EXCEPTION_MAXIMUM_PARAMETERS)
|
|
{
|
|
/* Too large */
|
|
_SEH2_YIELD(return STATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
/* Probe the entire parameters now*/
|
|
Size = (sizeof(EXCEPTION_RECORD) -
|
|
((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));
|
|
ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));
|
|
|
|
/* Now make copies in the stack */
|
|
RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
|
|
RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size);
|
|
Context = &LocalContext;
|
|
ExceptionRecord = &LocalExceptionRecord;
|
|
|
|
/* Update the parameter count */
|
|
ExceptionRecord->NumberParameters = ParameterCount;
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
/* Don't fail silently */
|
|
DPRINT1("KiRaiseException: Failed to Probe\n");
|
|
DbgBreakPoint();
|
|
|
|
/* Return the exception code */
|
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
|
}
|
|
_SEH2_END;
|
|
}
|
|
|
|
/* Convert the context record */
|
|
KeContextToTrapFrame(Context,
|
|
ExceptionFrame,
|
|
TrapFrame,
|
|
Context->ContextFlags,
|
|
PreviousMode);
|
|
|
|
/* Dispatch the exception */
|
|
ExceptionRecord->ExceptionCode &= ~KI_EXCEPTION_INTERNAL;
|
|
KiDispatchException(ExceptionRecord,
|
|
ExceptionFrame,
|
|
TrapFrame,
|
|
PreviousMode,
|
|
SearchFrames);
|
|
|
|
/* We are done */
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/* EOF */
|