211 lines
4.5 KiB
C
211 lines
4.5 KiB
C
/*++
|
||
|
||
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);
|
||
|
||
}
|