1 /* $Id: proc.c,v 1.35 2000/09/05 13:52:30 ekohl Exp $
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)
12 /* INCLUDES ****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <ntdll/rtl.h>
17 #include <kernel32/proc.h>
18 #include <kernel32/thread.h>
19 #include <kernel32/error.h>
22 #include <napi/i386/segment.h>
24 #include <ntdll/csr.h>
25 #include <ntdll/ldr.h>
29 #include <kernel32/kernel32.h>
32 /* GLOBALS *******************************************************************/
34 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle
;
36 LPSTARTUPINFO lpLocalStartupInfo
= NULL
;
40 RegisterWaitForInputIdle (
41 WaitForInputIdleType lpfnRegisterWaitForInputIdle
45 /* FUNCTIONS ****************************************************************/
62 LPFILETIME lpCreationTime
,
63 LPFILETIME lpExitTime
,
64 LPFILETIME lpKernelTime
,
69 KERNEL_USER_TIMES Kut
;
71 Status
= NtQueryInformationProcess (
78 if (!NT_SUCCESS(Status
))
80 SetLastErrorByStatus (Status
);
84 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
85 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
87 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
88 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
90 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
91 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
93 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
94 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
100 HANDLE STDCALL
GetCurrentProcess (VOID
)
102 return((HANDLE
)NtCurrentProcess());
106 HANDLE STDCALL
GetCurrentThread (VOID
)
108 return((HANDLE
)NtCurrentThread());
112 DWORD STDCALL
GetCurrentProcessId (VOID
)
114 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
126 PROCESS_BASIC_INFORMATION ProcessBasic
;
129 errCode
= NtQueryInformationProcess(hProcess
,
130 ProcessBasicInformation
,
132 sizeof(PROCESS_BASIC_INFORMATION
),
134 if (!NT_SUCCESS(errCode
))
136 SetLastErrorByStatus (errCode
);
139 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
152 PROCESS_BASIC_INFORMATION ProcessBasic
;
155 errCode
= NtQueryInformationProcess(hProcess
,
156 ProcessBasicInformation
,
158 sizeof(PROCESS_BASIC_INFORMATION
),
160 if (!NT_SUCCESS(errCode
))
162 SetLastErrorByStatus (errCode
);
165 memcpy( lpProcessId
,&ProcessBasic
.UniqueProcessId
,sizeof(DWORD
));
173 DWORD dwDesiredAccess
,
174 WINBOOL bInheritHandle
,
179 HANDLE ProcessHandle
;
180 OBJECT_ATTRIBUTES ObjectAttributes
;
183 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
184 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
186 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
187 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
188 ObjectAttributes
.SecurityDescriptor
= NULL
;
189 ObjectAttributes
.SecurityQualityOfService
= NULL
;
190 ObjectAttributes
.ObjectName
= NULL
;
192 if (bInheritHandle
== TRUE
)
193 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
195 ObjectAttributes
.Attributes
= 0;
197 errCode
= NtOpenProcess(&ProcessHandle
,
201 if (!NT_SUCCESS(errCode
))
203 SetLastErrorByStatus (errCode
);
206 return ProcessHandle
;
217 STARTUPINFOA StartupInfo
;
218 PROCESS_INFORMATION ProcessInformation
;
222 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
223 StartupInfo
.wShowWindow
= uCmdShow
;
224 StartupInfo
.dwFlags
= 0;
226 hInst
= (HINSTANCE
)CreateProcessA(NULL
,
235 &ProcessInformation
);
238 dosErr
= GetLastError();
241 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
243 lpfnGlobalRegisterWaitForInputIdle (
244 ProcessInformation
.hProcess
,
248 NtClose (ProcessInformation
.hProcess
);
249 NtClose (ProcessInformation
.hThread
);
256 RegisterWaitForInputIdle (
257 WaitForInputIdleType lpfnRegisterWaitForInputIdle
260 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
282 SleepEx (dwMilliseconds
, FALSE
);
290 DWORD dwMilliseconds
,
297 Interval
.QuadPart
= dwMilliseconds
* 1000;
299 errCode
= NtDelayExecution (bAlertable
, & Interval
);
300 if (!NT_SUCCESS(errCode
))
302 SetLastErrorByStatus (errCode
);
312 LPSTARTUPINFOW lpStartupInfo
315 PRTL_USER_PROCESS_PARAMETERS Params
;
317 if (lpStartupInfo
== NULL
)
319 SetLastError(ERROR_INVALID_PARAMETER
);
323 Params
= NtCurrentPeb ()->ProcessParameters
;
325 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
326 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
327 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
328 lpStartupInfo
->dwX
= Params
->StartingX
;
329 lpStartupInfo
->dwY
= Params
->StartingY
;
330 lpStartupInfo
->dwXSize
= Params
->CountX
;
331 lpStartupInfo
->dwYSize
= Params
->CountY
;
332 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
333 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
334 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
335 lpStartupInfo
->dwFlags
= Params
->Flags
;
336 lpStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
337 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
338 lpStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
339 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
341 lpStartupInfo
->hStdInput
= Params
->InputHandle
;
342 lpStartupInfo
->hStdOutput
= Params
->OutputHandle
;
343 lpStartupInfo
->hStdError
= Params
->ErrorHandle
;
350 LPSTARTUPINFOA lpStartupInfo
353 PRTL_USER_PROCESS_PARAMETERS Params
;
354 ANSI_STRING AnsiString
;
356 if (lpStartupInfo
== NULL
)
358 SetLastError(ERROR_INVALID_PARAMETER
);
362 Params
= NtCurrentPeb ()->ProcessParameters
;
364 RtlAcquirePebLock ();
366 if (lpLocalStartupInfo
== NULL
)
368 /* create new local startup info (ansi) */
369 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
371 sizeof(STARTUPINFOA
));
373 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
375 /* copy window title string */
376 RtlUnicodeStringToAnsiString (&AnsiString
,
377 &Params
->WindowTitle
,
379 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
381 /* copy desktop info string */
382 RtlUnicodeStringToAnsiString (&AnsiString
,
383 &Params
->DesktopInfo
,
385 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
387 /* copy shell info string */
388 RtlUnicodeStringToAnsiString (&AnsiString
,
391 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
393 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
394 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
395 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
396 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
397 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
398 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
399 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
400 lpLocalStartupInfo
->dwFlags
= Params
->Flags
;
401 lpLocalStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
402 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
403 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
405 lpLocalStartupInfo
->hStdInput
= Params
->InputHandle
;
406 lpLocalStartupInfo
->hStdOutput
= Params
->OutputHandle
;
407 lpLocalStartupInfo
->hStdError
= Params
->ErrorHandle
;
410 RtlReleasePebLock ();
412 /* copy local startup info data to external startup info */
413 memcpy (lpStartupInfo
,
415 sizeof(STARTUPINFOA
));
421 FlushInstructionCache (
423 LPCVOID lpBaseAddress
,
429 errCode
= NtFlushInstructionCache (
431 (PVOID
) lpBaseAddress
,
433 if (!NT_SUCCESS(errCode
))
435 SetLastErrorByStatus (errCode
);
448 /* unload all dll's */
449 LdrShutdownProcess ();
451 /* FIXME: notify csrss of process termination */
453 NtTerminateProcess (NtCurrentProcess (),
467 errCode
= NtTerminateProcess (hProcess
, uExitCode
);
468 if (!NT_SUCCESS(errCode
))
470 SetLastErrorByStatus (errCode
);
484 UNICODE_STRING MessageTextU
;
485 ANSI_STRING MessageText
;
487 RtlInitAnsiString (& MessageText
,
488 (LPSTR
) lpMessageText
);
490 RtlAnsiStringToUnicodeString (& MessageTextU
,
494 FatalAppExitW (uAction
,
495 MessageTextU
.Buffer
);
497 RtlFreeUnicodeString (&MessageTextU
);
505 LPCWSTR lpMessageText
518 ExitProcess(ExitCode
);
529 DWORD CsrPriorityClass
;
532 Status
= NtDuplicateObject (
537 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
541 if (!NT_SUCCESS(Status
))
543 SetLastErrorByStatus (Status
);
544 return (0); /* ERROR */
546 /* Ask CSRSS to set it */
547 CsrSetPriorityClass (
551 NtClose (hProcessTmp
);
552 /* Translate CSR->W32 priorities */
553 switch (CsrPriorityClass
)
555 case CSR_PRIORITY_CLASS_NORMAL
:
556 return (NORMAL_PRIORITY_CLASS
); /* 32 */
557 case CSR_PRIORITY_CLASS_IDLE
:
558 return (IDLE_PRIORITY_CLASS
); /* 64 */
559 case CSR_PRIORITY_CLASS_HIGH
:
560 return (HIGH_PRIORITY_CLASS
); /* 128 */
561 case CSR_PRIORITY_CLASS_REALTIME
:
562 return (REALTIME_PRIORITY_CLASS
); /* 256 */
564 SetLastError (ERROR_ACCESS_DENIED
);
565 return (0); /* ERROR */
574 DWORD dwPriorityClass
578 DWORD CsrPriorityClass
;
581 switch (dwPriorityClass
)
583 case NORMAL_PRIORITY_CLASS
: /* 32 */
584 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
586 case IDLE_PRIORITY_CLASS
: /* 64 */
587 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
589 case HIGH_PRIORITY_CLASS
: /* 128 */
590 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
592 case REALTIME_PRIORITY_CLASS
: /* 256 */
593 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
596 SetLastError (ERROR_INVALID_PARAMETER
);
599 Status
= NtDuplicateObject (
604 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
608 if (!NT_SUCCESS(Status
))
610 SetLastErrorByStatus (Status
);
611 return (FALSE
); /* ERROR */
613 /* Ask CSRSS to set it */
614 Status
= CsrSetPriorityClass (
618 NtClose (hProcessTmp
);
619 if (!NT_SUCCESS(Status
))
621 SetLastErrorByStatus (Status
);