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 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