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 BOOLEAN
STDCALL STDCALL
KeRemoveSystemServiceTable( KeRemoveSystemServiceTable(
IN PUCHAR Number IN ULONG TableIndex
); );
NTSTATUS NTSTATUS

View file

@ -247,7 +247,6 @@ OBJECTS_EX = \
ex/list.o \ ex/list.o \
ex/lookas.o \ ex/lookas.o \
ex/mutant.o \ ex/mutant.o \
ex/napi.o \
ex/power.o \ ex/power.o \
ex/profile.o \ ex/profile.o \
ex/resource.o \ ex/resource.o \
@ -438,7 +437,6 @@ TARGET_CLEAN = \
$(PATH_TO_TOP)/include/reactos/bugcodes.h \ $(PATH_TO_TOP)/include/reactos/bugcodes.h \
$(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc $(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 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/process.c * 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 *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ntoskrnl.h> #include <ntoskrnl.h>
#include <ntdll/napi.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.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 }
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static inline void static inline void
UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process) 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 stack and the thread structure of the current process may be
the process we're attaching to. That would lead to a page fault * located in a page which is not present in the page directory of
when this function returns. However, since the processor can't * the process we're attaching to. That would lead to a page fault
call the page fault handler 'cause it can't push EIP on the stack, * when this function returns. However, since the processor can't
this will show up as a stack fault which will crash the entire system. * call the page fault handler 'cause it can't push EIP on the stack,
To prevent this, make sure the page directory of the process we're * this will show up as a stack fault which will crash the entire system.
attaching to is up-to-date. */ * To prevent this, make sure the page directory of the process we're
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE); * attaching to is up-to-date.
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); */
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
} }
/* /*
@ -38,29 +60,33 @@ VOID
STDCALL STDCALL
KeAttachProcess(PKPROCESS Process) KeAttachProcess(PKPROCESS Process)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread(); PKTHREAD Thread = KeGetCurrentThread();
DPRINT("KeAttachProcess: %x\n", Process); DPRINT("KeAttachProcess: %x\n", Process);
UpdatePageDirs(Thread, Process); /* Make sure that we are in the right page directory */
UpdatePageDirs(Thread, Process);
/* Lock Dispatcher */ /* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */ /* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) { if (KeIsExecutingDpc()) {
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */ DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) { KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
DPRINT("Process already Attached. Exitting\n"); }
KeReleaseDispatcherDatabaseLock(OldIrql);
} else { /* Check if the Target Process is already attached */
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
}
DPRINT("Process already Attached. Exitting\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
} else {
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
}
} }
VOID VOID
@ -68,52 +94,54 @@ STDCALL
KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState) 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 */ /* Increase Stack Count */
Process->StackCount++; Process->StackCount++;
/* Swap the APC Environment */ /* Swap the APC Environment */
KiMoveApcState(&Thread->ApcState, SavedApcState); KiMoveApcState(&Thread->ApcState, SavedApcState);
/* Reinitialize Apc State */ /* Reinitialize Apc State */
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]); InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
Thread->ApcState.Process = Process; Thread->ApcState.Process = Process;
Thread->ApcState.KernelApcInProgress = FALSE; Thread->ApcState.KernelApcInProgress = FALSE;
Thread->ApcState.KernelApcPending = FALSE; Thread->ApcState.KernelApcPending = FALSE;
Thread->ApcState.UserApcPending = FALSE; Thread->ApcState.UserApcPending = FALSE;
/* Update Environment Pointers if needed*/ /* Update Environment Pointers if needed*/
if (SavedApcState == &Thread->SavedApcState) { if (SavedApcState == &Thread->SavedApcState) {
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
Thread->ApcStateIndex = AttachedApcEnvironment;
}
/* Swap the Processes */ Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
KiSwapProcess(Process, SavedApcState->Process); Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
Thread->ApcStateIndex = AttachedApcEnvironment;
}
/* Return to old IRQL*/ /* Swap the Processes */
KeReleaseDispatcherDatabaseLock(ApcLock); KiSwapProcess(Process, SavedApcState->Process);
DPRINT("KiAttachProcess Completed Sucesfully\n"); /* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(ApcLock);
DPRINT("KiAttachProcess Completed Sucesfully\n");
} }
VOID VOID
STDCALL STDCALL
KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess) KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess)
{ {
//PKPCR Pcr = KeGetCurrentKpcr(); //PKPCR Pcr = KeGetCurrentKpcr();
/* Do they have an LDT? */ /* Do they have an LDT? */
if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) { 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 */ /* 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 BOOLEAN
STDCALL STDCALL
KeIsAttachedProcess( KeIsAttachedProcess(VOID)
VOID
)
{ {
return KeGetCurrentThread()->ApcStateIndex; /* Return the APC State */
return KeGetCurrentThread()->ApcStateIndex;
} }
/* /*
@ -133,36 +160,41 @@ KeIsAttachedProcess(
*/ */
VOID VOID
STDCALL STDCALL
KeStackAttachProcess ( KeStackAttachProcess(IN PKPROCESS Process,
IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
OUT PRKAPC_STATE ApcState
)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread(); PKTHREAD Thread = KeGetCurrentThread();
UpdatePageDirs(Thread, Process); /* Make sure that we are in the right page directory */
UpdatePageDirs(Thread, Process);
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
/* Crash system if DPC is being executed! */ /* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) { if (KeIsExecutingDpc()) {
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */ DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
if (Thread->ApcState.Process == Process) { KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
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*/ /* Check if the Target Process is already attached */
if (Thread->ApcStateIndex != OriginalApcEnvironment) { if (Thread->ApcState.Process == Process) {
KiAttachProcess(Thread, Process, OldIrql, ApcState);
} else { ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
ApcState->Process = NULL; } 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 VOID STDCALL
KeDetachProcess (VOID) KeDetachProcess (VOID)
{ {
PKTHREAD Thread; PKTHREAD Thread;
KIRQL OldIrql; KIRQL OldIrql;
DPRINT("KeDetachProcess()\n"); DPRINT("KeDetachProcess()\n");
/* Get Current Thread and Lock */ /* Get Current Thread and Lock */
Thread = KeGetCurrentThread(); Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
/* Check if it's attached */ /* Check if it's attached */
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex); DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
if (Thread->ApcStateIndex == OriginalApcEnvironment) { if (Thread->ApcStateIndex == OriginalApcEnvironment) {
DPRINT1("Invalid detach (thread was not attached)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Decrease Stack Count */ DPRINT1("Invalid detach (thread was not attached)\n");
Thread->ApcState.Process->StackCount--; KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
/* Restore the APC State */ /* Decrease Stack Count */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); Thread->ApcState.Process->StackCount--;
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* Swap Processes */ /* Restore the APC State */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
/* Unlock Dispatcher */ /* Swap Processes */
KeReleaseDispatcherDatabaseLock(OldIrql); KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
/* Unlock Dispatcher */
KeReleaseDispatcherDatabaseLock(OldIrql);
} }
/* /*
@ -214,55 +247,56 @@ KeUnstackDetachProcess (
IN PRKAPC_STATE ApcState IN PRKAPC_STATE ApcState
) )
{ {
KIRQL OldIrql; KIRQL OldIrql;
PKTHREAD Thread; 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; * 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(); Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */ /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) { 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 */ DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
if (ApcState->Process) { KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
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 */ /* Restore the Old APC State if a Process was present */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); if (ApcState->Process) {
/* Return to old IRQL*/ KiMoveApcState(ApcState, &Thread->ApcState);
KeReleaseDispatcherDatabaseLock(OldIrql);
} 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);
/* 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 * @implemented
*/ */
BOOLEAN STDCALL BOOLEAN STDCALL
KeAddSystemServiceTable ( KeAddSystemServiceTable(PSSDT SSDT,
PSSDT SSDT, PULONG ServiceCounterTable,
PULONG ServiceCounterTable, ULONG NumberOfServices,
ULONG NumberOfServices, PSSPT SSPT,
PSSPT SSPT, ULONG TableIndex)
ULONG TableIndex
)
{ {
/* check if descriptor table entry is free */ /* check if descriptor table entry is free */
if ((TableIndex > SSDT_MAX_ENTRIES - 1) || if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||
@ -280,15 +314,37 @@ KeAddSystemServiceTable (
} }
/* /*
* @unimplemented * @implemented
*/ */
BOOLEAN BOOLEAN
STDCALL STDCALL
KeRemoveSystemServiceTable( KeRemoveSystemServiceTable(IN ULONG TableIndex)
IN PUCHAR Number
)
{ {
UNIMPLEMENTED; /* Make sure the Index is valid */
return FALSE; 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 */ /* EOF */