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
->Open
= NULL
;
102 RtlInitUnicodeString(&PsThreadType
->TypeName
, L
"Thread");
104 ObpCreateTypeObject(PsThreadType
);
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
;
113 DPRINT("FirstThread %x\n",FirstThread
);
117 ExInitializeWorkItem(&PspReaperWorkItem
, PspReapRoutine
, NULL
);
122 PsInitProcessManagment(VOID
)
127 ShortPsLockDelay
.QuadPart
= -100LL;
128 PsLockTimeout
.QuadPart
= -10000000LL; /* one second */
130 * Register the process object type
133 PsProcessType
= ExAllocatePool(NonPagedPool
, sizeof(OBJECT_TYPE
));
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
;
153 RtlInitUnicodeString(&PsProcessType
->TypeName
, L
"Process");
155 ObpCreateTypeObject(PsProcessType
);
157 InitializeListHead(&PsActiveProcessHead
);
158 ExInitializeFastMutex(&PspActiveProcessMutex
);
161 * Initialize the idle process
163 Status
= ObCreateObject(KernelMode
,
171 (PVOID
*)&PsIdleProcess
);
172 if (!NT_SUCCESS(Status
))
174 DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status
);
179 RtlZeroMemory(PsIdleProcess
, sizeof(EPROCESS
));
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
,
192 PsIdleProcess
->Pcb
.DirectoryTableBase
=
193 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
194 strcpy(PsIdleProcess
->ImageFileName
, "Idle");
197 * Initialize the system process
199 Status
= ObCreateObject(KernelMode
,
207 (PVOID
*)&PsInitialSystemProcess
);
208 if (!NT_SUCCESS(Status
))
210 DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status
);
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
,
226 KProcess
= &PsInitialSystemProcess
->Pcb
;
228 MmInitializeAddressSpace(PsInitialSystemProcess
,
229 &PsInitialSystemProcess
->AddressSpace
);
231 KeInitializeEvent(&PsInitialSystemProcess
->LockEvent
, SynchronizationEvent
, FALSE
);
233 #if defined(__GNUC__)
234 KProcess
->DirectoryTableBase
=
235 (LARGE_INTEGER
)(LONGLONG
)(ULONG
)MmGetPageDirectory();
239 dummy
.QuadPart
= (LONGLONG
)(ULONG
)MmGetPageDirectory();
240 KProcess
->DirectoryTableBase
= dummy
;
244 strcpy(PsInitialSystemProcess
->ImageFileName
, "System");
246 PsInitialSystemProcess
->Win32WindowStation
= (HANDLE
)0;
248 InsertHeadList(&PsActiveProcessHead
,
249 &PsInitialSystemProcess
->ActiveProcessLinks
);
250 InitializeListHead(&PsInitialSystemProcess
->ThreadListHead
);
252 #ifndef SCHED_REWRITE
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
);
264 PspPostInitSystemProcess(VOID
)
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
271 PsInitClientIDManagment();
273 ObCreateHandleTable(NULL
, FALSE
, PsInitialSystemProcess
);
274 ObpKernelHandleTable
= PsInitialSystemProcess
->ObjectTable
;
276 Status
= PsCreateCidHandle(PsInitialSystemProcess
,
278 &PsInitialSystemProcess
->UniqueProcessId
);
279 if(!NT_SUCCESS(Status
))
281 DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
285 /**********************************************************************
290 * Retrieves the current OS version.
293 * MajorVersion Pointer to a variable that will be set to the
294 * major version of the OS. Can be NULL.
296 * MinorVersion Pointer to a variable that will be set to the
297 * minor version of the OS. Can be NULL.
299 * BuildNumber Pointer to a variable that will be set to the
300 * build number of the OS. Can be NULL.
302 * CSDVersion Pointer to a variable that will be set to the
303 * CSD string of the OS. Can be NULL.
306 * TRUE OS is a checked build.
307 * FALSE OS is a free build.
315 PsGetVersion(PULONG MajorVersion OPTIONAL
,
316 PULONG MinorVersion OPTIONAL
,
317 PULONG BuildNumber OPTIONAL
,
318 PUNICODE_STRING CSDVersion OPTIONAL
)
321 *MajorVersion
= NtMajorVersion
;
324 *MinorVersion
= NtMinorVersion
;
327 *BuildNumber
= NtBuildNumber
;
331 CSDVersion
->Length
= 0;
332 CSDVersion
->MaximumLength
= 0;
333 CSDVersion
->Buffer
= NULL
;
335 CSDVersion
->Length
= CmCSDVersionString
.Length
;
336 CSDVersion
->MaximumLength
= CmCSDVersionString
.Maximum
;
337 CSDVersion
->Buffer
= CmCSDVersionString
.Buffer
;
341 /* Check the High word */
342 return (NtBuildNumber
>> 28) == 0xC;