1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ps/amd64/psctx.c
5 * PURPOSE: Process Manager: Set/Get Context for i386
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Timo Kreuzer (timo.kreuzer@reactos.org)
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ******************************************************************/
17
18
_IRQL_requires_(APC_LEVEL)19 _IRQL_requires_(APC_LEVEL)
20 VOID
21 NTAPI
22 PspGetOrSetContextKernelRoutine(
23 _In_ PKAPC Apc,
24 _Inout_ PKNORMAL_ROUTINE* NormalRoutine,
25 _Inout_ PVOID* NormalContext,
26 _Inout_ PVOID* SystemArgument1,
27 _Inout_ PVOID* SystemArgument2)
28 {
29 PGET_SET_CTX_CONTEXT GetSetContext;
30 PKTHREAD Thread;
31 PKTRAP_FRAME TrapFrame = NULL;
32
33 PAGED_CODE();
34
35 /* Get the Context Structure */
36 GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
37 Thread = Apc->SystemArgument2;
38 NT_ASSERT(KeGetCurrentThread() == Thread);
39
40 /* If this is a kernel-mode request, grab the saved trap frame */
41 if (GetSetContext->Mode == KernelMode)
42 {
43 TrapFrame = Thread->TrapFrame;
44 }
45
46 /* If we don't have one, grab it from the stack */
47 if (TrapFrame == NULL)
48 {
49 /* Get the thread's base trap frame */
50 TrapFrame = KeGetTrapFrame(KeGetCurrentThread());
51 }
52
53 /* Check if it's a set or get */
54 if (Apc->SystemArgument1 != 0)
55 {
56 /* Set the nonvolatiles on the stack, target frame is the trap frame */
57 KiSetTrapContext(TrapFrame, &GetSetContext->Context, GetSetContext->Mode);
58 }
59 else
60 {
61 /* Convert the trap frame to a context */
62 KeTrapFrameToContext(TrapFrame,
63 NULL,
64 &GetSetContext->Context);
65 }
66
67 /* Notify the Native API that we are done */
68 KeSetEvent(&GetSetContext->Event, IO_NO_INCREMENT, FALSE);
69 }
70
71 /* EOF */
72