3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/psmgr.c
6 * PURPOSE: Process management
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
11 /* INCLUDES **************************************************************/
15 #include <internal/debug.h>
17 extern LARGE_INTEGER ShortPsLockDelay
, PsLockTimeout
;
18 extern LIST_ENTRY PriorityListHead
[MAXIMUM_PRIORITY
];
20 static GENERIC_MAPPING PiProcessMapping
= {
21 STANDARD_RIGHTS_READ
| PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
,
22 STANDARD_RIGHTS_WRITE
| PROCESS_CREATE_PROCESS
| PROCESS_CREATE_THREAD
|
23 PROCESS_VM_OPERATION
| PROCESS_VM_WRITE
| PROCESS_DUP_HANDLE
|
24 PROCESS_TERMINATE
| PROCESS_SET_QUOTA
| PROCESS_SET_INFORMATION
|
25 PROCESS_SUSPEND_RESUME
,
26 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
,
29 static GENERIC_MAPPING PiThreadMapping
= {
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
,
36 BOOLEAN DoneInitYet
= FALSE
;
38 extern ULONG NtBuildNumber
;
39 extern ULONG NtMajorVersion
;
40 extern ULONG NtMinorVersion
;
44 PsInitClientIDManagment(VOID
);
46 VOID STDCALL
PspKillMostProcesses();
48 /* FUNCTIONS ***************************************************************/
50 VOID
PiShutdownProcessManager(VOID
)
52 DPRINT("PiShutdownProcessManager()\n");
54 PspKillMostProcesses();
58 PiInitProcessManager(VOID
)
61 PsInitProcessManagment();
62 PsInitThreadManagment();
64 PsInitialiseW32Call();
69 PsInitThreadManagment(VOID
)
71 * FUNCTION: Initialize thread managment
75 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
79 for (i
=0; i
< MAXIMUM_PRIORITY
; i
++)
81 InitializeListHead(&PriorityListHead
[i
]);
84 DPRINT("Creating Thread Object Type\n");
86 /* Initialize the Thread type */
87 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
88 RtlInitUnicodeString(&Name
, L
"Thread");
89 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
90 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(ETHREAD
);
91 ObjectTypeInitializer
.GenericMapping
= PiThreadMapping
;
92 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
93 ObjectTypeInitializer
.ValidAccessMask
= THREAD_ALL_ACCESS
;
94 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
95 ObjectTypeInitializer
.DeleteProcedure
= PspDeleteThread
;
96 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &PsThreadType
);
98 PsInitializeIdleOrFirstThread(PsInitialSystemProcess
, &FirstThread
, NULL
, KernelMode
, TRUE
);
99 FirstThread
->Tcb
.State
= Running
;
100 FirstThread
->Tcb
.FreezeCount
= 0;
101 FirstThread
->Tcb
.UserAffinity
= (1 << 0); /* Set the affinity of the first thread to the boot processor */
102 FirstThread
->Tcb
.Affinity
= (1 << 0);
103 KeGetCurrentPrcb()->CurrentThread
= (PVOID
)FirstThread
;
105 DPRINT("FirstThread %x\n",FirstThread
);
109 ExInitializeWorkItem(&PspReaperWorkItem
, PspReapRoutine
, NULL
);
114 PsInitProcessManagment(VOID
)
119 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
121 ShortPsLockDelay
.QuadPart
= -100LL;
122 PsLockTimeout
.QuadPart
= -10000000LL; /* one second */
124 * Register the process object type
127 DPRINT("Creating Process Object Type\n");
129 /* Initialize the Thread type */
130 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
131 RtlInitUnicodeString(&Name
, L
"Process");
132 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
133 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(EPROCESS
);
134 ObjectTypeInitializer
.GenericMapping
= PiProcessMapping
;
135 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
136 ObjectTypeInitializer
.ValidAccessMask
= PROCESS_ALL_ACCESS
;
137 ObjectTypeInitializer
.UseDefaultObject
= TRUE
;
138 ObjectTypeInitializer
.DeleteProcedure
= PspDeleteProcess
;
139 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &PsProcessType
);
141 InitializeListHead(&PsActiveProcessHead
);
142 ExInitializeFastMutex(&PspActiveProcessMutex
);
145 * Initialize the idle process
147 Status
= ObCreateObject(KernelMode
,
155 (PVOID
*)&PsIdleProcess
);
156 if (!NT_SUCCESS(Status
))
158 DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status
);
163 RtlZeroMemory(PsIdleProcess
, sizeof(EPROCESS
));
165 PsIdleProcess
->Pcb
.Affinity
= 0xFFFFFFFF;
166 PsIdleProcess
->Pcb
.IopmOffset
= 0xffff;
167 PsIdleProcess
->Pcb
.BasePriority
= PROCESS_PRIO_IDLE
;
168 PsIdleProcess
->Pcb
.QuantumReset
= 6;
169 InitializeListHead(&PsIdleProcess
->Pcb
.ThreadListHead
);
170 InitializeListHead(&PsIdleProcess
->ThreadListHead
);
171 InitializeListHead(&PsIdleProcess
->ActiveProcessLinks
);
172 KeInitializeDispatcherHeader(&PsIdleProcess
->Pcb
.Header
,
176 PsIdleProcess
->Pcb
.DirectoryTableBase
=
177 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
178 strcpy(PsIdleProcess
->ImageFileName
, "Idle");
181 * Initialize the system process
183 Status
= ObCreateObject(KernelMode
,
191 (PVOID
*)&PsInitialSystemProcess
);
192 if (!NT_SUCCESS(Status
))
194 DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status
);
199 /* System threads may run on any processor. */
200 RtlZeroMemory(PsInitialSystemProcess
, sizeof(EPROCESS
));
201 PsInitialSystemProcess
->Pcb
.Affinity
= 0xFFFFFFFF;
202 PsInitialSystemProcess
->Pcb
.IopmOffset
= 0xffff;
203 PsInitialSystemProcess
->Pcb
.BasePriority
= PROCESS_PRIO_NORMAL
;
204 PsInitialSystemProcess
->Pcb
.QuantumReset
= 6;
205 InitializeListHead(&PsInitialSystemProcess
->Pcb
.ThreadListHead
);
206 KeInitializeDispatcherHeader(&PsInitialSystemProcess
->Pcb
.Header
,
210 KProcess
= &PsInitialSystemProcess
->Pcb
;
212 MmInitializeAddressSpace(PsInitialSystemProcess
,
213 &PsInitialSystemProcess
->AddressSpace
);
215 KeInitializeEvent(&PsInitialSystemProcess
->LockEvent
, SynchronizationEvent
, FALSE
);
217 #if defined(__GNUC__)
218 KProcess
->DirectoryTableBase
=
219 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
223 dummy
.QuadPart
= (LONGLONG
)(ULONG
)MmGetPageDirectory();
224 KProcess
->DirectoryTableBase
= dummy
;
228 strcpy(PsInitialSystemProcess
->ImageFileName
, "System");
230 PsInitialSystemProcess
->Win32WindowStation
= (HANDLE
)0;
232 InsertHeadList(&PsActiveProcessHead
,
233 &PsInitialSystemProcess
->ActiveProcessLinks
);
234 InitializeListHead(&PsInitialSystemProcess
->ThreadListHead
);
236 #ifndef SCHED_REWRITE
239 /* No parent, this is the Initial System Process. Assign Boot Token */
240 BootToken
= SepCreateSystemProcessToken();
241 BootToken
->TokenInUse
= TRUE
;
242 PsInitialSystemProcess
->Token
.Object
= BootToken
; /* FIXME */
243 ObReferenceObject(BootToken
);
248 PspPostInitSystemProcess(VOID
)
252 /* this routine is called directly after the exectuive handle tables were
253 initialized. We'll set up the Client ID handle table and assign the system
255 PsInitClientIDManagment();
257 ObCreateHandleTable(NULL
, FALSE
, PsInitialSystemProcess
);
258 ObpKernelHandleTable
= PsInitialSystemProcess
->ObjectTable
;
260 Status
= PsCreateCidHandle(PsInitialSystemProcess
,
262 &PsInitialSystemProcess
->UniqueProcessId
);
263 if(!NT_SUCCESS(Status
))
265 DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
269 /**********************************************************************
274 * Retrieves the current OS version.
277 * MajorVersion Pointer to a variable that will be set to the
278 * major version of the OS. Can be NULL.
280 * MinorVersion Pointer to a variable that will be set to the
281 * minor version of the OS. Can be NULL.
283 * BuildNumber Pointer to a variable that will be set to the
284 * build number of the OS. Can be NULL.
286 * CSDVersion Pointer to a variable that will be set to the
287 * CSD string of the OS. Can be NULL.
290 * TRUE OS is a checked build.
291 * FALSE OS is a free build.
299 PsGetVersion(PULONG MajorVersion OPTIONAL
,
300 PULONG MinorVersion OPTIONAL
,
301 PULONG BuildNumber OPTIONAL
,
302 PUNICODE_STRING CSDVersion OPTIONAL
)
305 *MajorVersion
= NtMajorVersion
;
308 *MinorVersion
= NtMinorVersion
;
311 *BuildNumber
= NtBuildNumber
;
315 CSDVersion
->Length
= 0;
316 CSDVersion
->MaximumLength
= 0;
317 CSDVersion
->Buffer
= NULL
;
319 CSDVersion
->Length
= CmCSDVersionString
.Length
;
320 CSDVersion
->MaximumLength
= CmCSDVersionString
.Maximum
;
321 CSDVersion
->Buffer
= CmCSDVersionString
.Buffer
;
325 /* Check the High word */
326 return (NtBuildNumber
>> 28) == 0xC;