Added process ids.
[reactos.git] / reactos / ntoskrnl / ps / process.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ps/process.c
5 * PURPOSE: Process managment
6 * PROGRAMMER: David Welch (welch@cwcom.net)
7 * REVISION HISTORY:
8 * 21/07/98: Created
9 */
10
11 /* INCLUDES ******************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/ob.h>
15 #include <internal/mm.h>
16 #include <internal/ke.h>
17 #include <internal/ps.h>
18 #include <string.h>
19 #include <internal/string.h>
20 #include <internal/id.h>
21
22 #define NDEBUG
23 #include <internal/debug.h>
24
25 /* GLOBALS ******************************************************************/
26
27 PEPROCESS SystemProcess = NULL;
28 HANDLE SystemProcessHandle = NULL;
29
30 POBJECT_TYPE PsProcessType = NULL;
31
32 static ULONG NextUniqueProcessId = 0;
33
34 /* FUNCTIONS *****************************************************************/
35
36 VOID PsInitProcessManagment(VOID)
37 {
38 ANSI_STRING AnsiString;
39 PKPROCESS KProcess;
40
41 /*
42 * Register the process object type
43 */
44
45 PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
46
47 PsProcessType->TotalObjects = 0;
48 PsProcessType->TotalHandles = 0;
49 PsProcessType->MaxObjects = ULONG_MAX;
50 PsProcessType->MaxHandles = ULONG_MAX;
51 PsProcessType->PagedPoolCharge = 0;
52 PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
53 PsProcessType->Dump = NULL;
54 PsProcessType->Open = NULL;
55 PsProcessType->Close = NULL;
56 PsProcessType->Delete = PiDeleteProcess;
57 PsProcessType->Parse = NULL;
58 PsProcessType->Security = NULL;
59 PsProcessType->QueryName = NULL;
60 PsProcessType->OkayToClose = NULL;
61
62 RtlInitAnsiString(&AnsiString,"Process");
63 RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
64
65 /*
66 * Initialize the system process
67 */
68 SystemProcess = ObCreateObject(NULL,
69 PROCESS_ALL_ACCESS,
70 NULL,
71 PsProcessType);
72 KeInitializeDispatcherHeader(&SystemProcess->Pcb.DispatcherHeader,
73 ID_PROCESS_OBJECT,
74 sizeof(EPROCESS),
75 FALSE);
76 DPRINT("SystemProcess->Pcb.Type %x\n",
77 SystemProcess->Pcb.Type);
78 KProcess = &SystemProcess->Pcb;
79
80 InitializeListHead(&(KProcess->MemoryAreaList));
81 ObCreateHandleTable(NULL,FALSE,SystemProcess);
82 KProcess->PageTableDirectory = get_page_directory();
83
84 SystemProcess->UniqueProcessId = NextUniqueProcessId;
85 SystemProcess->InheritedFromUniqueProcessId = NextUniqueProcessId;
86
87 ObCreateHandle(SystemProcess,
88 SystemProcess,
89 PROCESS_ALL_ACCESS,
90 FALSE,
91 &SystemProcessHandle);
92 }
93
94 PKPROCESS KeGetCurrentProcess(VOID)
95 /*
96 * FUNCTION: Returns a pointer to the current process
97 */
98 {
99 return(&(PsGetCurrentProcess()->Pcb));
100 }
101
102 struct _EPROCESS* PsGetCurrentProcess(VOID)
103 /*
104 * FUNCTION: Returns a pointer to the current process
105 */
106 {
107 if (PsGetCurrentThread() == NULL ||
108 PsGetCurrentThread()->ThreadsProcess == NULL)
109 {
110 return(SystemProcess);
111 }
112 else
113 {
114 return(PsGetCurrentThread()->ThreadsProcess);
115 }
116 }
117
118 NTSTATUS STDCALL NtCreateProcess(
119 OUT PHANDLE ProcessHandle,
120 IN ACCESS_MASK DesiredAccess,
121 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
122 IN HANDLE ParentProcessHandle,
123 IN BOOLEAN InheritObjectTable,
124 IN HANDLE SectionHandle OPTIONAL,
125 IN HANDLE DebugPort OPTIONAL,
126 IN HANDLE ExceptionPort OPTIONAL)
127 {
128 return(ZwCreateProcess(ProcessHandle,
129 DesiredAccess,
130 ObjectAttributes,
131 ParentProcessHandle,
132 InheritObjectTable,
133 SectionHandle,
134 DebugPort,
135 ExceptionPort));
136 }
137
138 NTSTATUS STDCALL ZwCreateProcess(
139 OUT PHANDLE ProcessHandle,
140 IN ACCESS_MASK DesiredAccess,
141 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
142 IN HANDLE ParentProcessHandle,
143 IN BOOLEAN InheritObjectTable,
144 IN HANDLE SectionHandle OPTIONAL,
145 IN HANDLE DebugPort OPTIONAL,
146 IN HANDLE ExceptionPort OPTIONAL)
147 /*
148 * FUNCTION: Creates a process.
149 * ARGUMENTS:
150 * ProcessHandle (OUT) = Caller supplied storage for the resulting
151 * handle
152 * DesiredAccess = Specifies the allowed or desired access to the
153 * process can be a combination of
154 * STANDARD_RIGHTS_REQUIRED| ..
155 * ObjectAttribute = Initialized attributes for the object, contains
156 * the rootdirectory and the filename
157 * ParentProcess = Handle to the parent process.
158 * InheritObjectTable = Specifies to inherit the objects of the parent
159 * process if true.
160 * SectionHandle = Handle to a section object to back the image file
161 * DebugPort = Handle to a DebugPort if NULL the system default debug
162 * port will be used.
163 * ExceptionPort = Handle to a exception port.
164 * REMARKS:
165 * This function maps to the win32 CreateProcess.
166 * RETURNS: Status
167 */
168 {
169 PEPROCESS Process;
170 PEPROCESS ParentProcess;
171 PKPROCESS KProcess;
172 NTSTATUS Status;
173
174 DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
175
176 Status = ObReferenceObjectByHandle(ParentProcessHandle,
177 PROCESS_CREATE_PROCESS,
178 PsProcessType,
179 UserMode,
180 (PVOID*)&ParentProcess,
181 NULL);
182
183 if (Status != STATUS_SUCCESS)
184 {
185 DPRINT("ZwCreateProcess() = %x\n",Status);
186 return(Status);
187 }
188
189 Process = ObCreateObject(ProcessHandle,
190 DesiredAccess,
191 ObjectAttributes,
192 PsProcessType);
193 KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
194 ID_PROCESS_OBJECT,
195 sizeof(EPROCESS),
196 FALSE);
197 KProcess = &(Process->Pcb);
198
199 InitializeListHead(&(KProcess->MemoryAreaList));
200 Process->UniqueProcessId = InterlockedIncrement(&NextUniqueProcessId);
201 Process->InheritedFromUniqueProcessId = ParentProcess->UniqueProcessId;
202 ObCreateHandleTable(ParentProcess,
203 InheritObjectTable,
204 Process);
205 MmCopyMmInfo(ParentProcess, Process);
206
207 /*
208 * FIXME: I don't what I'm supposed to know with a section handle
209 */
210 if (SectionHandle != NULL)
211 {
212 DbgPrint("ZwCreateProcess() non-NULL SectionHandle\n");
213 return(STATUS_UNSUCCESSFUL);
214 }
215
216 Process->Pcb.ProcessState = PROCESS_STATE_ACTIVE;
217 ObDereferenceObject(Process);
218 ObDereferenceObject(ParentProcess);
219 return(STATUS_SUCCESS);
220 }
221
222
223 NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,
224 IN ACCESS_MASK DesiredAccess,
225 IN POBJECT_ATTRIBUTES ObjectAttributes,
226 IN PCLIENT_ID ClientId)
227 {
228 return(ZwOpenProcess(ProcessHandle,
229 DesiredAccess,
230 ObjectAttributes,
231 ClientId));
232 }
233
234 NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,
235 IN ACCESS_MASK DesiredAccess,
236 IN POBJECT_ATTRIBUTES ObjectAttributes,
237 IN PCLIENT_ID ClientId)
238 {
239 UNIMPLEMENTED;
240 }
241
242 NTSTATUS STDCALL NtQueryInformationProcess(IN HANDLE ProcessHandle,
243 IN CINT ProcessInformationClass,
244 OUT PVOID ProcessInformation,
245 IN ULONG ProcessInformationLength,
246 OUT PULONG ReturnLength)
247 {
248 return(ZwQueryInformationProcess(ProcessHandle,
249 ProcessInformationClass,
250 ProcessInformation,
251 ProcessInformationLength,
252 ReturnLength));
253 }
254
255 NTSTATUS STDCALL ZwQueryInformationProcess(IN HANDLE ProcessHandle,
256 IN CINT ProcessInformationClass,
257 OUT PVOID ProcessInformation,
258 IN ULONG ProcessInformationLength,
259 OUT PULONG ReturnLength)
260 {
261 PEPROCESS Process;
262 NTSTATUS Status;
263 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP;
264
265 Status = ObReferenceObjectByHandle(ProcessHandle,
266 PROCESS_SET_INFORMATION,
267 PsProcessType,
268 UserMode,
269 (PVOID*)&Process,
270 NULL);
271 if (Status != STATUS_SUCCESS)
272 {
273 return(Status);
274 }
275
276 switch (ProcessInformationClass)
277 {
278 case ProcessBasicInformation:
279 ProcessBasicInformationP = (PPROCESS_BASIC_INFORMATION)
280 ProcessInformation;
281 memset(ProcessBasicInformationP, 0, sizeof(PROCESS_BASIC_INFORMATION));
282 ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity;
283 ProcessBasicInformationP->UniqueProcessId =
284 Process->UniqueProcessId;
285 ProcessBasicInformationP->InheritedFromUniqueProcessId =
286 Process->InheritedFromUniqueProcessId;
287 Status = STATUS_SUCCESS;
288 break;
289
290 case ProcessQuotaLimits:
291 case ProcessIoCounters:
292 case ProcessVmCounters:
293 case ProcessTimes:
294 case ProcessBasePriority:
295 case ProcessRaisePriority:
296 case ProcessDebugPort:
297 case ProcessExceptionPort:
298 case ProcessAccessToken:
299 case ProcessLdtInformation:
300 case ProcessLdtSize:
301 case ProcessDefaultHardErrorMode:
302 case ProcessIoPortHandlers:
303 case ProcessWorkingSetWatch:
304 case ProcessUserModeIOPL:
305 case ProcessEnableAlignmentFaultFixup:
306 case ProcessPriorityClass:
307 case ProcessWx86Information:
308 case ProcessHandleCount:
309 case ProcessAffinityMask:
310 default:
311 Status = STATUS_NOT_IMPLEMENTED;
312 }
313 ObDereferenceObject(Process);
314 return(Status);
315 }
316
317 NTSTATUS STDCALL NtSetInformationProcess(IN HANDLE ProcessHandle,
318 IN CINT ProcessInformationClass,
319 IN PVOID ProcessInformation,
320 IN ULONG ProcessInformationLength)
321 {
322 return(ZwSetInformationProcess(ProcessHandle,
323 ProcessInformationClass,
324 ProcessInformation,
325 ProcessInformationLength));
326 }
327
328 NTSTATUS STDCALL ZwSetInformationProcess(IN HANDLE ProcessHandle,
329 IN CINT ProcessInformationClass,
330 IN PVOID ProcessInformation,
331 IN ULONG ProcessInformationLength)
332 {
333 PEPROCESS Process;
334 NTSTATUS Status;
335 PPROCESS_BASIC_INFORMATION ProcessBasicInformationP;
336
337 Status = ObReferenceObjectByHandle(ProcessHandle,
338 PROCESS_SET_INFORMATION,
339 PsProcessType,
340 UserMode,
341 (PVOID*)&Process,
342 NULL);
343 if (Status != STATUS_SUCCESS)
344 {
345 return(Status);
346 }
347
348 switch (ProcessInformationClass)
349 {
350 case ProcessBasicInformation:
351 ProcessBasicInformationP = (PPROCESS_BASIC_INFORMATION)
352 ProcessInformation;
353 memset(ProcessBasicInformationP, 0, sizeof(PROCESS_BASIC_INFORMATION));
354 Process->Pcb.Affinity = ProcessBasicInformationP->AffinityMask;
355 Status = STATUS_SUCCESS;
356 break;
357
358 case ProcessQuotaLimits:
359 case ProcessIoCounters:
360 case ProcessVmCounters:
361 case ProcessTimes:
362 case ProcessBasePriority:
363 case ProcessRaisePriority:
364 case ProcessDebugPort:
365 case ProcessExceptionPort:
366 case ProcessAccessToken:
367 case ProcessLdtInformation:
368 case ProcessLdtSize:
369 case ProcessDefaultHardErrorMode:
370 case ProcessIoPortHandlers:
371 case ProcessWorkingSetWatch:
372 case ProcessUserModeIOPL:
373 case ProcessEnableAlignmentFaultFixup:
374 case ProcessPriorityClass:
375 case ProcessWx86Information:
376 case ProcessHandleCount:
377 case ProcessAffinityMask:
378 default:
379 Status = STATUS_NOT_IMPLEMENTED;
380 }
381 ObDereferenceObject(Process);
382 return(Status);
383 }