xref: /reactos/ntoskrnl/ps/amd64/psctx.c (revision 34593d93)
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