1 /* $Id: proc.c,v 1.69 2004/10/02 21:14:08 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
);
30 InternalGetProcessId (HANDLE hProcess
, LPDWORD lpProcessId
);
33 /* FUNCTIONS ****************************************************************/
39 GetProcessAffinityMask (HANDLE hProcess
,
40 LPDWORD lpProcessAffinityMask
,
41 LPDWORD lpSystemAffinityMask
)
43 PROCESS_BASIC_INFORMATION ProcessInfo
;
47 Status
= NtQueryInformationProcess (hProcess
,
48 ProcessBasicInformation
,
50 sizeof(PROCESS_BASIC_INFORMATION
),
52 if (!NT_SUCCESS(Status
))
54 SetLastErrorByStatus (Status
);
58 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
61 *lpSystemAffinityMask
= 0x00000001;
71 SetProcessAffinityMask (HANDLE hProcess
,
72 DWORD dwProcessAffinityMask
)
76 Status
= NtSetInformationProcess (hProcess
,
78 (PVOID
)&dwProcessAffinityMask
,
80 if (!NT_SUCCESS(Status
))
82 SetLastErrorByStatus (Status
);
94 GetProcessShutdownParameters (LPDWORD lpdwLevel
,
97 CSRSS_API_REQUEST CsrRequest
;
98 CSRSS_API_REPLY CsrReply
;
101 CsrRequest
.Type
= CSRSS_GET_SHUTDOWN_PARAMETERS
;
102 Status
= CsrClientCallServer(&CsrRequest
,
104 sizeof(CSRSS_API_REQUEST
),
105 sizeof(CSRSS_API_REPLY
));
106 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
108 SetLastErrorByStatus (Status
);
112 *lpdwLevel
= CsrReply
.Data
.GetShutdownParametersReply
.Level
;
113 *lpdwFlags
= CsrReply
.Data
.GetShutdownParametersReply
.Flags
;
123 SetProcessShutdownParameters (DWORD dwLevel
,
126 CSRSS_API_REQUEST CsrRequest
;
127 CSRSS_API_REPLY CsrReply
;
130 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
131 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
133 CsrRequest
.Type
= CSRSS_SET_SHUTDOWN_PARAMETERS
;
134 Status
= CsrClientCallServer(&CsrRequest
,
136 sizeof(CSRSS_API_REQUEST
),
137 sizeof(CSRSS_API_REPLY
));
138 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
140 SetLastErrorByStatus (Status
);
152 GetProcessWorkingSetSize (HANDLE hProcess
,
153 PSIZE_T lpMinimumWorkingSetSize
,
154 PSIZE_T lpMaximumWorkingSetSize
)
156 QUOTA_LIMITS QuotaLimits
;
159 Status
= NtQueryInformationProcess(hProcess
,
162 sizeof(QUOTA_LIMITS
),
164 if (!NT_SUCCESS(Status
))
166 SetLastErrorByStatus(Status
);
170 *lpMinimumWorkingSetSize
= QuotaLimits
.MinimumWorkingSetSize
;
171 *lpMaximumWorkingSetSize
= QuotaLimits
.MaximumWorkingSetSize
;
181 SetProcessWorkingSetSize(HANDLE hProcess
,
182 SIZE_T dwMinimumWorkingSetSize
,
183 SIZE_T dwMaximumWorkingSetSize
)
185 QUOTA_LIMITS QuotaLimits
;
188 QuotaLimits
.MinimumWorkingSetSize
= dwMinimumWorkingSetSize
;
189 QuotaLimits
.MaximumWorkingSetSize
= dwMaximumWorkingSetSize
;
191 Status
= NtSetInformationProcess(hProcess
,
194 sizeof(QUOTA_LIMITS
));
195 if (!NT_SUCCESS(Status
))
197 SetLastErrorByStatus(Status
);
209 GetProcessTimes(HANDLE hProcess
,
210 LPFILETIME lpCreationTime
,
211 LPFILETIME lpExitTime
,
212 LPFILETIME lpKernelTime
,
213 LPFILETIME lpUserTime
)
215 KERNEL_USER_TIMES Kut
;
218 Status
= NtQueryInformationProcess(hProcess
,
223 if (!NT_SUCCESS(Status
))
225 SetLastErrorByStatus(Status
);
229 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
230 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
232 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
233 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
235 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
236 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
238 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
239 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
249 GetCurrentProcess(VOID
)
251 return((HANDLE
)NtCurrentProcess());
259 GetCurrentThread(VOID
)
261 return((HANDLE
)NtCurrentThread());
269 GetCurrentProcessId(VOID
)
271 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
279 GetExitCodeProcess(HANDLE hProcess
,
282 PROCESS_BASIC_INFORMATION ProcessBasic
;
286 Status
= NtQueryInformationProcess(hProcess
,
287 ProcessBasicInformation
,
289 sizeof(PROCESS_BASIC_INFORMATION
),
291 if (!NT_SUCCESS(Status
))
293 SetLastErrorByStatus(Status
);
297 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
307 InternalGetProcessId(HANDLE hProcess
,
310 PROCESS_BASIC_INFORMATION ProcessBasic
;
314 Status
= NtQueryInformationProcess(hProcess
,
315 ProcessBasicInformation
,
317 sizeof(PROCESS_BASIC_INFORMATION
),
319 if (!NT_SUCCESS(Status
))
321 SetLastErrorByStatus(Status
);
325 memcpy(lpProcessId
, &ProcessBasic
.UniqueProcessId
, sizeof(DWORD
));
336 GetProcessId(HANDLE Process
)
340 if(!InternalGetProcessId(Process
, &ProcessId
))
352 OpenProcess(DWORD dwDesiredAccess
,
357 HANDLE ProcessHandle
;
358 OBJECT_ATTRIBUTES ObjectAttributes
;
361 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
362 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
364 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
365 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
366 ObjectAttributes
.SecurityDescriptor
= NULL
;
367 ObjectAttributes
.SecurityQualityOfService
= NULL
;
368 ObjectAttributes
.ObjectName
= NULL
;
370 if (bInheritHandle
== TRUE
)
371 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
373 ObjectAttributes
.Attributes
= 0;
375 errCode
= NtOpenProcess(&ProcessHandle
,
379 if (!NT_SUCCESS(errCode
))
381 SetLastErrorByStatus (errCode
);
384 return ProcessHandle
;
392 WinExec(LPCSTR lpCmdLine
,
395 STARTUPINFOA StartupInfo
;
396 PROCESS_INFORMATION ProcessInformation
;
399 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
400 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
401 StartupInfo
.wShowWindow
= uCmdShow
;
402 StartupInfo
.dwFlags
= 0;
404 if (! CreateProcessA(NULL
,
413 &ProcessInformation
))
415 dosErr
= GetLastError();
416 return dosErr
< 32 ? dosErr
: ERROR_BAD_FORMAT
;
418 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
420 lpfnGlobalRegisterWaitForInputIdle (
421 ProcessInformation
.hProcess
,
425 NtClose(ProcessInformation
.hProcess
);
426 NtClose(ProcessInformation
.hThread
);
428 return 33; /* Something bigger than 31 means success. */
436 RegisterWaitForInputIdle (
437 WaitForInputIdleType lpfnRegisterWaitForInputIdle
440 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
462 Sleep(DWORD dwMilliseconds
)
464 SleepEx(dwMilliseconds
, FALSE
);
473 SleepEx(DWORD dwMilliseconds
,
479 if (dwMilliseconds
!= INFINITE
)
482 * System time units are 100 nanoseconds (a nanosecond is a billionth of
485 Interval
.QuadPart
= -((ULONGLONG
)dwMilliseconds
* 10000);
489 /* Approximately 292000 years hence */
490 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFFLL
;
493 errCode
= NtDelayExecution (bAlertable
, &Interval
);
494 if (!NT_SUCCESS(errCode
))
496 SetLastErrorByStatus (errCode
);
507 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
509 PRTL_USER_PROCESS_PARAMETERS Params
;
511 if (lpStartupInfo
== NULL
)
513 SetLastError(ERROR_INVALID_PARAMETER
);
517 Params
= NtCurrentPeb()->ProcessParameters
;
519 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
520 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
521 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
522 lpStartupInfo
->dwX
= Params
->dwX
;
523 lpStartupInfo
->dwY
= Params
->dwY
;
524 lpStartupInfo
->dwXSize
= Params
->dwXSize
;
525 lpStartupInfo
->dwYSize
= Params
->dwYSize
;
526 lpStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
527 lpStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
528 lpStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
529 lpStartupInfo
->dwFlags
= Params
->dwFlags
;
530 lpStartupInfo
->wShowWindow
= Params
->wShowWindow
;
531 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
532 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
533 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
535 lpStartupInfo
->hStdInput
= Params
->hStdInput
;
536 lpStartupInfo
->hStdOutput
= Params
->hStdOutput
;
537 lpStartupInfo
->hStdError
= Params
->hStdError
;
545 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
547 PRTL_USER_PROCESS_PARAMETERS Params
;
548 ANSI_STRING AnsiString
;
550 if (lpStartupInfo
== NULL
)
552 SetLastError(ERROR_INVALID_PARAMETER
);
556 Params
= NtCurrentPeb ()->ProcessParameters
;
558 RtlAcquirePebLock ();
560 if (lpLocalStartupInfo
== NULL
)
562 /* create new local startup info (ansi) */
563 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
565 sizeof(STARTUPINFOA
));
567 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
569 /* copy window title string */
570 RtlUnicodeStringToAnsiString (&AnsiString
,
571 &Params
->WindowTitle
,
573 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
575 /* copy desktop info string */
576 RtlUnicodeStringToAnsiString (&AnsiString
,
577 &Params
->DesktopInfo
,
579 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
581 /* copy shell info string */
582 RtlUnicodeStringToAnsiString (&AnsiString
,
585 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
587 lpLocalStartupInfo
->dwX
= Params
->dwX
;
588 lpLocalStartupInfo
->dwY
= Params
->dwY
;
589 lpLocalStartupInfo
->dwXSize
= Params
->dwXSize
;
590 lpLocalStartupInfo
->dwYSize
= Params
->dwYSize
;
591 lpLocalStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
592 lpLocalStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
593 lpLocalStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
594 lpLocalStartupInfo
->dwFlags
= Params
->dwFlags
;
595 lpLocalStartupInfo
->wShowWindow
= Params
->wShowWindow
;
596 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
597 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
599 lpLocalStartupInfo
->hStdInput
= Params
->hStdInput
;
600 lpLocalStartupInfo
->hStdOutput
= Params
->hStdOutput
;
601 lpLocalStartupInfo
->hStdError
= Params
->hStdError
;
604 RtlReleasePebLock ();
606 /* copy local startup info data to external startup info */
607 memcpy (lpStartupInfo
,
609 sizeof(STARTUPINFOA
));
617 FlushInstructionCache (HANDLE hProcess
,
618 LPCVOID lpBaseAddress
,
623 Status
= NtFlushInstructionCache(hProcess
,
624 (PVOID
)lpBaseAddress
,
626 if (!NT_SUCCESS(Status
))
628 SetLastErrorByStatus(Status
);
639 ExitProcess(UINT uExitCode
)
641 CSRSS_API_REQUEST CsrRequest
;
642 CSRSS_API_REPLY CsrReply
;
645 /* unload all dll's */
646 LdrShutdownProcess ();
648 /* notify csrss of process termination */
649 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
650 Status
= CsrClientCallServer(&CsrRequest
,
652 sizeof(CSRSS_API_REQUEST
),
653 sizeof(CSRSS_API_REPLY
));
654 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
656 DPRINT("Failed to tell csrss about terminating process\n");
660 NtTerminateProcess (NtCurrentProcess (),
663 /* should never get here */
673 TerminateProcess (HANDLE hProcess
,
678 Status
= NtTerminateProcess (hProcess
, uExitCode
);
679 if (NT_SUCCESS(Status
))
683 SetLastErrorByStatus (Status
);
692 FatalAppExitA (UINT uAction
,
693 LPCSTR lpMessageText
)
695 UNICODE_STRING MessageTextU
;
696 ANSI_STRING MessageText
;
698 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
700 RtlAnsiStringToUnicodeString (&MessageTextU
,
704 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
706 RtlFreeUnicodeString (&MessageTextU
);
714 FatalAppExitW(UINT uAction
,
715 LPCWSTR lpMessageText
)
725 FatalExit (int ExitCode
)
727 ExitProcess(ExitCode
);
735 GetPriorityClass (HANDLE hProcess
)
738 PROCESS_PRIORITY_CLASS PriorityClass
;
740 Status
= NtQueryInformationProcess(hProcess
,
741 ProcessPriorityClass
,
743 sizeof(PROCESS_PRIORITY_CLASS
),
745 if(NT_SUCCESS(Status
))
747 switch(PriorityClass
.PriorityClass
)
749 case PROCESS_PRIORITY_CLASS_IDLE
:
750 return IDLE_PRIORITY_CLASS
;
752 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
753 return BELOW_NORMAL_PRIORITY_CLASS
;
755 case PROCESS_PRIORITY_CLASS_NORMAL
:
756 return NORMAL_PRIORITY_CLASS
;
758 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
759 return ABOVE_NORMAL_PRIORITY_CLASS
;
761 case PROCESS_PRIORITY_CLASS_HIGH
:
762 return HIGH_PRIORITY_CLASS
;
764 case PROCESS_PRIORITY_CLASS_REALTIME
:
765 return REALTIME_PRIORITY_CLASS
;
768 return NORMAL_PRIORITY_CLASS
;
772 SetLastErrorByStatus(Status
);
781 SetPriorityClass (HANDLE hProcess
,
782 DWORD dwPriorityClass
)
785 PROCESS_PRIORITY_CLASS PriorityClass
;
787 switch(dwPriorityClass
)
789 case IDLE_PRIORITY_CLASS
:
790 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
793 case BELOW_NORMAL_PRIORITY_CLASS
:
794 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
797 case NORMAL_PRIORITY_CLASS
:
798 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
801 case ABOVE_NORMAL_PRIORITY_CLASS
:
802 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
805 case HIGH_PRIORITY_CLASS
:
806 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
809 case REALTIME_PRIORITY_CLASS
:
810 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
814 SetLastError(ERROR_INVALID_PARAMETER
);
818 PriorityClass
.Foreground
= FALSE
;
820 Status
= NtSetInformationProcess(hProcess
,
821 ProcessPriorityClass
,
823 sizeof(PROCESS_PRIORITY_CLASS
));
825 if(!NT_SUCCESS(Status
))
827 SetLastErrorByStatus(Status
);
839 GetProcessVersion (DWORD ProcessId
)
842 PIMAGE_NT_HEADERS NtHeader
= NULL
;
843 PVOID BaseAddress
= NULL
;
846 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
848 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
849 NtHeader
= RtlImageNtHeader (BaseAddress
);
850 if (NULL
!= NtHeader
)
853 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
854 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
857 else /* other process */
859 /* FIXME: open the other process */
860 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
871 GetProcessIoCounters(
873 PIO_COUNTERS lpIoCounters
)
877 Status
= NtQueryInformationProcess(hProcess
,
882 if (!NT_SUCCESS(Status
))
884 SetLastErrorByStatus(Status
);
897 GetProcessPriorityBoost(HANDLE hProcess
,
898 PBOOL pDisablePriorityBoost
)
903 Status
= NtQueryInformationProcess(hProcess
,
904 ProcessPriorityBoost
,
908 if (NT_SUCCESS(Status
))
910 *pDisablePriorityBoost
= PriorityBoost
;
914 SetLastErrorByStatus(Status
);
924 SetProcessPriorityBoost(HANDLE hProcess
,
925 BOOL bDisablePriorityBoost
)
928 BOOL PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
930 Status
= NtSetInformationProcess(hProcess
,
931 ProcessPriorityBoost
,
934 if (!NT_SUCCESS(Status
))
936 SetLastErrorByStatus(Status
);
949 GetProcessHandleCount(HANDLE hProcess
,
950 PDWORD pdwHandleCount
)
952 ULONG phc
, BytesWritten
;
955 Status
= NtQueryInformationProcess(hProcess
,
960 if(NT_SUCCESS(Status
))
962 *pdwHandleCount
= phc
;
966 SetLastErrorByStatus(Status
);