Update KPROCESS structure to latest version and document all its fields on the Wiki...
[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 PETHREAD FirstThread;
75 ULONG i;
76
77 for (i=0; i < MAXIMUM_PRIORITY; i++)
78 {
79 InitializeListHead(&PriorityListHead[i]);
80 }
81
82 PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
83
84 PsThreadType->Tag = TAG('T', 'H', 'R', 'T');
85 PsThreadType->TotalObjects = 0;
86 PsThreadType->TotalHandles = 0;
87 PsThreadType->PeakObjects = 0;
88 PsThreadType->PeakHandles = 0;
89 PsThreadType->PagedPoolCharge = 0;
90 PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);
91 PsThreadType->Mapping = &PiThreadMapping;
92 PsThreadType->Dump = NULL;
93 PsThreadType->Open = NULL;
94 PsThreadType->Close = NULL;
95 PsThreadType->Delete = PspDeleteThread;
96 PsThreadType->Parse = NULL;
97 PsThreadType->Security = NULL;
98 PsThreadType->QueryName = NULL;
99 PsThreadType->OkayToClose = NULL;
100 PsThreadType->Create = NULL;
101 PsThreadType->DuplicationNotify = NULL;
102
103 RtlInitUnicodeString(&PsThreadType->TypeName, L"Thread");
104
105 ObpCreateTypeObject(PsThreadType);
106
107 PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE);
108 FirstThread->Tcb.State = Running;
109 FirstThread->Tcb.FreezeCount = 0;
110 FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */
111 FirstThread->Tcb.Affinity = (1 << 0);
112 KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread;
113
114 DPRINT("FirstThread %x\n",FirstThread);
115
116 DoneInitYet = TRUE;
117
118 ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
119 }
120
121 VOID
122 INIT_FUNCTION
123 PsInitProcessManagment(VOID)
124 {
125 PKPROCESS KProcess;
126 NTSTATUS Status;
127
128 ShortPsLockDelay.QuadPart = -100LL;
129 PsLockTimeout.QuadPart = -10000000LL; /* one second */
130 /*
131 * Register the process object type
132 */
133
134 PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
135
136 PsProcessType->Tag = TAG('P', 'R', 'O', 'C');
137 PsProcessType->TotalObjects = 0;
138 PsProcessType->TotalHandles = 0;
139 PsProcessType->PeakObjects = 0;
140 PsProcessType->PeakHandles = 0;
141 PsProcessType->PagedPoolCharge = 0;
142 PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
143 PsProcessType->Mapping = &PiProcessMapping;
144 PsProcessType->Dump = NULL;
145 PsProcessType->Open = NULL;
146 PsProcessType->Close = NULL;
147 PsProcessType->Delete = PspDeleteProcess;
148 PsProcessType->Parse = NULL;
149 PsProcessType->Security = NULL;
150 PsProcessType->QueryName = NULL;
151 PsProcessType->OkayToClose = NULL;
152 PsProcessType->Create = NULL;
153 PsProcessType->DuplicationNotify = NULL;
154
155 RtlInitUnicodeString(&PsProcessType->TypeName, L"Process");
156
157 ObpCreateTypeObject(PsProcessType);
158
159 InitializeListHead(&PsActiveProcessHead);
160 ExInitializeFastMutex(&PspActiveProcessMutex);
161
162 /*
163 * Initialize the idle process
164 */
165 Status = ObCreateObject(KernelMode,
166 PsProcessType,
167 NULL,
168 KernelMode,
169 NULL,
170 sizeof(EPROCESS),
171 0,
172 0,
173 (PVOID*)&PsIdleProcess);
174 if (!NT_SUCCESS(Status))
175 {
176 DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status);
177 KEBUGCHECK(0);
178 return;
179 }
180
181 RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
182
183 PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
184 PsIdleProcess->Pcb.IopmOffset = 0xffff;
185 PsIdleProcess->Pcb.BasePriority = PROCESS_PRIO_IDLE;
186 PsIdleProcess->Pcb.QuantumReset = 6;
187 InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead);
188 InitializeListHead(&PsIdleProcess->ThreadListHead);
189 InitializeListHead(&PsIdleProcess->ProcessListEntry);
190 KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.Header,
191 ProcessObject,
192 sizeof(EPROCESS),
193 FALSE);
194 PsIdleProcess->Pcb.DirectoryTableBase =
195 (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
196 strcpy(PsIdleProcess->ImageFileName, "Idle");
197
198 /*
199 * Initialize the system process
200 */
201 Status = ObCreateObject(KernelMode,
202 PsProcessType,
203 NULL,
204 KernelMode,
205 NULL,
206 sizeof(EPROCESS),
207 0,
208 0,
209 (PVOID*)&PsInitialSystemProcess);
210 if (!NT_SUCCESS(Status))
211 {
212 DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status);
213 KEBUGCHECK(0);
214 return;
215 }
216
217 /* System threads may run on any processor. */
218 RtlZeroMemory(PsInitialSystemProcess, sizeof(EPROCESS));
219 PsInitialSystemProcess->Pcb.Affinity = 0xFFFFFFFF;
220 PsInitialSystemProcess->Pcb.IopmOffset = 0xffff;
221 PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIO_NORMAL;
222 PsInitialSystemProcess->Pcb.QuantumReset = 6;
223 InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead);
224 KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.Header,
225 ProcessObject,
226 sizeof(EPROCESS),
227 FALSE);
228 KProcess = &PsInitialSystemProcess->Pcb;
229
230 MmInitializeAddressSpace(PsInitialSystemProcess,
231 &PsInitialSystemProcess->AddressSpace);
232
233 KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
234
235 #if defined(__GNUC__)
236 KProcess->DirectoryTableBase =
237 (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
238 #else
239 {
240 LARGE_INTEGER dummy;
241 dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory();
242 KProcess->DirectoryTableBase = dummy;
243 }
244 #endif
245
246 strcpy(PsInitialSystemProcess->ImageFileName, "System");
247
248 PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
249
250 InsertHeadList(&PsActiveProcessHead,
251 &PsInitialSystemProcess->ProcessListEntry);
252 InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
253
254 #ifndef SCHED_REWRITE
255 PTOKEN BootToken;
256
257 /* No parent, this is the Initial System Process. Assign Boot Token */
258 BootToken = SepCreateSystemProcessToken();
259 BootToken->TokenInUse = TRUE;
260 PsInitialSystemProcess->Token = BootToken;
261 ObReferenceObject(BootToken);
262 #endif
263 }
264
265 VOID
266 PspPostInitSystemProcess(VOID)
267 {
268 NTSTATUS Status;
269
270 /* this routine is called directly after the exectuive handle tables were
271 initialized. We'll set up the Client ID handle table and assign the system
272 process a PID */
273 PsInitClientIDManagment();
274
275 ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
276 ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
277
278 Status = PsCreateCidHandle(PsInitialSystemProcess,
279 PsProcessType,
280 &PsInitialSystemProcess->UniqueProcessId);
281 if(!NT_SUCCESS(Status))
282 {
283 DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
284 KEBUGCHECK(0);
285 }
286 }
287 /**********************************************************************
288 * NAME EXPORTED
289 * PsGetVersion
290 *
291 * DESCRIPTION
292 * Retrieves the current OS version.
293 *
294 * ARGUMENTS
295 * MajorVersion Pointer to a variable that will be set to the
296 * major version of the OS. Can be NULL.
297 *
298 * MinorVersion Pointer to a variable that will be set to the
299 * minor version of the OS. Can be NULL.
300 *
301 * BuildNumber Pointer to a variable that will be set to the
302 * build number of the OS. Can be NULL.
303 *
304 * CSDVersion Pointer to a variable that will be set to the
305 * CSD string of the OS. Can be NULL.
306 *
307 * RETURN VALUE
308 * TRUE OS is a checked build.
309 * FALSE OS is a free build.
310 *
311 * NOTES
312 *
313 * @implemented
314 */
315 BOOLEAN
316 STDCALL
317 PsGetVersion(PULONG MajorVersion OPTIONAL,
318 PULONG MinorVersion OPTIONAL,
319 PULONG BuildNumber OPTIONAL,
320 PUNICODE_STRING CSDVersion OPTIONAL)
321 {
322 if (MajorVersion)
323 *MajorVersion = NtMajorVersion;
324
325 if (MinorVersion)
326 *MinorVersion = NtMinorVersion;
327
328 if (BuildNumber)
329 *BuildNumber = NtBuildNumber;
330
331 if (CSDVersion)
332 {
333 CSDVersion->Length = 0;
334 CSDVersion->MaximumLength = 0;
335 CSDVersion->Buffer = NULL;
336 #if 0
337 CSDVersion->Length = CmCSDVersionString.Length;
338 CSDVersion->MaximumLength = CmCSDVersionString.Maximum;
339 CSDVersion->Buffer = CmCSDVersionString.Buffer;
340 #endif
341 }
342
343 /* Check the High word */
344 return (NtBuildNumber >> 28) == 0xC;
345 }
346
347 /* EOF */