Alex Ionescu <ionucu@videotron.ca>

- Clean up formatting of ke/process.c (which I had messed up at the time due to MSVC)
- Acknowledge Blight's work
- Implement KeRemoveServiceDescriptorTable
- Remove ex/napi.c and move the Tables into ke/process.c

svn path=/trunk/; revision=13971
This commit is contained in:
Thomas Bluemel 2005-03-12 18:10:03 +00:00
parent 62fe406292
commit 052a86b641
4 changed files with 234 additions and 216 deletions

View file

@ -720,7 +720,7 @@ KeCapturePersistentThreadState(
BOOLEAN
STDCALL
KeRemoveSystemServiceTable(
IN PUCHAR Number
IN ULONG TableIndex
);
NTSTATUS

View file

@ -247,7 +247,6 @@ OBJECTS_EX = \
ex/list.o \
ex/lookas.o \
ex/mutant.o \
ex/napi.o \
ex/power.o \
ex/profile.o \
ex/resource.o \
@ -438,7 +437,6 @@ TARGET_CLEAN = \
$(PATH_TO_TOP)/include/reactos/bugcodes.h \
$(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc
ex/napi.o: ex/zw.S $(PATH_TO_TOP)/include/ntdll/napi.h
ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h

View file

@ -1,36 +0,0 @@
/* $Id:$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/napi.c
* PURPOSE: Native API support routines
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#include <ntdll/napi.h>
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
SSDT_ENTRY
__declspec(dllexport)
KeServiceDescriptorTable[SSDT_MAX_ENTRIES] =
{
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL }
};
SSDT_ENTRY
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] =
{
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL }
};

View file

@ -1,34 +1,56 @@
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/process.c
* PURPOSE: Microkernel process management
* PURPOSE: Attaching/Detaching and System Call Tables
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
* PROGRAMMERS: Alex Ionescu (Implemented Attach/Detach and KeRemoveSystemServiceTable)
* Gregor Anich (Bugfixes to Attach Functions)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#include <ntdll/napi.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS *****************************************************************/
SSDT_ENTRY
__declspec(dllexport)
KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = {
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL }
};
SSDT_ENTRY
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL },
{ NULL, NULL, 0, NULL }
};
/* FUNCTIONS *****************************************************************/
static inline void
UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
{
/* The stack and the thread structure of the current process may be
located in a page which is not present in the page directory of
the process we're attaching to. That would lead to a page fault
when this function returns. However, since the processor can't
call the page fault handler 'cause it can't push EIP on the stack,
this will show up as a stack fault which will crash the entire system.
To prevent this, make sure the page directory of the process we're
attaching to is up-to-date. */
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
/*
* The stack and the thread structure of the current process may be
* located in a page which is not present in the page directory of
* the process we're attaching to. That would lead to a page fault
* when this function returns. However, since the processor can't
* call the page fault handler 'cause it can't push EIP on the stack,
* this will show up as a stack fault which will crash the entire system.
* To prevent this, make sure the page directory of the process we're
* attaching to is up-to-date.
*/
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
}
/*
@ -38,29 +60,33 @@ VOID
STDCALL
KeAttachProcess(PKPROCESS Process)
{
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
DPRINT("KeAttachProcess: %x\n", Process);
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
UpdatePageDirs(Thread, Process);
DPRINT("KeAttachProcess: %x\n", Process);
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
DPRINT("Process already Attached. Exitting\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
} else {
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
}
/* Make sure that we are in the right page directory */
UpdatePageDirs(Thread, Process);
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
DPRINT("Process already Attached. Exitting\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
} else {
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
}
}
VOID
@ -68,52 +94,54 @@ STDCALL
KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState)
{
DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState);
DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState);
/* Increase Stack Count */
Process->StackCount++;
/* Swap the APC Environment */
KiMoveApcState(&Thread->ApcState, SavedApcState);
/* Reinitialize Apc State */
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
Thread->ApcState.Process = Process;
Thread->ApcState.KernelApcInProgress = FALSE;
Thread->ApcState.KernelApcPending = FALSE;
Thread->ApcState.UserApcPending = FALSE;
/* Increase Stack Count */
Process->StackCount++;
/* Swap the APC Environment */
KiMoveApcState(&Thread->ApcState, SavedApcState);
/* Update Environment Pointers if needed*/
if (SavedApcState == &Thread->SavedApcState) {
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
Thread->ApcStateIndex = AttachedApcEnvironment;
}
/* Swap the Processes */
KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(ApcLock);
DPRINT("KiAttachProcess Completed Sucesfully\n");
/* Reinitialize Apc State */
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
Thread->ApcState.Process = Process;
Thread->ApcState.KernelApcInProgress = FALSE;
Thread->ApcState.KernelApcPending = FALSE;
Thread->ApcState.UserApcPending = FALSE;
/* Update Environment Pointers if needed*/
if (SavedApcState == &Thread->SavedApcState) {
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
Thread->ApcStateIndex = AttachedApcEnvironment;
}
/* Swap the Processes */
KiSwapProcess(Process, SavedApcState->Process);
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(ApcLock);
DPRINT("KiAttachProcess Completed Sucesfully\n");
}
VOID
STDCALL
KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess)
{
//PKPCR Pcr = KeGetCurrentKpcr();
//PKPCR Pcr = KeGetCurrentKpcr();
/* Do they have an LDT? */
if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) {
/* FIXME : SWitch GDT/IDT */
}
DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
/* FIXME: Set IopmOffset in TSS */
/* Do they have an LDT? */
if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) {
/* FIXME : SWitch GDT/IDT */
}
DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
/* FIXME: Set IopmOffset in TSS */
}
/*
@ -121,11 +149,10 @@ KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess)
*/
BOOLEAN
STDCALL
KeIsAttachedProcess(
VOID
)
KeIsAttachedProcess(VOID)
{
return KeGetCurrentThread()->ApcStateIndex;
/* Return the APC State */
return KeGetCurrentThread()->ApcStateIndex;
}
/*
@ -133,36 +160,41 @@ KeIsAttachedProcess(
*/
VOID
STDCALL
KeStackAttachProcess (
IN PKPROCESS Process,
OUT PRKAPC_STATE ApcState
)
KeStackAttachProcess(IN PKPROCESS Process,
OUT PRKAPC_STATE ApcState)
{
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
UpdatePageDirs(Thread, Process);
/* Make sure that we are in the right page directory */
UpdatePageDirs(Thread, Process);
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */
if (Thread->ApcState.Process == Process) {
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
} else {
/* Check if the Current Thread is already attached and call the Internal Function*/
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
KiAttachProcess(Thread, Process, OldIrql, ApcState);
} else {
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
ApcState->Process = NULL;
}
}
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */
if (Thread->ApcState.Process == Process) {
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
} else {
/* Check if the Current Thread is already attached and call the Internal Function*/
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
KiAttachProcess(Thread, Process, OldIrql, ApcState);
} else {
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
ApcState->Process = NULL;
}
}
}
/*
@ -171,38 +203,39 @@ KeStackAttachProcess (
VOID STDCALL
KeDetachProcess (VOID)
{
PKTHREAD Thread;
KIRQL OldIrql;
PKTHREAD Thread;
KIRQL OldIrql;
DPRINT("KeDetachProcess()\n");
DPRINT("KeDetachProcess()\n");
/* Get Current Thread and Lock */
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if it's attached */
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
if (Thread->ApcStateIndex == OriginalApcEnvironment) {
DPRINT1("Invalid detach (thread was not attached)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Get Current Thread and Lock */
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if it's attached */
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
if (Thread->ApcStateIndex == OriginalApcEnvironment) {
DPRINT1("Invalid detach (thread was not attached)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Decrease Stack Count */
Thread->ApcState.Process->StackCount--;
/* Restore the APC State */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Decrease Stack Count */
Thread->ApcState.Process->StackCount--;
/* Restore the APC State */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Unlock Dispatcher */
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Unlock Dispatcher */
KeReleaseDispatcherDatabaseLock(OldIrql);
}
/*
@ -214,55 +247,56 @@ KeUnstackDetachProcess (
IN PRKAPC_STATE ApcState
)
{
KIRQL OldIrql;
PKTHREAD Thread;
KIRQL OldIrql;
PKTHREAD Thread;
/* If the special "We tried to attach to the process already being attached to" flag is there, don't do anything */
if (ApcState->Process == (PKPROCESS)1) return;
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Restore the Old APC State if a Process was present */
if (ApcState->Process) {
KiMoveApcState(ApcState, &Thread->ApcState);
} else {
/* The ApcState parameter is useless, so use the saved data and reset it */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStateIndex = OriginalApcEnvironment;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
}
/*
* If the special "We tried to attach to the process already being
* attached to" flag is there, don't do anything
*/
if (ApcState->Process == (PKPROCESS)1) return;
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Restore the Old APC State if a Process was present */
if (ApcState->Process) {
KiMoveApcState(ApcState, &Thread->ApcState);
} else {
/* The ApcState parameter is useless, so use the saved data and reset it */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStateIndex = OriginalApcEnvironment;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
}
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(OldIrql);
}
/* This function should be used by win32k.sys to add its own user32/gdi32 services
* TableIndex is 0 based
* ServiceCountTable its not used at the moment
*/
/*
* @implemented
*/
BOOLEAN STDCALL
KeAddSystemServiceTable (
PSSDT SSDT,
PULONG ServiceCounterTable,
ULONG NumberOfServices,
PSSPT SSPT,
ULONG TableIndex
)
KeAddSystemServiceTable(PSSDT SSDT,
PULONG ServiceCounterTable,
ULONG NumberOfServices,
PSSPT SSPT,
ULONG TableIndex)
{
/* check if descriptor table entry is free */
if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||
@ -280,15 +314,37 @@ KeAddSystemServiceTable (
}
/*
* @unimplemented
* @implemented
*/
BOOLEAN
STDCALL
KeRemoveSystemServiceTable(
IN PUCHAR Number
)
KeRemoveSystemServiceTable(IN ULONG TableIndex)
{
UNIMPLEMENTED;
return FALSE;
/* Make sure the Index is valid */
if (TableIndex > SSDT_MAX_ENTRIES - 1) return FALSE;
/* Is there a Normal Descriptor Table? */
if (!KeServiceDescriptorTable[TableIndex].SSDT) {
/* Not with the index, is there a shadow at least? */
if (!KeServiceDescriptorTableShadow[TableIndex].SSDT) return FALSE;
}
/* Now clear from the Shadow Table. */
KeServiceDescriptorTableShadow[TableIndex].SSDT = NULL;
KeServiceDescriptorTableShadow[TableIndex].SSPT = NULL;
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = 0;
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = NULL;
/* Check if we should clean from the Master one too */
if (TableIndex == 1) {
KeServiceDescriptorTable[TableIndex].SSDT = NULL;
KeServiceDescriptorTable[TableIndex].SSPT = NULL;
KeServiceDescriptorTable[TableIndex].NumberOfServices = 0;
KeServiceDescriptorTable[TableIndex].ServiceCounterTable = NULL;
}
return TRUE;
}
/* EOF */