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
.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
= 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
;
440 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
442 PRTL_USER_PROCESS_PARAMETERS Params
;
444 if (lpStartupInfo
== NULL
)
446 SetLastError(ERROR_INVALID_PARAMETER
);
450 Params
= NtCurrentPeb()->ProcessParameters
;
452 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
453 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
454 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
455 lpStartupInfo
->dwX
= Params
->StartingX
;
456 lpStartupInfo
->dwY
= Params
->StartingY
;
457 lpStartupInfo
->dwXSize
= Params
->CountX
;
458 lpStartupInfo
->dwYSize
= Params
->CountY
;
459 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
460 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
461 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
462 lpStartupInfo
->dwFlags
= Params
->WindowFlags
;
463 lpStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
464 lpStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
465 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
467 lpStartupInfo
->hStdInput
= Params
->StandardInput
;
468 lpStartupInfo
->hStdOutput
= Params
->StandardOutput
;
469 lpStartupInfo
->hStdError
= Params
->StandardError
;
477 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
479 PRTL_USER_PROCESS_PARAMETERS Params
;
480 ANSI_STRING AnsiString
;
482 if (lpStartupInfo
== NULL
)
484 SetLastError(ERROR_INVALID_PARAMETER
);
488 Params
= NtCurrentPeb ()->ProcessParameters
;
490 RtlAcquirePebLock ();
492 /* FIXME - not thread-safe */
493 if (lpLocalStartupInfo
== NULL
)
495 /* create new local startup info (ansi) */
496 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
498 sizeof(STARTUPINFOA
));
499 if (lpLocalStartupInfo
== NULL
)
501 RtlReleasePebLock ();
502 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
506 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
508 /* copy window title string */
509 RtlUnicodeStringToAnsiString (&AnsiString
,
510 &Params
->WindowTitle
,
512 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
514 /* copy desktop info string */
515 RtlUnicodeStringToAnsiString (&AnsiString
,
516 &Params
->DesktopInfo
,
518 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
520 /* copy shell info string */
521 RtlUnicodeStringToAnsiString (&AnsiString
,
524 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
526 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
527 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
528 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
529 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
530 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
531 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
532 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
533 lpLocalStartupInfo
->dwFlags
= Params
->WindowFlags
;
534 lpLocalStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
535 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeData
.Length
;
536 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeData
.Buffer
;
538 lpLocalStartupInfo
->hStdInput
= Params
->StandardInput
;
539 lpLocalStartupInfo
->hStdOutput
= Params
->StandardOutput
;
540 lpLocalStartupInfo
->hStdError
= Params
->StandardError
;
543 RtlReleasePebLock ();
545 /* copy local startup info data to external startup info */
546 memcpy (lpStartupInfo
,
548 sizeof(STARTUPINFOA
));
556 FlushInstructionCache (HANDLE hProcess
,
557 LPCVOID lpBaseAddress
,
562 Status
= NtFlushInstructionCache(hProcess
,
563 (PVOID
)lpBaseAddress
,
565 if (!NT_SUCCESS(Status
))
567 SetLastErrorByStatus(Status
);
578 ExitProcess(UINT uExitCode
)
580 CSR_API_MESSAGE CsrRequest
;
584 /* unload all dll's */
585 LdrShutdownProcess ();
587 /* notify csrss of process termination */
588 Request
= TERMINATE_PROCESS
;
589 Status
= CsrClientCallServer(&CsrRequest
,
591 MAKE_CSR_API(Request
, CSR_NATIVE
),
592 sizeof(CSR_API_MESSAGE
));
593 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrRequest
.Status
))
595 DPRINT("Failed to tell csrss about terminating process\n");
599 NtTerminateProcess (NtCurrentProcess (),
602 /* should never get here */
612 TerminateProcess (HANDLE hProcess
,
617 Status
= NtTerminateProcess (hProcess
, uExitCode
);
618 if (NT_SUCCESS(Status
))
622 SetLastErrorByStatus (Status
);
631 FatalAppExitA (UINT uAction
,
632 LPCSTR lpMessageText
)
634 UNICODE_STRING MessageTextU
;
635 ANSI_STRING MessageText
;
637 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
639 RtlAnsiStringToUnicodeString (&MessageTextU
,
643 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
645 RtlFreeUnicodeString (&MessageTextU
);
653 FatalAppExitW(UINT uAction
,
654 LPCWSTR lpMessageText
)
664 FatalExit (int ExitCode
)
666 ExitProcess(ExitCode
);
674 GetPriorityClass (HANDLE hProcess
)
677 PROCESS_PRIORITY_CLASS PriorityClass
;
679 Status
= NtQueryInformationProcess(hProcess
,
680 ProcessPriorityClass
,
682 sizeof(PROCESS_PRIORITY_CLASS
),
684 if(NT_SUCCESS(Status
))
686 switch(PriorityClass
.PriorityClass
)
688 case PROCESS_PRIORITY_CLASS_IDLE
:
689 return IDLE_PRIORITY_CLASS
;
691 case PROCESS_PRIORITY_CLASS_BELOW_NORMAL
:
692 return BELOW_NORMAL_PRIORITY_CLASS
;
694 case PROCESS_PRIORITY_CLASS_NORMAL
:
695 return NORMAL_PRIORITY_CLASS
;
697 case PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
:
698 return ABOVE_NORMAL_PRIORITY_CLASS
;
700 case PROCESS_PRIORITY_CLASS_HIGH
:
701 return HIGH_PRIORITY_CLASS
;
703 case PROCESS_PRIORITY_CLASS_REALTIME
:
704 return REALTIME_PRIORITY_CLASS
;
707 return NORMAL_PRIORITY_CLASS
;
711 SetLastErrorByStatus(Status
);
720 SetPriorityClass (HANDLE hProcess
,
721 DWORD dwPriorityClass
)
724 PROCESS_PRIORITY_CLASS PriorityClass
;
726 switch(dwPriorityClass
)
728 case IDLE_PRIORITY_CLASS
:
729 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_IDLE
;
732 case BELOW_NORMAL_PRIORITY_CLASS
:
733 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_BELOW_NORMAL
;
736 case NORMAL_PRIORITY_CLASS
:
737 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_NORMAL
;
740 case ABOVE_NORMAL_PRIORITY_CLASS
:
741 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
;
744 case HIGH_PRIORITY_CLASS
:
745 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_HIGH
;
748 case REALTIME_PRIORITY_CLASS
:
749 PriorityClass
.PriorityClass
= PROCESS_PRIORITY_CLASS_REALTIME
;
753 SetLastError(ERROR_INVALID_PARAMETER
);
757 PriorityClass
.Foreground
= FALSE
;
759 Status
= NtSetInformationProcess(hProcess
,
760 ProcessPriorityClass
,
762 sizeof(PROCESS_PRIORITY_CLASS
));
764 if(!NT_SUCCESS(Status
))
766 SetLastErrorByStatus(Status
);
778 GetProcessVersion (DWORD ProcessId
)
781 PIMAGE_NT_HEADERS NtHeader
= NULL
;
782 PVOID BaseAddress
= NULL
;
785 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
787 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
788 NtHeader
= RtlImageNtHeader (BaseAddress
);
789 if (NULL
!= NtHeader
)
792 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
793 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
796 else /* other process */
798 /* FIXME: open the other process */
799 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
810 GetProcessIoCounters(
812 PIO_COUNTERS lpIoCounters
)
816 Status
= NtQueryInformationProcess(hProcess
,
821 if (!NT_SUCCESS(Status
))
823 SetLastErrorByStatus(Status
);
836 GetProcessPriorityBoost(HANDLE hProcess
,
837 PBOOL pDisablePriorityBoost
)
842 Status
= NtQueryInformationProcess(hProcess
,
843 ProcessPriorityBoost
,
847 if (NT_SUCCESS(Status
))
849 *pDisablePriorityBoost
= PriorityBoost
;
853 SetLastErrorByStatus(Status
);
863 SetProcessPriorityBoost(HANDLE hProcess
,
864 BOOL bDisablePriorityBoost
)
867 ULONG PriorityBoost
= (bDisablePriorityBoost
? TRUE
: FALSE
); /* prevent setting values other than 1 and 0 */
869 Status
= NtSetInformationProcess(hProcess
,
870 ProcessPriorityBoost
,
873 if (!NT_SUCCESS(Status
))
875 SetLastErrorByStatus(Status
);
888 GetProcessHandleCount(HANDLE hProcess
,
889 PDWORD pdwHandleCount
)
894 Status
= NtQueryInformationProcess(hProcess
,
899 if(NT_SUCCESS(Status
))
901 *pdwHandleCount
= phc
;
905 SetLastErrorByStatus(Status
);