reactos/ntoskrnl/ps/amd64/psctx.c
2021-06-11 15:33:08 +03:00

72 lines
2 KiB
C

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ps/amd64/psctx.c
* PURPOSE: Process Manager: Set/Get Context for i386
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ******************************************************************/
_IRQL_requires_(APC_LEVEL)
VOID
NTAPI
PspGetOrSetContextKernelRoutine(
_In_ PKAPC Apc,
_Inout_ PKNORMAL_ROUTINE* NormalRoutine,
_Inout_ PVOID* NormalContext,
_Inout_ PVOID* SystemArgument1,
_Inout_ PVOID* SystemArgument2)
{
PGET_SET_CTX_CONTEXT GetSetContext;
PKTHREAD Thread;
PKTRAP_FRAME TrapFrame = NULL;
PAGED_CODE();
/* Get the Context Structure */
GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
Thread = Apc->SystemArgument2;
NT_ASSERT(KeGetCurrentThread() == Thread);
/* If this is a kernel-mode request, grab the saved trap frame */
if (GetSetContext->Mode == KernelMode)
{
TrapFrame = Thread->TrapFrame;
}
/* If we don't have one, grab it from the stack */
if (TrapFrame == NULL)
{
/* Get the thread's base trap frame */
TrapFrame = KeGetTrapFrame(KeGetCurrentThread());
}
/* Check if it's a set or get */
if (Apc->SystemArgument1 != 0)
{
/* Set the nonvolatiles on the stack, target frame is the trap frame */
KiSetTrapContext(TrapFrame, &GetSetContext->Context, GetSetContext->Mode);
}
else
{
/* Convert the trap frame to a context */
KeTrapFrameToContext(TrapFrame,
NULL,
&GetSetContext->Context);
}
/* Notify the Native API that we are done */
KeSetEvent(&GetSetContext->Event, IO_NO_INCREMENT, FALSE);
}
/* EOF */