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