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 Modified: trunk/reactos/include/ddk/kefuncs.h Modified: trunk/reactos/ntoskrnl/Makefile Deleted: trunk/reactos/ntoskrnl/ex/napi.c Modified: trunk/reactos/ntoskrnl/ke/process.c _____
Modified: trunk/reactos/include/ddk/kefuncs.h --- trunk/reactos/include/ddk/kefuncs.h 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/include/ddk/kefuncs.h 2005-03-12 18:10:03 UTC (rev 13971) @@ -720,7 +720,7 @@
BOOLEAN STDCALL KeRemoveSystemServiceTable( - IN PUCHAR Number + IN ULONG TableIndex );
NTSTATUS _____
Modified: trunk/reactos/ntoskrnl/Makefile --- trunk/reactos/ntoskrnl/Makefile 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/ntoskrnl/Makefile 2005-03-12 18:10:03 UTC (rev 13971) @@ -247,7 +247,6 @@
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 @@ $(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
_____
Deleted: trunk/reactos/ntoskrnl/ex/napi.c --- trunk/reactos/ntoskrnl/ex/napi.c 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/ntoskrnl/ex/napi.c 2005-03-12 18:10:03 UTC (rev 13971) @@ -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 } -}; _____
Modified: trunk/reactos/ntoskrnl/ke/process.c --- trunk/reactos/ntoskrnl/ke/process.c 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/ntoskrnl/ke/process.c 2005-03-12 18:10:03 UTC (rev 13971) @@ -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 @@ 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 @@ 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 @@ */ BOOLEAN STDCALL -KeIsAttachedProcess( - VOID - ) +KeIsAttachedProcess(VOID) { - return KeGetCurrentThread()->ApcStateIndex; + /* Return the APC State */ + return KeGetCurrentThread()->ApcStateIndex; }
/* @@ -133,36 +160,41 @@ */ 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 @@ 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 @@ 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 @@ }
/* - * @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 */