a19d8eaa7a13ca8dc02845e4ed5d78345cd83e60
[reactos.git] / reactos / ntoskrnl / ps / psmgr.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ps/psmgr.c
6 * PURPOSE: Process management
7 *
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 */
10
11 /* INCLUDES **************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
18 extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
19
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,
27 PROCESS_ALL_ACCESS};
28
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,
34 THREAD_ALL_ACCESS};
35
36 BOOLEAN DoneInitYet = FALSE;
37
38 extern ULONG NtBuildNumber;
39 extern ULONG NtMajorVersion;
40 extern ULONG NtMinorVersion;
41
42 VOID
43 INIT_FUNCTION
44 PsInitClientIDManagment(VOID);
45
46 VOID STDCALL PspKillMostProcesses();
47
48 /* FUNCTIONS ***************************************************************/
49
50 VOID PiShutdownProcessManager(VOID)
51 {
52 DPRINT("PiShutdownProcessManager()\n");
53
54 PspKillMostProcesses();
55 }
56
57 VOID INIT_FUNCTION
58 PiInitProcessManager(VOID)
59 {
60 PsInitJobManagment();
61 PsInitProcessManagment();
62 PsInitThreadManagment();
63 PsInitIdleThread();
64 PsInitialiseW32Call();
65 }
66
67 VOID
68 INIT_FUNCTION
69 PsInitThreadManagment(VOID)
70 /*
71 * FUNCTION: Initialize thread managment
72 */
73 {
74 UNICODE_STRING Name;
75 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
76 PETHREAD FirstThread;
77 ULONG i;
78
79 for (i=0; i < MAXIMUM_PRIORITY; i++)
80 {
81 InitializeListHead(&PriorityListHead[i]);
82 }
83
84 DPRINT("Creating Thread Object Type\n");
85
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);
97
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;
104
105 DPRINT("FirstThread %x\n",FirstThread);
106
107 DoneInitYet = TRUE;
108
109 ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
110 }
111
112 VOID
113 INIT_FUNCTION
114 PsInitProcessManagment(VOID)
115 {
116 PKPROCESS KProcess;
117 NTSTATUS Status;
118 UNICODE_STRING Name;
119 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
120
121 ShortPsLockDelay.QuadPart = -100LL;
122 PsLockTimeout.QuadPart = -10000000LL; /* one second */
123 /*
124 * Register the process object type
125 */
126
127 DPRINT("Creating Process Object Type\n");
128
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);
140
141 InitializeListHead(&PsActiveProcessHead);
142 ExInitializeFastMutex(&PspActiveProcessMutex);
143
144 /*
145 * Initialize the idle process
146 */
147 Status = ObCreateObject(KernelMode,
148 PsProcessType,
149 NULL,
150 KernelMode,
151 NULL,
152 sizeof(EPROCESS),
153 0,
154 0,
155 (PVOID*)&PsIdleProcess);
156 if (!NT_SUCCESS(Status))
157 {
158 DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status);
159 KEBUGCHECK(0);
160 return;
161 }
162
163 RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
164
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,
173 ProcessObject,
174 sizeof(EPROCESS),
175 FALSE);
176 PsIdleProcess->Pcb.DirectoryTableBase =
177 (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
178 strcpy(PsIdleProcess->ImageFileName, "Idle");
179
180 /*
181 * Initialize the system process
182 */
183 Status = ObCreateObject(KernelMode,
184 PsProcessType,
185 NULL,
186 KernelMode,
187 NULL,
188 sizeof(EPROCESS),
189 0,
190 0,
191 (PVOID*)&PsInitialSystemProcess);
192 if (!NT_SUCCESS(Status))
193 {
194 DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status);
195 KEBUGCHECK(0);
196 return;
197 }
198
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,
207 ProcessObject,
208 sizeof(EPROCESS),
209 FALSE);
210 KProcess = &PsInitialSystemProcess->Pcb;
211
212 MmInitializeAddressSpace(PsInitialSystemProcess,
213 &PsInitialSystemProcess->AddressSpace);
214
215 KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
216
217 #if defined(__GNUC__)
218 KProcess->DirectoryTableBase =
219 (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
220 #else
221 {
222 LARGE_INTEGER dummy;
223 dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory();
224 KProcess->DirectoryTableBase = dummy;
225 }
226 #endif
227
228 strcpy(PsInitialSystemProcess->ImageFileName, "System");
229
230 PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
231
232 InsertHeadList(&PsActiveProcessHead,
233 &PsInitialSystemProcess->ActiveProcessLinks);
234 InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
235
236 #ifndef SCHED_REWRITE
237 PTOKEN BootToken;
238
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);
244 #endif
245 }
246
247 VOID
248 PspPostInitSystemProcess(VOID)
249 {
250 NTSTATUS Status;
251
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
254 process a PID */
255 PsInitClientIDManagment();
256
257 ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
258 ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
259
260 Status = PsCreateCidHandle(PsInitialSystemProcess,
261 PsProcessType,
262 &PsInitialSystemProcess->UniqueProcessId);
263 if(!NT_SUCCESS(Status))
264 {
265 DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
266 KEBUGCHECK(0);
267 }
268 }
269 /**********************************************************************
270 * NAME EXPORTED
271 * PsGetVersion
272 *
273 * DESCRIPTION
274 * Retrieves the current OS version.
275 *
276 * ARGUMENTS
277 * MajorVersion Pointer to a variable that will be set to the
278 * major version of the OS. Can be NULL.
279 *
280 * MinorVersion Pointer to a variable that will be set to the
281 * minor version of the OS. Can be NULL.
282 *
283 * BuildNumber Pointer to a variable that will be set to the
284 * build number of the OS. Can be NULL.
285 *
286 * CSDVersion Pointer to a variable that will be set to the
287 * CSD string of the OS. Can be NULL.
288 *
289 * RETURN VALUE
290 * TRUE OS is a checked build.
291 * FALSE OS is a free build.
292 *
293 * NOTES
294 *
295 * @implemented
296 */
297 BOOLEAN
298 STDCALL
299 PsGetVersion(PULONG MajorVersion OPTIONAL,
300 PULONG MinorVersion OPTIONAL,
301 PULONG BuildNumber OPTIONAL,
302 PUNICODE_STRING CSDVersion OPTIONAL)
303 {
304 if (MajorVersion)
305 *MajorVersion = NtMajorVersion;
306
307 if (MinorVersion)
308 *MinorVersion = NtMinorVersion;
309
310 if (BuildNumber)
311 *BuildNumber = NtBuildNumber;
312
313 if (CSDVersion)
314 {
315 CSDVersion->Length = 0;
316 CSDVersion->MaximumLength = 0;
317 CSDVersion->Buffer = NULL;
318 #if 0
319 CSDVersion->Length = CmCSDVersionString.Length;
320 CSDVersion->MaximumLength = CmCSDVersionString.Maximum;
321 CSDVersion->Buffer = CmCSDVersionString.Buffer;
322 #endif
323 }
324
325 /* Check the High word */
326 return (NtBuildNumber >> 28) == 0xC;
327 }
328
329 /* EOF */