Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
4.5 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
psctx.c
Abstract:
This procedure implements Get/Set Context Thread
Author:
Mark Lucovsky (markl) 25-May-1989
Notes:
There IS NO NonVolatileContext stored outside of the trap
frame on a 386, with the exception of floating point. Hence,
the NonVolatileContextPointers argument to Get/SetContext is
always NULL on the 386.
Revision History:
8-Jan-90 bryanwi
Port to 386
--*/
#include "psp.h"
#define PSPALIGN_DOWN(address,amt) ((ULONG)(address) & ~(( amt ) - 1))
#define PSPALIGN_UP(address,amt) (PSPALIGN_DOWN( (address + (amt) - 1), (amt) ))
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,PspGetContext )
#pragma alloc_text(PAGE,PspGetSetContextSpecialApc )
#pragma alloc_text(PAGE,PspSetContext)
#endif
VOID
PspGetContext(
IN PKTRAP_FRAME TrapFrame,
IN PKNONVOLATILE_CONTEXT_POINTERS NonVolatileContext,
IN OUT PCONTEXT Context
)
/*++
Routine Description:
This function moves the contents of the specified trap and NonVolatile
context into the specified context record. It's primary user will
be NtGetContextThread.
N.B. - NonVolatileContext is IGNORED on the 386.
Arguments:
TrapFrame - Supplies the contents of a trap frame that should be
restored copied into the proper location in the context
record.
Context - Returns the threads current context.
Return Value:
None.
--*/
{
UNREFERENCED_PARAMETER( NonVolatileContext );
PAGED_CODE();
KeContextFromKframes(TrapFrame, NULL, Context);
}
VOID
PspSetContext(
OUT PKTRAP_FRAME TrapFrame,
OUT PKNONVOLATILE_CONTEXT_POINTERS NonVolatileContext,
IN PCONTEXT Context,
KPROCESSOR_MODE Mode
)
/*++
Routine Description:
This function moves the contents of the specified context record
into the specified trap frame, and modifies the thread's non volatile
context by storing through the thread's nonvolatile context pointers.
N.B. - NonVolatileContext is IGNORED on the 386.
Arguments:
TrapFrame - Returns selected pieces of the context record.
Context - Supplies a context record to be copied in the trap and
nonvolatile context.
Mode - Supplies the mode to be used when sanitizing the psr, epsr and fsr
Return Value:
None.
--*/
{
UNREFERENCED_PARAMETER( NonVolatileContext );
PAGED_CODE();
KeContextToKframes(TrapFrame, NULL, Context, Context->ContextFlags, Mode);
}
VOID
PspGetSetContextSpecialApc(
IN PKAPC Apc,
IN PKNORMAL_ROUTINE *NormalRoutine,
IN PVOID *NormalContext,
IN PVOID *SystemArgument1,
IN PVOID *SystemArgument2
)
/*++
Routine Description:
This function either captures the usermode state of the current
thread, or sets the usermode state of the current thread. The
operation type is determined by the value of SystemArgument1. A
NULL value is used for get context, and a non-NULL value is used
for set context.
Arguments:
Apc - Supplies a pointer to the APC control object that caused entry
into this routine.
NormalRoutine - Supplies a pointer to a pointer to the normal routine
function that was specifed when the APC was initialized.
NormalContext - Supplies a pointer to a pointer to an arbitrary data
structure that was specified when the APC was initialized.
SystemArgument1, SystemArgument2 - Supplies a set of two pointer to two
arguments that contain untyped data.
Return Value:
None.
--*/
{
PGETSETCONTEXT Ctx;
PKTRAP_FRAME TrapFrame;
PETHREAD Thread;
PAGED_CODE();
UNREFERENCED_PARAMETER( NormalRoutine );
UNREFERENCED_PARAMETER( NormalContext );
UNREFERENCED_PARAMETER( SystemArgument1 );
UNREFERENCED_PARAMETER( SystemArgument2 );
Ctx = CONTAINING_RECORD(Apc,GETSETCONTEXT,Apc);
Thread = Apc->SystemArgument2;
TrapFrame = 0;
if (Ctx->Mode == KernelMode) {
TrapFrame = Thread->Tcb.TrapFrame;
}
if (TrapFrame == NULL) {
TrapFrame = (PKTRAP_FRAME)((PUCHAR)Thread->Tcb.InitialStack -
PSPALIGN_UP(sizeof(KTRAP_FRAME),KTRAP_FRAME_ALIGN) -
sizeof(FX_SAVE_AREA));
}
if ( Apc->SystemArgument1 ) {
//
// Set Context
//
PspSetContext(TrapFrame,NULL,&Ctx->Context,Ctx->Mode);
} else {
//
// Get Context
//
PspGetContext(TrapFrame,NULL,&Ctx->Context);
}
KeSetEvent(&Ctx->OperationComplete,0,FALSE);
}