From 837baf14b463d5ed67ae0c125b28649e6f8a5b40 Mon Sep 17 00:00:00 2001 From: Royce Mitchell III Date: Fri, 2 Jul 2004 00:47:57 +0000 Subject: [PATCH] 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 --- reactos/ntoskrnl/Makefile.i386 | 5 +- reactos/ntoskrnl/ke/i386/syscall.S | 21 +++++- reactos/ntoskrnl/ps/i386/continue.c | 99 +++++++++++++++++++++++++++++ reactos/ntoskrnl/ps/thread.c | 98 +++++++++++----------------- 4 files changed, 157 insertions(+), 66 deletions(-) create mode 100644 reactos/ntoskrnl/ps/i386/continue.c diff --git a/reactos/ntoskrnl/Makefile.i386 b/reactos/ntoskrnl/Makefile.i386 index 0d8870edf2f..76c401c421d 100644 --- a/reactos/ntoskrnl/Makefile.i386 +++ b/reactos/ntoskrnl/Makefile.i386 @@ -51,7 +51,10 @@ OBJECTS_RTL_I386 := \ rtl/i386/exception.o \ rtl/i386/seh.o +OBJECTS_PS_I386 := \ + ps/i386/continue.o + RTL_EXCLUDE_FILTER := OBJECTS_ARCH = $(OBJECTS_BOOT) $(OBJECTS_EX_I386) $(OBJECTS_KE_I386) $(OBJECTS_MM_I386) \ - $(OBJECTS_RTL_I386) + $(OBJECTS_RTL_I386) $(OBJECTS_PS_I386) diff --git a/reactos/ntoskrnl/ke/i386/syscall.S b/reactos/ntoskrnl/ke/i386/syscall.S index db7a885abe7..78de008b62b 100644 --- a/reactos/ntoskrnl/ke/i386/syscall.S +++ b/reactos/ntoskrnl/ke/i386/syscall.S @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * 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 * PURPOSE: 2E trap handler @@ -94,6 +94,7 @@ L3: pushl $0 /* XXX: TempCS */ pushl $0 /* XXX: DebugPointer */ pushl $0 /* XXX: DebugArgMark */ + #ifdef DBG /* Trick gdb 6 into backtracing over the system call */ movl 4(%ebp), %ebx @@ -260,6 +261,17 @@ KeReturnFromSystemCall: movl %ebx, KTHREAD_TRAP_FRAME(%esi) 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 */ addl $0x30, %esp popl %gs @@ -291,6 +303,11 @@ KiRosTrapReturn: */ .globl @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 */ pushl %esp call _KiAfterSystemCallHook @@ -302,6 +319,4 @@ KiRosTrapReturn: /* Restore the old trap frame pointer */ movl %edx, KTHREAD_TRAP_FRAME(%esi) - /* point %esp to the trap frame to restore */ - movl %ecx, %esp jmp KiRosTrapReturn; diff --git a/reactos/ntoskrnl/ps/i386/continue.c b/reactos/ntoskrnl/ps/i386/continue.c new file mode 100644 index 00000000000..00fdd8c5e14 --- /dev/null +++ b/reactos/ntoskrnl/ps/i386/continue.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +#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 diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index a8e33d9b6e8..e04ff087bd6 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -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 * PROJECT: ReactOS kernel * FILE: ntoskrnl/ps/thread.c * PURPOSE: Thread managment * PROGRAMMER: David Welch (welch@mcmail.com) - * REVISION HISTORY: + * REVISION HISTORY: * 23/06/98: Created * 12/10/99: Phillip Susi: Thread priorities, and APC work */ /* * NOTE: - * + * * All of the routines that manipulate the thread queue synchronize on * a single spinlock - * + * */ /* INCLUDES ****************************************************************/ @@ -79,7 +79,7 @@ HANDLE STDCALL PsGetCurrentThreadId(VOID) return(PsGetCurrentThread()->Cid.UniqueThread); } -static VOID +static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread) { assert(THREAD_STATE_READY == Thread->Tcb.State); @@ -111,16 +111,16 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem) PETHREAD current; ULONG t; ULONG i; - + current_entry = PiThreadListHead.Flink; t = 0; - + while (current_entry != &PiThreadListHead) { PULONG Ebp; PULONG Esp; - current = CONTAINING_RECORD(current_entry, ETHREAD, + current = CONTAINING_RECORD(current_entry, ETHREAD, Tcb.ThreadListEntry); t++; if (t > PiNrThreads) @@ -131,9 +131,9 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem) if (IncludeSystem || current->ThreadsProcess->UniqueProcessId >= 6) { DbgPrint("current->Tcb.State %d PID.TID %d.%d Name %.8s Stack: \n", - current->Tcb.State, + current->Tcb.State, current->ThreadsProcess->UniqueProcessId, - current->Cid.UniqueThread, + current->Cid.UniqueThread, current->ThreadsProcess->ImageFileName); if (current->Tcb.State == THREAD_STATE_READY || current->Tcb.State == THREAD_STATE_SUSPENDED || @@ -227,7 +227,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) DPRINT("PsDispatchThread() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(), CurrentThread->Cid.UniqueThread, NewThreadStatus, CurrentThread->Tcb.State); - + CurrentThread->Tcb.State = (UCHAR)NewThreadStatus; if (CurrentThread->Tcb.State == THREAD_STATE_READY) { @@ -238,7 +238,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) { PiNrThreadsAwaitingReaping++; } - + Affinity = 1 << KeGetCurrentProcessorNumber(); for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; @@ -256,12 +256,12 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) PETHREAD OldThread; DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority); - + Candidate->Tcb.State = THREAD_STATE_RUNNING; - + OldThread = CurrentThread; CurrentThread = Candidate; -#if 0 +#if 0 /* * This code is moved to the end of KiArchContextSwitch. * It should be execute after the context switch. @@ -271,7 +271,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) { PiWakeupReaperThread(); } -#endif +#endif KiArchContextSwitch(&CurrentThread->Tcb, &OldThread->Tcb); return; } @@ -284,12 +284,12 @@ VOID STDCALL PsDispatchThread(ULONG NewThreadStatus) { KIRQL oldIrql; - + if (!DoneInitYet) { return; } - + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); /* * Save wait IRQL @@ -385,8 +385,8 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, VOID PsFreezeAllThreads(PEPROCESS Process) /* - * Used by the debugging code to freeze all the process's threads - * while the debugger is examining their state. + * Used by the debugging code to freeze all the process's threads + * while the debugger is examining their state. */ { KIRQL oldIrql; @@ -398,7 +398,7 @@ PsFreezeAllThreads(PEPROCESS Process) current_entry = Process->ThreadListHead.Flink; while (current_entry != &Process->ThreadListHead) { - current = CONTAINING_RECORD(current_entry, ETHREAD, + current = CONTAINING_RECORD(current_entry, ETHREAD, Tcb.ProcessThreadListEntry); /* @@ -408,14 +408,14 @@ PsFreezeAllThreads(PEPROCESS Process) current_entry = current_entry->Flink; } - + KeReleaseSpinLock(&PiThreadListLock, oldIrql); } VOID PsApplicationProcessorInit(VOID) { - ((PIKPCR) KeGetCurrentKPCR())->CurrentThread = + ((PIKPCR) KeGetCurrentKPCR())->CurrentThread = (PVOID)IdleThreads[KeGetCurrentProcessorNumber()]; } @@ -429,7 +429,7 @@ PsPrepareForApplicationProcessorInit(ULONG Id) &IdleThread, &IdleThreadHandle, THREAD_ALL_ACCESS, - NULL, + NULL, TRUE); IdleThread->Tcb.State = THREAD_STATE_RUNNING; IdleThread->Tcb.FreezeCount = 0; @@ -452,7 +452,7 @@ PsInitThreadManagment(VOID) ULONG i; HANDLE FirstThreadHandle; NTSTATUS Status; - + KeInitializeSpinLock(&PiThreadListLock); for (i=0; i < MAXIMUM_PRIORITY; i++) { @@ -460,9 +460,9 @@ PsInitThreadManagment(VOID) } InitializeListHead(&PiThreadListHead); - + PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE)); - + PsThreadType->Tag = TAG('T', 'H', 'R', 'T'); PsThreadType->TotalObjects = 0; PsThreadType->TotalHandles = 0; @@ -481,9 +481,9 @@ PsInitThreadManagment(VOID) PsThreadType->OkayToClose = NULL; PsThreadType->Create = NULL; PsThreadType->DuplicationNotify = NULL; - + RtlRosInitUnicodeStringFromLiteral(&PsThreadType->TypeName, L"Thread"); - + ObpCreateTypeObject(PsThreadType); PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle, @@ -492,9 +492,9 @@ PsInitThreadManagment(VOID) FirstThread->Tcb.FreezeCount = 0; ((PIKPCR) KeGetCurrentKPCR())->CurrentThread = (PVOID)FirstThread; NtClose(FirstThreadHandle); - + DPRINT("FirstThread %x\n",FirstThread); - + DoneInitYet = TRUE; /* @@ -559,12 +559,12 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority) KIRQL oldIrql; PKTHREAD CurrentThread; ULONG Mask; - + if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY) { KEBUGCHECK(0); } - + KeAcquireSpinLock(&PiThreadListLock, &oldIrql); OldPriority = Thread->Priority; @@ -635,7 +635,7 @@ NtAlertThread (IN HANDLE ThreadHandle) PETHREAD Thread; NTSTATUS Status; NTSTATUS ThreadStatus; - + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_SUSPEND_RESUME, PsThreadType, @@ -646,10 +646,10 @@ NtAlertThread (IN HANDLE ThreadHandle) { return(Status); } - + ThreadStatus = STATUS_ALERTED; (VOID)PsUnblockThread(Thread, &ThreadStatus); - + ObDereferenceObject(Thread); return(STATUS_SUCCESS); } @@ -721,32 +721,6 @@ NtOpenThread(OUT PHANDLE ThreadHandle, 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 NtYieldExecution(VOID) { -- 2.17.1