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
;
40 SYSTEM_BASIC_INFORMATION SystemInfo
;
43 Status
= NtQuerySystemInformation(SystemBasicInformation
,
47 if (!NT_SUCCESS(Status
))
49 SetLastErrorByStatus (Status
);
53 Status
= NtQueryInformationProcess (hProcess
,
54 ProcessBasicInformation
,
56 sizeof(PROCESS_BASIC_INFORMATION
),
58 if (!NT_SUCCESS(Status
))
60 SetLastErrorByStatus (Status
);
64 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
65 *lpSystemAffinityMask
= (DWORD
)SystemInfo
.ActiveProcessors
;
75 SetProcessAffinityMask (HANDLE hProcess
,
76 DWORD dwProcessAffinityMask
)
80 Status
= NtSetInformationProcess (hProcess
,
82 (PVOID
)&dwProcessAffinityMask
,
84 if (!NT_SUCCESS(Status
))
86 SetLastErrorByStatus (Status
);
98 GetProcessShutdownParameters (LPDWORD lpdwLevel
,
101 CSRSS_API_REQUEST CsrRequest
;
102 CSRSS_API_REPLY CsrReply
;
105 CsrRequest
.Type
= CSRSS_GET_SHUTDOWN_PARAMETERS
;
106 Status
= CsrClientCallServer(&CsrRequest
,
108 sizeof(CSRSS_API_REQUEST
),
109 sizeof(CSRSS_API_REPLY
));
110 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
112 SetLastErrorByStatus (Status
);
116 *lpdwLevel
= CsrReply
.Data
.GetShutdownParametersReply
.Level
;
117 *lpdwFlags
= CsrReply
.Data
.GetShutdownParametersReply
.Flags
;
127 SetProcessShutdownParameters (DWORD dwLevel
,
130 CSRSS_API_REQUEST CsrRequest
;
131 CSRSS_API_REPLY CsrReply
;
134 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
135 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
137 CsrRequest
.Type
= CSRSS_SET_SHUTDOWN_PARAMETERS
;
138 Status
= CsrClientCallServer(&CsrRequest
,
140 sizeof(CSRSS_API_REQUEST
),
141 sizeof(CSRSS_API_REPLY
));
142 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
144 SetLastErrorByStatus (Status
);
156 GetProcessWorkingSetSize (HANDLE hProcess
,
157 PSIZE_T lpMinimumWorkingSetSize
,
158 PSIZE_T lpMaximumWorkingSetSize
)
160 QUOTA_LIMITS QuotaLimits
;
163 Status
= NtQueryInformationProcess(hProcess
,
166 sizeof(QUOTA_LIMITS
),
168 if (!NT_SUCCESS(Status
))
170 SetLastErrorByStatus(Status
);
174 *lpMinimumWorkingSetSize
= QuotaLimits
.MinimumWorkingSetSize
;
175 *lpMaximumWorkingSetSize
= QuotaLimits
.MaximumWorkingSetSize
;
185 SetProcessWorkingSetSize(HANDLE hProcess
,
186 SIZE_T dwMinimumWorkingSetSize
,
187 SIZE_T dwMaximumWorkingSetSize
)
189 QUOTA_LIMITS QuotaLimits
;
192 QuotaLimits
.MinimumWorkingSetSize
= dwMinimumWorkingSetSize
;
193 QuotaLimits
.MaximumWorkingSetSize
= dwMaximumWorkingSetSize
;
195 Status
= NtSetInformationProcess(hProcess
,
198 sizeof(QUOTA_LIMITS
));
199 if (!NT_SUCCESS(Status
))
201 SetLastErrorByStatus(Status
);
213 GetProcessTimes(HANDLE hProcess
,
214 LPFILETIME lpCreationTime
,
215 LPFILETIME lpExitTime
,
216 LPFILETIME lpKernelTime
,
217 LPFILETIME lpUserTime
)
219 KERNEL_USER_TIMES Kut
;
222 Status
= NtQueryInformationProcess(hProcess
,
227 if (!NT_SUCCESS(Status
))
229 SetLastErrorByStatus(Status
);
233 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
234 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
236 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
237 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
239 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
240 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
242 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
243 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
253 GetCurrentProcess(VOID
)
255 return((HANDLE
)NtCurrentProcess());
263 GetCurrentThread(VOID
)
265 return((HANDLE
)NtCurrentThread());
273 GetCurrentProcessId(VOID
)
275 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
283 GetExitCodeProcess(HANDLE hProcess
,
286 PROCESS_BASIC_INFORMATION ProcessBasic
;
289 Status
= NtQueryInformationProcess(hProcess
,
290 ProcessBasicInformation
,
292 sizeof(PROCESS_BASIC_INFORMATION
),
294 if (!NT_SUCCESS(Status
))
296 SetLastErrorByStatus(Status
);
300 *lpExitCode
= (DWORD
)ProcessBasic
.ExitStatus
;
311 GetProcessId(HANDLE Process
)
313 PROCESS_BASIC_INFORMATION ProcessBasic
;
316 Status
= NtQueryInformationProcess(Process
,
317 ProcessBasicInformation
,
319 sizeof(PROCESS_BASIC_INFORMATION
),
321 if (!NT_SUCCESS(Status
))
323 SetLastErrorByStatus(Status
);
327 return (DWORD
)ProcessBasic
.UniqueProcessId
;
335 OpenProcess(DWORD dwDesiredAccess
,
340 HANDLE ProcessHandle
;
341 OBJECT_ATTRIBUTES ObjectAttributes
;
344 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
345 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
347 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
348 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
349 ObjectAttributes
.SecurityDescriptor
= NULL
;
350 ObjectAttributes
.SecurityQualityOfService
= NULL
;
351 ObjectAttributes
.ObjectName
= NULL
;
353 if (bInheritHandle
== TRUE
)
354 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
356 ObjectAttributes
.Attributes
= 0;
358 errCode
= NtOpenProcess(&ProcessHandle
,
362 if (!NT_SUCCESS(errCode
))
364 SetLastErrorByStatus (errCode
);
367 return ProcessHandle
;
375 WinExec(LPCSTR lpCmdLine
,
378 STARTUPINFOA StartupInfo
;
379 PROCESS_INFORMATION ProcessInformation
;
382 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
383 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
384 StartupInfo
.wShowWindow
= uCmdShow
;
385 StartupInfo
.dwFlags
= 0;
387 if (! CreateProcessA(NULL
,
396 &ProcessInformation
))
398 dosErr
= GetLastError();
399 return dosErr
< 32 ? dosErr
: ERROR_BAD_FORMAT
;
401 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
403 lpfnGlobalRegisterWaitForInputIdle (
404 ProcessInformation
.hProcess
,
408 NtClose(ProcessInformation
.hProcess
);
409 NtClose(ProcessInformation
.hThread
);
411 return 33; /* Something bigger than 31 means success. */
419 RegisterWaitForInputIdle (
420 WaitForInputIdleType lpfnRegisterWaitForInputIdle
423 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
445 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
447 PRTL_USER_PROCESS_PARAMETERS Params
;
449 if (lpStartupInfo
== NULL
)
451 SetLastError(ERROR_INVALID_PARAMETER
);
455 Params
= NtCurrentPeb()->ProcessParameters
;
457 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
458 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
459 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
460 lpStartupInfo
->dwX
= Params
->dwX
;
461 lpStartupInfo
->dwY
= Params
->dwY
;
462 lpStartupInfo
->dwXSize
= Params
->dwXSize
;
463 lpStartupInfo
->dwYSize
= Params
->dwYSize
;
464 lpStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
465 lpStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
466 lpStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
467 lpStartupInfo
->dwFlags
= Params
->dwFlags
;
468 lpStartupInfo
->wShowWindow
= Params
->wShowWindow
;
469 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
470 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
471 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
473 lpStartupInfo
->hStdInput
= Params
->hStdInput
;
474 lpStartupInfo
->hStdOutput
= Params
->hStdOutput
;
475 lpStartupInfo
->hStdError
= Params
->hStdError
;
483 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
485 PRTL_USER_PROCESS_PARAMETERS Params
;
486 ANSI_STRING AnsiString
;
488 if (lpStartupInfo
== NULL
)
490 SetLastError(ERROR_INVALID_PARAMETER
);
494 Params
= NtCurrentPeb ()->ProcessParameters
;
496 RtlAcquirePebLock ();
498 if (lpLocalStartupInfo
== NULL
)
500 /* create new local startup info (ansi) */
501 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
503 sizeof(STARTUPINFOA
));
505 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
507 /* copy window title string */
508 RtlUnicodeStringToAnsiString (&AnsiString
,
509 &Params
->WindowTitle
,
511 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
513 /* copy desktop info string */
514 RtlUnicodeStringToAnsiString (&AnsiString
,
515 &Params
->DesktopInfo
,
517 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
519 /* copy shell info string */
520 RtlUnicodeStringToAnsiString (&AnsiString
,
523 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
525 lpLocalStartupInfo
->dwX
= Params
->dwX
;
526 lpLocalStartupInfo
->dwY
= Params
->dwY
;
527 lpLocalStartupInfo
->dwXSize
= Params
->dwXSize
;
528 lpLocalStartupInfo
->dwYSize
= Params
->dwYSize
;
529 lpLocalStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
530 lpLocalStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
531 lpLocalStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
532 lpLocalStartupInfo
->dwFlags
= Params
->dwFlags
;
533 lpLocalStartupInfo
->wShowWindow
= Params
->wShowWindow
;
534 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
535 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
537 lpLocalStartupInfo
->hStdInput
= Params
->hStdInput
;
538 lpLocalStartupInfo
->hStdOutput
= Params
->hStdOutput
;
539 lpLocalStartupInfo
->hStdError
= Params
->hStdError
;
542 RtlReleasePebLock ();
544 /* copy local startup info data to external startup info */
545 memcpy (lpStartupInfo
,
547 sizeof(STARTUPINFOA
));
555 FlushInstructionCache (HANDLE hProcess
,
556 LPCVOID lpBaseAddress
,
561 Status
= NtFlushInstructionCache(hProcess
,
562 (PVOID
)lpBaseAddress
,
564 if (!NT_SUCCESS(Status
))
566 SetLastErrorByStatus(Status
);
577 ExitProcess(UINT uExitCode
)
579 CSRSS_API_REQUEST CsrRequest
;
580 CSRSS_API_REPLY CsrReply
;
583 /* unload all dll's */
584 LdrShutdownProcess ();
586 /* notify csrss of process termination */
587 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
588 Status
= CsrClientCallServer(&CsrRequest
,
590 sizeof(CSRSS_API_REQUEST
),
591 sizeof(CSRSS_API_REPLY
));
592 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
594 DPRINT("Failed to tell csrss about terminating process\n");
598 NtTerminateProcess (NtCurrentProcess (),
601 /* should never get here */
611 TerminateProcess (HANDLE hProcess
,
616 Status
= NtTerminateProcess (hProcess
, uExitCode
);
617 if (NT_SUCCESS(Status
))
621 SetLastErrorByStatus (Status
);
630 FatalAppExitA (UINT uAction
,
631 LPCSTR lpMessageText
)
633 UNICODE_STRING MessageTextU
;
634 ANSI_STRING MessageText
;
636 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
638 RtlAnsiStringToUnicodeString (&MessageTextU
,
642 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
644 RtlFreeUnicodeString (&MessageTextU
);
652 FatalAppExitW(UINT uAction
,
653 LPCWSTR lpMessageText
)
663 FatalExit (int ExitCode
)
665 ExitProcess(ExitCode
);
673 GetPriorityClass (HANDLE hProcess
)
676 PROCESS_PRIORITY_CLASS PriorityClass
;
678 Status
= NtQueryInformationProcess(hProcess
,
679 ProcessPriorityClass
,
681 sizeof(PROCESS_PRIORITY_CLASS
),
683 if(NT_SUCCESS(Status
))
685 switch(PriorityClass
.PriorityClass
)
687 case PROCESS_PRIORITY_CLASS_IDLE
:
688 return IDLE_PRIORITY_CLASS
;
690 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
691 return BELOW_NORMAL_PRIORITY_CLASS
;
693 case PROCESS_PRIORITY_CLASS_NORMAL
:
694 return NORMAL_PRIORITY_CLASS
;
696 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
697 return ABOVE_NORMAL_PRIORITY_CLASS
;
699 case PROCESS_PRIORITY_CLASS_HIGH
:
700 return HIGH_PRIORITY_CLASS
;
702 case PROCESS_PRIORITY_CLASS_REALTIME
:
703 return REALTIME_PRIORITY_CLASS
;
706 return NORMAL_PRIORITY_CLASS
;
710 SetLastErrorByStatus(Status
);
719 SetPriorityClass (HANDLE hProcess
,
720 DWORD dwPriorityClass
)
723 PROCESS_PRIORITY_CLASS PriorityClass
;
725 switch(dwPriorityClass
)
727 case IDLE_PRIORITY_CLASS
:
728 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
731 case BELOW_NORMAL_PRIORITY_CLASS
:
732 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
735 case NORMAL_PRIORITY_CLASS
:
736 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
739 case ABOVE_NORMAL_PRIORITY_CLASS
:
740 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
743 case HIGH_PRIORITY_CLASS
:
744 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
747 case REALTIME_PRIORITY_CLASS
:
748 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
752 SetLastError(ERROR_INVALID_PARAMETER
);
756 PriorityClass
.Foreground
= FALSE
;
758 Status
= NtSetInformationProcess(hProcess
,
759 ProcessPriorityClass
,
761 sizeof(PROCESS_PRIORITY_CLASS
));
763 if(!NT_SUCCESS(Status
))
765 SetLastErrorByStatus(Status
);
777 GetProcessVersion (DWORD ProcessId
)
780 PIMAGE_NT_HEADERS NtHeader
= NULL
;
781 PVOID BaseAddress
= NULL
;
784 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
786 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
787 NtHeader
= RtlImageNtHeader (BaseAddress
);
788 if (NULL
!= NtHeader
)
791 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
792 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
795 else /* other process */
797 /* FIXME: open the other process */
798 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
809 GetProcessIoCounters(
811 PIO_COUNTERS lpIoCounters
)
815 Status
= NtQueryInformationProcess(hProcess
,
820 if (!NT_SUCCESS(Status
))
822 SetLastErrorByStatus(Status
);
835 GetProcessPriorityBoost(HANDLE hProcess
,
836 PBOOL pDisablePriorityBoost
)
841 Status
= NtQueryInformationProcess(hProcess
,
842 ProcessPriorityBoost
,
846 if (NT_SUCCESS(Status
))
848 *pDisablePriorityBoost
= PriorityBoost
;
852 SetLastErrorByStatus(Status
);
862 SetProcessPriorityBoost(HANDLE hProcess
,
863 BOOL bDisablePriorityBoost
)
866 ULONG PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
868 Status
= NtSetInformationProcess(hProcess
,
869 ProcessPriorityBoost
,
872 if (!NT_SUCCESS(Status
))
874 SetLastErrorByStatus(Status
);
887 GetProcessHandleCount(HANDLE hProcess
,
888 PDWORD pdwHandleCount
)
893 Status
= NtQueryInformationProcess(hProcess
,
898 if(NT_SUCCESS(Status
))
900 *pdwHandleCount
= phc
;
904 SetLastErrorByStatus(Status
);