mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
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:
parent
62fe406292
commit
052a86b641
4 changed files with 234 additions and 216 deletions
|
@ -720,7 +720,7 @@ KeCapturePersistentThreadState(
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
KeRemoveSystemServiceTable(
|
KeRemoveSystemServiceTable(
|
||||||
IN PUCHAR Number
|
IN ULONG TableIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 }
|
|
||||||
};
|
|
|
@ -1,32 +1,54 @@
|
||||||
/* $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
|
||||||
|
* attaching to is up-to-date.
|
||||||
|
*/
|
||||||
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
|
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
|
||||||
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
|
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
|
||||||
}
|
}
|
||||||
|
@ -43,6 +65,7 @@ KeAttachProcess(PKPROCESS Process)
|
||||||
|
|
||||||
DPRINT("KeAttachProcess: %x\n", Process);
|
DPRINT("KeAttachProcess: %x\n", Process);
|
||||||
|
|
||||||
|
/* Make sure that we are in the right page directory */
|
||||||
UpdatePageDirs(Thread, Process);
|
UpdatePageDirs(Thread, Process);
|
||||||
|
|
||||||
/* Lock Dispatcher */
|
/* Lock Dispatcher */
|
||||||
|
@ -50,15 +73,18 @@ KeAttachProcess(PKPROCESS Process)
|
||||||
|
|
||||||
/* 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");
|
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
|
||||||
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the Target Process is already attached */
|
/* Check if the Target Process is already attached */
|
||||||
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
|
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
|
||||||
|
|
||||||
DPRINT("Process already Attached. Exitting\n");
|
DPRINT("Process already Attached. Exitting\n");
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,6 +112,7 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE
|
||||||
|
|
||||||
/* 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[OriginalApcEnvironment] = &Thread->SavedApcState;
|
||||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
|
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
|
||||||
Thread->ApcStateIndex = AttachedApcEnvironment;
|
Thread->ApcStateIndex = AttachedApcEnvironment;
|
||||||
|
@ -108,6 +135,7 @@ KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess)
|
||||||
|
|
||||||
/* Do they have an LDT? */
|
/* Do they have an LDT? */
|
||||||
if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) {
|
if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) {
|
||||||
|
|
||||||
/* FIXME : SWitch GDT/IDT */
|
/* FIXME : SWitch GDT/IDT */
|
||||||
}
|
}
|
||||||
DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
|
DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
|
||||||
|
@ -121,10 +149,9 @@ KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess)
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
KeIsAttachedProcess(
|
KeIsAttachedProcess(VOID)
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
/* Return the APC State */
|
||||||
return KeGetCurrentThread()->ApcStateIndex;
|
return KeGetCurrentThread()->ApcStateIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,32 +160,37 @@ 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();
|
||||||
|
|
||||||
|
/* Make sure that we are in the right page directory */
|
||||||
UpdatePageDirs(Thread, Process);
|
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");
|
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
|
||||||
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the Target Process is already attached */
|
/* Check if the Target Process is already attached */
|
||||||
if (Thread->ApcState.Process == Process) {
|
if (Thread->ApcState.Process == Process) {
|
||||||
|
|
||||||
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
|
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Check if the Current Thread is already attached and call the Internal Function*/
|
/* Check if the Current Thread is already attached and call the Internal Function*/
|
||||||
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
|
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
|
||||||
|
|
||||||
KiAttachProcess(Thread, Process, OldIrql, ApcState);
|
KiAttachProcess(Thread, Process, OldIrql, ApcState);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
||||||
ApcState->Process = NULL;
|
ApcState->Process = NULL;
|
||||||
}
|
}
|
||||||
|
@ -184,6 +216,7 @@ KeDetachProcess (VOID)
|
||||||
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");
|
DPRINT1("Invalid detach (thread was not attached)\n");
|
||||||
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
||||||
}
|
}
|
||||||
|
@ -217,7 +250,10 @@ KeUnstackDetachProcess (
|
||||||
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 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 (ApcState->Process == (PKPROCESS)1) return;
|
||||||
|
|
||||||
Thread = KeGetCurrentThread();
|
Thread = KeGetCurrentThread();
|
||||||
|
@ -225,14 +261,18 @@ KeUnstackDetachProcess (
|
||||||
|
|
||||||
/* 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");
|
DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
|
||||||
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the Old APC State if a Process was present */
|
/* Restore the Old APC State if a Process was present */
|
||||||
if (ApcState->Process) {
|
if (ApcState->Process) {
|
||||||
|
|
||||||
KiMoveApcState(ApcState, &Thread->ApcState);
|
KiMoveApcState(ApcState, &Thread->ApcState);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* The ApcState parameter is useless, so use the saved data and reset it */
|
/* The ApcState parameter is useless, so use the saved data and reset it */
|
||||||
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
|
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
|
||||||
Thread->SavedApcState.Process = NULL;
|
Thread->SavedApcState.Process = NULL;
|
||||||
|
@ -248,21 +288,15 @@ KeUnstackDetachProcess (
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
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 */
|
||||||
|
|
Loading…
Reference in a new issue