diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 9642d12b7b3..d8e3674fa55 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -7,6 +7,9 @@ extern TIME_ZONE_INFORMATION ExpTimeZoneInfo; extern LARGE_INTEGER ExpTimeZoneBias; extern ULONG ExpTimeZoneId; extern POBJECT_TYPE ExEventPairObjectType; +extern ULONG NtBuildNumber; +extern ULONG NtMajorVersion; +extern ULONG NtMinorVersion; #define MAX_FAST_REFS 7 @@ -45,6 +48,12 @@ VOID NTAPI ExInit2(VOID); +VOID +NTAPI +ExPhase2Init( + IN PVOID Context +); + VOID NTAPI ExpInitTimeZoneInfo(VOID); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index f14a2657eb6..4ddb372711c 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -129,6 +129,10 @@ extern ULONG KiMask32Array[MAXIMUM_PRIORITY]; extern ULONG KiIdleSummary; extern VOID KiTrap8(VOID); extern VOID KiTrap2(VOID); +extern PVOID KeUserApcDispatcher; +extern PVOID KeUserCallbackDispatcher; +extern PVOID KeUserExceptionDispatcher; +extern PVOID KeRaiseUserExceptionDispatcher; /* MACROS *************************************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index cadf8379bb7..60d3acfed36 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -79,51 +79,6 @@ PspShutdownProcessManager( VOID ); -VOID -INIT_FUNCTION -NTAPI -PsInitThreadManagment( - VOID -); - -VOID -INIT_FUNCTION -NTAPI -PiInitProcessManager( - VOID -); - -VOID -INIT_FUNCTION -NTAPI -PsInitProcessManagment( - VOID -); - -VOID -INIT_FUNCTION -NTAPI -PsInitIdleThread( - VOID -); - -NTSTATUS -NTAPI -PsInitializeIdleOrFirstThread( - IN PEPROCESS Process, - OUT PETHREAD* ThreadPtr, - IN PKSTART_ROUTINE StartRoutine, - IN KPROCESSOR_MODE AccessMode, - IN BOOLEAN First -); - -VOID -NTAPI -INIT_FUNCTION -PsInitJobManagment( - VOID -); - // // Utility Routines // @@ -173,6 +128,23 @@ PsReferenceProcessFilePointer( OUT PFILE_OBJECT *FileObject ); +// +// Process Routines +// +NTSTATUS +NTAPI +PspCreateProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN HANDLE ParentProcess OPTIONAL, + IN ULONG Flags, + IN HANDLE SectionHandle OPTIONAL, + IN HANDLE DebugPort OPTIONAL, + IN HANDLE ExceptionPort OPTIONAL, + IN BOOLEAN InJob +); + // // Security Routines // @@ -335,6 +307,18 @@ PspRemoveProcessFromJob( IN PEJOB Job ); +VOID +NTAPI +PspInitializeJobStructures( + VOID +); + +VOID +NTAPI +PspDeleteJob( + IN PVOID ObjectBody +); + // // Global data inside the Process Manager // @@ -367,6 +351,11 @@ extern BOOLEAN PspUseJobSchedulingClasses; extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES]; extern ULONG PsRawPrioritySeparation; extern POBJECT_TYPE _PsThreadType; +extern PTOKEN PspBootAccessToken; +extern GENERIC_MAPPING PspJobMapping; +extern POBJECT_TYPE PsJobType; +extern LARGE_INTEGER ShortPsLockDelay; +extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; // // Inlined Functions diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index d0708efd820..158a443db72 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -1,22 +1,17 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ps/psmgr.c - * PURPOSE: Process management - * - * PROGRAMMERS: David Welch (welch@mcmail.com) + * PURPOSE: Process Manager: Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES **************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG #include -extern LARGE_INTEGER ShortPsLockDelay; -extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY]; - GENERIC_MAPPING PspProcessMapping = { STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, @@ -37,18 +32,16 @@ GENERIC_MAPPING PspThreadMapping = THREAD_ALL_ACCESS }; -extern ULONG NtBuildNumber; -extern ULONG NtMajorVersion; -extern ULONG NtMinorVersion; -extern PVOID KeUserApcDispatcher; -extern PVOID KeUserCallbackDispatcher; -extern PVOID KeUserExceptionDispatcher; -extern PVOID KeRaiseUserExceptionDispatcher; - PVOID PspSystemDllBase; PVOID PspSystemDllSection; PVOID PspSystemDllEntryPoint; +ANSI_STRING ThunkName = RTL_CONSTANT_STRING("LdrInitializeThunk"); +ANSI_STRING ApcName = RTL_CONSTANT_STRING("KiUserApcDispatcher"); +ANSI_STRING ExceptName = RTL_CONSTANT_STRING("KiUserExceptionDispatcher"); +ANSI_STRING CallbackName = RTL_CONSTANT_STRING("KiUserCallbackDispatcher"); +ANSI_STRING RaiseName = RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher"); + PHANDLE_TABLE PspCidTable; PEPROCESS PsInitialSystemProcess = NULL; @@ -64,40 +57,141 @@ struct ULONG PspDefaultPagedLimit, PspDefaultNonPagedLimit, PspDefaultPagefileLimit; BOOLEAN PspDoingGiveBacks; -extern PTOKEN PspBootAccessToken; - -extern GENERIC_MAPPING PspJobMapping; -extern POBJECT_TYPE PsJobType; - -VOID -NTAPI -PspInitializeJobStructures(VOID); - -VOID -NTAPI -PspDeleteJob(IN PVOID ObjectBody); - -/* FUNCTIONS ***************************************************************/ +/* PRIVATE FUNCTIONS *********************************************************/ NTSTATUS NTAPI -PspCreateProcess(OUT PHANDLE ProcessHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN HANDLE ParentProcess OPTIONAL, - IN ULONG Flags, - IN HANDLE SectionHandle OPTIONAL, - IN HANDLE DebugPort OPTIONAL, - IN HANDLE ExceptionPort OPTIONAL, - IN BOOLEAN InJob); +PspLookupSystemDllEntryPoint(IN PANSI_STRING Name, + IN PVOID *EntryPoint) +{ + /* Call the LDR Routine */ + return LdrGetProcedureAddress(PspSystemDllBase, Name, 0, EntryPoint); +} -/* FUNCTIONS *****************************************************************/ - -VOID +NTSTATUS NTAPI -ExPhase2Init( - IN PVOID Context -); +PspLookupKernelUserEntryPoints(VOID) +{ + NTSTATUS Status; + + /* Get user-mode startup thunk */ + Status = PspLookupSystemDllEntryPoint(&ThunkName, + &PspSystemDllEntryPoint); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode APC trampoline */ + Status = PspLookupSystemDllEntryPoint(&ApcName, + &KeUserApcDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode exception dispatcher */ + Status = PspLookupSystemDllEntryPoint(&ExceptName, + &KeUserExceptionDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode callback dispatcher */ + Status = PspLookupSystemDllEntryPoint(&CallbackName, + &KeUserCallbackDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode exception raise trampoline */ + Status = PspLookupSystemDllEntryPoint(&RaiseName, + &KeRaiseUserExceptionDispatcher); + return Status; +} + +NTSTATUS +NTAPI +PspMapSystemDll(IN PEPROCESS Process, + IN PVOID *DllBase) +{ + NTSTATUS Status; + LARGE_INTEGER Offset = {{0}}; + SIZE_T ViewSize = 0; + PVOID ImageBase = 0; + + /* Map the System DLL */ + Status = MmMapViewOfSection(PspSystemDllSection, + Process, + (PVOID*)&ImageBase, + 0, + 0, + &Offset, + &ViewSize, + ViewShare, + 0, + PAGE_READWRITE); + + /* Write the image base and return status */ + if (DllBase) *DllBase = ImageBase; + return Status; +} + +NTSTATUS +NTAPI +PsLocateSystemDll(VOID) +{ + UNICODE_STRING DllName = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll"); + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle, SectionHandle; + NTSTATUS Status; + ULONG_PTR HardErrorParameters; + ULONG HardErrorResponse; + + /* Locate and open NTDLL to determine ImageBase and LdrStartup */ + InitializeObjectAttributes(&ObjectAttributes, &DllName, 0, NULL, NULL); + Status = ZwOpenFile(&FileHandle, + FILE_READ_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + 0); + if (!NT_SUCCESS(Status)) return Status; + + /* FIXME: Check if the image is valid */ + Status = STATUS_SUCCESS; //MmCheckSystemImage(FileHandle, TRUE); + if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH) + { + /* Raise a hard error */ + HardErrorParameters = (ULONG_PTR)&DllName; + NtRaiseHardError(Status, + 1, + 1, + &HardErrorParameters, + OptionOk, + &HardErrorResponse); + return Status; + } + + /* Create a section for NTDLL */ + Status = ZwCreateSection(&SectionHandle, + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + FileHandle); + ZwClose(FileHandle); + if (!NT_SUCCESS(Status)) return Status; + + /* Reference the Section */ + Status = ObReferenceObjectByHandle(SectionHandle, + SECTION_ALL_ACCESS, + MmSectionObjectType, + KernelMode, + (PVOID*)&PspSystemDllSection, + NULL); + ZwClose(SectionHandle); + if (!NT_SUCCESS(Status)) return Status; + + /* Map it */ + Status = PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase); + + /* Now get the Entrypoints */ + PspLookupKernelUserEntryPoints(); + return STATUS_SUCCESS; +} BOOLEAN NTAPI @@ -268,9 +362,7 @@ PspInitPhase0(VOID) NULL); /* The PD we gave it is invalid at this point, do what old ROS did */ - PsInitialSystemProcess->Pcb.DirectoryTableBase = (LARGE_INTEGER) - (LONGLONG) - (ULONG)MmGetPageDirectory(); + PsInitialSystemProcess->Pcb.DirectoryTableBase.LowPart = (ULONG)MmGetPageDirectory(); PsIdleProcess->Pcb.DirectoryTableBase = PsInitialSystemProcess->Pcb.DirectoryTableBase; /* Copy the process names */ @@ -305,271 +397,21 @@ PspInitPhase0(VOID) return TRUE; } -NTSTATUS -STDCALL -INIT_FUNCTION -PspLookupKernelUserEntryPoints(VOID) -{ - ANSI_STRING ProcedureName; - NTSTATUS Status; +/* PUBLIC FUNCTIONS **********************************************************/ - /* Retrieve ntdll's startup address */ - DPRINT("Getting Entrypoint: %p\n", PspSystemDllBase); - RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &PspSystemDllEntryPoint); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get User APC Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiUserApcDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeUserApcDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get Exception Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeUserExceptionDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get Callback Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeUserCallbackDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Get Raise Exception Dispatcher */ - DPRINT("Getting Entrypoint\n"); - RtlInitAnsiString(&ProcedureName, "KiRaiseUserExceptionDispatcher"); - Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase, - &ProcedureName, - 0, - &KeRaiseUserExceptionDispatcher); - - if (!NT_SUCCESS(Status)) { - - DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status); - return (Status); - } - - /* Return success */ - return(STATUS_SUCCESS); -} - -NTSTATUS -STDCALL -PspMapSystemDll(PEPROCESS Process, - PVOID *DllBase) -{ - NTSTATUS Status; - SIZE_T ViewSize = 0; - PVOID ImageBase = 0; - - /* Map the System DLL */ - DPRINT("Mapping System DLL\n"); - Status = MmMapViewOfSection(PspSystemDllSection, - Process, - (PVOID*)&ImageBase, - 0, - 0, - NULL, - &ViewSize, - 0, - MEM_COMMIT, - PAGE_READWRITE); - - if (!NT_SUCCESS(Status)) { - - DPRINT1("Failed to map System DLL Into Process\n"); - } - - if (DllBase) *DllBase = ImageBase; - - return Status; -} - -NTSTATUS -STDCALL -INIT_FUNCTION -PsLocateSystemDll(VOID) -{ - UNICODE_STRING DllPathname = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll"); - OBJECT_ATTRIBUTES FileObjectAttributes; - IO_STATUS_BLOCK Iosb; - HANDLE FileHandle; - HANDLE NTDllSectionHandle; - NTSTATUS Status; - CHAR BlockBuffer[1024]; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS NTHeaders; - - /* Locate and open NTDLL to determine ImageBase and LdrStartup */ - InitializeObjectAttributes(&FileObjectAttributes, - &DllPathname, - 0, - NULL, - NULL); - - DPRINT("Opening NTDLL\n"); - Status = ZwOpenFile(&FileHandle, - FILE_READ_ACCESS, - &FileObjectAttributes, - &Iosb, - FILE_SHARE_READ, - FILE_SYNCHRONOUS_IO_NONALERT); - - if (!NT_SUCCESS(Status)) { - DPRINT1("NTDLL open failed (Status %x)\n", Status); - return Status; - } - - /* Load NTDLL is valid */ - DPRINT("Reading NTDLL\n"); - Status = ZwReadFile(FileHandle, - 0, - 0, - 0, - &Iosb, - BlockBuffer, - sizeof(BlockBuffer), - 0, - 0); - if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) { - - DPRINT1("NTDLL header read failed (Status %x)\n", Status); - ZwClose(FileHandle); - return Status; - } - - /* Check if it's valid */ - DosHeader = (PIMAGE_DOS_HEADER)BlockBuffer; - NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew); - - if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) || - (DosHeader->e_lfanew == 0L) || - (*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE)) { - - DPRINT1("NTDLL format invalid\n"); - ZwClose(FileHandle); - return(STATUS_UNSUCCESSFUL); - } - - /* Create a section for NTDLL */ - DPRINT("Creating section\n"); - Status = ZwCreateSection(&NTDllSectionHandle, - SECTION_ALL_ACCESS, - NULL, - NULL, - PAGE_READONLY, - SEC_IMAGE | SEC_COMMIT, - FileHandle); - if (!NT_SUCCESS(Status)) { - - DPRINT1("NTDLL create section failed (Status %x)\n", Status); - ZwClose(FileHandle); - return(Status); - } - ZwClose(FileHandle); - - /* Reference the Section */ - DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle); - Status = ObReferenceObjectByHandle(NTDllSectionHandle, - SECTION_ALL_ACCESS, - MmSectionObjectType, - KernelMode, - (PVOID*)&PspSystemDllSection, - NULL); - if (!NT_SUCCESS(Status)) { - - DPRINT1("NTDLL section reference failed (Status %x)\n", Status); - return(Status); - } - - /* Map it */ - PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase); - DPRINT("LdrpSystemDllBase: %x\n", PspSystemDllBase); - - /* Now get the Entrypoints */ - PspLookupKernelUserEntryPoints(); - - return STATUS_SUCCESS; -} - - -/********************************************************************** - * NAME EXPORTED - * PsGetVersion - * - * DESCRIPTION - * Retrieves the current OS version. - * - * ARGUMENTS - * MajorVersion Pointer to a variable that will be set to the - * major version of the OS. Can be NULL. - * - * MinorVersion Pointer to a variable that will be set to the - * minor version of the OS. Can be NULL. - * - * BuildNumber Pointer to a variable that will be set to the - * build number of the OS. Can be NULL. - * - * CSDVersion Pointer to a variable that will be set to the - * CSD string of the OS. Can be NULL. - * - * RETURN VALUE - * TRUE OS is a checked build. - * FALSE OS is a free build. - * - * NOTES - * +/* * @implemented */ BOOLEAN -STDCALL -PsGetVersion(PULONG MajorVersion OPTIONAL, - PULONG MinorVersion OPTIONAL, - PULONG BuildNumber OPTIONAL, - PUNICODE_STRING CSDVersion OPTIONAL) +NTAPI +PsGetVersion(IN PULONG MajorVersion OPTIONAL, + IN PULONG MinorVersion OPTIONAL, + IN PULONG BuildNumber OPTIONAL, + IN PUNICODE_STRING CSDVersion OPTIONAL) { - if (MajorVersion) - *MajorVersion = NtMajorVersion; - - if (MinorVersion) - *MinorVersion = NtMinorVersion; - - if (BuildNumber) - *BuildNumber = NtBuildNumber; + if (MajorVersion) *MajorVersion = NtMajorVersion; + if (MinorVersion) *MinorVersion = NtMinorVersion; + if (BuildNumber) *BuildNumber = NtBuildNumber; if (CSDVersion) {