2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ps/psmgr.c
5 * PURPOSE: Process Manager: Initialization Code
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 #include <internal/debug.h>
15 extern ULONG ExpInitializationPhase
;
17 GENERIC_MAPPING PspProcessMapping
=
19 STANDARD_RIGHTS_READ
| PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
,
20 STANDARD_RIGHTS_WRITE
| PROCESS_CREATE_PROCESS
| PROCESS_CREATE_THREAD
|
21 PROCESS_VM_OPERATION
| PROCESS_VM_WRITE
| PROCESS_DUP_HANDLE
|
22 PROCESS_TERMINATE
| PROCESS_SET_QUOTA
| PROCESS_SET_INFORMATION
|
23 PROCESS_SUSPEND_RESUME
,
24 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
,
28 GENERIC_MAPPING PspThreadMapping
=
30 STANDARD_RIGHTS_READ
| THREAD_GET_CONTEXT
| THREAD_QUERY_INFORMATION
,
31 STANDARD_RIGHTS_WRITE
| THREAD_TERMINATE
| THREAD_SUSPEND_RESUME
|
32 THREAD_ALERT
| THREAD_SET_INFORMATION
| THREAD_SET_CONTEXT
,
33 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
,
37 PVOID PspSystemDllBase
;
38 PVOID PspSystemDllSection
;
39 PVOID PspSystemDllEntryPoint
;
41 ANSI_STRING ThunkName
= RTL_CONSTANT_STRING("LdrInitializeThunk");
42 ANSI_STRING ApcName
= RTL_CONSTANT_STRING("KiUserApcDispatcher");
43 ANSI_STRING ExceptName
= RTL_CONSTANT_STRING("KiUserExceptionDispatcher");
44 ANSI_STRING CallbackName
= RTL_CONSTANT_STRING("KiUserCallbackDispatcher");
45 ANSI_STRING RaiseName
= RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher");
46 ANSI_STRING FastName
= RTL_CONSTANT_STRING("KiFastSystemCall");
47 ANSI_STRING FastReturnName
= RTL_CONSTANT_STRING("KiFastSystemCallRet");
48 ANSI_STRING InterruptName
= RTL_CONSTANT_STRING("KiIntSystemCall");
50 UNICODE_STRING PsNtDllPathName
=
51 RTL_CONSTANT_STRING(L
"\\SystemRoot\\system32\\ntdll.dll");
53 PHANDLE_TABLE PspCidTable
;
55 PEPROCESS PsInitialSystemProcess
= NULL
;
56 PEPROCESS PsIdleProcess
= NULL
;
57 HANDLE PspInitialSystemProcessHandle
;
59 ULONG PsMinimumWorkingSet
, PsMaximumWorkingSet
;
64 } PspWorkingSetChangeHead
;
65 ULONG PspDefaultPagedLimit
, PspDefaultNonPagedLimit
, PspDefaultPagefileLimit
;
66 BOOLEAN PspDoingGiveBacks
;
68 /* PRIVATE FUNCTIONS *********************************************************/
72 PspLookupSystemDllEntryPoint(IN PANSI_STRING Name
,
75 /* Call the LDR Routine */
76 return LdrGetProcedureAddress(PspSystemDllBase
, Name
, 0, EntryPoint
);
81 PspLookupKernelUserEntryPoints(VOID
)
85 /* Get user-mode APC trampoline */
86 Status
= PspLookupSystemDllEntryPoint(&ApcName
,
87 &KeUserApcDispatcher
);
88 if (!NT_SUCCESS(Status
)) return Status
;
90 /* Get user-mode exception dispatcher */
91 Status
= PspLookupSystemDllEntryPoint(&ExceptName
,
92 &KeUserExceptionDispatcher
);
93 if (!NT_SUCCESS(Status
)) return Status
;
95 /* Get user-mode callback dispatcher */
96 Status
= PspLookupSystemDllEntryPoint(&CallbackName
,
97 &KeUserCallbackDispatcher
);
98 if (!NT_SUCCESS(Status
)) return Status
;
100 /* Get user-mode exception raise trampoline */
101 Status
= PspLookupSystemDllEntryPoint(&RaiseName
,
102 &KeRaiseUserExceptionDispatcher
);
103 if (!NT_SUCCESS(Status
)) return Status
;
105 /* Check if this is a machine that supports SYSENTER */
106 if (KeFeatureBits
& KF_FAST_SYSCALL
)
108 /* Get user-mode sysenter stub */
109 Status
= PspLookupSystemDllEntryPoint(&FastName
,
110 (PVOID
)&SharedUserData
->
112 if (!NT_SUCCESS(Status
)) return Status
;
114 /* Get user-mode sysenter return stub */
115 Status
= PspLookupSystemDllEntryPoint(&FastReturnName
,
116 (PVOID
)&SharedUserData
->
121 /* Get the user-mode interrupt stub */
122 Status
= PspLookupSystemDllEntryPoint(&InterruptName
,
123 (PVOID
)&SharedUserData
->
127 /* Set the test instruction */
128 if (!NT_SUCCESS(Status
)) SharedUserData
->TestRetInstruction
= 0xC3;
130 /* Return the status */
136 PspMapSystemDll(IN PEPROCESS Process
,
140 LARGE_INTEGER Offset
= {{0}};
144 /* Map the System DLL */
145 Status
= MmMapViewOfSection(PspSystemDllSection
,
156 /* Write the image base and return status */
157 if (DllBase
) *DllBase
= ImageBase
;
163 PsLocateSystemDll(VOID
)
165 OBJECT_ATTRIBUTES ObjectAttributes
;
166 IO_STATUS_BLOCK IoStatusBlock
;
167 HANDLE FileHandle
, SectionHandle
;
169 ULONG_PTR HardErrorParameters
;
170 ULONG HardErrorResponse
;
172 /* Locate and open NTDLL to determine ImageBase and LdrStartup */
173 InitializeObjectAttributes(&ObjectAttributes
,
178 Status
= ZwOpenFile(&FileHandle
,
184 if (!NT_SUCCESS(Status
))
186 /* Failed, bugcheck */
187 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED
, Status
, 2, 0, 0);
190 /* FIXME: Check if the image is valid */
191 Status
= MmCheckSystemImage(FileHandle
, TRUE
);
192 if (Status
== STATUS_IMAGE_CHECKSUM_MISMATCH
)
194 /* Raise a hard error */
195 HardErrorParameters
= (ULONG_PTR
)&PsNtDllPathName
;
196 NtRaiseHardError(Status
,
199 &HardErrorParameters
,
205 /* Create a section for NTDLL */
206 Status
= ZwCreateSection(&SectionHandle
,
214 if (!NT_SUCCESS(Status
))
216 /* Failed, bugcheck */
217 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED
, Status
, 3, 0, 0);
220 /* Reference the Section */
221 Status
= ObReferenceObjectByHandle(SectionHandle
,
225 (PVOID
*)&PspSystemDllSection
,
227 ZwClose(SectionHandle
);
228 if (!NT_SUCCESS(Status
))
230 /* Failed, bugcheck */
231 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED
, Status
, 4, 0, 0);
235 Status
= PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase
);
236 if (!NT_SUCCESS(Status
))
238 /* Failed, bugcheck */
239 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED
, Status
, 5, 0, 0);
248 PspInitializeSystemDll(VOID
)
252 /* Get user-mode startup thunk */
253 Status
= PspLookupSystemDllEntryPoint(&ThunkName
, &PspSystemDllEntryPoint
);
254 if (!NT_SUCCESS(Status
))
256 /* Failed, bugcheck */
257 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED
, Status
, 7, 0, 0);
260 /* Get all the other entrypoints */
261 Status
= PspLookupKernelUserEntryPoints();
262 if (!NT_SUCCESS(Status
))
264 /* Failed, bugcheck */
265 KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED
, Status
, 8, 0, 0);
276 /* Initialize the System DLL and return status of operation */
277 if (!NT_SUCCESS(PspInitializeSystemDll())) return FALSE
;
283 PspInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
286 OBJECT_ATTRIBUTES ObjectAttributes
;
287 HANDLE SysThreadHandle
;
289 MM_SYSTEMSIZE SystemSize
;
291 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
294 /* Get the system size */
295 SystemSize
= MmQuerySystemSize();
297 /* Setup some memory options */
298 PspDefaultPagefileLimit
= -1;
301 /* Medimum systems */
304 /* Increase the WS sizes a bit */
305 PsMinimumWorkingSet
+= 10;
306 PsMaximumWorkingSet
+= 100;
311 /* Increase the WS sizes a bit more */
312 PsMinimumWorkingSet
+= 30;
313 PsMaximumWorkingSet
+= 300;
315 /* Small and other systems */
320 /* Setup callbacks */
321 for (i
= 0; i
< PSP_MAX_CREATE_THREAD_NOTIFY
; i
++)
323 ExInitializeCallBack(&PspThreadNotifyRoutine
[i
]);
325 for (i
= 0; i
< PSP_MAX_CREATE_PROCESS_NOTIFY
; i
++)
327 ExInitializeCallBack(&PspProcessNotifyRoutine
[i
]);
329 for (i
= 0; i
< PSP_MAX_LOAD_IMAGE_NOTIFY
; i
++)
331 ExInitializeCallBack(&PspLoadImageNotifyRoutine
[i
]);
334 /* Setup the quantum table */
335 PsChangeQuantumTable(FALSE
, PsRawPrioritySeparation
);
337 /* Set quota settings */
338 if (!PspDefaultPagedLimit
) PspDefaultPagedLimit
= 0;
339 if (!PspDefaultNonPagedLimit
) PspDefaultNonPagedLimit
= 0;
340 if (!(PspDefaultNonPagedLimit
) && !(PspDefaultPagedLimit
))
342 /* Enable give-backs */
343 PspDoingGiveBacks
= TRUE
;
348 PspDoingGiveBacks
= FALSE
;
351 /* Now multiply limits by 1MB */
352 PspDefaultPagedLimit
<<= 20;
353 PspDefaultNonPagedLimit
<<= 20;
354 if (PspDefaultPagefileLimit
!= -1) PspDefaultPagefileLimit
<<= 20;
356 /* Initialize the Active Process List */
357 InitializeListHead(&PsActiveProcessHead
);
358 KeInitializeGuardedMutex(&PspActiveProcessMutex
);
360 /* Get the idle process */
361 PsIdleProcess
= PsGetCurrentProcess();
363 /* Setup the locks */
364 PsIdleProcess
->ProcessLock
.Value
= 0;
365 ExInitializeRundownProtection(&PsIdleProcess
->RundownProtect
);
367 /* Initialize the thread list */
368 InitializeListHead(&PsIdleProcess
->ThreadListHead
);
370 /* Clear kernel time */
371 PsIdleProcess
->Pcb
.KernelTime
= 0;
373 /* Initialize Object Initializer */
374 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
375 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
376 ObjectTypeInitializer
.InvalidAttributes
= OBJ_OPENLINK
|
380 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
381 ObjectTypeInitializer
.SecurityRequired
= TRUE
;
383 /* Initialize the Process type */
384 RtlInitUnicodeString(&Name
, L
"Process");
385 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(EPROCESS
);
386 ObjectTypeInitializer
.GenericMapping
= PspProcessMapping
;
387 ObjectTypeInitializer
.ValidAccessMask
= PROCESS_ALL_ACCESS
;
388 ObjectTypeInitializer
.DeleteProcedure
= PspDeleteProcess
;
389 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &PsProcessType
);
391 /* Initialize the Thread type */
392 RtlInitUnicodeString(&Name
, L
"Thread");
393 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
394 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(ETHREAD
);
395 ObjectTypeInitializer
.GenericMapping
= PspThreadMapping
;
396 ObjectTypeInitializer
.ValidAccessMask
= THREAD_ALL_ACCESS
;
397 ObjectTypeInitializer
.DeleteProcedure
= PspDeleteThread
;
398 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &PsThreadType
);
400 /* Initialize the Job type */
401 RtlInitUnicodeString(&Name
, L
"Job");
402 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
403 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(EJOB
);
404 ObjectTypeInitializer
.GenericMapping
= PspJobMapping
;
405 ObjectTypeInitializer
.ValidAccessMask
= JOB_OBJECT_ALL_ACCESS
;
406 ObjectTypeInitializer
.DeleteProcedure
= PspDeleteJob
;
407 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &PsJobType
);
409 /* Initialize job structures external to this file */
410 PspInitializeJobStructures();
412 /* Initialize the Working Set data */
413 InitializeListHead(&PspWorkingSetChangeHead
.List
);
414 KeInitializeGuardedMutex(&PspWorkingSetChangeHead
.Lock
);
416 /* Create the CID Handle table */
417 PspCidTable
= ExCreateHandleTable(NULL
);
418 if (!PspCidTable
) return FALSE
;
420 /* FIXME: Initialize LDT/VDM support */
422 /* Setup the reaper */
423 ExInitializeWorkItem(&PspReaperWorkItem
, PspReapRoutine
, NULL
);
425 /* Set the boot access token */
426 PspBootAccessToken
= (PTOKEN
)(PsIdleProcess
->Token
.Value
& ~MAX_FAST_REFS
);
428 /* Setup default object attributes */
429 InitializeObjectAttributes(&ObjectAttributes
,
435 /* Create the Initial System Process */
436 Status
= PspCreateProcess(&PspInitialSystemProcessHandle
,
445 if (!NT_SUCCESS(Status
)) return FALSE
;
447 /* Get a reference to it */
448 ObReferenceObjectByHandle(PspInitialSystemProcessHandle
,
452 (PVOID
*)&PsInitialSystemProcess
,
455 /* Copy the process names */
456 strcpy(PsIdleProcess
->ImageFileName
, "Idle");
457 strcpy(PsInitialSystemProcess
->ImageFileName
, "System");
459 /* Allocate a structure for the audit name */
460 PsInitialSystemProcess
->SeAuditProcessCreationInfo
.ImageFileName
=
461 ExAllocatePoolWithTag(PagedPool
,
462 sizeof(OBJECT_NAME_INFORMATION
),
464 if (!PsInitialSystemProcess
->SeAuditProcessCreationInfo
.ImageFileName
)
466 /* Allocation failed */
471 RtlZeroMemory(PsInitialSystemProcess
->
472 SeAuditProcessCreationInfo
.ImageFileName
,
473 sizeof(OBJECT_NAME_INFORMATION
));
475 /* Setup the system initialization thread */
476 Status
= PsCreateSystemThread(&SysThreadHandle
,
481 Phase1Initialization
,
483 if (!NT_SUCCESS(Status
)) return FALSE
;
485 /* Create a handle to it */
486 ObReferenceObjectByHandle(SysThreadHandle
,
492 ZwClose(SysThreadHandle
);
500 PsInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
502 /* Check the initialization phase */
503 switch (ExpInitializationPhase
)
508 return PspInitPhase0(LoaderBlock
);
513 return PspInitPhase1();
517 /* Don't know any other phase! Bugcheck! */
518 KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL
,
520 ExpInitializationPhase
,
527 /* PUBLIC FUNCTIONS **********************************************************/
534 PsGetVersion(IN PULONG MajorVersion OPTIONAL
,
535 IN PULONG MinorVersion OPTIONAL
,
536 IN PULONG BuildNumber OPTIONAL
,
537 IN PUNICODE_STRING CSDVersion OPTIONAL
)
539 if (MajorVersion
) *MajorVersion
= NtMajorVersion
;
540 if (MinorVersion
) *MinorVersion
= NtMinorVersion
;
541 if (BuildNumber
) *BuildNumber
= NtBuildNumber
;
545 CSDVersion
->Length
= 0;
546 CSDVersion
->MaximumLength
= 0;
547 CSDVersion
->Buffer
= NULL
;
549 CSDVersion
->Length
= CmCSDVersionString
.Length
;
550 CSDVersion
->MaximumLength
= CmCSDVersionString
.Maximum
;
551 CSDVersion
->Buffer
= CmCSDVersionString
.Buffer
;
555 /* Check the High word */
556 return (NtBuildNumber
>> 28) == 0xC;
561 NtApphelpCacheControl(IN APPHELPCACHESERVICECLASS Service
,
562 IN PVOID ServiceData
)
565 return STATUS_NOT_IMPLEMENTED
;