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 ****************************************************************/
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
.ActiveProcessorsAffinityMask
;
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 CSR_API_MESSAGE CsrRequest
;
105 Request
= GET_SHUTDOWN_PARAMETERS
;
106 Status
= CsrClientCallServer(&CsrRequest
,
108 MAKE_CSR_API(Request
, CSR_NATIVE
),
109 sizeof(CSR_API_MESSAGE
));
110 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
112 SetLastErrorByStatus (Status
);
116 *lpdwLevel
= CsrRequest
.Data
.GetShutdownParametersRequest
.Level
;
117 *lpdwFlags
= CsrRequest
.Data
.GetShutdownParametersRequest
.Flags
;
127 SetProcessShutdownParameters (DWORD dwLevel
,
130 CSR_API_MESSAGE CsrRequest
;
134 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
135 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
137 Request
= SET_SHUTDOWN_PARAMETERS
;
138 Status
= CsrClientCallServer(&CsrRequest
,
140 MAKE_CSR_API(Request
, CSR_NATIVE
),
141 sizeof(CSR_API_MESSAGE
));
142 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.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
= 0;
347 InitializeObjectAttributes(&ObjectAttributes
,
349 (bInheritHandle
? OBJ_INHERIT
: 0),
353 errCode
= NtOpenProcess(&ProcessHandle
,
357 if (!NT_SUCCESS(errCode
))
359 SetLastErrorByStatus (errCode
);
362 return ProcessHandle
;
370 WinExec(LPCSTR lpCmdLine
,
373 STARTUPINFOA StartupInfo
;
374 PROCESS_INFORMATION ProcessInformation
;
377 RtlZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
378 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
379 StartupInfo
.wShowWindow
= (WORD
)uCmdShow
;
380 StartupInfo
.dwFlags
= 0;
382 if (! CreateProcessA(NULL
,
391 &ProcessInformation
))
393 dosErr
= GetLastError();
394 return dosErr
< 32 ? dosErr
: ERROR_BAD_FORMAT
;
396 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
398 lpfnGlobalRegisterWaitForInputIdle (
399 ProcessInformation
.hProcess
,
403 NtClose(ProcessInformation
.hProcess
);
404 NtClose(ProcessInformation
.hThread
);
406 return 33; /* Something bigger than 31 means success. */
414 RegisterWaitForInputIdle (
415 WaitForInputIdleType lpfnRegisterWaitForInputIdle
418 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
426 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
428 PRTL_USER_PROCESS_PARAMETERS Params
;
430 if (lpStartupInfo
== NULL
)
432 SetLastError(ERROR_INVALID_PARAMETER
);
436 Params
= NtCurrentPeb()->ProcessParameters
;
438 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
439 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
440 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
441 lpStartupInfo
->dwX
= Params
->StartingX
;
442 lpStartupInfo
->dwY
= Params
->StartingY
;
443 lpStartupInfo
->dwXSize
= Params
->CountX
;
444 lpStartupInfo
->dwYSize
= Params
->CountY
;
445 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
446 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
447 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
448 lpStartupInfo
->dwFlags
= Params
->WindowFlags
;
449 lpStartupInfo
->wShowWindow
= (WORD
)Params
->ShowWindowFlags
;
450 lpStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
451 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
453 lpStartupInfo
->hStdInput
= Params
->StandardInput
;
454 lpStartupInfo
->hStdOutput
= Params
->StandardOutput
;
455 lpStartupInfo
->hStdError
= Params
->StandardError
;
463 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
465 PRTL_USER_PROCESS_PARAMETERS Params
;
466 ANSI_STRING AnsiString
;
468 if (lpStartupInfo
== NULL
)
470 SetLastError(ERROR_INVALID_PARAMETER
);
474 Params
= NtCurrentPeb ()->ProcessParameters
;
476 RtlAcquirePebLock ();
478 /* FIXME - not thread-safe */
479 if (lpLocalStartupInfo
== NULL
)
481 /* create new local startup info (ansi) */
482 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
484 sizeof(STARTUPINFOA
));
485 if (lpLocalStartupInfo
== NULL
)
487 RtlReleasePebLock ();
488 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
492 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
494 /* copy window title string */
495 RtlUnicodeStringToAnsiString (&AnsiString
,
496 &Params
->WindowTitle
,
498 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
500 /* copy desktop info string */
501 RtlUnicodeStringToAnsiString (&AnsiString
,
502 &Params
->DesktopInfo
,
504 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
506 /* copy shell info string */
507 RtlUnicodeStringToAnsiString (&AnsiString
,
510 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
512 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
513 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
514 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
515 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
516 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
517 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
518 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
519 lpLocalStartupInfo
->dwFlags
= Params
->WindowFlags
;
520 lpLocalStartupInfo
->wShowWindow
= (WORD
)Params
->ShowWindowFlags
;
521 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
522 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
524 lpLocalStartupInfo
->hStdInput
= Params
->StandardInput
;
525 lpLocalStartupInfo
->hStdOutput
= Params
->StandardOutput
;
526 lpLocalStartupInfo
->hStdError
= Params
->StandardError
;
529 RtlReleasePebLock ();
531 /* copy local startup info data to external startup info */
532 memcpy (lpStartupInfo
,
534 sizeof(STARTUPINFOA
));
542 FlushInstructionCache (HANDLE hProcess
,
543 LPCVOID lpBaseAddress
,
548 Status
= NtFlushInstructionCache(hProcess
,
549 (PVOID
)lpBaseAddress
,
551 if (!NT_SUCCESS(Status
))
553 SetLastErrorByStatus(Status
);
564 ExitProcess(UINT uExitCode
)
566 CSR_API_MESSAGE CsrRequest
;
570 /* kill sibling threads ... we want to be alone at this point */
571 NtTerminateProcess (NULL
, 0);
573 /* unload all dll's */
574 LdrShutdownProcess ();
576 /* notify csrss of process termination */
577 Request
= TERMINATE_PROCESS
;
578 Status
= CsrClientCallServer(&CsrRequest
,
580 MAKE_CSR_API(Request
, CSR_NATIVE
),
581 sizeof(CSR_API_MESSAGE
));
582 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
584 DPRINT("Failed to tell csrss about terminating process\n");
588 NtTerminateProcess (NtCurrentProcess (),
591 /* should never get here */
601 TerminateProcess (HANDLE hProcess
,
606 Status
= NtTerminateProcess (hProcess
, uExitCode
);
607 if (NT_SUCCESS(Status
))
611 SetLastErrorByStatus (Status
);
620 FatalAppExitA (UINT uAction
,
621 LPCSTR lpMessageText
)
623 UNICODE_STRING MessageTextU
;
624 ANSI_STRING MessageText
;
626 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
628 RtlAnsiStringToUnicodeString (&MessageTextU
,
632 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
634 RtlFreeUnicodeString (&MessageTextU
);
642 FatalAppExitW(UINT uAction
,
643 LPCWSTR lpMessageText
)
653 FatalExit (int ExitCode
)
655 ExitProcess(ExitCode
);
663 GetPriorityClass (HANDLE hProcess
)
666 PROCESS_PRIORITY_CLASS PriorityClass
;
668 Status
= NtQueryInformationProcess(hProcess
,
669 ProcessPriorityClass
,
671 sizeof(PROCESS_PRIORITY_CLASS
),
673 if(NT_SUCCESS(Status
))
675 switch(PriorityClass
.PriorityClass
)
677 case PROCESS_PRIORITY_CLASS_IDLE
:
678 return IDLE_PRIORITY_CLASS
;
680 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
681 return BELOW_NORMAL_PRIORITY_CLASS
;
683 case PROCESS_PRIORITY_CLASS_NORMAL
:
684 return NORMAL_PRIORITY_CLASS
;
686 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
687 return ABOVE_NORMAL_PRIORITY_CLASS
;
689 case PROCESS_PRIORITY_CLASS_HIGH
:
690 return HIGH_PRIORITY_CLASS
;
692 case PROCESS_PRIORITY_CLASS_REALTIME
:
693 return REALTIME_PRIORITY_CLASS
;
696 return NORMAL_PRIORITY_CLASS
;
700 SetLastErrorByStatus(Status
);
709 SetPriorityClass (HANDLE hProcess
,
710 DWORD dwPriorityClass
)
713 PROCESS_PRIORITY_CLASS PriorityClass
;
715 switch(dwPriorityClass
)
717 case IDLE_PRIORITY_CLASS
:
718 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
721 case BELOW_NORMAL_PRIORITY_CLASS
:
722 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
725 case NORMAL_PRIORITY_CLASS
:
726 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
729 case ABOVE_NORMAL_PRIORITY_CLASS
:
730 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
733 case HIGH_PRIORITY_CLASS
:
734 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
737 case REALTIME_PRIORITY_CLASS
:
738 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
742 SetLastError(ERROR_INVALID_PARAMETER
);
746 PriorityClass
.Foreground
= FALSE
;
748 Status
= NtSetInformationProcess(hProcess
,
749 ProcessPriorityClass
,
751 sizeof(PROCESS_PRIORITY_CLASS
));
753 if(!NT_SUCCESS(Status
))
755 SetLastErrorByStatus(Status
);
767 GetProcessVersion (DWORD ProcessId
)
770 PIMAGE_NT_HEADERS NtHeader
= NULL
;
771 PVOID BaseAddress
= NULL
;
774 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
776 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
777 NtHeader
= RtlImageNtHeader (BaseAddress
);
778 if (NULL
!= NtHeader
)
781 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
782 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
785 else /* other process */
787 /* FIXME: open the other process */
788 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
799 GetProcessIoCounters(
801 PIO_COUNTERS lpIoCounters
)
805 Status
= NtQueryInformationProcess(hProcess
,
810 if (!NT_SUCCESS(Status
))
812 SetLastErrorByStatus(Status
);
825 GetProcessPriorityBoost(HANDLE hProcess
,
826 PBOOL pDisablePriorityBoost
)
831 Status
= NtQueryInformationProcess(hProcess
,
832 ProcessPriorityBoost
,
836 if (NT_SUCCESS(Status
))
838 *pDisablePriorityBoost
= PriorityBoost
;
842 SetLastErrorByStatus(Status
);
852 SetProcessPriorityBoost(HANDLE hProcess
,
853 BOOL bDisablePriorityBoost
)
856 ULONG PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
858 Status
= NtSetInformationProcess(hProcess
,
859 ProcessPriorityBoost
,
862 if (!NT_SUCCESS(Status
))
864 SetLastErrorByStatus(Status
);
877 GetProcessHandleCount(HANDLE hProcess
,
878 PDWORD pdwHandleCount
)
883 Status
= NtQueryInformationProcess(hProcess
,
888 if(NT_SUCCESS(Status
))
890 *pdwHandleCount
= phc
;
894 SetLastErrorByStatus(Status
);