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