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
77 for (i
=0; i
< MAXIMUM_PRIORITY
; i
++)
79 InitializeListHead(&PriorityListHead
[i
]);
82 PsThreadType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
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
;
103 RtlInitUnicodeString(&PsThreadType
->TypeName
, L
"Thread");
105 ObpCreateTypeObject(PsThreadType
);
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
;
114 DPRINT("FirstThread %x\n",FirstThread
);
118 ExInitializeWorkItem(&PspReaperWorkItem
, PspReapRoutine
, NULL
);
123 PsInitProcessManagment(VOID
)
128 ShortPsLockDelay
.QuadPart
= -100LL;
129 PsLockTimeout
.QuadPart
= -10000000LL; /* one second */
131 * Register the process object type
134 PsProcessType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
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
;
155 RtlInitUnicodeString(&PsProcessType
->TypeName
, L
"Process");
157 ObpCreateTypeObject(PsProcessType
);
159 InitializeListHead(&PsActiveProcessHead
);
160 ExInitializeFastMutex(&PspActiveProcessMutex
);
163 * Initialize the idle process
165 Status
= ObCreateObject(KernelMode
,
173 (PVOID
*)&PsIdleProcess
);
174 if (!NT_SUCCESS(Status
))
176 DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status
);
181 RtlZeroMemory(PsIdleProcess
, sizeof(EPROCESS
));
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
,
194 PsIdleProcess
->Pcb
.DirectoryTableBase
=
195 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
196 strcpy(PsIdleProcess
->ImageFileName
, "Idle");
199 * Initialize the system process
201 Status
= ObCreateObject(KernelMode
,
209 (PVOID
*)&PsInitialSystemProcess
);
210 if (!NT_SUCCESS(Status
))
212 DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status
);
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
,
228 KProcess
= &PsInitialSystemProcess
->Pcb
;
230 MmInitializeAddressSpace(PsInitialSystemProcess
,
231 &PsInitialSystemProcess
->AddressSpace
);
233 KeInitializeEvent(&PsInitialSystemProcess
->LockEvent
, SynchronizationEvent
, FALSE
);
235 #if defined(__GNUC__)
236 KProcess
->DirectoryTableBase
=
237 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
241 dummy
.QuadPart
= (LONGLONG
)(ULONG
)MmGetPageDirectory();
242 KProcess
->DirectoryTableBase
= dummy
;
246 strcpy(PsInitialSystemProcess
->ImageFileName
, "System");
248 PsInitialSystemProcess
->Win32WindowStation
= (HANDLE
)0;
250 InsertHeadList(&PsActiveProcessHead
,
251 &PsInitialSystemProcess
->ProcessListEntry
);
252 InitializeListHead(&PsInitialSystemProcess
->ThreadListHead
);
254 #ifndef SCHED_REWRITE
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
);
266 PspPostInitSystemProcess(VOID
)
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
273 PsInitClientIDManagment();
275 ObCreateHandleTable(NULL
, FALSE
, PsInitialSystemProcess
);
276 ObpKernelHandleTable
= PsInitialSystemProcess
->ObjectTable
;
278 Status
= PsCreateCidHandle(PsInitialSystemProcess
,
280 &PsInitialSystemProcess
->UniqueProcessId
);
281 if(!NT_SUCCESS(Status
))
283 DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
287 /**********************************************************************
292 * Retrieves the current OS version.
295 * MajorVersion Pointer to a variable that will be set to the
296 * major version of the OS. Can be NULL.
298 * MinorVersion Pointer to a variable that will be set to the
299 * minor version of the OS. Can be NULL.
301 * BuildNumber Pointer to a variable that will be set to the
302 * build number of the OS. Can be NULL.
304 * CSDVersion Pointer to a variable that will be set to the
305 * CSD string of the OS. Can be NULL.
308 * TRUE OS is a checked build.
309 * FALSE OS is a free build.
317 PsGetVersion(PULONG MajorVersion OPTIONAL
,
318 PULONG MinorVersion OPTIONAL
,
319 PULONG BuildNumber OPTIONAL
,
320 PUNICODE_STRING CSDVersion OPTIONAL
)
323 *MajorVersion
= NtMajorVersion
;
326 *MinorVersion
= NtMinorVersion
;
329 *BuildNumber
= NtBuildNumber
;
333 CSDVersion
->Length
= 0;
334 CSDVersion
->MaximumLength
= 0;
335 CSDVersion
->Buffer
= NULL
;
337 CSDVersion
->Length
= CmCSDVersionString
.Length
;
338 CSDVersion
->MaximumLength
= CmCSDVersionString
.Maximum
;
339 CSDVersion
->Buffer
= CmCSDVersionString
.Buffer
;
343 /* Check the High word */
344 return (NtBuildNumber
>> 28) == 0xC;