1 /* $Id: proc.c,v 1.53 2003/04/26 23:13:28 hyperion 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 ****************************************************************/
18 #include <kernel32/kernel32.h>
21 /* GLOBALS *******************************************************************/
23 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle
;
25 LPSTARTUPINFO lpLocalStartupInfo
= NULL
;
28 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
31 GetProcessId (HANDLE hProcess
, LPDWORD lpProcessId
);
34 /* FUNCTIONS ****************************************************************/
37 GetProcessAffinityMask (HANDLE hProcess
,
38 LPDWORD lpProcessAffinityMask
,
39 LPDWORD lpSystemAffinityMask
)
41 PROCESS_BASIC_INFORMATION ProcessInfo
;
45 Status
= NtQueryInformationProcess (hProcess
,
46 ProcessBasicInformation
,
48 sizeof(PROCESS_BASIC_INFORMATION
),
50 if (!NT_SUCCESS(Status
))
52 SetLastError (Status
);
56 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
59 *lpSystemAffinityMask
= 0x00000001;
66 SetProcessAffinityMask (HANDLE hProcess
,
67 DWORD dwProcessAffinityMask
)
71 Status
= NtSetInformationProcess (hProcess
,
73 (PVOID
)&dwProcessAffinityMask
,
75 if (!NT_SUCCESS(Status
))
77 SetLastError (Status
);
86 GetProcessShutdownParameters (LPDWORD lpdwLevel
,
89 CSRSS_API_REQUEST CsrRequest
;
90 CSRSS_API_REPLY CsrReply
;
93 CsrRequest
.Type
= CSRSS_GET_SHUTDOWN_PARAMETERS
;
94 Status
= CsrClientCallServer(&CsrRequest
,
96 sizeof(CSRSS_API_REQUEST
),
97 sizeof(CSRSS_API_REPLY
));
98 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
100 SetLastError(Status
);
104 *lpdwLevel
= CsrReply
.Data
.GetShutdownParametersReply
.Level
;
105 *lpdwFlags
= CsrReply
.Data
.GetShutdownParametersReply
.Flags
;
112 SetProcessShutdownParameters (DWORD dwLevel
,
115 CSRSS_API_REQUEST CsrRequest
;
116 CSRSS_API_REPLY CsrReply
;
119 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
120 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
122 CsrRequest
.Type
= CSRSS_SET_SHUTDOWN_PARAMETERS
;
123 Status
= CsrClientCallServer(&CsrRequest
,
125 sizeof(CSRSS_API_REQUEST
),
126 sizeof(CSRSS_API_REPLY
));
127 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
129 SetLastError(Status
);
138 GetProcessWorkingSetSize (HANDLE hProcess
,
139 LPDWORD lpMinimumWorkingSetSize
,
140 LPDWORD lpMaximumWorkingSetSize
)
142 QUOTA_LIMITS QuotaLimits
;
145 Status
= NtQueryInformationProcess(hProcess
,
148 sizeof(QUOTA_LIMITS
),
150 if (!NT_SUCCESS(Status
))
152 SetLastErrorByStatus(Status
);
156 *lpMinimumWorkingSetSize
= (DWORD
)QuotaLimits
.MinimumWorkingSetSize
;
157 *lpMaximumWorkingSetSize
= (DWORD
)QuotaLimits
.MaximumWorkingSetSize
;
164 SetProcessWorkingSetSize(HANDLE hProcess
,
165 DWORD dwMinimumWorkingSetSize
,
166 DWORD dwMaximumWorkingSetSize
)
168 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
174 GetProcessTimes(HANDLE hProcess
,
175 LPFILETIME lpCreationTime
,
176 LPFILETIME lpExitTime
,
177 LPFILETIME lpKernelTime
,
178 LPFILETIME lpUserTime
)
180 KERNEL_USER_TIMES Kut
;
183 Status
= NtQueryInformationProcess(hProcess
,
188 if (!NT_SUCCESS(Status
))
190 SetLastErrorByStatus(Status
);
194 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
195 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
197 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
198 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
200 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
201 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
203 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
204 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
211 GetCurrentProcess(VOID
)
213 return((HANDLE
)NtCurrentProcess());
218 GetCurrentThread(VOID
)
220 return((HANDLE
)NtCurrentThread());
225 GetCurrentProcessId(VOID
)
227 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
232 GetExitCodeProcess(HANDLE hProcess
,
235 PROCESS_BASIC_INFORMATION ProcessBasic
;
239 Status
= NtQueryInformationProcess(hProcess
,
240 ProcessBasicInformation
,
242 sizeof(PROCESS_BASIC_INFORMATION
),
244 if (!NT_SUCCESS(Status
))
246 SetLastErrorByStatus(Status
);
250 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
257 GetProcessId(HANDLE hProcess
,
260 PROCESS_BASIC_INFORMATION ProcessBasic
;
264 Status
= NtQueryInformationProcess(hProcess
,
265 ProcessBasicInformation
,
267 sizeof(PROCESS_BASIC_INFORMATION
),
269 if (!NT_SUCCESS(Status
))
271 SetLastErrorByStatus(Status
);
275 memcpy(lpProcessId
, &ProcessBasic
.UniqueProcessId
, sizeof(DWORD
));
282 OpenProcess(DWORD dwDesiredAccess
,
283 WINBOOL bInheritHandle
,
287 HANDLE ProcessHandle
;
288 OBJECT_ATTRIBUTES ObjectAttributes
;
291 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
292 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
294 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
295 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
296 ObjectAttributes
.SecurityDescriptor
= NULL
;
297 ObjectAttributes
.SecurityQualityOfService
= NULL
;
298 ObjectAttributes
.ObjectName
= NULL
;
300 if (bInheritHandle
== TRUE
)
301 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
303 ObjectAttributes
.Attributes
= 0;
305 errCode
= NtOpenProcess(&ProcessHandle
,
309 if (!NT_SUCCESS(errCode
))
311 SetLastErrorByStatus (errCode
);
314 return ProcessHandle
;
319 WinExec(LPCSTR lpCmdLine
,
322 STARTUPINFOA StartupInfo
;
323 PROCESS_INFORMATION ProcessInformation
;
327 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
328 StartupInfo
.wShowWindow
= uCmdShow
;
329 StartupInfo
.dwFlags
= 0;
331 hInst
= (HINSTANCE
)CreateProcessA(NULL
,
340 &ProcessInformation
);
343 dosErr
= GetLastError();
346 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
348 lpfnGlobalRegisterWaitForInputIdle (
349 ProcessInformation
.hProcess
,
353 NtClose (ProcessInformation
.hProcess
);
354 NtClose (ProcessInformation
.hThread
);
360 RegisterWaitForInputIdle (
361 WaitForInputIdleType lpfnRegisterWaitForInputIdle
364 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
380 Sleep(DWORD dwMilliseconds
)
382 SleepEx(dwMilliseconds
, FALSE
);
388 SleepEx(DWORD dwMilliseconds
,
394 if (dwMilliseconds
!= INFINITE
)
397 * System time units are 100 nanoseconds (a nanosecond is a billionth of
400 Interval
.QuadPart
= dwMilliseconds
;
401 Interval
.QuadPart
= -(Interval
.QuadPart
* 10000);
405 /* Approximately 292000 years hence */
406 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFF;
409 errCode
= NtDelayExecution (bAlertable
, &Interval
);
410 if (!NT_SUCCESS(errCode
))
412 SetLastErrorByStatus (errCode
);
420 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
422 PRTL_USER_PROCESS_PARAMETERS Params
;
424 if (lpStartupInfo
== NULL
)
426 SetLastError(ERROR_INVALID_PARAMETER
);
430 Params
= NtCurrentPeb()->ProcessParameters
;
432 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
433 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
434 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
435 lpStartupInfo
->dwX
= Params
->dwX
;
436 lpStartupInfo
->dwY
= Params
->dwY
;
437 lpStartupInfo
->dwXSize
= Params
->dwXSize
;
438 lpStartupInfo
->dwYSize
= Params
->dwYSize
;
439 lpStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
440 lpStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
441 lpStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
442 lpStartupInfo
->dwFlags
= Params
->dwFlags
;
443 lpStartupInfo
->wShowWindow
= Params
->wShowWindow
;
444 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
445 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
446 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
448 lpStartupInfo
->hStdInput
= Params
->hStdInput
;
449 lpStartupInfo
->hStdOutput
= Params
->hStdOutput
;
450 lpStartupInfo
->hStdError
= Params
->hStdError
;
455 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
457 PRTL_USER_PROCESS_PARAMETERS Params
;
458 ANSI_STRING AnsiString
;
460 if (lpStartupInfo
== NULL
)
462 SetLastError(ERROR_INVALID_PARAMETER
);
466 Params
= NtCurrentPeb ()->ProcessParameters
;
468 RtlAcquirePebLock ();
470 if (lpLocalStartupInfo
== NULL
)
472 /* create new local startup info (ansi) */
473 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
475 sizeof(STARTUPINFOA
));
477 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
479 /* copy window title string */
480 RtlUnicodeStringToAnsiString (&AnsiString
,
481 &Params
->WindowTitle
,
483 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
485 /* copy desktop info string */
486 RtlUnicodeStringToAnsiString (&AnsiString
,
487 &Params
->DesktopInfo
,
489 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
491 /* copy shell info string */
492 RtlUnicodeStringToAnsiString (&AnsiString
,
495 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
497 lpLocalStartupInfo
->dwX
= Params
->dwX
;
498 lpLocalStartupInfo
->dwY
= Params
->dwY
;
499 lpLocalStartupInfo
->dwXSize
= Params
->dwXSize
;
500 lpLocalStartupInfo
->dwYSize
= Params
->dwYSize
;
501 lpLocalStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
502 lpLocalStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
503 lpLocalStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
504 lpLocalStartupInfo
->dwFlags
= Params
->dwFlags
;
505 lpLocalStartupInfo
->wShowWindow
= Params
->wShowWindow
;
506 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
507 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
509 lpLocalStartupInfo
->hStdInput
= Params
->hStdInput
;
510 lpLocalStartupInfo
->hStdOutput
= Params
->hStdOutput
;
511 lpLocalStartupInfo
->hStdError
= Params
->hStdError
;
514 RtlReleasePebLock ();
516 /* copy local startup info data to external startup info */
517 memcpy (lpStartupInfo
,
519 sizeof(STARTUPINFOA
));
524 FlushInstructionCache (HANDLE hProcess
,
525 LPCVOID lpBaseAddress
,
530 Status
= NtFlushInstructionCache(hProcess
,
531 (PVOID
)lpBaseAddress
,
533 if (!NT_SUCCESS(Status
))
535 SetLastErrorByStatus(Status
);
543 ExitProcess(UINT uExitCode
)
545 CSRSS_API_REQUEST CsrRequest
;
546 CSRSS_API_REPLY CsrReply
;
549 /* unload all dll's */
550 LdrShutdownProcess ();
552 /* notify csrss of process termination */
553 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
554 Status
= CsrClientCallServer(&CsrRequest
,
556 sizeof(CSRSS_API_REQUEST
),
557 sizeof(CSRSS_API_REPLY
));
558 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
560 DbgPrint("Failed to tell csrss about terminating process. "
561 "Expect trouble.\n");
565 NtTerminateProcess (NtCurrentProcess (),
568 /* should never get here */
575 TerminateProcess (HANDLE hProcess
,
580 Status
= NtTerminateProcess (hProcess
, uExitCode
);
581 if (NT_SUCCESS(Status
))
585 SetLastErrorByStatus (Status
);
591 FatalAppExitA (UINT uAction
,
592 LPCSTR lpMessageText
)
594 UNICODE_STRING MessageTextU
;
595 ANSI_STRING MessageText
;
597 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
599 RtlAnsiStringToUnicodeString (&MessageTextU
,
603 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
605 RtlFreeUnicodeString (&MessageTextU
);
610 FatalAppExitW(UINT uAction
,
611 LPCWSTR lpMessageText
)
618 FatalExit (int ExitCode
)
620 ExitProcess(ExitCode
);
625 GetPriorityClass (HANDLE hProcess
)
628 DWORD CsrPriorityClass
= 0; // This tells CSRSS we want to GET it!
632 NtDuplicateObject (GetCurrentProcess(),
636 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
639 if (!NT_SUCCESS(Status
))
641 SetLastErrorByStatus (Status
);
642 return (0); /* ERROR */
644 /* Ask CSRSS to set it */
645 CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
646 NtClose (hProcessTmp
);
647 /* Translate CSR->W32 priorities */
648 switch (CsrPriorityClass
)
650 case CSR_PRIORITY_CLASS_NORMAL
:
651 return (NORMAL_PRIORITY_CLASS
); /* 32 */
652 case CSR_PRIORITY_CLASS_IDLE
:
653 return (IDLE_PRIORITY_CLASS
); /* 64 */
654 case CSR_PRIORITY_CLASS_HIGH
:
655 return (HIGH_PRIORITY_CLASS
); /* 128 */
656 case CSR_PRIORITY_CLASS_REALTIME
:
657 return (REALTIME_PRIORITY_CLASS
); /* 256 */
659 SetLastError (ERROR_ACCESS_DENIED
);
660 return (0); /* ERROR */
666 SetPriorityClass (HANDLE hProcess
,
667 DWORD dwPriorityClass
)
670 DWORD CsrPriorityClass
;
673 switch (dwPriorityClass
)
675 case NORMAL_PRIORITY_CLASS
: /* 32 */
676 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
678 case IDLE_PRIORITY_CLASS
: /* 64 */
679 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
681 case HIGH_PRIORITY_CLASS
: /* 128 */
682 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
684 case REALTIME_PRIORITY_CLASS
: /* 256 */
685 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
688 SetLastError (ERROR_INVALID_PARAMETER
);
692 NtDuplicateObject (GetCurrentProcess(),
696 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
699 if (!NT_SUCCESS(Status
))
701 SetLastErrorByStatus (Status
);
702 return (FALSE
); /* ERROR */
704 /* Ask CSRSS to set it */
705 Status
= CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
706 NtClose (hProcessTmp
);
707 if (!NT_SUCCESS(Status
))
709 SetLastErrorByStatus (Status
);
717 GetProcessVersion (DWORD ProcessId
)
720 PIMAGE_NT_HEADERS NtHeader
= NULL
;
721 PVOID BaseAddress
= NULL
;
724 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
726 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
727 NtHeader
= RtlImageNtHeader (BaseAddress
);
728 if (NULL
!= NtHeader
)
731 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
732 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
735 else /* other process */
737 /* FIXME: open the other process */
738 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);