mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 15:51:21 +00:00
[NTOS:KE:X64] Simplify KiInitializeUserApc
This commit is contained in:
parent
aaa86d078e
commit
52d1bb5ec9
1 changed files with 65 additions and 71 deletions
|
@ -11,7 +11,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
/*! \name KiInitializeUserApc
|
/*!
|
||||||
|
* \name KiInitializeUserApc
|
||||||
*
|
*
|
||||||
* \brief
|
* \brief
|
||||||
* Prepares the current trap frame (which must have come from user mode)
|
* Prepares the current trap frame (which must have come from user mode)
|
||||||
|
@ -19,12 +20,16 @@
|
||||||
* record with the context from the old trap frame to the threads user
|
* record with the context from the old trap frame to the threads user
|
||||||
* mode stack.
|
* mode stack.
|
||||||
*
|
*
|
||||||
* \param ExceptionFrame
|
* \param ExceptionFrame - Pointer to the Exception Frame
|
||||||
* \param TrapFrame
|
*
|
||||||
* \param NormalRoutine
|
* \param TrapFrame Pointer to the Trap Frame.
|
||||||
* \param NormalContext
|
*
|
||||||
* \param SystemArgument1
|
* \param NormalRoutine - Pointer to the NormalRoutine to call.
|
||||||
* \param SystemArgument2
|
*
|
||||||
|
* \param NormalContext - Pointer to the context to send to the Normal Routine.
|
||||||
|
*
|
||||||
|
* \param SystemArgument[1-2]
|
||||||
|
* Pointer to a set of two parameters that contain untyped data.
|
||||||
*
|
*
|
||||||
* \remarks
|
* \remarks
|
||||||
* This function is called from KiDeliverApc, when the trap frame came
|
* This function is called from KiDeliverApc, when the trap frame came
|
||||||
|
@ -48,67 +53,56 @@ KiInitializeUserApc(
|
||||||
_In_ PVOID SystemArgument1,
|
_In_ PVOID SystemArgument1,
|
||||||
_In_ PVOID SystemArgument2)
|
_In_ PVOID SystemArgument2)
|
||||||
{
|
{
|
||||||
CONTEXT Context;
|
PCONTEXT Context;
|
||||||
ULONG64 AlignedRsp, Stack;
|
EXCEPTION_RECORD ExceptionRecord;
|
||||||
EXCEPTION_RECORD SehExceptRecord;
|
|
||||||
|
|
||||||
/* Sanity check, that the trap frame is from user mode */
|
/* Sanity check, that the trap frame is from user mode */
|
||||||
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
||||||
|
|
||||||
/* Convert the current trap frame to a context */
|
/* Align the user tack to 16 bytes and allocate space for a CONTEXT structure */
|
||||||
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
Context = (PCONTEXT)ALIGN_DOWN_POINTER_BY(TrapFrame->Rsp, 16) - 1;
|
||||||
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
|
|
||||||
|
|
||||||
/* We jump to KiUserApcDispatcher in ntdll */
|
|
||||||
TrapFrame->Rip = (ULONG64)KeUserApcDispatcher;
|
|
||||||
|
|
||||||
/* Setup Ring 3 segments */
|
|
||||||
TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
|
|
||||||
TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
|
|
||||||
TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
|
|
||||||
/* Sanitize EFLAGS, enable interrupts */
|
|
||||||
TrapFrame->EFlags = (Context.EFlags & EFLAGS_USER_SANITIZE);
|
|
||||||
TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
|
|
||||||
|
|
||||||
/* Set parameters for KiUserApcDispatcher */
|
|
||||||
Context.P1Home = (ULONG64)NormalContext;
|
|
||||||
Context.P2Home = (ULONG64)SystemArgument1;
|
|
||||||
Context.P3Home = (ULONG64)SystemArgument2;
|
|
||||||
Context.P4Home = (ULONG64)NormalRoutine;
|
|
||||||
|
|
||||||
/* Check if thread has IOPL and force it enabled if so */
|
|
||||||
//if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
|
|
||||||
|
|
||||||
/* Align Stack to 16 bytes and allocate space */
|
|
||||||
AlignedRsp = Context.Rsp & ~15;
|
|
||||||
Stack = AlignedRsp - sizeof(CONTEXT);
|
|
||||||
TrapFrame->Rsp = Stack;
|
|
||||||
|
|
||||||
/* The stack must be 16 byte aligned for KiUserApcDispatcher */
|
|
||||||
ASSERT((Stack & 15) == 0);
|
|
||||||
|
|
||||||
/* Protect with SEH */
|
/* Protect with SEH */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Probe the stack */
|
/* Probe the context */
|
||||||
ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8);
|
ProbeForWrite(Context, sizeof(CONTEXT), 16);
|
||||||
|
|
||||||
/* Copy the context */
|
/* Convert the current trap frame to a context */
|
||||||
RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT));
|
Context->ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||||
|
KeTrapFrameToContext(TrapFrame, ExceptionFrame, Context);
|
||||||
|
|
||||||
|
/* Set parameters for KiUserApcDispatcher */
|
||||||
|
Context->P1Home = (ULONG64)NormalContext;
|
||||||
|
Context->P2Home = (ULONG64)SystemArgument1;
|
||||||
|
Context->P3Home = (ULONG64)SystemArgument2;
|
||||||
|
Context->P4Home = (ULONG64)NormalRoutine;
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
|
_SEH2_EXCEPT(ExceptionRecord = *_SEH2_GetExceptionInformation()->ExceptionRecord, EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
/* Dispatch the exception */
|
/* Dispatch the exception */
|
||||||
SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
|
ExceptionRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
|
||||||
KiDispatchException(&SehExceptRecord,
|
KiDispatchException(&ExceptionRecord,
|
||||||
ExceptionFrame,
|
ExceptionFrame,
|
||||||
TrapFrame,
|
TrapFrame,
|
||||||
UserMode,
|
UserMode,
|
||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* Set the stack pointer to the context record */
|
||||||
|
TrapFrame->Rsp = (ULONG64)Context;
|
||||||
|
|
||||||
|
/* We jump to KiUserApcDispatcher in ntdll */
|
||||||
|
TrapFrame->Rip = (ULONG64)KeUserApcDispatcher;
|
||||||
|
|
||||||
|
/* Setup Ring 3 segments */
|
||||||
|
TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
|
||||||
|
TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
|
||||||
|
TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
|
||||||
|
TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
|
||||||
|
|
||||||
|
/* Sanitize EFLAGS, enable interrupts */
|
||||||
|
TrapFrame->EFlags &= EFLAGS_USER_SANITIZE;
|
||||||
|
TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue