- Fix one of the oldest hacks in ReactOS: KeGetCurrentThread() and PsGetcurrentProcess used to be NULL during early boot stage. We also didn't have an official idle therad/process. Also system intialization was not in its sepearte thread. Changes:

- Implemented SeAssignPrimaryToken.
   - Setup Boot/System Token for Idle Process in SeInit2.
   - Remove ROS hack in SeCaptureSubjectContextEx.
   - Call SeAssignPrimaryToken in PspInitializeProcessSecurty when called for the Initial Process creation.
   - Implement PsInitiailizeQuotaSystem and set PspDefauptQuotaBlock for the idle process so that it can be used for the initial process.
   - Rewrite Process Manager Phase 0 initialization from scratch, to create a new initial system process and thread which will be used for Phase 1 (in ROS, phase 2) initialization of the executive.
   - Fix a bug in PspCreateProcess which was using an uninitialized value of SectionObject in some cases, instead of NULL.
   - Call PsInitailizeQuotaSystem from ObInit, and also create the system handle table inside the idle process, and make it the ObpKernelHandleTable.
   - Do Executive Phase 0 Initialization at APC_LEVEL.
   - Start idle thread at HIGH_PRIORITY then lower it to 0 once the Initial Thread is setup, so that it can run, then keep priority to 0 at DISPATCH_LEVEL and jump into idle loop code.
   - Add NtYieldExecution to idle loop code since it's now being used.
   - Fix IoGetCurrentProcess which was previously hacked.
   - Remove some checks for Thread == NULL in ke_x.h, since this is now impossible.
   - Split Phase 0/1 initialization in ex\init.c, since one runs in a separate thread now. Also don't lower IRQL to PASSIVE_LEVEL anymore (run at APC_LEVEL).

svn path=/trunk/; revision=24148
This commit is contained in:
Alex Ionescu 2006-09-16 20:37:49 +00:00
parent 0d996fd421
commit 78ef70deda
14 changed files with 404 additions and 438 deletions

View file

@ -33,10 +33,10 @@
// - FEATURES:
// * New optimized table-based tick-hashed timer implementation.
// * New Thread Scheduler based on 2003.
// * Proper Idle/Initial Thread setup and 2nd stage boot.
// * Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
//
// Ex:
// - Implement Generic Callback mechanism.
// - Use pushlocks for handle implementation.
//
///////////////////////////////////////////////////////////////////////////////

View file

@ -36,14 +36,12 @@ extern ULONG_PTR LastKrnlPhysAddr;
extern ULONG_PTR LastKernelAddress;
extern LOADER_MODULE KeLoaderModules[64];
extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
BOOLEAN SetupMode = TRUE;
BOOLEAN NoGuiBoot = FALSE;
VOID PspPostInitSystemProcess(VOID);
static VOID INIT_FUNCTION InitSystemSharedUserPage (PCSZ ParameterLine);
VOID INIT_FUNCTION ExpDisplayNotice(VOID);
INIT_FUNCTION NTSTATUS ExpLoadInitialProcess(PHANDLE ProcessHandle, PHANDLE ThreadHandle);
static BOOLEAN BootLog = FALSE;
static ULONG MaxMem = 0;
BOOLEAN SetupMode = TRUE;
static BOOLEAN ForceAcpiDisable = FALSE;
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, InitSystemSharedUserPage)
@ -53,6 +51,12 @@ INIT_FUNCTION NTSTATUS ExpLoadInitialProcess(PHANDLE ProcessHandle, PHANDLE Thre
#pragma alloc_text(INIT, ExInit2)
#endif
BOOLEAN
NTAPI
PspInitPhase0(
VOID
);
/* FUNCTIONS ****************************************************************/
static
@ -493,21 +497,32 @@ ExpLoadInitialProcess(PHANDLE ProcessHandle,
}
VOID
INIT_FUNCTION
STDCALL
NTAPI
ExInit2(VOID)
{
ExpInitLookasideLists();
ExpInitializeHandleTables();
}
VOID
NTAPI
ExInit3(VOID)
{
ExpInitializeEventImplementation();
ExpInitializeEventPairImplementation();
ExpInitializeMutantImplementation();
ExpInitializeSemaphoreImplementation();
ExpInitializeTimerImplementation();
LpcpInitSystem();
ExpInitializeProfileImplementation();
ExpWin32kInit();
ExpInitUuids();
}
VOID
NTAPI
ExpInitializeExecutive(VOID)
{
UNICODE_STRING EventName;
HANDLE InitDoneEventHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
BOOLEAN BootLog = FALSE;
ULONG MaxMem = 0;
BOOLEAN ForceAcpiDisable = FALSE;
LARGE_INTEGER Timeout;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
NTSTATUS Status;
/* Check if the structures match the ASM offset constants */
ExecuteRuntimeAsserts();
@ -520,9 +535,6 @@ ExpInitializeExecutive(VOID)
/* Setup bugcheck messages */
KiInitializeBugCheck();
/* Lower the IRQL to Dispatch Level */
KeLowerIrql(DISPATCH_LEVEL);
/* Sets up the VDM Data */
NtEarlyInitVdm();
@ -546,17 +558,14 @@ ExpInitializeExecutive(VOID)
/* Initialize the second stage of the kernel */
KeInit2();
/* Bring back the IRQL to Passive */
KeLowerIrql(PASSIVE_LEVEL);
/* Initialize resources */
ExpResourceInitialization();
/* Load basic Security for other Managers */
if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
/* Initialize Lookaside Lists */
ExpInitLookasideLists();
/* Initialize Lookaside Lists and Handle Table */
ExInit2();
/* Create the Basic Object Manager Types to allow new Object Types */
ObInit();
@ -568,7 +577,7 @@ ExpInitializeExecutive(VOID)
if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
/* Initalize the Process Manager */
PiInitProcessManager();
PspInitPhase0();
/* Break into the Debugger if requested */
if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
@ -578,15 +587,25 @@ ExpInitializeExecutive(VOID)
/* Do Phase 1 HAL Initalization */
HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
}
VOID
NTAPI
ExPhase2Init(PVOID Context)
{
UNICODE_STRING EventName;
HANDLE InitDoneEventHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
LARGE_INTEGER Timeout;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
NTSTATUS Status;
/* Set us at maximum priority */
KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY);
/* Initialize Basic System Objects and Worker Threads */
ExInit2();
/* Create the system handle table, assign it to the system process, create
the client id table and assign a PID for the system process. This needs
to be done before the worker threads are initialized so the system
process gets the first PID (4) */
PspPostInitSystemProcess();
ExInit3();
/* initialize the worker threads */
ExpInitializeWorkerThreads();
@ -747,23 +766,25 @@ ExpInitializeExecutive(VOID)
KiTimerSystemAuditing = 1;
ZwClose(ThreadHandle);
ZwClose(ProcessHandle);
}
VOID
STDCALL
INIT_FUNCTION
ExInit2(VOID)
{
ExpInitializeEventImplementation();
ExpInitializeEventPairImplementation();
ExpInitializeMutantImplementation();
ExpInitializeSemaphoreImplementation();
ExpInitializeTimerImplementation();
LpcpInitSystem();
ExpInitializeProfileImplementation();
ExpWin32kInit();
ExpInitUuids();
ExpInitializeHandleTables();
DPRINT1("System initialization complete\n");
{
/* FIXME: We should instead jump to zero-page thread */
/* Free initial kernel memory */
MiFreeInitMemory();
/* Set our priority to 0 */
KeGetCurrentThread()->BasePriority = 0;
KeSetPriorityThread(KeGetCurrentThread(), 0);
/* Wait ad-infinitum */
for (;;)
{
LARGE_INTEGER Timeout;
Timeout.QuadPart = 0x7fffffffffffffffLL;
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
}
}
}
/* EOF */

View file

@ -58,8 +58,7 @@
#define KeEnterCriticalRegion() \
{ \
PKTHREAD Thread = KeGetCurrentThread(); \
if (Thread) \
{ \
\
/* Sanity checks */ \
ASSERT(Thread == KeGetCurrentThread()); \
ASSERT((Thread->KernelApcDisable <= 0) && \
@ -67,7 +66,6 @@
\
/* Disable Kernel APCs */ \
Thread->KernelApcDisable--; \
} \
}
//
@ -76,8 +74,7 @@
#define KeLeaveCriticalRegion() \
{ \
PKTHREAD Thread = KeGetCurrentThread(); \
if (Thread) \
{ \
\
/* Sanity checks */ \
ASSERT(Thread == KeGetCurrentThread()); \
ASSERT(Thread->KernelApcDisable < 0); \
@ -96,7 +93,6 @@
KiCheckForKernelApcDelivery(); \
} \
} \
} \
}
//

View file

@ -85,16 +85,7 @@ PEPROCESS
NTAPI
IoGetCurrentProcess(VOID)
{
/* FIXME: Completely broken */
if (PsGetCurrentThread() == NULL ||
PsGetCurrentThread()->Tcb.ApcState.Process == NULL)
{
return(PsInitialSystemProcess);
}
else
{
return(PEPROCESS)(PsGetCurrentThread()->Tcb.ApcState.Process);
}
return (PEPROCESS)PsGetCurrentThread()->Tcb.ApcState.Process;
}
/*

View file

@ -558,6 +558,9 @@ MainLoop:
call @KfLowerIrql@4
CheckSchedule:
/* FIXME: ROS HACK */
call _NtYieldExecution@0
/* Check if a next thread is queued */
cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
#ifdef CONFIG_SMP

View file

@ -14,6 +14,10 @@
/* GLOBALS *******************************************************************/
VOID
FASTCALL
KiIdleLoop(VOID);
/* Spinlocks used only on X86 */
KSPIN_LOCK KiFreezeExecutionLock;
KSPIN_LOCK Ki486CompatibilityLock;
@ -134,6 +138,9 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
/* Set the current MP Master KPRCB to the Boot PRCB */
Prcb->MultiThreadSetMaster = Prcb;
/* Lower to APC_LEVEL */
KfLowerIrql(APC_LEVEL);
/* Initialize some spinlocks */
KeInitializeSpinLock(&KiFreezeExecutionLock);
KeInitializeSpinLock(&Ki486CompatibilityLock);
@ -157,7 +164,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
DPRINT1("SMP Boot support not yet present\n");
}
#if 0
/* Setup the Idle Thread */
KeInitializeThread(InitProcess,
InitThread,
@ -167,7 +173,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
NULL,
NULL,
IdleStack);
#endif
InitThread->NextProcessor = Number;
InitThread->Priority = HIGH_PRIORITY;
InitThread->State = Running;
@ -175,10 +180,13 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
InitThread->WaitIrql = DISPATCH_LEVEL;
InitProcess->ActiveProcessors = 1 << Number;
/* HACK for MmUpdatePageDir */
((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
/* Set up the thread-related fields in the PRCB */
//Prcb->CurrentThread = InitThread;
Prcb->CurrentThread = InitThread;
Prcb->NextThread = NULL;
//Prcb->IdleThread = InitThread;
Prcb->IdleThread = InitThread;
/* Initialize the Kernel Executive */
ExpInitializeExecutive();
@ -212,19 +220,11 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
}
}
/* Free Initial Memory */
MiFreeInitMemory();
/* Raise to Dispatch */
KfRaiseIrql(DISPATCH_LEVEL);
while (1)
{
LARGE_INTEGER Timeout;
Timeout.QuadPart = 0x7fffffffffffffffLL;
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
}
/* Bug Check and loop forever if anything failed */
KEBUGCHECK(0);
for(;;);
/* Set the Idle Priority to 0. This will jump into Phase 1 */
KeSetPriorityThread(InitThread, 0);
}
VOID
@ -303,5 +303,14 @@ AppCpuInit:
Prcb,
Cpu,
LoaderBlock);
/* Lower IRQL back to DISPATCH_LEVEL */
KfLowerIrql(DISPATCH_LEVEL);
/* Set the priority of this thread to 0 */
KeGetCurrentThread()->Priority = 0;
/* Jump into the idle loop */
KiIdleLoop();
}

View file

@ -40,6 +40,10 @@ GENERIC_MAPPING ObpDirectoryMapping =
PDEVICE_MAP ObSystemDeviceMap = NULL;
ULONG ObpTraceLevel = OB_HANDLE_DEBUG | OB_REFERENCE_DEBUG;
VOID
NTAPI
PsInitializeQuotaSystem(VOID);
/* PRIVATE FUNCTIONS *********************************************************/
VOID
@ -148,6 +152,13 @@ ObInit(VOID)
/* Initialize lookaside lists */
ObInit2();
/* Initialize default Quota block */
PsInitializeQuotaSystem();
/* Create kernel handle table */
PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL);
ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;
/* Create the Type Type */
DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));

View file

@ -41,7 +41,7 @@ CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES] =
10 * 6
};
static GENERIC_MAPPING PiJobMapping =
GENERIC_MAPPING PspJobMapping =
{
STANDARD_RIGHTS_READ | JOB_OBJECT_QUERY,
STANDARD_RIGHTS_WRITE | JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_SET_ATTRIBUTES | JOB_OBJECT_TERMINATE | JOB_OBJECT_SET_SECURITY_ATTRIBUTES,
@ -53,7 +53,7 @@ static GENERIC_MAPPING PiJobMapping =
VOID
NTAPI
PiDeleteJob ( PVOID ObjectBody )
PspDeleteJob ( PVOID ObjectBody )
{
PEJOB Job = (PEJOB)ObjectBody;
@ -74,28 +74,10 @@ PiDeleteJob ( PVOID ObjectBody )
ExDeleteResource(&Job->JobLock);
}
VOID
INIT_FUNCTION
VOID
NTAPI
PsInitJobManagment ( VOID )
PspInitializeJobStructures(VOID)
{
UNICODE_STRING Name;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
DPRINT("Creating Job Object Type\n");
/* Initialize the Job type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Job");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB);
ObjectTypeInitializer.GenericMapping = PiJobMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.DeleteProcedure = PiDeleteJob;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsJobType);
InitializeListHead(&PsJobListHead);
ExInitializeFastMutex(&PsJobListLock);
}

View file

@ -15,12 +15,9 @@
/* GLOBALS *******************************************************************/
PEPROCESS PsInitialSystemProcess = NULL;
PEPROCESS PsIdleProcess = NULL;
POBJECT_TYPE PsProcessType = NULL;
extern ULONG PsMinimumWorkingSet, PsMaximumWorkingSet;
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
ULONG PsMinimumWorkingSet, PsMaximumWorkingSet;
POBJECT_TYPE PsProcessType = NULL;
LIST_ENTRY PsActiveProcessHead;
KGUARDED_MUTEX PspActiveProcessMutex;
@ -384,13 +381,13 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
SECURITY_SUBJECT_CONTEXT SubjectContext;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG,
"ProcessHandle: %p Parent: %p\n", ProcessHandle, Parent);
"ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess);
/* Validate flags */
if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER;
/* Check for parent */
if(ParentProcess)
if (ParentProcess)
{
/* Reference it */
Status = ObReferenceObjectByHandle(ParentProcess,
@ -417,14 +414,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
{
/* We have no parent */
Parent = NULL;
#ifdef CONFIG_SMP
/*
* FIXME: Only the boot cpu is initialized in the early boot phase.
*/
Affinity = 0xffffffff;
#else
Affinity = KeActiveProcessors;
#endif
}
/* Save working set data */
@ -488,6 +478,9 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
}
else
{
/* Assume no section object */
SectionObject = NULL;
/* Is the parent the initial process? */
if (Parent != PsInitialSystemProcess)
{

View file

@ -14,28 +14,28 @@
#define NDEBUG
#include <internal/debug.h>
#define LockEvent Spare0[0]
#define LockCount Spare0[1]
#define LockOwner Spare0[2]
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
extern LARGE_INTEGER ShortPsLockDelay;
extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
static GENERIC_MAPPING PiProcessMapping = {
GENERIC_MAPPING PspProcessMapping =
{
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
PROCESS_SUSPEND_RESUME,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
PROCESS_ALL_ACCESS};
PROCESS_ALL_ACCESS
};
static GENERIC_MAPPING PiThreadMapping = {
GENERIC_MAPPING PspThreadMapping =
{
STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME |
THREAD_ALERT | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
THREAD_ALL_ACCESS};
THREAD_ALL_ACCESS
};
extern ULONG NtBuildNumber;
extern ULONG NtMajorVersion;
@ -45,336 +45,264 @@ extern PVOID KeUserCallbackDispatcher;
extern PVOID KeUserExceptionDispatcher;
extern PVOID KeRaiseUserExceptionDispatcher;
PVOID PspSystemDllBase = NULL;
PVOID PspSystemDllSection = NULL;
PVOID PspSystemDllEntryPoint = NULL;
PHANDLE_TABLE PspCidTable = NULL;
VOID STDCALL PspKillMostProcesses();
VOID INIT_FUNCTION NTAPI PsInitClientIDManagment(VOID);
NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID);
PVOID PspSystemDllBase;
PVOID PspSystemDllSection;
PVOID PspSystemDllEntryPoint;
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, PiInitProcessManager)
#pragma alloc_text(INIT, PsInitClientIDManagment)
#pragma alloc_text(INIT, PsInitThreadManagment)
#pragma alloc_text(INIT, PsInitProcessManagment)
#pragma alloc_text(INIT, PspLookupKernelUserEntryPoints)
#pragma alloc_text(INIT, PsLocateSystemDll)
#endif
PHANDLE_TABLE PspCidTable;
PEPROCESS PsInitialSystemProcess = NULL;
PEPROCESS PsIdleProcess = NULL;
HANDLE PspInitialSystemProcessHandle;
ULONG PsMinimumWorkingSet, PsMaximumWorkingSet;
struct
{
LIST_ENTRY List;
KGUARDED_MUTEX Lock;
} PspWorkingSetChangeHead;
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 ***************************************************************/
VOID
FASTCALL
KiIdleLoop(VOID);
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);
/* FUNCTIONS *****************************************************************/
/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
VOID
INIT_FUNCTION
NTAPI
PsInitHackThread(VOID)
{
PETHREAD IdleThread;
ExPhase2Init(
IN PVOID Context
);
IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD));
RtlZeroMemory(IdleThread, sizeof(ETHREAD));
IdleThread->ThreadsProcess = PsIdleProcess;
KeInitializeThread(&PsIdleProcess->Pcb,
&IdleThread->Tcb,
PspSystemThreadStartup,
(PVOID)KiIdleLoop,
NULL,
NULL,
NULL,
(PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) +
KERNEL_STACK_SIZE));
InitializeListHead(&IdleThread->IrpList);
KeReadyThread(&IdleThread->Tcb);
KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb;
KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY);
KeSetAffinityThread(&IdleThread->Tcb, 1 << 0);
}
/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
VOID
INIT_FUNCTION
BOOLEAN
NTAPI
PsInitHackThread2(IN PETHREAD *Hack)
PspInitPhase0(VOID)
{
PETHREAD IdleThread;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE SysThreadHandle;
PETHREAD SysThread;
MM_SYSTEMSIZE SystemSize;
UNICODE_STRING Name;
ULONG i;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD));
RtlZeroMemory(IdleThread, sizeof(ETHREAD));
IdleThread->ThreadsProcess = PsInitialSystemProcess;
KeInitializeThread(&PsInitialSystemProcess->Pcb,
&IdleThread->Tcb,
PspSystemThreadStartup,
NULL,
NULL,
NULL,
NULL,
P0BootStack);
InitializeListHead(&IdleThread->IrpList);
*Hack = IdleThread;
}
/* FIXME: Initialize Lock Data do it STATIC */
ShortPsLockDelay.QuadPart = -100LL;
VOID
INIT_FUNCTION
NTAPI
PiInitProcessManager(VOID)
{
PsInitJobManagment();
PsInitProcessManagment();
PsInitThreadManagment();
PsInitHackThread();
}
/* Get the system size */
SystemSize = MmQuerySystemSize();
VOID
INIT_FUNCTION
NTAPI
PsInitClientIDManagment(VOID)
{
PspCidTable = ExCreateHandleTable(NULL);
ASSERT(PspCidTable);
}
/* Setup some memory options */
PspDefaultPagefileLimit = -1;
switch (SystemSize)
{
/* Medimum systems */
case MmMediumSystem:
VOID
INIT_FUNCTION
NTAPI
PsInitThreadManagment(VOID)
/*
* FUNCTION: Initialize thread managment
*/
{
UNICODE_STRING Name;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
PETHREAD FirstThread;
ULONG i;
/* Increase the WS sizes a bit */
PsMinimumWorkingSet += 10;
PsMaximumWorkingSet += 100;
for (i=0; i < MAXIMUM_PRIORITY; i++)
{
InitializeListHead(&PriorityListHead[i]);
}
/* Large systems */
case MmLargeSystem:
/* Increase the WS sizes a bit more */
PsMinimumWorkingSet += 30;
PsMaximumWorkingSet += 300;
/* Small and other systems */
default:
break;
}
/* Setup the quantum table */
PsChangeQuantumTable(FALSE, PsRawPrioritySeparation);
/* Setup callbacks when we implement Generic Callbacks */
/* Set quota settings */
if (!PspDefaultPagedLimit) PspDefaultPagedLimit = 0;
if (!PspDefaultNonPagedLimit) PspDefaultNonPagedLimit = 0;
if (!(PspDefaultNonPagedLimit) && !(PspDefaultPagedLimit))
{
/* Enable give-backs */
PspDoingGiveBacks = TRUE;
}
else
{
/* Disable them */
PspDoingGiveBacks = FALSE;
}
/* Now multiply limits by 1MB */
PspDefaultPagedLimit <<= 20;
PspDefaultNonPagedLimit <<= 20;
if (PspDefaultPagefileLimit != -1) PspDefaultPagefileLimit <<= 20;
/* Initialize the Active Process List */
InitializeListHead(&PsActiveProcessHead);
KeInitializeGuardedMutex(&PspActiveProcessMutex);
/* Get the idle process */
PsIdleProcess = PsGetCurrentProcess();
/* Setup the locks */
PsIdleProcess->ProcessLock.Value = 0;
ExInitializeRundownProtection(&PsIdleProcess->RundownProtect);
/* Initialize the thread list */
InitializeListHead(&PsIdleProcess->ThreadListHead);
/* Clear kernel time */
PsIdleProcess->Pcb.KernelTime = 0;
/* Initialize the Process type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Process");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EPROCESS);
ObjectTypeInitializer.GenericMapping = PspProcessMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsProcessType);
/* Setup ROS Scheduler lists (HACK!) */
for (i = 0; i < MAXIMUM_PRIORITY; i++)
{
InitializeListHead(&PriorityListHead[i]);
}
DPRINT("Creating Thread Object Type\n");
/* Initialize the Thread type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Thread");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETHREAD);
ObjectTypeInitializer.GenericMapping = PiThreadMapping;
ObjectTypeInitializer.GenericMapping = PspThreadMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
ObjectTypeInitializer.DeleteProcedure = PspDeleteThread;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType);
PsInitHackThread2(&FirstThread);
FirstThread->Tcb.State = Running;
FirstThread->Tcb.FreezeCount = 0;
FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */
FirstThread->Tcb.Affinity = (1 << 0);
KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread;
/* Initialize the Job type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Job");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EJOB);
ObjectTypeInitializer.GenericMapping = PspJobMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.DeleteProcedure = PspDeleteJob;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsJobType);
DPRINT("FirstThread %x\n",FirstThread);
/* Initialize job structures external to this file */
PspInitializeJobStructures();
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
}
/* Initialize the Working Set data */
InitializeListHead(&PspWorkingSetChangeHead.List);
KeInitializeGuardedMutex(&PspWorkingSetChangeHead.Lock);
VOID
INIT_FUNCTION
NTAPI
PsInitProcessManagment(VOID)
{
PKPROCESS KProcess;
NTSTATUS Status;
UNICODE_STRING Name;
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
/* Create the CID Handle table */
PspCidTable = ExCreateHandleTable(NULL);
ShortPsLockDelay.QuadPart = -100LL;
/* FIXME: Initialize LDT/VDM support */
/*
* Register the process object type
*/
/* Setup the reaper */
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
DPRINT("Creating Process Object Type\n");
/* Initialize the Process type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
RtlInitUnicodeString(&Name, L"Process");
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EPROCESS);
ObjectTypeInitializer.GenericMapping = PiProcessMapping;
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsProcessType);
/* Set the boot access token */
PspBootAccessToken = (PTOKEN)(PsIdleProcess->Token.Value & ~MAX_FAST_REFS);
InitializeListHead(&PsActiveProcessHead);
KeInitializeGuardedMutex(&PspActiveProcessMutex);
/* Setup default object attributes */
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0,
NULL,
NULL);
/* Setup the quantum table */
PsChangeQuantumTable(FALSE, PsRawPrioritySeparation);
/* Create the Initial System Process */
Status = PspCreateProcess(&PspInitialSystemProcessHandle,
PROCESS_ALL_ACCESS,
&ObjectAttributes,
0,
FALSE,
0,
0,
0,
FALSE);
if (!NT_SUCCESS(Status)) return FALSE;
/*
* Initialize the default quota block.
*/
/* Get a reference to it */
ObReferenceObjectByHandle(PspInitialSystemProcessHandle,
0,
PsProcessType,
KernelMode,
(PVOID*)&PsInitialSystemProcess,
NULL);
RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1;
PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1;
PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */
/* The PD we gave it is invalid at this point, do what old ROS did */
PsInitialSystemProcess->Pcb.DirectoryTableBase = (LARGE_INTEGER)
(LONGLONG)
(ULONG)MmGetPageDirectory();
PsIdleProcess->Pcb.DirectoryTableBase = PsInitialSystemProcess->Pcb.DirectoryTableBase;
/*
* Initialize the idle process
*/
Status = ObCreateObject(KernelMode,
PsProcessType,
NULL,
KernelMode,
NULL,
sizeof(EPROCESS),
0,
0,
(PVOID*)&PsIdleProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status);
KEBUGCHECK(0);
return;
}
/* Copy the process names */
strcpy(PsIdleProcess->ImageFileName, "Idle");
strcpy(PsInitialSystemProcess->ImageFileName, "System");
RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
/* Allocate a structure for the audit name */
PsIdleProcess->SeAuditProcessCreationInfo.ImageFileName =
ExAllocatePoolWithTag(PagedPool, sizeof(UNICODE_STRING), TAG_SEPA);
if (!PsIdleProcess->SeAuditProcessCreationInfo.ImageFileName) KEBUGCHECK(0);
PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
PsIdleProcess->Pcb.IopmOffset = 0xffff;
PsIdleProcess->Pcb.BasePriority = PROCESS_PRIORITY_IDLE;
PsIdleProcess->Pcb.QuantumReset = 6;
InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead);
InitializeListHead(&PsIdleProcess->ThreadListHead);
InitializeListHead(&PsIdleProcess->ActiveProcessLinks);
ObInitializeFastReference(&PsIdleProcess->Token, NULL);
KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.Header,
ProcessObject,
sizeof(EPROCESS) / sizeof(LONG),
FALSE);
PsIdleProcess->Pcb.DirectoryTableBase.QuadPart = (ULONG_PTR)MmGetPageDirectory();
strcpy(PsIdleProcess->ImageFileName, "Idle");
PspInheritQuota(PsIdleProcess, NULL);
/* Setup the system initailization thread */
Status = PsCreateSystemThread(&SysThreadHandle,
THREAD_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
ExPhase2Init,
NULL);
if (!NT_SUCCESS(Status)) return FALSE;
/*
* Initialize the system process
*/
Status = ObCreateObject(KernelMode,
PsProcessType,
NULL,
KernelMode,
NULL,
sizeof(EPROCESS),
0,
0,
(PVOID*)&PsInitialSystemProcess);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status);
KEBUGCHECK(0);
return;
}
/* Create a handle to it */
ObReferenceObjectByHandle(SysThreadHandle,
0,
PsThreadType,
KernelMode,
(PVOID*)&SysThread,
NULL);
ZwClose(SysThreadHandle);
/* System threads may run on any processor. */
RtlZeroMemory(PsInitialSystemProcess, sizeof(EPROCESS));
#ifdef CONFIG_SMP
/* FIXME:
* Only the boot cpu is initialized. Threads of the
* system process should be able to run on all cpus.
*/
PsInitialSystemProcess->Pcb.Affinity = 0xffffffff;
#else
PsInitialSystemProcess->Pcb.Affinity = KeActiveProcessors;
#endif
PsInitialSystemProcess->Pcb.IopmOffset = 0xffff;
PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIORITY_NORMAL;
PsInitialSystemProcess->Pcb.QuantumReset = 6;
InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead);
KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.Header,
ProcessObject,
sizeof(EPROCESS) / sizeof(LONG),
FALSE);
KProcess = &PsInitialSystemProcess->Pcb;
PspInheritQuota(PsInitialSystemProcess, NULL);
MmInitializeAddressSpace(PsInitialSystemProcess,
(PMADDRESS_SPACE)&(PsInitialSystemProcess)->VadRoot);
(PsInitialSystemProcess)->LockEvent =
ExAllocatePoolWithTag(PagedPool, sizeof(KEVENT), TAG('P', 's', 'L', 'k'));
KeInitializeEvent((PsInitialSystemProcess)->LockEvent, SynchronizationEvent, FALSE);
#if defined(__GNUC__)
KProcess->DirectoryTableBase =
(LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
#else
{
LARGE_INTEGER dummy;
dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory();
KProcess->DirectoryTableBase = dummy;
}
#endif
strcpy(PsInitialSystemProcess->ImageFileName, "System");
PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
InsertHeadList(&PsActiveProcessHead,
&PsInitialSystemProcess->ActiveProcessLinks);
InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
#ifndef SCHED_REWRITE
{
PTOKEN BootToken;
/* No parent, this is the Initial System Process. Assign Boot Token */
BootToken = SepCreateSystemProcessToken();
BootToken->TokenInUse = TRUE;
ObInitializeFastReference(&PsInitialSystemProcess->Token, BootToken);
}
#endif
}
VOID
PspPostInitSystemProcess(VOID)
{
HANDLE_TABLE_ENTRY CidEntry;
/* this routine is called directly after the exectuive handle tables were
initialized. We'll set up the Client ID handle table and assign the system
process a PID */
PsInitClientIDManagment();
ObpCreateHandleTable(NULL, PsInitialSystemProcess);
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
CidEntry.Object = PsInitialSystemProcess;
CidEntry.GrantedAccess = 0;
PsInitialSystemProcess->UniqueProcessId = ExCreateHandle(PspCidTable, &CidEntry);
if(!PsInitialSystemProcess->UniqueProcessId)
{
DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
KEBUGCHECK(0);
}
/* Return success */
return TRUE;
}
NTSTATUS

View file

@ -13,8 +13,21 @@
#define NDEBUG
#include <internal/debug.h>
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock;
/* FUNCTIONS ***************************************************************/
VOID
NTAPI
PsInitializeQuotaSystem(VOID)
{
RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1;
PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1;
PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */
PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;
}
VOID
STDCALL
PspInheritQuota(PEPROCESS Process, PEPROCESS ParentProcess)

View file

@ -14,6 +14,15 @@
#define NDEBUG
#include <internal/debug.h>
PTOKEN PspBootAccessToken;
VOID
NTAPI
SeAssignPrimaryToken(
IN PEPROCESS Process,
IN PTOKEN Token
);
/* PRIVATE FUNCTIONS *********************************************************/
VOID
@ -86,13 +95,9 @@ PspInitializeProcessSecurity(IN PEPROCESS Process,
}
else
{
#ifdef SCHED_REWRITE
/* No parent, assign the Boot Token */
ObInitializeFastReference(&Process->Token, NULL);
SeAssignPrimaryToken(Process, PspBootAccessToken);
#else
DPRINT1("PspInitializeProcessSecurity called with no parent.\n");
#endif
}
/* Return to caller */

View file

@ -67,9 +67,18 @@ INIT_FUNCTION
NTAPI
SeInit2(VOID)
{
SepInitializeTokenImplementation();
/* Initialize token objects */
SepInitializeTokenImplementation();
return TRUE;
/* Clear impersonation info for the idle thread */
PsGetCurrentThread()->ImpersonationInfo = NULL;
PspClearCrossThreadFlag(PsGetCurrentThread(), CT_ACTIVE_IMPERSONATION_INFO_BIT);
/* Initailize the boot token */
ObInitializeFastReference(&PsGetCurrentProcess()->Token, NULL);
ObInitializeFastReference(&PsGetCurrentProcess()->Token,
SepCreateSystemProcessToken());
return TRUE;
}
@ -425,15 +434,6 @@ SeCaptureSubjectContextEx(IN PETHREAD Thread,
BOOLEAN CopyOnOpen, EffectiveOnly;
PAGED_CODE();
/* ROS HACK */
if (!Process)
{
SubjectContext->PrimaryToken = NULL;
SubjectContext->ProcessAuditId = 0;
SubjectContext->ClientToken = NULL;
return;
}
/* Save the unique ID */
SubjectContext->ProcessAuditId = Process->UniqueProcessId;

View file

@ -1896,6 +1896,26 @@ NtAdjustPrivilegesToken (IN HANDLE TokenHandle,
return Status;
}
VOID
NTAPI
SeAssignPrimaryToken(IN PEPROCESS Process,
IN PTOKEN Token)
{
PAGED_CODE();
/* Sanity checks */
ASSERT(Token->TokenType == TokenPrimary);
ASSERT(!Token->TokenInUse);
/* Clean any previous token */
if (Process->Token.Object) SeDeassignPrimaryToken(Process);
/* Set the new token */
ObReferenceObject(Token);
Token->TokenInUse = TRUE;
ObInitializeFastReference(&Process->Token, Token);
}
PTOKEN
STDCALL
SepCreateSystemProcessToken(VOID)
@ -1933,12 +1953,6 @@ SepCreateSystemProcessToken(VOID)
{
return NULL;
}
Status = ObInsertObject(AccessToken,
NULL,
TOKEN_ALL_ACCESS,
0,
NULL,
NULL);
Status = ExpAllocateLocallyUniqueId(&AccessToken->TokenId);
if (!NT_SUCCESS(Status))