1 /* $Id: proc.c,v 1.71 2004/11/02 21:51:25 weiden 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 ****************************************************************/
17 #include "../include/debug.h"
20 /* GLOBALS *******************************************************************/
22 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle
;
24 LPSTARTUPINFOA lpLocalStartupInfo
= NULL
;
27 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
29 /* FUNCTIONS ****************************************************************/
35 GetProcessAffinityMask (HANDLE hProcess
,
36 LPDWORD lpProcessAffinityMask
,
37 LPDWORD lpSystemAffinityMask
)
39 PROCESS_BASIC_INFORMATION ProcessInfo
;
42 Status
= NtQueryInformationProcess (hProcess
,
43 ProcessBasicInformation
,
45 sizeof(PROCESS_BASIC_INFORMATION
),
47 if (!NT_SUCCESS(Status
))
49 SetLastErrorByStatus (Status
);
53 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
56 *lpSystemAffinityMask
= 0x00000001;
66 SetProcessAffinityMask (HANDLE hProcess
,
67 DWORD dwProcessAffinityMask
)
71 Status
= NtSetInformationProcess (hProcess
,
73 (PVOID
)&dwProcessAffinityMask
,
75 if (!NT_SUCCESS(Status
))
77 SetLastErrorByStatus (Status
);
89 GetProcessShutdownParameters (LPDWORD lpdwLevel
,
92 CSRSS_API_REQUEST CsrRequest
;
93 CSRSS_API_REPLY CsrReply
;
96 CsrRequest
.Type
= CSRSS_GET_SHUTDOWN_PARAMETERS
;
97 Status
= CsrClientCallServer(&CsrRequest
,
99 sizeof(CSRSS_API_REQUEST
),
100 sizeof(CSRSS_API_REPLY
));
101 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
103 SetLastErrorByStatus (Status
);
107 *lpdwLevel
= CsrReply
.Data
.GetShutdownParametersReply
.Level
;
108 *lpdwFlags
= CsrReply
.Data
.GetShutdownParametersReply
.Flags
;
118 SetProcessShutdownParameters (DWORD dwLevel
,
121 CSRSS_API_REQUEST CsrRequest
;
122 CSRSS_API_REPLY CsrReply
;
125 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
126 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
128 CsrRequest
.Type
= CSRSS_SET_SHUTDOWN_PARAMETERS
;
129 Status
= CsrClientCallServer(&CsrRequest
,
131 sizeof(CSRSS_API_REQUEST
),
132 sizeof(CSRSS_API_REPLY
));
133 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
135 SetLastErrorByStatus (Status
);
147 GetProcessWorkingSetSize (HANDLE hProcess
,
148 PSIZE_T lpMinimumWorkingSetSize
,
149 PSIZE_T lpMaximumWorkingSetSize
)
151 QUOTA_LIMITS QuotaLimits
;
154 Status
= NtQueryInformationProcess(hProcess
,
157 sizeof(QUOTA_LIMITS
),
159 if (!NT_SUCCESS(Status
))
161 SetLastErrorByStatus(Status
);
165 *lpMinimumWorkingSetSize
= QuotaLimits
.MinimumWorkingSetSize
;
166 *lpMaximumWorkingSetSize
= QuotaLimits
.MaximumWorkingSetSize
;
176 SetProcessWorkingSetSize(HANDLE hProcess
,
177 SIZE_T dwMinimumWorkingSetSize
,
178 SIZE_T dwMaximumWorkingSetSize
)
180 QUOTA_LIMITS QuotaLimits
;
183 QuotaLimits
.MinimumWorkingSetSize
= dwMinimumWorkingSetSize
;
184 QuotaLimits
.MaximumWorkingSetSize
= dwMaximumWorkingSetSize
;
186 Status
= NtSetInformationProcess(hProcess
,
189 sizeof(QUOTA_LIMITS
));
190 if (!NT_SUCCESS(Status
))
192 SetLastErrorByStatus(Status
);
204 GetProcessTimes(HANDLE hProcess
,
205 LPFILETIME lpCreationTime
,
206 LPFILETIME lpExitTime
,
207 LPFILETIME lpKernelTime
,
208 LPFILETIME lpUserTime
)
210 KERNEL_USER_TIMES Kut
;
213 Status
= NtQueryInformationProcess(hProcess
,
218 if (!NT_SUCCESS(Status
))
220 SetLastErrorByStatus(Status
);
224 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
225 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
227 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
228 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
230 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
231 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
233 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
234 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
244 GetCurrentProcess(VOID
)
246 return((HANDLE
)NtCurrentProcess());
254 GetCurrentThread(VOID
)
256 return((HANDLE
)NtCurrentThread());
264 GetCurrentProcessId(VOID
)
266 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
274 GetExitCodeProcess(HANDLE hProcess
,
277 PROCESS_BASIC_INFORMATION ProcessBasic
;
280 Status
= NtQueryInformationProcess(hProcess
,
281 ProcessBasicInformation
,
283 sizeof(PROCESS_BASIC_INFORMATION
),
285 if (!NT_SUCCESS(Status
))
287 SetLastErrorByStatus(Status
);
291 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
302 GetProcessId(HANDLE Process
)
304 PROCESS_BASIC_INFORMATION ProcessBasic
;
307 Status
= NtQueryInformationProcess(Process
,
308 ProcessBasicInformation
,
310 sizeof(PROCESS_BASIC_INFORMATION
),
312 if (!NT_SUCCESS(Status
))
314 SetLastErrorByStatus(Status
);
318 return ProcessBasic
.UniqueProcessId
;
326 OpenProcess(DWORD dwDesiredAccess
,
331 HANDLE ProcessHandle
;
332 OBJECT_ATTRIBUTES ObjectAttributes
;
335 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
336 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
338 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
339 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
340 ObjectAttributes
.SecurityDescriptor
= NULL
;
341 ObjectAttributes
.SecurityQualityOfService
= NULL
;
342 ObjectAttributes
.ObjectName
= NULL
;
344 if (bInheritHandle
== TRUE
)
345 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
347 ObjectAttributes
.Attributes
= 0;
349 errCode
= NtOpenProcess(&ProcessHandle
,
353 if (!NT_SUCCESS(errCode
))
355 SetLastErrorByStatus (errCode
);
358 return ProcessHandle
;
366 WinExec(LPCSTR lpCmdLine
,
369 STARTUPINFOA StartupInfo
;
370 PROCESS_INFORMATION ProcessInformation
;
373 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
374 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
375 StartupInfo
.wShowWindow
= uCmdShow
;
376 StartupInfo
.dwFlags
= 0;
378 if (! CreateProcessA(NULL
,
387 &ProcessInformation
))
389 dosErr
= GetLastError();
390 return dosErr
< 32 ? dosErr
: ERROR_BAD_FORMAT
;
392 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
394 lpfnGlobalRegisterWaitForInputIdle (
395 ProcessInformation
.hProcess
,
399 NtClose(ProcessInformation
.hProcess
);
400 NtClose(ProcessInformation
.hThread
);
402 return 33; /* Something bigger than 31 means success. */
410 RegisterWaitForInputIdle (
411 WaitForInputIdleType lpfnRegisterWaitForInputIdle
414 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
436 Sleep(DWORD dwMilliseconds
)
438 SleepEx(dwMilliseconds
, FALSE
);
447 SleepEx(DWORD dwMilliseconds
,
453 if (dwMilliseconds
!= INFINITE
)
456 * System time units are 100 nanoseconds (a nanosecond is a billionth of
459 Interval
.QuadPart
= -((ULONGLONG
)dwMilliseconds
* 10000);
463 /* Approximately 292000 years hence */
464 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFFLL
;
467 errCode
= NtDelayExecution (bAlertable
, &Interval
);
468 if (!NT_SUCCESS(errCode
))
470 SetLastErrorByStatus (errCode
);
481 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
483 PRTL_USER_PROCESS_PARAMETERS Params
;
485 if (lpStartupInfo
== NULL
)
487 SetLastError(ERROR_INVALID_PARAMETER
);
491 Params
= NtCurrentPeb()->ProcessParameters
;
493 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
494 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
495 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
496 lpStartupInfo
->dwX
= Params
->dwX
;
497 lpStartupInfo
->dwY
= Params
->dwY
;
498 lpStartupInfo
->dwXSize
= Params
->dwXSize
;
499 lpStartupInfo
->dwYSize
= Params
->dwYSize
;
500 lpStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
501 lpStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
502 lpStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
503 lpStartupInfo
->dwFlags
= Params
->dwFlags
;
504 lpStartupInfo
->wShowWindow
= Params
->wShowWindow
;
505 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
506 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
507 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
509 lpStartupInfo
->hStdInput
= Params
->hStdInput
;
510 lpStartupInfo
->hStdOutput
= Params
->hStdOutput
;
511 lpStartupInfo
->hStdError
= Params
->hStdError
;
519 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
521 PRTL_USER_PROCESS_PARAMETERS Params
;
522 ANSI_STRING AnsiString
;
524 if (lpStartupInfo
== NULL
)
526 SetLastError(ERROR_INVALID_PARAMETER
);
530 Params
= NtCurrentPeb ()->ProcessParameters
;
532 RtlAcquirePebLock ();
534 if (lpLocalStartupInfo
== NULL
)
536 /* create new local startup info (ansi) */
537 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
539 sizeof(STARTUPINFOA
));
541 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
543 /* copy window title string */
544 RtlUnicodeStringToAnsiString (&AnsiString
,
545 &Params
->WindowTitle
,
547 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
549 /* copy desktop info string */
550 RtlUnicodeStringToAnsiString (&AnsiString
,
551 &Params
->DesktopInfo
,
553 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
555 /* copy shell info string */
556 RtlUnicodeStringToAnsiString (&AnsiString
,
559 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
561 lpLocalStartupInfo
->dwX
= Params
->dwX
;
562 lpLocalStartupInfo
->dwY
= Params
->dwY
;
563 lpLocalStartupInfo
->dwXSize
= Params
->dwXSize
;
564 lpLocalStartupInfo
->dwYSize
= Params
->dwYSize
;
565 lpLocalStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
566 lpLocalStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
567 lpLocalStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
568 lpLocalStartupInfo
->dwFlags
= Params
->dwFlags
;
569 lpLocalStartupInfo
->wShowWindow
= Params
->wShowWindow
;
570 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
571 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
573 lpLocalStartupInfo
->hStdInput
= Params
->hStdInput
;
574 lpLocalStartupInfo
->hStdOutput
= Params
->hStdOutput
;
575 lpLocalStartupInfo
->hStdError
= Params
->hStdError
;
578 RtlReleasePebLock ();
580 /* copy local startup info data to external startup info */
581 memcpy (lpStartupInfo
,
583 sizeof(STARTUPINFOA
));
591 FlushInstructionCache (HANDLE hProcess
,
592 LPCVOID lpBaseAddress
,
597 Status
= NtFlushInstructionCache(hProcess
,
598 (PVOID
)lpBaseAddress
,
600 if (!NT_SUCCESS(Status
))
602 SetLastErrorByStatus(Status
);
613 ExitProcess(UINT uExitCode
)
615 CSRSS_API_REQUEST CsrRequest
;
616 CSRSS_API_REPLY CsrReply
;
619 /* unload all dll's */
620 LdrShutdownProcess ();
622 /* notify csrss of process termination */
623 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
624 Status
= CsrClientCallServer(&CsrRequest
,
626 sizeof(CSRSS_API_REQUEST
),
627 sizeof(CSRSS_API_REPLY
));
628 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
630 DPRINT("Failed to tell csrss about terminating process\n");
634 NtTerminateProcess (NtCurrentProcess (),
637 /* should never get here */
647 TerminateProcess (HANDLE hProcess
,
652 Status
= NtTerminateProcess (hProcess
, uExitCode
);
653 if (NT_SUCCESS(Status
))
657 SetLastErrorByStatus (Status
);
666 FatalAppExitA (UINT uAction
,
667 LPCSTR lpMessageText
)
669 UNICODE_STRING MessageTextU
;
670 ANSI_STRING MessageText
;
672 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
674 RtlAnsiStringToUnicodeString (&MessageTextU
,
678 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
680 RtlFreeUnicodeString (&MessageTextU
);
688 FatalAppExitW(UINT uAction
,
689 LPCWSTR lpMessageText
)
699 FatalExit (int ExitCode
)
701 ExitProcess(ExitCode
);
709 GetPriorityClass (HANDLE hProcess
)
712 PROCESS_PRIORITY_CLASS PriorityClass
;
714 Status
= NtQueryInformationProcess(hProcess
,
715 ProcessPriorityClass
,
717 sizeof(PROCESS_PRIORITY_CLASS
),
719 if(NT_SUCCESS(Status
))
721 switch(PriorityClass
.PriorityClass
)
723 case PROCESS_PRIORITY_CLASS_IDLE
:
724 return IDLE_PRIORITY_CLASS
;
726 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
727 return BELOW_NORMAL_PRIORITY_CLASS
;
729 case PROCESS_PRIORITY_CLASS_NORMAL
:
730 return NORMAL_PRIORITY_CLASS
;
732 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
733 return ABOVE_NORMAL_PRIORITY_CLASS
;
735 case PROCESS_PRIORITY_CLASS_HIGH
:
736 return HIGH_PRIORITY_CLASS
;
738 case PROCESS_PRIORITY_CLASS_REALTIME
:
739 return REALTIME_PRIORITY_CLASS
;
742 return NORMAL_PRIORITY_CLASS
;
746 SetLastErrorByStatus(Status
);
755 SetPriorityClass (HANDLE hProcess
,
756 DWORD dwPriorityClass
)
759 PROCESS_PRIORITY_CLASS PriorityClass
;
761 switch(dwPriorityClass
)
763 case IDLE_PRIORITY_CLASS
:
764 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
767 case BELOW_NORMAL_PRIORITY_CLASS
:
768 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
771 case NORMAL_PRIORITY_CLASS
:
772 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
775 case ABOVE_NORMAL_PRIORITY_CLASS
:
776 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
779 case HIGH_PRIORITY_CLASS
:
780 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
783 case REALTIME_PRIORITY_CLASS
:
784 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
788 SetLastError(ERROR_INVALID_PARAMETER
);
792 PriorityClass
.Foreground
= FALSE
;
794 Status
= NtSetInformationProcess(hProcess
,
795 ProcessPriorityClass
,
797 sizeof(PROCESS_PRIORITY_CLASS
));
799 if(!NT_SUCCESS(Status
))
801 SetLastErrorByStatus(Status
);
813 GetProcessVersion (DWORD ProcessId
)
816 PIMAGE_NT_HEADERS NtHeader
= NULL
;
817 PVOID BaseAddress
= NULL
;
820 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
822 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
823 NtHeader
= RtlImageNtHeader (BaseAddress
);
824 if (NULL
!= NtHeader
)
827 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
828 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
831 else /* other process */
833 /* FIXME: open the other process */
834 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
845 GetProcessIoCounters(
847 PIO_COUNTERS lpIoCounters
)
851 Status
= NtQueryInformationProcess(hProcess
,
856 if (!NT_SUCCESS(Status
))
858 SetLastErrorByStatus(Status
);
871 GetProcessPriorityBoost(HANDLE hProcess
,
872 PBOOL pDisablePriorityBoost
)
877 Status
= NtQueryInformationProcess(hProcess
,
878 ProcessPriorityBoost
,
882 if (NT_SUCCESS(Status
))
884 *pDisablePriorityBoost
= PriorityBoost
;
888 SetLastErrorByStatus(Status
);
898 SetProcessPriorityBoost(HANDLE hProcess
,
899 BOOL bDisablePriorityBoost
)
902 BOOL PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
904 Status
= NtSetInformationProcess(hProcess
,
905 ProcessPriorityBoost
,
908 if (!NT_SUCCESS(Status
))
910 SetLastErrorByStatus(Status
);
923 GetProcessHandleCount(HANDLE hProcess
,
924 PDWORD pdwHandleCount
)
929 Status
= NtQueryInformationProcess(hProcess
,
934 if(NT_SUCCESS(Status
))
936 *pdwHandleCount
= phc
;
940 SetLastErrorByStatus(Status
);