mirror of
https://github.com/reactos/reactos.git
synced 2024-06-16 17:41:56 +00:00
[NTOS:KE:X64] Move KiInitializeUserApc to usercall.c
This commit is contained in:
parent
fbdff437fd
commit
aaa86d078e
|
@ -243,108 +243,6 @@ KiIdleLoop(VOID)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \name KiInitializeUserApc
|
||||
*
|
||||
* \brief
|
||||
* Prepares the current trap frame (which must have come from user mode)
|
||||
* with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT
|
||||
* record with the context from the old trap frame to the threads user
|
||||
* mode stack.
|
||||
*
|
||||
* \param ExceptionFrame
|
||||
* \param TrapFrame
|
||||
* \param NormalRoutine
|
||||
* \param NormalContext
|
||||
* \param SystemArgument1
|
||||
* \param SystemArgument2
|
||||
*
|
||||
* \remarks
|
||||
* This function is called from KiDeliverApc, when the trap frame came
|
||||
* from user mode. This happens before a systemcall or interrupt exits back
|
||||
* to usermode or when a thread is started from PspUserThreadstartup.
|
||||
* The trap exit code will then leave to KiUserApcDispatcher which in turn
|
||||
* calls the NormalRoutine, passing NormalContext, SystemArgument1 and
|
||||
* SystemArgument2 as parameters. When that function returns, it calls
|
||||
* NtContinue to return back to the kernel, where the old context that was
|
||||
* saved on the usermode stack is restored and execution is transferred
|
||||
* back to usermode, where the original trap originated from.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
||||
IN PVOID NormalContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
CONTEXT Context = { 0 };
|
||||
ULONG64 AlignedRsp, Stack;
|
||||
EXCEPTION_RECORD SehExceptRecord;
|
||||
|
||||
/* Sanity check, that the trap frame is from user mode */
|
||||
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
||||
|
||||
/* Convert the current trap frame to a context */
|
||||
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
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 */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Probe the stack */
|
||||
ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8);
|
||||
|
||||
/* Copy the context */
|
||||
RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT));
|
||||
}
|
||||
_SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
|
||||
{
|
||||
/* Dispatch the exception */
|
||||
SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
|
||||
KiDispatchException(&SehExceptRecord,
|
||||
ExceptionFrame,
|
||||
TrapFrame,
|
||||
UserMode,
|
||||
TRUE);
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSwapProcess(IN PKPROCESS NewProcess,
|
||||
|
|
114
ntoskrnl/ke/amd64/usercall.c
Normal file
114
ntoskrnl/ke/amd64/usercall.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - 2.0 + (https ://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: AMD64 User-mode Callout Mechanisms (APC and Win32K Callbacks)
|
||||
* COPYRIGHT: Timo Kreuzer(timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/*! \name KiInitializeUserApc
|
||||
*
|
||||
* \brief
|
||||
* Prepares the current trap frame (which must have come from user mode)
|
||||
* with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT
|
||||
* record with the context from the old trap frame to the threads user
|
||||
* mode stack.
|
||||
*
|
||||
* \param ExceptionFrame
|
||||
* \param TrapFrame
|
||||
* \param NormalRoutine
|
||||
* \param NormalContext
|
||||
* \param SystemArgument1
|
||||
* \param SystemArgument2
|
||||
*
|
||||
* \remarks
|
||||
* This function is called from KiDeliverApc, when the trap frame came
|
||||
* from user mode. This happens before a systemcall or interrupt exits back
|
||||
* to usermode or when a thread is started from PspUserThreadstartup.
|
||||
* The trap exit code will then leave to KiUserApcDispatcher which in turn
|
||||
* calls the NormalRoutine, passing NormalContext, SystemArgument1 and
|
||||
* SystemArgument2 as parameters. When that function returns, it calls
|
||||
* NtContinue to return back to the kernel, where the old context that was
|
||||
* saved on the usermode stack is restored and execution is transferred
|
||||
* back to usermode, where the original trap originated from.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeUserApc(
|
||||
_In_ PKEXCEPTION_FRAME ExceptionFrame,
|
||||
_Inout_ PKTRAP_FRAME TrapFrame,
|
||||
_In_ PKNORMAL_ROUTINE NormalRoutine,
|
||||
_In_ PVOID NormalContext,
|
||||
_In_ PVOID SystemArgument1,
|
||||
_In_ PVOID SystemArgument2)
|
||||
{
|
||||
CONTEXT Context;
|
||||
ULONG64 AlignedRsp, Stack;
|
||||
EXCEPTION_RECORD SehExceptRecord;
|
||||
|
||||
/* Sanity check, that the trap frame is from user mode */
|
||||
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
||||
|
||||
/* Convert the current trap frame to a context */
|
||||
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||
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 */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Probe the stack */
|
||||
ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8);
|
||||
|
||||
/* Copy the context */
|
||||
RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT));
|
||||
}
|
||||
_SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
|
||||
{
|
||||
/* Dispatch the exception */
|
||||
SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
|
||||
KiDispatchException(&SehExceptRecord,
|
||||
ExceptionFrame,
|
||||
TrapFrame,
|
||||
UserMode,
|
||||
TRUE);
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
|
@ -325,11 +325,12 @@ elseif(ARCH STREQUAL "amd64")
|
|||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/kiinit.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/krnlinit.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/spinlock.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/thrdini.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/init.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/page.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c)
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/usercall.c)
|
||||
elseif(ARCH STREQUAL "arm")
|
||||
list(APPEND ASM_SOURCE
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ex/arm/ioport.s
|
||||
|
|
Loading…
Reference in a new issue