NtContinue fixed to return failure on invalid params ( not checking for access violations yet ), but not clobber EAX on success. This patch was made possiblel by the collaborative efforts of myself, kjk_hyperion, Art Yerkes, and Skywing.

svn path=/trunk/; revision=9964
This commit is contained in:
Royce Mitchell III 2004-07-02 00:47:57 +00:00
parent 8467d37d7d
commit 837baf14b4
4 changed files with 157 additions and 66 deletions

View file

@ -51,7 +51,10 @@ OBJECTS_RTL_I386 := \
rtl/i386/exception.o \ rtl/i386/exception.o \
rtl/i386/seh.o rtl/i386/seh.o
OBJECTS_PS_I386 := \
ps/i386/continue.o
RTL_EXCLUDE_FILTER := RTL_EXCLUDE_FILTER :=
OBJECTS_ARCH = $(OBJECTS_BOOT) $(OBJECTS_EX_I386) $(OBJECTS_KE_I386) $(OBJECTS_MM_I386) \ OBJECTS_ARCH = $(OBJECTS_BOOT) $(OBJECTS_EX_I386) $(OBJECTS_KE_I386) $(OBJECTS_MM_I386) \
$(OBJECTS_RTL_I386) $(OBJECTS_RTL_I386) $(OBJECTS_PS_I386)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: syscall.S,v 1.15 2004/07/01 01:52:37 royce Exp $ /* $Id: syscall.S,v 1.16 2004/07/02 00:47:57 royce Exp $
* *
* FILE: ntoskrnl/hal/x86/syscall.s * FILE: ntoskrnl/hal/x86/syscall.s
* PURPOSE: 2E trap handler * PURPOSE: 2E trap handler
@ -94,6 +94,7 @@ L3:
pushl $0 /* XXX: TempCS */ pushl $0 /* XXX: TempCS */
pushl $0 /* XXX: DebugPointer */ pushl $0 /* XXX: DebugPointer */
pushl $0 /* XXX: DebugArgMark */ pushl $0 /* XXX: DebugArgMark */
#ifdef DBG #ifdef DBG
/* Trick gdb 6 into backtracing over the system call */ /* Trick gdb 6 into backtracing over the system call */
movl 4(%ebp), %ebx movl 4(%ebp), %ebx
@ -260,6 +261,17 @@ KeReturnFromSystemCall:
movl %ebx, KTHREAD_TRAP_FRAME(%esi) movl %ebx, KTHREAD_TRAP_FRAME(%esi)
KiRosTrapReturn: KiRosTrapReturn:
#if 0
mov KTRAP_FRAME_RESERVED1(%ebp), %ax
cmp %ax, SSIDX_NTCONTINUE
jnz KeNoEpilogPrint
movl KTRAP_FRAME_ESP(%ebp), %ecx
movl KTRAP_FRAME_EBP(%ebp), %edx
call @KeRosPrintEspEbp@8
KeNoEpilogPrint:
#endif
/* Skip debug information and unsaved registers */ /* Skip debug information and unsaved registers */
addl $0x30, %esp addl $0x30, %esp
popl %gs popl %gs
@ -291,6 +303,11 @@ KiRosTrapReturn:
*/ */
.globl @KeRosTrapReturn@8 .globl @KeRosTrapReturn@8
@KeRosTrapReturn@8: @KeRosTrapReturn@8:
/* point %esp to the trap frame to restore */
movl %ecx, %esp
movl %esp, %ebp
/* Call the post system call hook and deliver any pending APCs */ /* Call the post system call hook and deliver any pending APCs */
pushl %esp pushl %esp
call _KiAfterSystemCallHook call _KiAfterSystemCallHook
@ -302,6 +319,4 @@ KiRosTrapReturn:
/* Restore the old trap frame pointer */ /* Restore the old trap frame pointer */
movl %edx, KTHREAD_TRAP_FRAME(%esi) movl %edx, KTHREAD_TRAP_FRAME(%esi)
/* point %esp to the trap frame to restore */
movl %ecx, %esp
jmp KiRosTrapReturn; jmp KiRosTrapReturn;

View file

@ -0,0 +1,99 @@
/* $Id: continue.c,v 1.1 2004/07/02 00:47:57 royce Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/i386/continue.c
* PURPOSE: i386 implementation of NtContinue()
* PROGRAMMER: Royce Mitchell III, kjk_hyperion
* REVISION HISTORY:
* 29/06/04: Created
*/
/* INCLUDES ****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ob.h>
#include <internal/ps.h>
#include <internal/ob.h>
#include <internal/pool.h>
#include <ntos/minmax.h>
#include <internal/ldr.h>
#include <rosrtl/string.h>
#define NDEBUG
#include <internal/debug.h>
#if 1
VOID
FASTCALL
KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
VOID STDCALL
KeRosDumpStackFrames ( PULONG Frame, ULONG FrameCount );
/*
* @implemented
*/
NTSTATUS STDCALL
NtContinue (
IN PCONTEXT Context,
IN BOOLEAN TestAlert)
{
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
DPRINT1("NtContinue: Context: Eip=0x%x, Esp=0x%x\n", Context->Eip, Context->Esp );
PULONG Frame = 0;
__asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
DbgPrint ( "NtContinue(): Ebp=%x, prev/TF=%x/%x\n", Frame, Frame[0], TrapFrame );
KeRosDumpStackFrames(NULL,5);
if ( Context == NULL )
{
DPRINT1("NtContinue called with NULL Context\n");
return STATUS_INVALID_PARAMETER;
}
if ( TrapFrame == NULL )
{
CPRINT("NtContinue called but TrapFrame was NULL\n");
KEBUGCHECK(0);
}
/*
* Copy the supplied context over the register information that was saved
* on entry to kernel mode, it will then be restored on exit
* FIXME: Validate the context
*/
KeContextToTrapFrame ( Context, TrapFrame );
KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
return STATUS_SUCCESS; /* this doesn't actually happen b/c KeRosTrapReturn() won't return */
}
#else
NTSTATUS STDCALL
NtContinue (
IN PCONTEXT Context,
IN BOOLEAN TestAlert)
{
PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
PULONG Frame = 0;
__asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
DbgPrint ( "NtContinue(): Ebp=%x, prev/TF=%x/%x\n", Frame, Frame[0], TrapFrame );
/*
* Copy the supplied context over the register information that was saved
* on entry to kernel mode, it will then be restored on exit
* FIXME: Validate the context
*/
if ( TrapFrame == NULL )
{
CPRINT("NtContinue called but TrapFrame was NULL\n");
KEBUGCHECK(0);
}
KeContextToTrapFrame ( Context, TrapFrame );
return(STATUS_SUCCESS);
}
#endif

View file

@ -1,21 +1,21 @@
/* $Id: thread.c,v 1.125 2004/07/01 02:40:23 hyperion Exp $ /* $Id: thread.c,v 1.126 2004/07/02 00:47:57 royce Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/thread.c * FILE: ntoskrnl/ps/thread.c
* PURPOSE: Thread managment * PURPOSE: Thread managment
* PROGRAMMER: David Welch (welch@mcmail.com) * PROGRAMMER: David Welch (welch@mcmail.com)
* REVISION HISTORY: * REVISION HISTORY:
* 23/06/98: Created * 23/06/98: Created
* 12/10/99: Phillip Susi: Thread priorities, and APC work * 12/10/99: Phillip Susi: Thread priorities, and APC work
*/ */
/* /*
* NOTE: * NOTE:
* *
* All of the routines that manipulate the thread queue synchronize on * All of the routines that manipulate the thread queue synchronize on
* a single spinlock * a single spinlock
* *
*/ */
/* INCLUDES ****************************************************************/ /* INCLUDES ****************************************************************/
@ -79,7 +79,7 @@ HANDLE STDCALL PsGetCurrentThreadId(VOID)
return(PsGetCurrentThread()->Cid.UniqueThread); return(PsGetCurrentThread()->Cid.UniqueThread);
} }
static VOID static VOID
PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread) PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
{ {
assert(THREAD_STATE_READY == Thread->Tcb.State); assert(THREAD_STATE_READY == Thread->Tcb.State);
@ -111,16 +111,16 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem)
PETHREAD current; PETHREAD current;
ULONG t; ULONG t;
ULONG i; ULONG i;
current_entry = PiThreadListHead.Flink; current_entry = PiThreadListHead.Flink;
t = 0; t = 0;
while (current_entry != &PiThreadListHead) while (current_entry != &PiThreadListHead)
{ {
PULONG Ebp; PULONG Ebp;
PULONG Esp; PULONG Esp;
current = CONTAINING_RECORD(current_entry, ETHREAD, current = CONTAINING_RECORD(current_entry, ETHREAD,
Tcb.ThreadListEntry); Tcb.ThreadListEntry);
t++; t++;
if (t > PiNrThreads) if (t > PiNrThreads)
@ -131,9 +131,9 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem)
if (IncludeSystem || current->ThreadsProcess->UniqueProcessId >= 6) if (IncludeSystem || current->ThreadsProcess->UniqueProcessId >= 6)
{ {
DbgPrint("current->Tcb.State %d PID.TID %d.%d Name %.8s Stack: \n", DbgPrint("current->Tcb.State %d PID.TID %d.%d Name %.8s Stack: \n",
current->Tcb.State, current->Tcb.State,
current->ThreadsProcess->UniqueProcessId, current->ThreadsProcess->UniqueProcessId,
current->Cid.UniqueThread, current->Cid.UniqueThread,
current->ThreadsProcess->ImageFileName); current->ThreadsProcess->ImageFileName);
if (current->Tcb.State == THREAD_STATE_READY || if (current->Tcb.State == THREAD_STATE_READY ||
current->Tcb.State == THREAD_STATE_SUSPENDED || current->Tcb.State == THREAD_STATE_SUSPENDED ||
@ -227,7 +227,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
DPRINT("PsDispatchThread() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(), DPRINT("PsDispatchThread() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(),
CurrentThread->Cid.UniqueThread, NewThreadStatus, CurrentThread->Tcb.State); CurrentThread->Cid.UniqueThread, NewThreadStatus, CurrentThread->Tcb.State);
CurrentThread->Tcb.State = (UCHAR)NewThreadStatus; CurrentThread->Tcb.State = (UCHAR)NewThreadStatus;
if (CurrentThread->Tcb.State == THREAD_STATE_READY) if (CurrentThread->Tcb.State == THREAD_STATE_READY)
{ {
@ -238,7 +238,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
{ {
PiNrThreadsAwaitingReaping++; PiNrThreadsAwaitingReaping++;
} }
Affinity = 1 << KeGetCurrentProcessorNumber(); Affinity = 1 << KeGetCurrentProcessorNumber();
for (CurrentPriority = HIGH_PRIORITY; for (CurrentPriority = HIGH_PRIORITY;
CurrentPriority >= LOW_PRIORITY; CurrentPriority >= LOW_PRIORITY;
@ -256,12 +256,12 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
PETHREAD OldThread; PETHREAD OldThread;
DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority); DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
Candidate->Tcb.State = THREAD_STATE_RUNNING; Candidate->Tcb.State = THREAD_STATE_RUNNING;
OldThread = CurrentThread; OldThread = CurrentThread;
CurrentThread = Candidate; CurrentThread = Candidate;
#if 0 #if 0
/* /*
* This code is moved to the end of KiArchContextSwitch. * This code is moved to the end of KiArchContextSwitch.
* It should be execute after the context switch. * It should be execute after the context switch.
@ -271,7 +271,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
{ {
PiWakeupReaperThread(); PiWakeupReaperThread();
} }
#endif #endif
KiArchContextSwitch(&CurrentThread->Tcb, &OldThread->Tcb); KiArchContextSwitch(&CurrentThread->Tcb, &OldThread->Tcb);
return; return;
} }
@ -284,12 +284,12 @@ VOID STDCALL
PsDispatchThread(ULONG NewThreadStatus) PsDispatchThread(ULONG NewThreadStatus)
{ {
KIRQL oldIrql; KIRQL oldIrql;
if (!DoneInitYet) if (!DoneInitYet)
{ {
return; return;
} }
KeAcquireSpinLock(&PiThreadListLock, &oldIrql); KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
/* /*
* Save wait IRQL * Save wait IRQL
@ -385,8 +385,8 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
VOID VOID
PsFreezeAllThreads(PEPROCESS Process) PsFreezeAllThreads(PEPROCESS Process)
/* /*
* Used by the debugging code to freeze all the process's threads * Used by the debugging code to freeze all the process's threads
* while the debugger is examining their state. * while the debugger is examining their state.
*/ */
{ {
KIRQL oldIrql; KIRQL oldIrql;
@ -398,7 +398,7 @@ PsFreezeAllThreads(PEPROCESS Process)
current_entry = Process->ThreadListHead.Flink; current_entry = Process->ThreadListHead.Flink;
while (current_entry != &Process->ThreadListHead) while (current_entry != &Process->ThreadListHead)
{ {
current = CONTAINING_RECORD(current_entry, ETHREAD, current = CONTAINING_RECORD(current_entry, ETHREAD,
Tcb.ProcessThreadListEntry); Tcb.ProcessThreadListEntry);
/* /*
@ -408,14 +408,14 @@ PsFreezeAllThreads(PEPROCESS Process)
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
} }
KeReleaseSpinLock(&PiThreadListLock, oldIrql); KeReleaseSpinLock(&PiThreadListLock, oldIrql);
} }
VOID VOID
PsApplicationProcessorInit(VOID) PsApplicationProcessorInit(VOID)
{ {
((PIKPCR) KeGetCurrentKPCR())->CurrentThread = ((PIKPCR) KeGetCurrentKPCR())->CurrentThread =
(PVOID)IdleThreads[KeGetCurrentProcessorNumber()]; (PVOID)IdleThreads[KeGetCurrentProcessorNumber()];
} }
@ -429,7 +429,7 @@ PsPrepareForApplicationProcessorInit(ULONG Id)
&IdleThread, &IdleThread,
&IdleThreadHandle, &IdleThreadHandle,
THREAD_ALL_ACCESS, THREAD_ALL_ACCESS,
NULL, NULL,
TRUE); TRUE);
IdleThread->Tcb.State = THREAD_STATE_RUNNING; IdleThread->Tcb.State = THREAD_STATE_RUNNING;
IdleThread->Tcb.FreezeCount = 0; IdleThread->Tcb.FreezeCount = 0;
@ -452,7 +452,7 @@ PsInitThreadManagment(VOID)
ULONG i; ULONG i;
HANDLE FirstThreadHandle; HANDLE FirstThreadHandle;
NTSTATUS Status; NTSTATUS Status;
KeInitializeSpinLock(&PiThreadListLock); KeInitializeSpinLock(&PiThreadListLock);
for (i=0; i < MAXIMUM_PRIORITY; i++) for (i=0; i < MAXIMUM_PRIORITY; i++)
{ {
@ -460,9 +460,9 @@ PsInitThreadManagment(VOID)
} }
InitializeListHead(&PiThreadListHead); InitializeListHead(&PiThreadListHead);
PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
PsThreadType->Tag = TAG('T', 'H', 'R', 'T'); PsThreadType->Tag = TAG('T', 'H', 'R', 'T');
PsThreadType->TotalObjects = 0; PsThreadType->TotalObjects = 0;
PsThreadType->TotalHandles = 0; PsThreadType->TotalHandles = 0;
@ -481,9 +481,9 @@ PsInitThreadManagment(VOID)
PsThreadType->OkayToClose = NULL; PsThreadType->OkayToClose = NULL;
PsThreadType->Create = NULL; PsThreadType->Create = NULL;
PsThreadType->DuplicationNotify = NULL; PsThreadType->DuplicationNotify = NULL;
RtlRosInitUnicodeStringFromLiteral(&PsThreadType->TypeName, L"Thread"); RtlRosInitUnicodeStringFromLiteral(&PsThreadType->TypeName, L"Thread");
ObpCreateTypeObject(PsThreadType); ObpCreateTypeObject(PsThreadType);
PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle, PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,
@ -492,9 +492,9 @@ PsInitThreadManagment(VOID)
FirstThread->Tcb.FreezeCount = 0; FirstThread->Tcb.FreezeCount = 0;
((PIKPCR) KeGetCurrentKPCR())->CurrentThread = (PVOID)FirstThread; ((PIKPCR) KeGetCurrentKPCR())->CurrentThread = (PVOID)FirstThread;
NtClose(FirstThreadHandle); NtClose(FirstThreadHandle);
DPRINT("FirstThread %x\n",FirstThread); DPRINT("FirstThread %x\n",FirstThread);
DoneInitYet = TRUE; DoneInitYet = TRUE;
/* /*
@ -559,12 +559,12 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority)
KIRQL oldIrql; KIRQL oldIrql;
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
ULONG Mask; ULONG Mask;
if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY) if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
{ {
KEBUGCHECK(0); KEBUGCHECK(0);
} }
KeAcquireSpinLock(&PiThreadListLock, &oldIrql); KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
OldPriority = Thread->Priority; OldPriority = Thread->Priority;
@ -635,7 +635,7 @@ NtAlertThread (IN HANDLE ThreadHandle)
PETHREAD Thread; PETHREAD Thread;
NTSTATUS Status; NTSTATUS Status;
NTSTATUS ThreadStatus; NTSTATUS ThreadStatus;
Status = ObReferenceObjectByHandle(ThreadHandle, Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME, THREAD_SUSPEND_RESUME,
PsThreadType, PsThreadType,
@ -646,10 +646,10 @@ NtAlertThread (IN HANDLE ThreadHandle)
{ {
return(Status); return(Status);
} }
ThreadStatus = STATUS_ALERTED; ThreadStatus = STATUS_ALERTED;
(VOID)PsUnblockThread(Thread, &ThreadStatus); (VOID)PsUnblockThread(Thread, &ThreadStatus);
ObDereferenceObject(Thread); ObDereferenceObject(Thread);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -721,32 +721,6 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
return(Status); return(Status);
} }
NTSTATUS STDCALL
NtContinue(IN PCONTEXT Context,
IN BOOLEAN TestAlert)
{
PKTRAP_FRAME TrapFrame;
/*
* Copy the supplied context over the register information that was saved
* on entry to kernel mode, it will then be restored on exit
* FIXME: Validate the context
*/
TrapFrame = KeGetCurrentThread()->TrapFrame;
if (TrapFrame == NULL)
{
CPRINT("NtContinue called but TrapFrame was NULL\n");
KEBUGCHECK(0);
}
KeContextToTrapFrame(Context, TrapFrame);
if(TestAlert)
KiTestAlert();
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NTSTATUS STDCALL
NtYieldExecution(VOID) NtYieldExecution(VOID)
{ {