mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Fixes for APC handling
Fixes for exceptions Remove KeAddTimeoutThread Beginnings of debug handling Fixes for contiguous memory allocation Cancel the thread timer before termination svn path=/trunk/; revision=1709
This commit is contained in:
parent
01846dd237
commit
d60628a01b
27 changed files with 951 additions and 715 deletions
|
@ -1,5 +1,5 @@
|
|||
file ntoskrnl/ntoskrnl.nostrip.exe
|
||||
#add-symbol-file lib/ntdll/ntdll.dll 0x77f61000
|
||||
#add-symbol-file apps/apc/apc.exe 0x401000
|
||||
#add-symbol-file apps/exp/exp.exe 0x401000
|
||||
#add-symbol-file subsys/csrss/csrss.exe 0x401000
|
||||
break exp.c:154
|
||||
break exp.c:254
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2001-03-17 David Welch <welch@cwcom.net>
|
||||
|
||||
* ntoskrnl/ke/catch.c (KiDispatchException): Implementation of
|
||||
exception handling, user-mode only.
|
||||
|
||||
2001-03-16 David Welch <welch@cwcom.net>
|
||||
|
||||
* include/ddk/zw.h: Corrected declarations of NtCreateProfile,
|
||||
|
|
|
@ -56,7 +56,7 @@ NET_DEVICE_DRIVERS = ne2000
|
|||
SYS_APPS = shell winlogon services
|
||||
|
||||
APPS = args hello test cat bench apc shm lpc thread event file gditest \
|
||||
pteb consume dump_shared_data vmtest regtest
|
||||
pteb consume dump_shared_data vmtest regtest exp
|
||||
|
||||
# objdir
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* $Id: zw.h,v 1.42 2001/03/16 18:11:20 dwelch Exp $
|
||||
/* $Id: zw.h,v 1.43 2001/03/18 19:35:11 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -3620,7 +3620,7 @@ STDCALL
|
|||
NtRaiseException(
|
||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOL IsDebugger OPTIONAL
|
||||
IN BOOLEAN SearchFrames
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -3628,7 +3628,7 @@ STDCALL
|
|||
ZwRaiseException(
|
||||
IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOL IsDebugger OPTIONAL
|
||||
IN BOOLEAN SearchFrames
|
||||
);
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __INCLUDE_NAPI_DBG_H
|
||||
#define __INCLUDE_NAPI_DBG_H
|
||||
|
||||
#include <napi/lpc.h>
|
||||
|
||||
#define DBG_EVENT_EXCEPTION (1)
|
||||
#define DBG_EVENT_CREATE_THREAD (2)
|
||||
#define DBG_EVENT_CREATE_PROCESS (3)
|
||||
|
@ -19,7 +21,7 @@ typedef struct _LPC_DBG_MESSAGE
|
|||
struct
|
||||
{
|
||||
EXCEPTION_RECORD ExceptionRecord;
|
||||
ULONG FirstChange;
|
||||
ULONG FirstChance;
|
||||
} Exception;
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -42,4 +42,5 @@ cp apps/vmtest/vmtest.exe $1/reactos/bin
|
|||
cp apps/uitest/uitest.exe $1/reactos/bin/
|
||||
cp apps/gditest/gditest.exe $1/reactos/bin/
|
||||
cp apps/ptest/ptest.exe $1/reactos/bin/
|
||||
cp apps/timer/timer.exe $1/reactos/bin/
|
||||
cp apps/timer/timer.exe $1/reactos/bin/
|
||||
cp apps/exp/exp.exe $1/reactos/bin
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: exception.c,v 1.4 2001/03/17 11:11:11 dwelch Exp $
|
||||
/* $Id: exception.c,v 1.5 2001/03/18 19:35:12 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -24,7 +24,7 @@ ULONG
|
|||
RtlDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||
PCONTEXT Context)
|
||||
{
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile,v 1.24 2001/03/16 23:04:59 dwelch Exp $
|
||||
# $Id: Makefile,v 1.25 2001/03/18 19:35:12 dwelch Exp $
|
||||
#
|
||||
# ReactOS Operating System
|
||||
#
|
||||
|
@ -238,7 +238,8 @@ OBJECTS_CM = \
|
|||
OBJECTS_DBG = \
|
||||
dbg/dbgctrl.o \
|
||||
dbg/errinfo.o \
|
||||
dbg/print.o
|
||||
dbg/print.o \
|
||||
dbg/user.o
|
||||
|
||||
# Loader
|
||||
OBJECTS_LDR = \
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
#ifndef __INCLUDE_INTERNAL_DBG_H
|
||||
#define __INCLUDE_INTERNAL_DBG_H
|
||||
|
||||
#include <napi/lpc.h>
|
||||
#include <napi/dbg.h>
|
||||
#include <internal/port.h>
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LpcSendDebugMessagePort(PEPORT Port,
|
||||
PLPC_DBG_MESSAGE Message);
|
||||
PLPC_DBG_MESSAGE Message,
|
||||
PLPC_DBG_MESSAGE Reply);
|
||||
VOID
|
||||
DbgkCreateThread(PVOID StartAddress);
|
||||
ULONG
|
||||
DbgkForwardException(EXCEPTION_RECORD Er, ULONG FirstChance);
|
||||
|
||||
#endif /* __INCLUDE_INTERNAL_DBG_H */
|
||||
|
|
|
@ -91,8 +91,6 @@ VOID KeExpireTimers( PKDPC Apc,
|
|||
PVOID Arg1,
|
||||
PVOID Arg2,
|
||||
PVOID Arg3 );
|
||||
NTSTATUS KeAddThreadTimeout(struct _KTHREAD* Thread,
|
||||
PLARGE_INTEGER Interval);
|
||||
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
|
||||
ULONG Size, ULONG SignalState);
|
||||
|
||||
|
@ -129,5 +127,12 @@ VOID
|
|||
NtEarlyInitVdm(VOID);
|
||||
VOID
|
||||
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Eip);
|
||||
|
||||
VOID
|
||||
KiDispatchException(PEXCEPTION_RECORD Er,
|
||||
PCONTEXT Context,
|
||||
PKTRAP_FRAME Tf,
|
||||
KPROCESSOR_MODE PreviousMode,
|
||||
BOOLEAN SearchFrames);
|
||||
VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
|
||||
PCONTEXT Context);
|
||||
#endif
|
||||
|
|
|
@ -95,7 +95,7 @@ KiDeliverNormalApc(VOID)
|
|||
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
||||
if (Apc->NormalRoutine != NULL)
|
||||
{
|
||||
(void)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
|
||||
(VOID)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||
Thread->Tcb.ApcState.KernelApcPending--;
|
||||
|
||||
|
@ -243,35 +243,39 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
|
|||
*/
|
||||
{
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
PLIST_ENTRY current;
|
||||
PLIST_ENTRY current_entry;
|
||||
PKAPC Apc;
|
||||
KIRQL oldlvl;
|
||||
|
||||
DPRINT("KiDeliverApc()\n");
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
while(!IsListEmpty(&(Thread->Tcb.ApcState.ApcListHead[0])))
|
||||
{
|
||||
current = Thread->Tcb.ApcState.ApcListHead[0].Blink;
|
||||
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
||||
if (Apc->NormalRoutine == NULL)
|
||||
{
|
||||
(void)RemoveTailList(&Thread->Tcb.ApcState.ApcListHead[0]);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||
Thread->Tcb.ApcState.KernelApcPending--;
|
||||
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
|
||||
Apc = CONTAINING_RECORD(current, KAPC, ApcListEntry);
|
||||
Apc->KernelRoutine(Apc,
|
||||
&Apc->NormalRoutine,
|
||||
&Apc->NormalContext,
|
||||
&Apc->SystemArgument1,
|
||||
&Apc->SystemArgument2);
|
||||
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||
}
|
||||
}
|
||||
current_entry = Thread->Tcb.ApcState.ApcListHead[0].Flink;
|
||||
while(current_entry != &Thread->Tcb.ApcState.ApcListHead[0])
|
||||
{
|
||||
Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
|
||||
if (Apc->NormalRoutine == NULL)
|
||||
{
|
||||
current_entry = current_entry->Flink;
|
||||
RemoveEntryList(&Apc->ApcListEntry);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress++;
|
||||
Thread->Tcb.ApcState.KernelApcPending--;
|
||||
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
|
||||
Apc->KernelRoutine(Apc,
|
||||
&Apc->NormalRoutine,
|
||||
&Apc->NormalContext,
|
||||
&Apc->SystemArgument1,
|
||||
&Apc->SystemArgument2);
|
||||
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
}
|
||||
|
||||
|
@ -320,13 +324,28 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
TargetThread->ApcState.UserApcPending++;
|
||||
}
|
||||
Apc->Inserted = TRUE;
|
||||
|
||||
|
||||
/*
|
||||
* If this is a kernel-mode APC and it is waiting at PASSIVE_LEVEL and
|
||||
* not inside a critical section then wake it up. Otherwise it will
|
||||
* execute the APC as soon as it returns to PASSIVE_LEVEL.
|
||||
* FIXME: Check for sending an APC to the current thread.
|
||||
* FIXME: If the thread is running on another processor then send an
|
||||
* IPI.
|
||||
* FIXME: Check if the thread is terminating.
|
||||
*/
|
||||
if (Apc->ApcMode == KernelMode && TargetThread->KernelApcDisable >= 1 &&
|
||||
TargetThread->WaitIrql < APC_LEVEL && Apc->NormalRoutine == NULL)
|
||||
{
|
||||
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
|
||||
STATUS_KERNEL_APC);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a 'funny' user-mode APC then mark the thread as
|
||||
* alerted so it will execute the APC on exit from kernel mode. If it
|
||||
* is waiting alertably then wake it up so it can return to user mode.
|
||||
*/
|
||||
if (Apc->ApcMode == KernelMode && Apc->NormalRoutine != NULL)
|
||||
{
|
||||
TargetThread->Alerted[1] = 1;
|
||||
|
@ -341,12 +360,9 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
}
|
||||
|
||||
/*
|
||||
* For user mode APCs if the thread is already waiting then we wait it
|
||||
* up and increment UserApcPending so it will deliver the APC on exit
|
||||
* from kernel mode. If the thread isn't waiting then before it
|
||||
* enters an alertable, user mode wait then it will check for
|
||||
* user mode APCs and if there are any pending then return immediately
|
||||
* and they will be delivered on exit from kernel mode
|
||||
* If the thread is waiting alertably then wake it up and it will
|
||||
* return to to user-mode executing the APC in the process. Otherwise the
|
||||
* thread will execute the APC next time it enters an alertable wait.
|
||||
*/
|
||||
if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE &&
|
||||
TargetThread->WaitMode == UserMode)
|
||||
|
@ -429,6 +445,7 @@ KeInitializeApc (PKAPC Apc,
|
|||
"KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
|
||||
"Context %x)\n",Apc,Thread,StateIndex,KernelRoutine,RundownRoutine,
|
||||
NormalRoutine,Mode,Context);
|
||||
|
||||
memset(Apc, 0, sizeof(KAPC));
|
||||
Apc->Thread = Thread;
|
||||
Apc->ApcListEntry.Flink = NULL;
|
||||
|
|
|
@ -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: catch.c,v 1.12 2001/03/17 11:11:11 dwelch Exp $
|
||||
/* $Id: catch.c,v 1.13 2001/03/18 19:35:12 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/catch.c
|
||||
|
@ -29,6 +29,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <internal/ke.h>
|
||||
#include <internal/ldr.h>
|
||||
#include <internal/ps.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
@ -36,26 +37,31 @@
|
|||
|
||||
VOID
|
||||
KiDispatchException(PEXCEPTION_RECORD Er,
|
||||
ULONG Reserved,
|
||||
PCONTEXT Context,
|
||||
PKTRAP_FRAME Tf,
|
||||
KPROCESSOR_MODE PreviousMode,
|
||||
BOOLEAN SearchFrames)
|
||||
{
|
||||
CONTEXT Context;
|
||||
CONTEXT TContext;
|
||||
|
||||
Context.ContextFlags = CONTEXT_FULL;
|
||||
if (PreviousMode == UserMode)
|
||||
{
|
||||
Context.ContextFlags = Context.ContextFlags | CONTEXT_DEBUGGER;
|
||||
}
|
||||
|
||||
/* PCR->KeExceptionDispatchCount++; */
|
||||
|
||||
// KeContextFromKframes(Tf, Reserved, &Context);
|
||||
if (Context != NULL)
|
||||
{
|
||||
TContext.ContextFlags = CONTEXT_FULL;
|
||||
if (PreviousMode == UserMode)
|
||||
{
|
||||
TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
|
||||
}
|
||||
|
||||
KeTrapFrameToContext(Tf, &TContext);
|
||||
|
||||
Context = &TContext;
|
||||
}
|
||||
|
||||
if (Er->ExceptionCode == STATUS_BREAKPOINT)
|
||||
{
|
||||
Context.Eip--;
|
||||
Context->Eip--;
|
||||
}
|
||||
|
||||
if (PreviousMode == UserMode)
|
||||
|
@ -86,7 +92,7 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
|||
/* Pointer to CONTEXT structure */
|
||||
Stack[2] = (ULONG)&Stack[CDest];
|
||||
memcpy(&Stack[3], Er, sizeof(EXCEPTION_RECORD));
|
||||
memcpy(&Stack[CDest], &Context, sizeof(CONTEXT));
|
||||
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||
|
||||
Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
|
||||
return;
|
||||
|
@ -94,13 +100,18 @@ KiDispatchException(PEXCEPTION_RECORD Er,
|
|||
|
||||
/* FIXME: Forward the exception to the debugger */
|
||||
|
||||
/* FIXME: Forward the exception to the debugger */
|
||||
/* FIXME: Forward the exception to the process exception port */
|
||||
|
||||
/* Terminate the offending thread */
|
||||
ZwTerminateThread(NtCurrentThread(), Er->ExceptionCode);
|
||||
|
||||
/* If that fails then bugcheck */
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
@ -116,7 +127,7 @@ ExRaiseDatatypeMisalignment (VOID)
|
|||
}
|
||||
|
||||
VOID STDCALL
|
||||
ExRaiseStatus (IN NTSTATUS Status)
|
||||
ExRaiseStatus (IN NTSTATUS Status)
|
||||
{
|
||||
DbgPrint("ExRaiseStatus(%x)\n",Status);
|
||||
for(;;);
|
||||
|
@ -125,11 +136,16 @@ ExRaiseStatus (IN NTSTATUS Status)
|
|||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOL IsDebugger OPTIONAL)
|
||||
NtRaiseException (IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
IN PCONTEXT Context,
|
||||
IN BOOLEAN SearchFrames)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
KiDispatchException(ExceptionRecord,
|
||||
Context,
|
||||
PsGetCurrentThread()->Tcb.TrapFrame,
|
||||
ExGetPreviousMode(),
|
||||
SearchFrames);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,24 +48,24 @@
|
|||
extern void interrupt_handler2e(void);
|
||||
extern void interrupt_handler2d(void);
|
||||
|
||||
extern void exception_handler0(void);
|
||||
extern void exception_handler1(void);
|
||||
extern void exception_handler2(void);
|
||||
extern void exception_handler3(void);
|
||||
extern void exception_handler4(void);
|
||||
extern void exception_handler5(void);
|
||||
extern void exception_handler6(void);
|
||||
extern void exception_handler7(void);
|
||||
extern void exception_handler8(void);
|
||||
extern void exception_handler9(void);
|
||||
extern void exception_handler10(void);
|
||||
extern void exception_handler11(void);
|
||||
extern void exception_handler12(void);
|
||||
extern void exception_handler13(void);
|
||||
extern void exception_handler14(void);
|
||||
extern void exception_handler15(void);
|
||||
extern void exception_handler16(void);
|
||||
extern void exception_handler_unknown(void);
|
||||
extern VOID KiTrap0(VOID);
|
||||
extern VOID KiTrap1(VOID);
|
||||
extern VOID KiTrap2(VOID);
|
||||
extern VOID KiTrap3(VOID);
|
||||
extern VOID KiTrap4(VOID);
|
||||
extern VOID KiTrap5(VOID);
|
||||
extern VOID KiTrap6(VOID);
|
||||
extern VOID KiTrap7(VOID);
|
||||
extern VOID KiTrap8(VOID);
|
||||
extern VOID KiTrap9(VOID);
|
||||
extern VOID KiTrap10(VOID);
|
||||
extern VOID KiTrap11(VOID);
|
||||
extern VOID KiTrap12(VOID);
|
||||
extern VOID KiTrap13(VOID);
|
||||
extern VOID KiTrap14(VOID);
|
||||
extern VOID KiTrap15(VOID);
|
||||
extern VOID KiTrap16(VOID);
|
||||
extern VOID KiTrapUnknown(VOID);
|
||||
|
||||
extern ULONG init_stack;
|
||||
extern ULONG init_stack_top;
|
||||
|
@ -105,7 +105,59 @@ print_address(PVOID address)
|
|||
}
|
||||
|
||||
ULONG
|
||||
exception_handler(struct trap_frame* tf)
|
||||
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
|
||||
{
|
||||
EXCEPTION_RECORD Er;
|
||||
|
||||
if (ExceptionNr == 0)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
|
||||
}
|
||||
else if (ExceptionNr == 1)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_SINGLE_STEP;
|
||||
}
|
||||
else if (ExceptionNr == 3)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_BREAKPOINT;
|
||||
}
|
||||
else if (ExceptionNr == 4)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
|
||||
}
|
||||
else if (ExceptionNr == 5)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED;
|
||||
}
|
||||
else if (ExceptionNr == 6)
|
||||
{
|
||||
Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
|
||||
}
|
||||
Er.ExceptionFlags = 0;
|
||||
Er.ExceptionRecord = NULL;
|
||||
Er.ExceptionAddress = (PVOID)Tf->Eip;
|
||||
if (ExceptionNr == 14)
|
||||
{
|
||||
Er.NumberParameters = 2;
|
||||
Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1;
|
||||
Er.ExceptionInformation[1] = (ULONG)Cr2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Er.NumberParameters = 0;
|
||||
}
|
||||
|
||||
|
||||
KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
|
||||
return(0);
|
||||
}
|
||||
|
||||
ULONG
|
||||
KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
|
||||
/*
|
||||
* FUNCTION: Called by the lowlevel execption handlers to print an amusing
|
||||
* message and halt the computer
|
||||
|
@ -118,6 +170,7 @@ exception_handler(struct trap_frame* tf)
|
|||
// unsigned int j, sym;
|
||||
PULONG stack;
|
||||
NTSTATUS Status;
|
||||
ULONG Esp0;
|
||||
static char *TypeStrings[] =
|
||||
{
|
||||
"Divide Error",
|
||||
|
@ -139,65 +192,70 @@ exception_handler(struct trap_frame* tf)
|
|||
"Alignment Check",
|
||||
"Machine Check"
|
||||
};
|
||||
|
||||
/* Use the address of the trap frame as approximation to the ring0 esp */
|
||||
Esp0 = (ULONG)Tf;
|
||||
|
||||
__asm__("movl %%cr2,%0\n\t"
|
||||
: "=d" (cr2));
|
||||
/* Get CR2 */
|
||||
__asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
|
||||
|
||||
/*
|
||||
* If this was a V86 mode exception then handle it specially
|
||||
*/
|
||||
#if 0
|
||||
if (tf->eflags & (1 << 17))
|
||||
{
|
||||
return(KeV86Exception(tf, cr2));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for stack underflow
|
||||
*/
|
||||
if (PsGetCurrentThread() != NULL &&
|
||||
tf->esp < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
|
||||
Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
|
||||
{
|
||||
DbgPrint("Stack underflow (tf->esp %x Limit %x)\n",
|
||||
tf->esp, (ULONG)PsGetCurrentThread()->Tcb.StackLimit);
|
||||
tf->type = 12;
|
||||
Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit);
|
||||
ExceptionNr = 12;
|
||||
}
|
||||
|
||||
if (tf->type == 14)
|
||||
if (ExceptionNr == 14)
|
||||
{
|
||||
__asm__("sti\n\t");
|
||||
Status = MmPageFault(tf->cs&0xffff,
|
||||
&tf->eip,
|
||||
&tf->eax,
|
||||
Status = MmPageFault(Tf->Cs&0xffff,
|
||||
&Tf->Eip,
|
||||
&Tf->Eax,
|
||||
cr2,
|
||||
tf->error_code);
|
||||
Tf->ErrorCode);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Something better
|
||||
*/
|
||||
if (tf->type==1)
|
||||
|
||||
if ((Tf->Cs & 0xFFFF) == USER_CS)
|
||||
{
|
||||
DbgPrint("Trap at CS:EIP %x:%x\n",tf->cs&0xffff,tf->eip);
|
||||
return(0);
|
||||
return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out the CPU registers
|
||||
*/
|
||||
if (tf->type < 19)
|
||||
if (ExceptionNr < 19)
|
||||
{
|
||||
DbgPrint("%s Exception: %d(%x)\n",TypeStrings[tf->type],tf->type,
|
||||
tf->error_code&0xffff);
|
||||
DbgPrint("%s Exception: %d(%x)\n",TypeStrings[ExceptionNr],
|
||||
ExceptionNr, Tf->ErrorCode&0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("Exception: %d(%x)\n",tf->type,tf->error_code&0xffff);
|
||||
DbgPrint("Exception: %d(%x)\n", ExceptionNr, Tf->ErrorCode&0xffff);
|
||||
}
|
||||
DbgPrint("CS:EIP %x:%x ",tf->cs&0xffff,tf->eip);
|
||||
print_address((PVOID)tf->eip);
|
||||
DbgPrint("CS:EIP %x:%x ", Tf->Cs&0xffff, Tf->Eip);
|
||||
print_address((PVOID)Tf->Eip);
|
||||
DbgPrint("\n");
|
||||
__asm__("movl %%cr3,%0\n\t"
|
||||
: "=d" (cr3));
|
||||
DbgPrint("cr2 %x cr3 %x ",cr2,cr3);
|
||||
// for(;;);
|
||||
__asm__("movl %%cr3,%0\n\t" : "=d" (cr3));
|
||||
DbgPrint("cr2 %x cr3 %x ", cr2, cr3);
|
||||
DbgPrint("Proc: %x ",PsGetCurrentProcess());
|
||||
if (PsGetCurrentProcess() != NULL)
|
||||
{
|
||||
|
@ -211,14 +269,14 @@ exception_handler(struct trap_frame* tf)
|
|||
PsGetCurrentThread()->Cid.UniqueThread);
|
||||
}
|
||||
DbgPrint("\n");
|
||||
DbgPrint("DS %x ES %x FS %x GS %x\n", tf->ds&0xffff, tf->es&0xffff,
|
||||
tf->fs&0xffff, tf->gs&0xfff);
|
||||
DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", tf->eax, tf->ebx, tf->ecx);
|
||||
DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", tf->edx, tf->ebp, tf->esi);
|
||||
DbgPrint("EDI: %.8x EFLAGS: %.8x ", tf->edi, tf->eflags);
|
||||
if ((tf->cs&0xffff) == KERNEL_CS)
|
||||
DbgPrint("DS %x ES %x FS %x GS %x\n", Tf->Ds&0xffff, Tf->Es&0xffff,
|
||||
Tf->Fs&0xffff, Tf->Gs&0xfff);
|
||||
DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", Tf->Eax, Tf->Ebx, Tf->Ecx);
|
||||
DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", Tf->Edx, Tf->Ebp, Tf->Esi);
|
||||
DbgPrint("EDI: %.8x EFLAGS: %.8x ", Tf->Edi, Tf->Eflags);
|
||||
if ((Tf->Cs&0xffff) == KERNEL_CS)
|
||||
{
|
||||
DbgPrint("kESP %.8x ", tf->esp);
|
||||
DbgPrint("kESP %.8x ", Esp0);
|
||||
if (PsGetCurrentThread() != NULL)
|
||||
{
|
||||
DbgPrint("kernel stack base %x\n",
|
||||
|
@ -228,12 +286,12 @@ exception_handler(struct trap_frame* tf)
|
|||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("kernel ESP %.8x\n", tf->esp);
|
||||
DbgPrint("User ESP %.8x\n", Tf->Esp);
|
||||
}
|
||||
if ((tf->cs & 0xffff) == KERNEL_CS)
|
||||
if ((Tf->Cs & 0xffff) == KERNEL_CS)
|
||||
{
|
||||
DbgPrint("ESP %x\n", tf->esp);
|
||||
stack = (PULONG) (tf->esp + 24);
|
||||
DbgPrint("ESP %x\n", Esp0);
|
||||
stack = (PULONG) (Esp0 + 24);
|
||||
stack = (PULONG)(((ULONG)stack) & (~0x3));
|
||||
|
||||
DbgPrint("stack<%p>: ", stack);
|
||||
|
@ -261,8 +319,8 @@ exception_handler(struct trap_frame* tf)
|
|||
else
|
||||
{
|
||||
#if 1
|
||||
DbgPrint("SS:ESP %x:%x\n", tf->ss0, tf->esp0);
|
||||
stack=(PULONG)(tf->esp0);
|
||||
DbgPrint("SS:ESP %x:%x\n", Tf->Ss, Tf->Esp);
|
||||
stack=(PULONG)(Tf->Esp);
|
||||
|
||||
DbgPrint("Stack:\n");
|
||||
for (i=0; i<64; i++)
|
||||
|
@ -277,11 +335,11 @@ exception_handler(struct trap_frame* tf)
|
|||
}
|
||||
}
|
||||
|
||||
if (MmIsPagePresent(NULL, (PVOID)tf->eip))
|
||||
if (MmIsPagePresent(NULL, (PVOID)Tf->Eip))
|
||||
{
|
||||
unsigned char instrs[512];
|
||||
|
||||
memcpy(instrs, (PVOID)tf->eip, 512);
|
||||
memcpy(instrs, (PVOID)Tf->Eip, 512);
|
||||
|
||||
DbgPrint("Instrs: ");
|
||||
|
||||
|
@ -294,13 +352,12 @@ exception_handler(struct trap_frame* tf)
|
|||
}
|
||||
|
||||
DbgPrint("\n");
|
||||
if ((tf->cs&0xffff) == USER_CS &&
|
||||
tf->eip < KERNEL_BASE)
|
||||
if ((Tf->Cs&0xffff) == USER_CS &&
|
||||
Tf->Eip < KERNEL_BASE)
|
||||
{
|
||||
DbgPrint("Killing current task\n");
|
||||
// for(;;);
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
if ((tf->cs&0xffff) == USER_CS)
|
||||
if ((Tf->Cs&0xffff) == USER_CS)
|
||||
{
|
||||
ZwTerminateProcess(NtCurrentProcess(),
|
||||
STATUS_NONCONTINUABLE_EXCEPTION);
|
||||
|
@ -366,27 +423,27 @@ void KeInitExceptions(void)
|
|||
|
||||
DPRINT("KeInitExceptions()\n",0);
|
||||
|
||||
set_interrupt_gate(0,(int)exception_handler0);
|
||||
set_interrupt_gate(1,(int)exception_handler1);
|
||||
set_interrupt_gate(2,(int)exception_handler2);
|
||||
set_interrupt_gate(3,(int)exception_handler3);
|
||||
set_interrupt_gate(4,(int)exception_handler4);
|
||||
set_interrupt_gate(5,(int)exception_handler5);
|
||||
set_interrupt_gate(6,(int)exception_handler6);
|
||||
set_interrupt_gate(7,(int)exception_handler7);
|
||||
set_interrupt_gate(8,(int)exception_handler8);
|
||||
set_interrupt_gate(9,(int)exception_handler9);
|
||||
set_interrupt_gate(10,(int)exception_handler10);
|
||||
set_interrupt_gate(11,(int)exception_handler11);
|
||||
set_interrupt_gate(12,(int)exception_handler12);
|
||||
set_interrupt_gate(13,(int)exception_handler13);
|
||||
set_interrupt_gate(14,(int)exception_handler14);
|
||||
set_interrupt_gate(15,(int)exception_handler15);
|
||||
set_interrupt_gate(16,(int)exception_handler16);
|
||||
set_interrupt_gate(0, (ULONG)KiTrap0);
|
||||
set_interrupt_gate(1, (ULONG)KiTrap1);
|
||||
set_interrupt_gate(2, (ULONG)KiTrap2);
|
||||
set_interrupt_gate(3, (ULONG)KiTrap3);
|
||||
set_interrupt_gate(4, (ULONG)KiTrap4);
|
||||
set_interrupt_gate(5, (ULONG)KiTrap5);
|
||||
set_interrupt_gate(6, (ULONG)KiTrap6);
|
||||
set_interrupt_gate(7, (ULONG)KiTrap7);
|
||||
set_interrupt_gate(8, (ULONG)KiTrap8);
|
||||
set_interrupt_gate(9, (ULONG)KiTrap9);
|
||||
set_interrupt_gate(10, (ULONG)KiTrap10);
|
||||
set_interrupt_gate(11, (ULONG)KiTrap11);
|
||||
set_interrupt_gate(12, (ULONG)KiTrap12);
|
||||
set_interrupt_gate(13, (ULONG)KiTrap13);
|
||||
set_interrupt_gate(14, (ULONG)KiTrap14);
|
||||
set_interrupt_gate(15, (ULONG)KiTrap15);
|
||||
set_interrupt_gate(16, (ULONG)KiTrap16);
|
||||
|
||||
for (i=17;i<256;i++)
|
||||
{
|
||||
set_interrupt_gate(i,(int)exception_handler_unknown);
|
||||
set_interrupt_gate(i,(int)KiTrapUnknown);
|
||||
}
|
||||
|
||||
set_system_call_gate(0x2d,(int)interrupt_handler2d);
|
||||
|
|
|
@ -706,6 +706,10 @@ lowmem_pagetable:
|
|||
.long 0x3f0007,0x3f1007,0x3f2007,0x3f3007,0x3f4007,0x3f5007,0x3f6007,0x3f7007
|
||||
.long 0x3f8007,0x3f9007,0x3fa007,0x3fb007,0x3fc007,0x3fd007,0x3fe007,0x3ff007
|
||||
|
||||
_init_stack:
|
||||
.fill 3*4096,1,0
|
||||
_init_stack_top:
|
||||
|
||||
_gdt_descr:
|
||||
.word (10*8)-1
|
||||
.long _KiGdt
|
||||
|
@ -713,8 +717,4 @@ _gdt_descr:
|
|||
_idt_descr:
|
||||
.word (256*8)-1
|
||||
.long _KiIdt
|
||||
|
||||
_init_stack:
|
||||
.fill 4096,1,0
|
||||
_init_stack_top:
|
||||
|
||||
|
|
|
@ -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.1 2000/12/10 23:42:00 dwelch Exp $
|
||||
/* $Id: syscall.S,v 1.2 2001/03/18 19:35:13 dwelch Exp $
|
||||
*
|
||||
* FILE: ntoskrnl/hal/x86/syscall.s
|
||||
* PURPOSE: 2E trap handler
|
||||
|
@ -96,7 +96,10 @@ L3:
|
|||
movl %ebx, %es
|
||||
movl %ebx, %gs
|
||||
|
||||
/* Save the old trap frame pointer (over the EDX register??) */
|
||||
/*
|
||||
* Save the old trap frame pointer over where we would save the EDX
|
||||
* register.
|
||||
*/
|
||||
movl KTHREAD_TRAP_FRAME(%esi), %ebx
|
||||
movl %ebx, 0x3C(%esp)
|
||||
|
||||
|
|
|
@ -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: trap.s,v 1.6 2000/12/23 02:37:40 dwelch Exp $
|
||||
/* $Id: trap.s,v 1.7 2001/03/18 19:35:13 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/i386/trap.s
|
||||
|
@ -36,336 +36,283 @@
|
|||
/*
|
||||
* Epilog for exception handlers
|
||||
*/
|
||||
_exception_handler_epilog:
|
||||
_KiTrapEpilog:
|
||||
cmpl $1, %eax /* Check for v86 recovery */
|
||||
jne _exception_handler_ret
|
||||
jne _KiTrapRet
|
||||
jmp _KiV86Complete
|
||||
_exception_handler_ret:
|
||||
addl $4, %esp /* Ignore pointer to trap frame */
|
||||
popa /* Restore general purpose registers */
|
||||
addl $4, %esp /* Ignore trap code */
|
||||
popl %ds /* Restore segment registers */
|
||||
popl %es
|
||||
popl %fs
|
||||
_KiTrapRet:
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:0x124, %esi
|
||||
|
||||
/* Restore the old trap frame pointer */
|
||||
movl 0x3c(%esp), %ebx
|
||||
movl %ebx, KTHREAD_TRAP_FRAME(%esi)
|
||||
|
||||
/* Skip debug information and unsaved registers */
|
||||
addl $0x30, %esp
|
||||
popl %gs
|
||||
addl $4, %esp /* Ignore error code */
|
||||
iret /* Return from interrupt */
|
||||
|
||||
.globl _exception_handler0
|
||||
_exception_handler0:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $0
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
popl %es
|
||||
popl %ds
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %eax
|
||||
|
||||
.globl _exception_handler1
|
||||
_exception_handler1:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $1
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
/* Restore the old previous mode */
|
||||
popl %ebx
|
||||
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
|
||||
|
||||
/* Restore the old exception handler list */
|
||||
popl %ebx
|
||||
movl %ebx, %fs:KPCR_EXCEPTION_LIST
|
||||
|
||||
popl %fs
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
addl $0x4, %esp /* Ignore error code */
|
||||
|
||||
iret
|
||||
|
||||
.globl _exception_handler2
|
||||
_exception_handler2:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $2
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler3
|
||||
_exception_handler3:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $3
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
|
||||
.globl _exception_handler4
|
||||
_exception_handler4:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $4
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler5
|
||||
_exception_handler5:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $5
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler6
|
||||
_exception_handler6:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $6
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler7
|
||||
_exception_handler7:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $7
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler8
|
||||
_exception_handler8:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $8
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler9
|
||||
_exception_handler9:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $9
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler10
|
||||
_exception_handler10:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $10
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler11
|
||||
_exception_handler11:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $11
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler12
|
||||
_exception_handler12:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $12
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler13
|
||||
_exception_handler13:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $13
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler14
|
||||
_exception_handler14:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $14
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler15
|
||||
_exception_handler15:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $15
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler16
|
||||
_exception_handler16:
|
||||
pushl %gs
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $16
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
.globl _exception_handler_unknown
|
||||
_exception_handler_unknown:
|
||||
pushl $0
|
||||
pushl %gs
|
||||
.globl _KiTrapProlog
|
||||
_KiTrapProlog:
|
||||
pushl %edi
|
||||
pushl %fs
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl $0xff
|
||||
pusha
|
||||
movw $KERNEL_DS,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%fs
|
||||
movw %ax,%gs
|
||||
pushl %esp
|
||||
call _exception_handler
|
||||
jmp _exception_handler_epilog
|
||||
|
||||
/* Load the PCR selector into fs */
|
||||
movl $PCR_SELECTOR, %ebx
|
||||
movl %ebx, %fs
|
||||
|
||||
/* Save the old exception list */
|
||||
movl %fs:KPCR_EXCEPTION_LIST, %ebx
|
||||
pushl %ebx
|
||||
|
||||
/* Put the exception handler chain terminator */
|
||||
movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
|
||||
|
||||
/* Get a pointer to the current thread */
|
||||
movl %fs:KPCR_CURRENT_THREAD, %edi
|
||||
|
||||
/* The current thread may be NULL early in the boot process */
|
||||
cmpl $0, %edi
|
||||
je .L4
|
||||
|
||||
/* Save the old previous mode */
|
||||
movl $0, %ebx
|
||||
movb %ss:KTHREAD_PREVIOUS_MODE(%edi), %bl
|
||||
pushl %ebx
|
||||
|
||||
/* Set the new previous mode based on the saved CS selector */
|
||||
movl 0x24(%esp), %ebx
|
||||
cmpl $KERNEL_CS, %ebx
|
||||
jne .L1
|
||||
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
|
||||
jmp .L3
|
||||
.L1:
|
||||
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
|
||||
.L3:
|
||||
|
||||
/* Save other registers */
|
||||
pushl %eax
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %ds
|
||||
pushl %es
|
||||
pushl %gs
|
||||
pushl $0 /* DR7 */
|
||||
pushl $0 /* DR6 */
|
||||
pushl $0 /* DR3 */
|
||||
pushl $0 /* DR2 */
|
||||
pushl $0 /* DR1 */
|
||||
pushl $0 /* DR0 */
|
||||
pushl $0 /* XXX: TempESP */
|
||||
pushl $0 /* XXX: TempCS */
|
||||
pushl $0 /* XXX: DebugPointer */
|
||||
pushl $0 /* XXX: DebugArgMark */
|
||||
pushl $0 /* XXX: DebugEIP */
|
||||
pushl $0 /* XXX: DebugEBP */
|
||||
|
||||
/* Load the segment registers */
|
||||
movl $KERNEL_DS, %ebx
|
||||
movl %ebx, %ds
|
||||
movl %ebx, %es
|
||||
movl %ebx, %gs
|
||||
|
||||
/* Set ES to kernel segment */
|
||||
movw $KERNEL_DS,%bx
|
||||
movw %bx,%es
|
||||
|
||||
/* Call the C exception handler */
|
||||
movl %esp, %ebx
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
call _KiTrapHandler
|
||||
addl $4, %esp
|
||||
addl $4, %esp
|
||||
|
||||
/* Return to the caller */
|
||||
jmp _KiTrapEpilog
|
||||
|
||||
/* Handle the no-thread case out of line */
|
||||
.L4:
|
||||
pushl $0
|
||||
jmp .L3
|
||||
|
||||
.globl _KiTrap0
|
||||
_KiTrap0:
|
||||
/* No error code */
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $0, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap1
|
||||
_KiTrap1:
|
||||
/* No error code */
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $1, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap2
|
||||
_KiTrap2:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $2, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap3
|
||||
_KiTrap3:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $3, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap4
|
||||
_KiTrap4:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $4, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap5
|
||||
_KiTrap5:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $5, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap6
|
||||
_KiTrap6:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $6, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap7
|
||||
_KiTrap7:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $7, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap8
|
||||
_KiTrap8:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $8, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap9
|
||||
_KiTrap9:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $9, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap10
|
||||
_KiTrap10:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $10, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap11
|
||||
_KiTrap11:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $11, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap12
|
||||
_KiTrap12:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $12, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap13
|
||||
_KiTrap13:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $13, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap14
|
||||
_KiTrap14:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $14, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap15
|
||||
_KiTrap15:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $15, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrap16
|
||||
_KiTrap16:
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $16, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
.globl _KiTrapUnknown
|
||||
_KiTrapUnknown:
|
||||
pushl $0
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
movl $255, %esi
|
||||
jmp _KiTrapProlog
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -124,6 +124,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
|||
* FIXME: Think how this might work
|
||||
*/
|
||||
Thread->NpxState = 0;
|
||||
|
||||
Thread->Saturation = 0;
|
||||
Thread->Priority = 0;
|
||||
InitializeListHead(&Thread->ApcState.ApcListHead[0]);
|
||||
|
|
|
@ -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: main.c,v 1.80 2001/03/16 18:11:23 dwelch Exp $
|
||||
/* $Id: main.c,v 1.81 2001/03/18 19:35:12 dwelch Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/main.c
|
||||
|
@ -588,7 +588,29 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
|
|||
LdrProcessDriver((PVOID)start, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DbgPrint("About to try MmAllocateContiguousAlignedMemory\n");
|
||||
do
|
||||
{
|
||||
extern PVOID STDCALL
|
||||
MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
|
||||
IN PHYSICAL_ADDRESS HighestAcceptableAddress,
|
||||
IN ULONG Alignment);
|
||||
PVOID v;
|
||||
PHYSICAL_ADDRESS p;
|
||||
p.QuadPart = 16*1024*1024;
|
||||
v = MmAllocateContiguousAlignedMemory(12*1024, p,
|
||||
64*1024);
|
||||
if (v != NULL)
|
||||
{
|
||||
DbgPrint("Worked\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("Failed\n");
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
|
||||
/* Create the SystemRoot symbolic link */
|
||||
DbgPrint("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: timer.c,v 1.42 2001/03/16 16:05:33 dwelch Exp $
|
||||
/* $Id: timer.c,v 1.43 2001/03/18 19:35:13 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -113,22 +113,6 @@ NTSTATUS STDCALL NtQueryPerformanceCounter (IN PLARGE_INTEGER Counter,
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS KeAddThreadTimeout(PKTHREAD Thread, PLARGE_INTEGER Interval)
|
||||
{
|
||||
assert(Thread != NULL);
|
||||
assert(Interval != NULL);
|
||||
|
||||
DPRINT("KeAddThreadTimeout(Thread %x, Interval %x)\n",Thread,Interval);
|
||||
|
||||
KeInitializeTimer(&Thread->Timer);
|
||||
KeSetTimer(&Thread->Timer, *Interval, &Thread->TimerDpc);
|
||||
|
||||
DPRINT("Thread->Timer.entry.Flink %x\n",
|
||||
Thread->Timer.TimerListEntry.Flink);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL NtDelayExecution(IN ULONG Alertable,
|
||||
IN TIME* Interval)
|
||||
|
@ -161,9 +145,11 @@ KeDelayExecutionThread (KPROCESSOR_MODE WaitMode,
|
|||
* RETURNS: Status
|
||||
*/
|
||||
{
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
KeAddThreadTimeout(CurrentThread, Interval);
|
||||
return (KeWaitForSingleObject(&CurrentThread->Timer,
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
|
||||
KeInitializeTimer(&Thread->Timer);
|
||||
KeSetTimer(&Thread->Timer, *Interval, NULL);
|
||||
return (KeWaitForSingleObject(&Thread->Timer,
|
||||
Executive,
|
||||
UserMode,
|
||||
Alertable,
|
||||
|
@ -286,7 +272,7 @@ KeCancelTimer (PKTIMER Timer)
|
|||
|
||||
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
|
||||
|
||||
KeRaiseIrql( HIGH_LEVEL, &oldlvl );
|
||||
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
|
||||
KeAcquireSpinLockAtDpcLevel( &TimerListLock );
|
||||
|
||||
if (Timer->TimerListEntry.Flink == NULL)
|
||||
|
@ -367,7 +353,8 @@ KeQueryTickCount (PLARGE_INTEGER TickCount)
|
|||
TickCount->QuadPart = KiTimerTicks;
|
||||
}
|
||||
|
||||
static void HandleExpiredTimer(PKTIMER current)
|
||||
STATIC VOID
|
||||
HandleExpiredTimer(PKTIMER current)
|
||||
{
|
||||
DPRINT("HandleExpiredTime(current %x)\n",current);
|
||||
if (current->Dpc != NULL)
|
||||
|
@ -449,10 +436,6 @@ KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip)
|
|||
KiTimerTicks++;
|
||||
system_time = system_time + CLOCK_INCREMENT;
|
||||
|
||||
/*
|
||||
* Display the tick count in the top left of the screen as a debugging
|
||||
* aid
|
||||
*/
|
||||
vidmem[0] = ' ';
|
||||
if (oldIrql < DISPATCH_LEVEL)
|
||||
{
|
||||
|
|
|
@ -199,65 +199,68 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus)
|
|||
|
||||
static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
|
||||
{
|
||||
PKWAIT_BLOCK current;
|
||||
PLIST_ENTRY current_entry;
|
||||
PKWAIT_BLOCK PrevBlock;
|
||||
NTSTATUS Status;
|
||||
PKWAIT_BLOCK current;
|
||||
PLIST_ENTRY current_entry;
|
||||
PKWAIT_BLOCK PrevBlock;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr);
|
||||
|
||||
if (IsListEmpty(&hdr->WaitListHead))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
while (!IsListEmpty(&(hdr->WaitListHead)))
|
||||
{
|
||||
current_entry = RemoveHeadList(&hdr->WaitListHead);
|
||||
current = CONTAINING_RECORD(current_entry,
|
||||
KWAIT_BLOCK,
|
||||
WaitListEntry);
|
||||
DPRINT("Waking %x\n",current->Thread);
|
||||
if (current->WaitType == WaitAny)
|
||||
{
|
||||
DPRINT("WaitAny: Remove all wait blocks.\n");
|
||||
for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock )
|
||||
if( PrevBlock != current )
|
||||
RemoveEntryList( &(PrevBlock->WaitListEntry) );
|
||||
current->Thread->WaitBlockList = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("WaitAll: Remove the current wait block only.\n");
|
||||
|
||||
PrevBlock = current->Thread->WaitBlockList;
|
||||
if (PrevBlock == current)
|
||||
{
|
||||
DPRINT( "WaitAll: Current block is list head.\n" );
|
||||
current->Thread->WaitBlockList = current->NextWaitBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT( "WaitAll: Current block is not list head.\n" );
|
||||
while ( PrevBlock && PrevBlock->NextWaitBlock != current)
|
||||
{
|
||||
PrevBlock = PrevBlock->NextWaitBlock;
|
||||
}
|
||||
if (PrevBlock)
|
||||
{
|
||||
PrevBlock->NextWaitBlock = current->NextWaitBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
KiSideEffectsBeforeWake(hdr, current->Thread);
|
||||
Status = current->WaitKey;
|
||||
if (current->Thread->WaitBlockList == NULL)
|
||||
{
|
||||
PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
|
||||
&Status);
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr);
|
||||
|
||||
if (IsListEmpty(&hdr->WaitListHead))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
while (!IsListEmpty(&hdr->WaitListHead))
|
||||
{
|
||||
current_entry = RemoveHeadList(&hdr->WaitListHead);
|
||||
current = CONTAINING_RECORD(current_entry,
|
||||
KWAIT_BLOCK,
|
||||
WaitListEntry);
|
||||
DPRINT("Waking %x\n",current->Thread);
|
||||
if (current->WaitType == WaitAny)
|
||||
{
|
||||
DPRINT("WaitAny: Remove all wait blocks.\n");
|
||||
for(PrevBlock = current->Thread->WaitBlockList; PrevBlock;
|
||||
PrevBlock = PrevBlock->NextWaitBlock)
|
||||
{
|
||||
if (PrevBlock != current)
|
||||
RemoveEntryList(&PrevBlock->WaitListEntry);
|
||||
}
|
||||
current->Thread->WaitBlockList = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("WaitAll: Remove the current wait block only.\n");
|
||||
|
||||
PrevBlock = current->Thread->WaitBlockList;
|
||||
if (PrevBlock == current)
|
||||
{
|
||||
DPRINT( "WaitAll: Current block is list head.\n" );
|
||||
current->Thread->WaitBlockList = current->NextWaitBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT( "WaitAll: Current block is not list head.\n" );
|
||||
while (PrevBlock && PrevBlock->NextWaitBlock != current)
|
||||
{
|
||||
PrevBlock = PrevBlock->NextWaitBlock;
|
||||
}
|
||||
if (PrevBlock)
|
||||
{
|
||||
PrevBlock->NextWaitBlock = current->NextWaitBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
KiSideEffectsBeforeWake(hdr, current->Thread);
|
||||
Status = current->WaitKey;
|
||||
if (current->Thread->WaitBlockList == NULL)
|
||||
{
|
||||
PsUnblockThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
|
||||
&Status);
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
|
||||
|
@ -342,31 +345,30 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
|||
case InternalSynchronizationEvent:
|
||||
return(KeDispatcherObjectWakeOne(hdr));
|
||||
|
||||
|
||||
case InternalSynchronizationTimer:
|
||||
return(KeDispatcherObjectWakeOne(hdr));
|
||||
|
||||
case InternalSemaphoreType:
|
||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
||||
if(hdr->SignalState>0)
|
||||
{
|
||||
do
|
||||
{
|
||||
{
|
||||
do
|
||||
{
|
||||
DPRINT("Waking one semaphore waiter\n");
|
||||
Ret = KeDispatcherObjectWakeOne(hdr);
|
||||
} while(hdr->SignalState > 0 && Ret) ;
|
||||
return(Ret);
|
||||
}
|
||||
} while(hdr->SignalState > 0 && Ret) ;
|
||||
return(Ret);
|
||||
}
|
||||
else return FALSE;
|
||||
|
||||
case InternalProcessType:
|
||||
case InternalProcessType:
|
||||
return(KeDispatcherObjectWakeAll(hdr));
|
||||
|
||||
case InternalThreadType:
|
||||
return(KeDispatcherObjectWakeAll(hdr));
|
||||
case InternalThreadType:
|
||||
return(KeDispatcherObjectWakeAll(hdr));
|
||||
|
||||
case InternalMutexType:
|
||||
return(KeDispatcherObjectWakeOne(hdr));
|
||||
case InternalMutexType:
|
||||
return(KeDispatcherObjectWakeOne(hdr));
|
||||
}
|
||||
DbgPrint("Dispatcher object %x has unknown type %d\n", hdr, hdr->Type);
|
||||
KeBugCheck(0);
|
||||
|
@ -398,29 +400,36 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
|||
NTSTATUS Status;
|
||||
KIRQL WaitIrql;
|
||||
|
||||
DPRINT("Entering KeWaitForSingleObject(Object %x) "
|
||||
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread());
|
||||
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
WaitIrql = KeGetCurrentIrql();
|
||||
|
||||
/*
|
||||
* Set up the timeout
|
||||
* FIXME: Check for zero timeout
|
||||
*/
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeAddThreadTimeout(CurrentThread, Timeout);
|
||||
KeInitializeTimer(&CurrentThread->Timer);
|
||||
KeSetTimer(&CurrentThread->Timer, *Timeout, NULL);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
|
||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
||||
|
||||
|
||||
/*
|
||||
* If we are going to wait alertably and a user apc is pending
|
||||
* then return
|
||||
*/
|
||||
if (Alertable && KiTestAlert())
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
return(STATUS_USER_APC);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the object is signalled
|
||||
*/
|
||||
if (KiIsObjectSignalled(hdr, CurrentThread))
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
|
@ -429,8 +438,25 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
|||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
return(STATUS_WAIT_0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we have already timed out
|
||||
*/
|
||||
if (Timeout != NULL &&
|
||||
KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread))
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
return(STATUS_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up for a wait
|
||||
*/
|
||||
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
|
||||
/* Append wait block to the KTHREAD wait block list */
|
||||
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
|
||||
|
@ -438,9 +464,24 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
|||
CurrentThread->WaitBlock[0].Thread = CurrentThread;
|
||||
CurrentThread->WaitBlock[0].WaitKey = 0;
|
||||
CurrentThread->WaitBlock[0].WaitType = WaitAny;
|
||||
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
||||
InsertTailList(&hdr->WaitListHead,
|
||||
&CurrentThread->WaitBlock[0].WaitListEntry);
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
CurrentThread->WaitBlock[0].NextWaitBlock =
|
||||
&CurrentThread->WaitBlock[1];
|
||||
CurrentThread->WaitBlock[1].Object = (PVOID)&CurrentThread->Timer;
|
||||
CurrentThread->WaitBlock[1].Thread = CurrentThread;
|
||||
CurrentThread->WaitBlock[1].WaitKey = 1;
|
||||
CurrentThread->WaitBlock[1].WaitType = WaitAny;
|
||||
CurrentThread->WaitBlock[1].NextWaitBlock = NULL;
|
||||
InsertTailList(&CurrentThread->Timer.Header.WaitListHead,
|
||||
&CurrentThread->WaitBlock[1].WaitListEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
||||
}
|
||||
PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql);
|
||||
} while (Status == STATUS_KERNEL_APC);
|
||||
|
||||
|
@ -448,21 +489,25 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
|||
{
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
|
||||
if (Status == (STATUS_WAIT_0 + 1))
|
||||
{
|
||||
Status = STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
DPRINT("Returning from KeWaitForSingleObject()\n");
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
KeWaitForMultipleObjects (ULONG Count,
|
||||
PVOID Object[],
|
||||
WAIT_TYPE WaitType,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout,
|
||||
PKWAIT_BLOCK WaitBlockArray)
|
||||
KeWaitForMultipleObjects (ULONG Count,
|
||||
PVOID Object[],
|
||||
WAIT_TYPE WaitType,
|
||||
KWAIT_REASON WaitReason,
|
||||
KPROCESSOR_MODE WaitMode,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout,
|
||||
PKWAIT_BLOCK WaitBlockArray)
|
||||
{
|
||||
DISPATCHER_HEADER* hdr;
|
||||
PKWAIT_BLOCK blk;
|
||||
|
@ -479,87 +524,150 @@ KeWaitForMultipleObjects (ULONG Count,
|
|||
CurrentThread = KeGetCurrentThread();
|
||||
WaitIrql = KeGetCurrentIrql();
|
||||
|
||||
/*
|
||||
* Work out where we are going to put the wait blocks
|
||||
*/
|
||||
if (WaitBlockArray == NULL)
|
||||
{
|
||||
if (Count > 4)
|
||||
if (Count > THREAD_WAIT_OBJECTS)
|
||||
{
|
||||
DbgPrint("(%s:%d) Too many objects!\n",
|
||||
__FILE__,__LINE__);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
blk = &CurrentThread->WaitBlock[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Count > 64)
|
||||
if (Count > EX_MAXIMUM_WAIT_OBJECTS)
|
||||
{
|
||||
DbgPrint("(%s:%d) Too many objects!\n",
|
||||
__FILE__,__LINE__);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
blk = WaitBlockArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the timeout if required
|
||||
*/
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeAddThreadTimeout(CurrentThread,Timeout);
|
||||
KeInitializeTimer(&CurrentThread->Timer);
|
||||
KeSetTimer(&CurrentThread->Timer, *Timeout, NULL);
|
||||
}
|
||||
|
||||
do {
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||
|
||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
||||
|
||||
if (KiIsObjectSignalled(hdr, CurrentThread))
|
||||
{
|
||||
CountSignaled++;
|
||||
|
||||
if (WaitType == WaitAny)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("One object is already signaled!\n");
|
||||
do
|
||||
{
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
|
||||
/*
|
||||
* If we are going to wait alertably and a user apc is pending
|
||||
* then return
|
||||
*/
|
||||
if (Alertable && KiTestAlert())
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
return(STATUS_USER_APC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the wait is already satisfied
|
||||
*/
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||
|
||||
if (KiIsObjectSignalled(hdr, CurrentThread))
|
||||
{
|
||||
CountSignaled++;
|
||||
|
||||
if (WaitType == WaitAny)
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("One object is already signaled!\n");
|
||||
return(STATUS_WAIT_0 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((WaitType == WaitAll) && (CountSignaled == Count))
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("All objects are already signaled!\n");
|
||||
return(STATUS_WAIT_0);
|
||||
}
|
||||
|
||||
if ((WaitType == WaitAll) && (CountSignaled == Count))
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("All objects are already signaled!\n");
|
||||
return(STATUS_WAIT_0);
|
||||
}
|
||||
|
||||
/* Append wait block to the KTHREAD wait block list */
|
||||
CurrentThread->WaitBlockList = blk;
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||
|
||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
||||
|
||||
blk->Object = Object[i];
|
||||
blk->Thread = CurrentThread;
|
||||
blk->WaitKey = i;
|
||||
blk->WaitType = WaitType;
|
||||
if (i == Count - 1)
|
||||
blk->NextWaitBlock = NULL;
|
||||
else
|
||||
blk->NextWaitBlock = blk + 1;
|
||||
|
||||
InsertTailList(&(hdr->WaitListHead),&(blk->WaitListEntry));
|
||||
|
||||
blk = blk->NextWaitBlock;
|
||||
}
|
||||
|
||||
PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql);
|
||||
} while( Status == STATUS_KERNEL_APC );
|
||||
/*
|
||||
* Check if we have already timed out
|
||||
*/
|
||||
if (Timeout != NULL &&
|
||||
KiIsObjectSignalled(&CurrentThread->Timer.Header, CurrentThread))
|
||||
{
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
return(STATUS_TIMEOUT);
|
||||
}
|
||||
|
||||
/* Append wait block to the KTHREAD wait block list */
|
||||
CurrentThread->WaitBlockList = blk;
|
||||
|
||||
/*
|
||||
* Set up the wait
|
||||
*/
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
hdr = (DISPATCHER_HEADER *)Object[i];
|
||||
|
||||
blk->Object = Object[i];
|
||||
blk->Thread = CurrentThread;
|
||||
blk->WaitKey = i;
|
||||
blk->WaitType = WaitType;
|
||||
if (i == (Count - 1))
|
||||
{
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
blk->NextWaitBlock = &CurrentThread->WaitBlock[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
blk->NextWaitBlock = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
blk->NextWaitBlock = blk + 1;
|
||||
}
|
||||
|
||||
InsertTailList(&hdr->WaitListHead, &blk->WaitListEntry);
|
||||
|
||||
blk = blk->NextWaitBlock;
|
||||
}
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
CurrentThread->WaitBlock[3].Object = (PVOID)&CurrentThread->Timer;
|
||||
CurrentThread->WaitBlock[3].Thread = CurrentThread;
|
||||
CurrentThread->WaitBlock[3].WaitKey = Count;
|
||||
CurrentThread->WaitBlock[3].WaitType = WaitAny;
|
||||
CurrentThread->WaitBlock[3].NextWaitBlock = NULL;
|
||||
InsertTailList(&CurrentThread->Timer.Header.WaitListHead,
|
||||
&CurrentThread->WaitBlock[3].WaitListEntry);
|
||||
}
|
||||
|
||||
PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql);
|
||||
} while(Status == STATUS_KERNEL_APC);
|
||||
|
||||
if (Timeout != NULL)
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
{
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
if (Status == (STATUS_WAIT_63 + 1))
|
||||
{
|
||||
Status = STATUS_TIMEOUT;
|
||||
}
|
||||
DPRINT("Returning from KeWaitForMultipleObjects()\n");
|
||||
return(Status);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: send.c,v 1.3 2000/10/22 16:36:51 ekohl Exp $
|
||||
/* $Id: send.c,v 1.4 2001/03/18 19:35:13 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -32,16 +32,16 @@
|
|||
* REVISIONS
|
||||
*
|
||||
*/
|
||||
NTSTATUS STDCALL LpcSendTerminationPort (IN PEPORT Port,
|
||||
IN TIME CreationTime)
|
||||
NTSTATUS STDCALL
|
||||
LpcSendTerminationPort (IN PEPORT Port,
|
||||
IN TIME CreationTime)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LPC_TERMINATION_MESSAGE Msg;
|
||||
NTSTATUS Status;
|
||||
LPC_TERMINATION_MESSAGE Msg;
|
||||
|
||||
Msg.CreationTime = CreationTime;
|
||||
Status = LpcRequestPort (Port,
|
||||
&Msg.Header);
|
||||
return(Status);
|
||||
Msg.CreationTime = CreationTime;
|
||||
Status = LpcRequestPort (Port, &Msg.Header);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,13 +57,45 @@ NTSTATUS STDCALL LpcSendTerminationPort (IN PEPORT Port,
|
|||
* REVISIONS
|
||||
*
|
||||
*/
|
||||
NTSTATUS STDCALL LpcSendDebugMessagePort (IN PEPORT Port,
|
||||
IN PLPC_DBG_MESSAGE Message)
|
||||
NTSTATUS STDCALL
|
||||
LpcSendDebugMessagePort (IN PEPORT Port,
|
||||
IN PLPC_DBG_MESSAGE Message,
|
||||
OUT PLPC_DBG_MESSAGE Reply)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
KIRQL oldIrql;
|
||||
PQUEUEDMESSAGE ReplyMessage;
|
||||
|
||||
Status = LpcRequestPort(Port, &Message->Header);
|
||||
return(Status);
|
||||
Status = EiReplyOrRequestPort(Port,
|
||||
&Message->Header,
|
||||
LPC_REQUEST,
|
||||
Port);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(Port);
|
||||
return(Status);
|
||||
}
|
||||
KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
/*
|
||||
* Wait for a reply
|
||||
*/
|
||||
KeWaitForSingleObject(&Port->Event,
|
||||
UserRequest,
|
||||
UserMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* Dequeue the reply
|
||||
*/
|
||||
KeAcquireSpinLock(&Port->Lock, &oldIrql);
|
||||
ReplyMessage = EiDequeueMessagePort(Port);
|
||||
KeReleaseSpinLock(&Port->Lock, oldIrql);
|
||||
memcpy(Reply, &ReplyMessage->Message, ReplyMessage->Message.MessageSize);
|
||||
ExFreePool(ReplyMessage);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -149,9 +181,10 @@ NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle,
|
|||
* REVISIONS
|
||||
*
|
||||
*/
|
||||
NTSTATUS STDCALL NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||
PLPC_MESSAGE LpcRequest,
|
||||
PLPC_MESSAGE LpcReply)
|
||||
NTSTATUS STDCALL
|
||||
NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||
PLPC_MESSAGE LpcRequest,
|
||||
PLPC_MESSAGE LpcReply)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PEPORT Port;
|
||||
|
@ -177,14 +210,13 @@ NTSTATUS STDCALL NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
|||
LpcRequest,
|
||||
LPC_REQUEST,
|
||||
Port);
|
||||
KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("Enqueue failed\n");
|
||||
ObDereferenceObject(Port);
|
||||
return(Status);
|
||||
}
|
||||
KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
|
||||
|
||||
/*
|
||||
* Wait for a reply
|
||||
|
|
|
@ -83,13 +83,13 @@ MmGetContinuousPages(ULONG NumberOfBytes,
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (start != -1)
|
||||
else
|
||||
{
|
||||
start = -1;
|
||||
/*
|
||||
* Fast forward to the base of the next aligned region
|
||||
*/
|
||||
i = i + (Alignment / PAGESIZE);
|
||||
i = ROUND_UP((i + 1), (Alignment / PAGESIZE));
|
||||
}
|
||||
}
|
||||
if (start == -1 || length != NrPages)
|
||||
|
@ -176,11 +176,19 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Page zero is reserved
|
||||
*/
|
||||
MmPageArray[0].Flags = MM_PHYSICAL_PAGE_BIOS;
|
||||
MmPageArray[0].ReferenceCount = 0;
|
||||
InsertTailList(&BiosPageListHead,
|
||||
&MmPageArray[0].ListEntry);
|
||||
|
||||
i = 1;
|
||||
if ((ULONG)FirstPhysKernelAddress < 0xa0000)
|
||||
{
|
||||
MmStats.NrFreePages += ((ULONG)FirstPhysKernelAddress/PAGESIZE);
|
||||
MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGESIZE) - 1);
|
||||
for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++)
|
||||
{
|
||||
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
|
||||
|
@ -216,7 +224,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
|||
}
|
||||
else
|
||||
{
|
||||
MmStats.NrFreePages += (0xa0000 / PAGESIZE);
|
||||
MmStats.NrFreePages += ((0xa0000 / PAGESIZE) - 1);
|
||||
for (; i<(0xa0000 / PAGESIZE); i++)
|
||||
{
|
||||
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_FREE;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.31 2001/03/16 18:11:24 dwelch Exp $
|
||||
/* $Id: create.c,v 1.32 2001/03/18 19:35:13 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -26,6 +26,7 @@
|
|||
#include <internal/ps.h>
|
||||
#include <internal/ob.h>
|
||||
#include <internal/id.h>
|
||||
#include <internal/dbg.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -577,27 +578,11 @@ NtCreateThread (PHANDLE ThreadHandle,
|
|||
/*
|
||||
* Maybe send a message to the process's debugger
|
||||
*/
|
||||
#if 0
|
||||
if (ParentProcess->DebugPort != NULL)
|
||||
{
|
||||
LPC_DBG_MESSAGE Message;
|
||||
PEPROCESS Process;
|
||||
|
||||
|
||||
Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE);
|
||||
Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
|
||||
sizeof(LPC_MESSAGE_HEADER);
|
||||
Message.EventCode = DBG_EVENT_CREATE_THREAD;
|
||||
Message.Data.CreateThread.StartAddress =
|
||||
;
|
||||
Message.Data.CreateProcess.Base = ImageBase;
|
||||
Message.Data.CreateProcess.EntryPoint = NULL; //
|
||||
|
||||
Status = LpcSendDebugMessagePort(ParentProcess->DebugPort,
|
||||
&Message);
|
||||
}
|
||||
#endif
|
||||
DbgkCreateThread((PVOID)ThreadContext->Eip);
|
||||
|
||||
/*
|
||||
* Start the thread running
|
||||
*/
|
||||
if (!CreateSuspended)
|
||||
{
|
||||
DPRINT("Not creating suspended\n");
|
||||
|
|
|
@ -133,6 +133,7 @@ VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
|
|||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
||||
|
||||
CurrentThread->ExitStatus = ExitStatus;
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
KeAcquireDispatcherDatabaseLock(FALSE);
|
||||
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
|
||||
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: process.c,v 1.58 2001/03/07 16:48:45 dwelch Exp $
|
||||
/* $Id: process.c,v 1.59 2001/03/18 19:35:14 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -532,6 +532,7 @@ NtCreateProcess (OUT PHANDLE ProcessHandle,
|
|||
/*
|
||||
* Maybe send a message to the creator process's debugger
|
||||
*/
|
||||
#if 0
|
||||
if (ParentProcess->DebugPort != NULL)
|
||||
{
|
||||
LPC_DBG_MESSAGE Message;
|
||||
|
@ -554,6 +555,7 @@ NtCreateProcess (OUT PHANDLE ProcessHandle,
|
|||
Status = LpcSendDebugMessagePort(ParentProcess->DebugPort,
|
||||
&Message);
|
||||
}
|
||||
#endif
|
||||
|
||||
ObDereferenceObject(Process);
|
||||
ObDereferenceObject(ParentProcess);
|
||||
|
|
|
@ -1,6 +1,23 @@
|
|||
/* $Id: suspend.c,v 1.4 2001/03/16 18:11:24 dwelch Exp $
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: suspend.c,v 1.5 2001/03/18 19:35:14 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ps/suspend.c
|
||||
* PURPOSE: Thread managment
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.71 2001/03/16 18:11:24 dwelch Exp $
|
||||
/* $Id: thread.c,v 1.72 2001/03/18 19:35:14 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -73,14 +73,6 @@ HANDLE STDCALL PsGetCurrentThreadId(VOID)
|
|||
|
||||
VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
|
||||
{
|
||||
// DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
|
||||
// Thread);
|
||||
// DPRINT("Offset %x\n", THREAD_PRIORITY_MAX + Priority);
|
||||
|
||||
if (PiThreadListLock.Lock == 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
if (Priority >= MAXIMUM_PRIORITY || Priority < 0)
|
||||
{
|
||||
DPRINT1("Invalid thread priority\n");
|
||||
|
@ -128,11 +120,6 @@ static PETHREAD PsScanThreadList (KPRIORITY Priority)
|
|||
PLIST_ENTRY current_entry;
|
||||
PETHREAD current;
|
||||
|
||||
// DPRINT("PsScanThreadList(Priority %d)\n",Priority);
|
||||
if (PiThreadListLock.Lock == 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
current_entry = RemoveHeadList(&PriorityListHead[Priority]);
|
||||
if (current_entry != &PriorityListHead[Priority])
|
||||
{
|
||||
|
@ -251,6 +238,36 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
|
|||
KeLowerIrql(WaitIrql);
|
||||
}
|
||||
|
||||
VOID
|
||||
PsFreezeAllThreads(PEPROCESS Process)
|
||||
/*
|
||||
* Used by the debugging code to freeze all the process's threads
|
||||
* while the debugger is examining their state.
|
||||
*/
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
PLIST_ENTRY current_entry;
|
||||
PETHREAD current;
|
||||
|
||||
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
|
||||
|
||||
current_entry = Process->ThreadListHead.Flink;
|
||||
while (current_entry != &Process->ThreadListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry, ETHREAD,
|
||||
Tcb.ProcessThreadListEntry);
|
||||
|
||||
/*
|
||||
* We have to be careful here, we can't just set the freeze the
|
||||
* thread inside kernel mode since it may be holding a lock.
|
||||
*/
|
||||
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&PiThreadListLock, oldIrql);
|
||||
}
|
||||
|
||||
VOID
|
||||
PsInitThreadManagment(VOID)
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue