(Hopefully) fix (parts of) terribly broken NtSet/GetContextThread functions ;-)

If we have a test for this anywhere, it must be reaaally broken!
Thanks to Alex and KJK for helping!

svn path=/trunk/; revision=18964
This commit is contained in:
Gregor Anich 2005-11-03 00:09:19 +00:00
parent de1acafe9a
commit cc0933a118

View file

@ -23,6 +23,7 @@ typedef struct _GET_SET_CTX_CONTEXT {
KEVENT Event; KEVENT Event;
CONTEXT Context; CONTEXT Context;
KPROCESSOR_MODE Mode; KPROCESSOR_MODE Mode;
NTSTATUS Status;
} GET_SET_CTX_CONTEXT, *PGET_SET_CTX_CONTEXT; } GET_SET_CTX_CONTEXT, *PGET_SET_CTX_CONTEXT;
@ -44,9 +45,11 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc,
PKEVENT Event; PKEVENT Event;
PCONTEXT Context; PCONTEXT Context;
KPROCESSOR_MODE Mode; KPROCESSOR_MODE Mode;
PETHREAD Thread;
PKTRAP_FRAME TrapFrame; PKTRAP_FRAME TrapFrame;
TrapFrame = (PKTRAP_FRAME)((ULONG_PTR)KeGetCurrentThread()->InitialStack -
sizeof (FX_SAVE_AREA) - sizeof (KTRAP_FRAME));
/* Get the Context Structure */ /* Get the Context Structure */
GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc); GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
Context = &GetSetContext->Context; Context = &GetSetContext->Context;
@ -54,21 +57,22 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc,
Mode = GetSetContext->Mode; Mode = GetSetContext->Mode;
Thread = SystemArgument2; Thread = SystemArgument2;
/* Get trap frame */ if (TrapFrame->Cs == KERNEL_CS && Mode != KernelMode)
TrapFrame = (PKTRAP_FRAME)((ULONG_PTR)Thread->Tcb.InitialStack -
sizeof(KTRAP_FRAME) - sizeof(FX_SAVE_AREA));
/* Check if it's a set or get */
if (SystemArgument1)
{ {
/* Get the Context */ GetSetContext->Status = STATUS_ACCESS_DENIED;
KeTrapFrameToContext(TrapFrame, NULL, Context);
} }
else else
{ {
/* Check if it's a set or get */
if (*SystemArgument1) {
/* Get the Context */
KeTrapFrameToContext(TrapFrame, NULL, Context);
} else {
/* Set the Context */ /* Set the Context */
KeContextToTrapFrame(Context, NULL, TrapFrame, Mode); KeContextToTrapFrame(Context, NULL, TrapFrame, Mode);
} }
GetSetContext->Status = STATUS_SUCCESS;
}
/* Notify the Native API that we are done */ /* Notify the Native API that we are done */
KeSetEvent(Event, IO_NO_INCREMENT, FALSE); KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
@ -77,7 +81,7 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc,
NTSTATUS NTSTATUS
STDCALL STDCALL
NtGetContextThread(IN HANDLE ThreadHandle, NtGetContextThread(IN HANDLE ThreadHandle,
OUT PCONTEXT ThreadContext) IN OUT PCONTEXT ThreadContext)
{ {
PETHREAD Thread; PETHREAD Thread;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
@ -94,6 +98,8 @@ NtGetContextThread(IN HANDLE ThreadHandle,
ProbeForWrite(ThreadContext, ProbeForWrite(ThreadContext,
sizeof(CONTEXT), sizeof(CONTEXT),
sizeof(ULONG)); sizeof(ULONG));
GetSetContext.Context = *ThreadContext;
} _SEH_HANDLE { } _SEH_HANDLE {
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
@ -159,6 +165,8 @@ NtGetContextThread(IN HANDLE ThreadHandle,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
if (NT_SUCCESS(Status))
Status = GetSetContext.Status;
} }
} }
@ -167,7 +175,6 @@ NtGetContextThread(IN HANDLE ThreadHandle,
/* Check for success and return the Context */ /* Check for success and return the Context */
if(NT_SUCCESS(Status)) { if(NT_SUCCESS(Status)) {
_SEH_TRY { _SEH_TRY {
*ThreadContext = GetSetContext.Context; *ThreadContext = GetSetContext.Context;
@ -231,13 +238,17 @@ NtSetContextThread(IN HANDLE ThreadHandle,
if(Thread == PsGetCurrentThread()) { if(Thread == PsGetCurrentThread()) {
/* /*
* I don't know if trying to get your own context makes much * I don't know if trying to set your own context makes much
* sense but we can handle it more efficently. * sense but we can handle it more efficently.
*/ */
KeContextToTrapFrame(&GetSetContext.Context, NULL, Thread->Tcb.TrapFrame, PreviousMode); KeContextToTrapFrame(ThreadContext, NULL, Thread->Tcb.TrapFrame, PreviousMode);
} else { } else {
/* Copy context into GetSetContext if not already done */
if(PreviousMode == KernelMode)
GetSetContext.Context = *ThreadContext;
/* Use an APC... Initialize the Event */ /* Use an APC... Initialize the Event */
KeInitializeEvent(&GetSetContext.Event, KeInitializeEvent(&GetSetContext.Event,
NotificationEvent, NotificationEvent,
@ -258,7 +269,7 @@ NtSetContextThread(IN HANDLE ThreadHandle,
/* Queue it as a Get APC */ /* Queue it as a Get APC */
if (!KeInsertQueueApc(&GetSetContext.Apc, if (!KeInsertQueueApc(&GetSetContext.Apc,
NULL, (PVOID)0,
NULL, NULL,
IO_NO_INCREMENT)) { IO_NO_INCREMENT)) {
@ -272,6 +283,8 @@ NtSetContextThread(IN HANDLE ThreadHandle,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
if (NT_SUCCESS(Status))
Status = GetSetContext.Status;
} }
} }