diff --git a/reactos/include/ddk/kefuncs.h b/reactos/include/ddk/kefuncs.h index e28a5bae9f3..115851a2885 100644 --- a/reactos/include/ddk/kefuncs.h +++ b/reactos/include/ddk/kefuncs.h @@ -720,7 +720,7 @@ KeCapturePersistentThreadState( BOOLEAN STDCALL KeRemoveSystemServiceTable( - IN PUCHAR Number + IN ULONG TableIndex ); NTSTATUS diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index 85da2f2602c..02780fdb269 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -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 diff --git a/reactos/ntoskrnl/ex/napi.c b/reactos/ntoskrnl/ex/napi.c deleted file mode 100644 index aa61d3bd5ba..00000000000 --- a/reactos/ntoskrnl/ex/napi.c +++ /dev/null @@ -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 -#include -#include - -/* 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 } -}; diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 15486ecbd3a..c5237917529 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -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 +#include #define NDEBUG #include +/* 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 */