Partially implemented (handlers only)
[reactos.git] / reactos / lib / kernel32 / process / proc.c
1 /* $Id: proc.c,v 1.32 2000/04/25 23:22:54 ea Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/proc/proc.c
6 * PURPOSE: Process functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <ntdll/rtl.h>
16 #include <windows.h>
17 #include <kernel32/proc.h>
18 #include <kernel32/thread.h>
19 #include <kernel32/error.h>
20 #include <wchar.h>
21 #include <string.h>
22 #include <internal/i386/segment.h>
23 #include <internal/teb.h>
24 #include <ntdll/csr.h>
25
26
27 #define NDEBUG
28 #include <kernel32/kernel32.h>
29
30
31 /* GLOBALS *******************************************************************/
32
33 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
34
35 LPSTARTUPINFO lpLocalStartupInfo = NULL;
36
37 VOID
38 STDCALL
39 RegisterWaitForInputIdle (
40 WaitForInputIdleType lpfnRegisterWaitForInputIdle
41 );
42
43
44 /* FUNCTIONS ****************************************************************/
45
46 WINBOOL
47 STDCALL
48 GetProcessId (
49 HANDLE hProcess,
50 LPDWORD lpProcessId
51 );
52
53
54
55
56
57 WINBOOL
58 STDCALL
59 GetProcessTimes (
60 HANDLE hProcess,
61 LPFILETIME lpCreationTime,
62 LPFILETIME lpExitTime,
63 LPFILETIME lpKernelTime,
64 LPFILETIME lpUserTime
65 )
66 {
67 NTSTATUS Status;
68 KERNEL_USER_TIMES Kut;
69
70 Status = NtQueryInformationProcess (
71 hProcess,
72 ProcessTimes,
73 & Kut,
74 sizeof Kut,
75 NULL
76 );
77 if (!NT_SUCCESS(Status))
78 {
79 SetLastErrorByStatus (Status);
80 return (FALSE);
81 }
82
83 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
84 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
85
86 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
87 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
88
89 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
90 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
91
92 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
93 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
94
95 return (TRUE);
96 }
97
98
99 HANDLE STDCALL GetCurrentProcess (VOID)
100 {
101 return((HANDLE)NtCurrentProcess());
102 }
103
104
105 HANDLE STDCALL GetCurrentThread (VOID)
106 {
107 return((HANDLE)NtCurrentThread());
108 }
109
110
111 DWORD STDCALL GetCurrentProcessId (VOID)
112 {
113 return((DWORD)GetTeb()->Cid.UniqueProcess);
114 }
115
116
117 WINBOOL
118 STDCALL
119 GetExitCodeProcess (
120 HANDLE hProcess,
121 LPDWORD lpExitCode
122 )
123 {
124 NTSTATUS errCode;
125 PROCESS_BASIC_INFORMATION ProcessBasic;
126 ULONG BytesWritten;
127
128 errCode = NtQueryInformationProcess(hProcess,
129 ProcessBasicInformation,
130 &ProcessBasic,
131 sizeof(PROCESS_BASIC_INFORMATION),
132 &BytesWritten);
133 if (!NT_SUCCESS(errCode))
134 {
135 SetLastErrorByStatus (errCode);
136 return FALSE;
137 }
138 memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
139 return TRUE;
140 }
141
142
143 WINBOOL
144 STDCALL
145 GetProcessId (
146 HANDLE hProcess,
147 LPDWORD lpProcessId
148 )
149 {
150 NTSTATUS errCode;
151 PROCESS_BASIC_INFORMATION ProcessBasic;
152 ULONG BytesWritten;
153
154 errCode = NtQueryInformationProcess(hProcess,
155 ProcessBasicInformation,
156 &ProcessBasic,
157 sizeof(PROCESS_BASIC_INFORMATION),
158 &BytesWritten);
159 if (!NT_SUCCESS(errCode))
160 {
161 SetLastErrorByStatus (errCode);
162 return FALSE;
163 }
164 memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
165 return TRUE;
166 }
167
168
169 HANDLE
170 STDCALL
171 OpenProcess (
172 DWORD dwDesiredAccess,
173 WINBOOL bInheritHandle,
174 DWORD dwProcessId
175 )
176 {
177 NTSTATUS errCode;
178 HANDLE ProcessHandle;
179 OBJECT_ATTRIBUTES ObjectAttributes;
180 CLIENT_ID ClientId ;
181
182 ClientId.UniqueProcess = (HANDLE)dwProcessId;
183 ClientId.UniqueThread = INVALID_HANDLE_VALUE;
184
185 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
186 ObjectAttributes.RootDirectory = (HANDLE)NULL;
187 ObjectAttributes.SecurityDescriptor = NULL;
188 ObjectAttributes.SecurityQualityOfService = NULL;
189 ObjectAttributes.ObjectName = NULL;
190
191 if (bInheritHandle == TRUE)
192 ObjectAttributes.Attributes = OBJ_INHERIT;
193 else
194 ObjectAttributes.Attributes = 0;
195
196 errCode = NtOpenProcess(&ProcessHandle,
197 dwDesiredAccess,
198 &ObjectAttributes,
199 &ClientId);
200 if (!NT_SUCCESS(errCode))
201 {
202 SetLastErrorByStatus (errCode);
203 return NULL;
204 }
205 return ProcessHandle;
206 }
207
208
209 UINT
210 STDCALL
211 WinExec (
212 LPCSTR lpCmdLine,
213 UINT uCmdShow
214 )
215 {
216 STARTUPINFOA StartupInfo;
217 PROCESS_INFORMATION ProcessInformation;
218 HINSTANCE hInst;
219 DWORD dosErr;
220
221 StartupInfo.cb = sizeof(STARTUPINFOA);
222 StartupInfo.wShowWindow = uCmdShow;
223 StartupInfo.dwFlags = 0;
224
225 hInst = (HINSTANCE)CreateProcessA(NULL,
226 (PVOID)lpCmdLine,
227 NULL,
228 NULL,
229 FALSE,
230 0,
231 NULL,
232 NULL,
233 &StartupInfo,
234 &ProcessInformation);
235 if ( hInst == NULL )
236 {
237 dosErr = GetLastError();
238 return dosErr;
239 }
240 if (NULL != lpfnGlobalRegisterWaitForInputIdle)
241 {
242 lpfnGlobalRegisterWaitForInputIdle (
243 ProcessInformation.hProcess,
244 10000
245 );
246 }
247 NtClose (ProcessInformation.hProcess);
248 NtClose (ProcessInformation.hThread);
249 return 0;
250 }
251
252
253 VOID
254 STDCALL
255 RegisterWaitForInputIdle (
256 WaitForInputIdleType lpfnRegisterWaitForInputIdle
257 )
258 {
259 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
260 return;
261 }
262
263
264 DWORD
265 STDCALL
266 WaitForInputIdle (
267 HANDLE hProcess,
268 DWORD dwMilliseconds
269 )
270 {
271 return 0;
272 }
273
274
275 VOID
276 STDCALL
277 Sleep (
278 DWORD dwMilliseconds
279 )
280 {
281 SleepEx (dwMilliseconds, FALSE);
282 return;
283 }
284
285
286 DWORD
287 STDCALL
288 SleepEx (
289 DWORD dwMilliseconds,
290 BOOL bAlertable
291 )
292 {
293 TIME Interval;
294 NTSTATUS errCode;
295
296 Interval.QuadPart = dwMilliseconds * 1000;
297
298 errCode = NtDelayExecution (bAlertable, & Interval);
299 if (!NT_SUCCESS(errCode))
300 {
301 SetLastErrorByStatus (errCode);
302 return -1;
303 }
304 return 0;
305 }
306
307
308 VOID
309 STDCALL
310 GetStartupInfoW (
311 LPSTARTUPINFOW lpStartupInfo
312 )
313 {
314 PRTL_USER_PROCESS_PARAMETERS Params;
315
316 if (lpStartupInfo == NULL)
317 {
318 SetLastError(ERROR_INVALID_PARAMETER);
319 return;
320 }
321
322 Params = NtCurrentPeb ()->ProcessParameters;
323
324 lpStartupInfo->cb = sizeof(STARTUPINFOW);
325 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
326 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
327 lpStartupInfo->dwX = Params->StartingX;
328 lpStartupInfo->dwY = Params->StartingY;
329 lpStartupInfo->dwXSize = Params->CountX;
330 lpStartupInfo->dwYSize = Params->CountY;
331 lpStartupInfo->dwXCountChars = Params->CountCharsX;
332 lpStartupInfo->dwYCountChars = Params->CountCharsY;
333 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
334 lpStartupInfo->dwFlags = Params->Flags;
335 lpStartupInfo->wShowWindow = Params->ShowWindowFlags;
336 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
337 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
338 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
339
340 lpStartupInfo->hStdInput = Params->InputHandle;
341 lpStartupInfo->hStdOutput = Params->OutputHandle;
342 lpStartupInfo->hStdError = Params->ErrorHandle;
343 }
344
345
346 VOID
347 STDCALL
348 GetStartupInfoA (
349 LPSTARTUPINFOA lpStartupInfo
350 )
351 {
352 PRTL_USER_PROCESS_PARAMETERS Params;
353 ANSI_STRING AnsiString;
354
355 if (lpStartupInfo == NULL)
356 {
357 SetLastError(ERROR_INVALID_PARAMETER);
358 return;
359 }
360
361 Params = NtCurrentPeb ()->ProcessParameters;
362
363 RtlAcquirePebLock ();
364
365 if (lpLocalStartupInfo == NULL)
366 {
367 /* create new local startup info (ansi) */
368 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
369 0,
370 sizeof(STARTUPINFOA));
371
372 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
373
374 /* copy window title string */
375 RtlUnicodeStringToAnsiString (&AnsiString,
376 &Params->WindowTitle,
377 TRUE);
378 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
379
380 /* copy desktop info string */
381 RtlUnicodeStringToAnsiString (&AnsiString,
382 &Params->DesktopInfo,
383 TRUE);
384 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
385
386 /* copy shell info string */
387 RtlUnicodeStringToAnsiString (&AnsiString,
388 &Params->ShellInfo,
389 TRUE);
390 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
391
392 lpLocalStartupInfo->dwX = Params->StartingX;
393 lpLocalStartupInfo->dwY = Params->StartingY;
394 lpLocalStartupInfo->dwXSize = Params->CountX;
395 lpLocalStartupInfo->dwYSize = Params->CountY;
396 lpLocalStartupInfo->dwXCountChars = Params->CountCharsX;
397 lpLocalStartupInfo->dwYCountChars = Params->CountCharsY;
398 lpLocalStartupInfo->dwFillAttribute = Params->FillAttribute;
399 lpLocalStartupInfo->dwFlags = Params->Flags;
400 lpLocalStartupInfo->wShowWindow = Params->ShowWindowFlags;
401 lpLocalStartupInfo->cbReserved2 = Params->RuntimeData.Length;
402 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
403
404 lpLocalStartupInfo->hStdInput = Params->InputHandle;
405 lpLocalStartupInfo->hStdOutput = Params->OutputHandle;
406 lpLocalStartupInfo->hStdError = Params->ErrorHandle;
407 }
408
409 RtlReleasePebLock ();
410
411 /* copy local startup info data to external startup info */
412 memcpy (lpStartupInfo,
413 lpLocalStartupInfo,
414 sizeof(STARTUPINFOA));
415 }
416
417
418 BOOL
419 STDCALL
420 FlushInstructionCache (
421 HANDLE hProcess,
422 LPCVOID lpBaseAddress,
423 DWORD dwSize
424 )
425 {
426 NTSTATUS errCode;
427
428 errCode = NtFlushInstructionCache (
429 hProcess,
430 (PVOID) lpBaseAddress,
431 dwSize);
432 if (!NT_SUCCESS(errCode))
433 {
434 SetLastErrorByStatus (errCode);
435 return FALSE;
436 }
437 return TRUE;
438 }
439
440
441 VOID
442 STDCALL
443 ExitProcess (
444 UINT uExitCode
445 )
446 {
447 NtTerminateProcess (NtCurrentProcess (),
448 uExitCode);
449 }
450
451
452 WINBOOL
453 STDCALL
454 TerminateProcess (
455 HANDLE hProcess,
456 UINT uExitCode
457 )
458 {
459 NTSTATUS errCode;
460
461 errCode = NtTerminateProcess (hProcess, uExitCode);
462 if (!NT_SUCCESS(errCode))
463 {
464 SetLastErrorByStatus (errCode);
465 return FALSE;
466 }
467 return TRUE;
468 }
469
470
471 VOID
472 STDCALL
473 FatalAppExitA (
474 UINT uAction,
475 LPCSTR lpMessageText
476 )
477 {
478 UNICODE_STRING MessageTextU;
479 ANSI_STRING MessageText;
480
481 RtlInitAnsiString (& MessageText,
482 (LPSTR) lpMessageText);
483
484 RtlAnsiStringToUnicodeString (& MessageTextU,
485 & MessageText,
486 TRUE);
487
488 FatalAppExitW (uAction,
489 MessageTextU.Buffer);
490
491 RtlFreeUnicodeString (&MessageTextU);
492 }
493
494
495 VOID
496 STDCALL
497 FatalAppExitW (
498 UINT uAction,
499 LPCWSTR lpMessageText
500 )
501 {
502 return;
503 }
504
505
506 DWORD
507 STDCALL
508 GetPriorityClass (
509 HANDLE hProcess
510 )
511 {
512 HANDLE hProcessTmp;
513 DWORD CsrPriorityClass;
514 NTSTATUS Status;
515
516 Status = NtDuplicateObject (
517 GetCurrentProcess(),
518 hProcess,
519 GetCurrentProcess(),
520 & hProcessTmp,
521 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
522 FALSE,
523 0
524 );
525 if (!NT_SUCCESS(Status))
526 {
527 SetLastErrorByStatus (Status);
528 return (0); /* ERROR */
529 }
530 /* Ask CSRSS to set it */
531 CsrSetPriorityClass (
532 hProcessTmp,
533 & CsrPriorityClass
534 );
535 NtClose (hProcessTmp);
536 /* Translate CSR->W32 priorities */
537 switch (CsrPriorityClass)
538 {
539 case CSR_PRIORITY_CLASS_NORMAL:
540 return (NORMAL_PRIORITY_CLASS); /* 32 */
541 case CSR_PRIORITY_CLASS_IDLE:
542 return (IDLE_PRIORITY_CLASS); /* 64 */
543 case CSR_PRIORITY_CLASS_HIGH:
544 return (HIGH_PRIORITY_CLASS); /* 128 */
545 case CSR_PRIORITY_CLASS_REALTIME:
546 return (REALTIME_PRIORITY_CLASS); /* 256 */
547 }
548 SetLastError (ERROR_ACCESS_DENIED);
549 return (0); /* ERROR */
550 }
551
552
553
554 WINBOOL
555 STDCALL
556 SetPriorityClass (
557 HANDLE hProcess,
558 DWORD dwPriorityClass
559 )
560 {
561 HANDLE hProcessTmp;
562 DWORD CsrPriorityClass;
563 NTSTATUS Status;
564
565 switch (dwPriorityClass)
566 {
567 case NORMAL_PRIORITY_CLASS: /* 32 */
568 CsrPriorityClass = CSR_PRIORITY_CLASS_NORMAL;
569 break;
570 case IDLE_PRIORITY_CLASS: /* 64 */
571 CsrPriorityClass = CSR_PRIORITY_CLASS_IDLE;
572 break;
573 case HIGH_PRIORITY_CLASS: /* 128 */
574 CsrPriorityClass = CSR_PRIORITY_CLASS_HIGH;
575 break;
576 case REALTIME_PRIORITY_CLASS: /* 256 */
577 CsrPriorityClass = CSR_PRIORITY_CLASS_REALTIME;
578 break;
579 default:
580 SetLastError (ERROR_INVALID_PARAMETER);
581 return (FALSE);
582 }
583 Status = NtDuplicateObject (
584 GetCurrentProcess(),
585 hProcess,
586 GetCurrentProcess(),
587 & hProcessTmp,
588 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
589 FALSE,
590 0
591 );
592 if (!NT_SUCCESS(Status))
593 {
594 SetLastErrorByStatus (Status);
595 return (FALSE); /* ERROR */
596 }
597 /* Ask CSRSS to set it */
598 Status = CsrSetPriorityClass (
599 hProcessTmp,
600 & CsrPriorityClass
601 );
602 NtClose (hProcessTmp);
603 if (!NT_SUCCESS(Status))
604 {
605 SetLastErrorByStatus (Status);
606 return (FALSE);
607 }
608 return (TRUE);
609 }
610
611
612 /* EOF */