1 /* $Id: proc.c,v 1.56 2003/08/28 19:37:00 gvg 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 ****************************************************************/
18 #include <kernel32/kernel32.h>
21 /* GLOBALS *******************************************************************/
23 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle
;
25 LPSTARTUPINFOA lpLocalStartupInfo
= NULL
;
28 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
31 InternalGetProcessId (HANDLE hProcess
, LPDWORD lpProcessId
);
34 /* FUNCTIONS ****************************************************************/
40 GetProcessAffinityMask (HANDLE hProcess
,
41 LPDWORD lpProcessAffinityMask
,
42 LPDWORD lpSystemAffinityMask
)
44 PROCESS_BASIC_INFORMATION ProcessInfo
;
48 Status
= NtQueryInformationProcess (hProcess
,
49 ProcessBasicInformation
,
51 sizeof(PROCESS_BASIC_INFORMATION
),
53 if (!NT_SUCCESS(Status
))
55 SetLastError (Status
);
59 *lpProcessAffinityMask
= (DWORD
)ProcessInfo
.AffinityMask
;
62 *lpSystemAffinityMask
= 0x00000001;
72 SetProcessAffinityMask (HANDLE hProcess
,
73 DWORD dwProcessAffinityMask
)
77 Status
= NtSetInformationProcess (hProcess
,
79 (PVOID
)&dwProcessAffinityMask
,
81 if (!NT_SUCCESS(Status
))
83 SetLastError (Status
);
95 GetProcessShutdownParameters (LPDWORD lpdwLevel
,
98 CSRSS_API_REQUEST CsrRequest
;
99 CSRSS_API_REPLY CsrReply
;
102 CsrRequest
.Type
= CSRSS_GET_SHUTDOWN_PARAMETERS
;
103 Status
= CsrClientCallServer(&CsrRequest
,
105 sizeof(CSRSS_API_REQUEST
),
106 sizeof(CSRSS_API_REPLY
));
107 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
109 SetLastError(Status
);
113 *lpdwLevel
= CsrReply
.Data
.GetShutdownParametersReply
.Level
;
114 *lpdwFlags
= CsrReply
.Data
.GetShutdownParametersReply
.Flags
;
124 SetProcessShutdownParameters (DWORD dwLevel
,
127 CSRSS_API_REQUEST CsrRequest
;
128 CSRSS_API_REPLY CsrReply
;
131 CsrRequest
.Data
.SetShutdownParametersRequest
.Level
= dwLevel
;
132 CsrRequest
.Data
.SetShutdownParametersRequest
.Flags
= dwFlags
;
134 CsrRequest
.Type
= CSRSS_SET_SHUTDOWN_PARAMETERS
;
135 Status
= CsrClientCallServer(&CsrRequest
,
137 sizeof(CSRSS_API_REQUEST
),
138 sizeof(CSRSS_API_REPLY
));
139 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
141 SetLastError(Status
);
153 GetProcessWorkingSetSize (HANDLE hProcess
,
154 LPDWORD lpMinimumWorkingSetSize
,
155 LPDWORD lpMaximumWorkingSetSize
)
157 QUOTA_LIMITS QuotaLimits
;
160 Status
= NtQueryInformationProcess(hProcess
,
163 sizeof(QUOTA_LIMITS
),
165 if (!NT_SUCCESS(Status
))
167 SetLastErrorByStatus(Status
);
171 *lpMinimumWorkingSetSize
= (DWORD
)QuotaLimits
.MinimumWorkingSetSize
;
172 *lpMaximumWorkingSetSize
= (DWORD
)QuotaLimits
.MaximumWorkingSetSize
;
182 SetProcessWorkingSetSize(HANDLE hProcess
,
183 DWORD dwMinimumWorkingSetSize
,
184 DWORD dwMaximumWorkingSetSize
)
186 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
195 GetProcessTimes(HANDLE hProcess
,
196 LPFILETIME lpCreationTime
,
197 LPFILETIME lpExitTime
,
198 LPFILETIME lpKernelTime
,
199 LPFILETIME lpUserTime
)
201 KERNEL_USER_TIMES Kut
;
204 Status
= NtQueryInformationProcess(hProcess
,
209 if (!NT_SUCCESS(Status
))
211 SetLastErrorByStatus(Status
);
215 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
216 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
218 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
219 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
221 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
222 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
224 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
225 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
235 GetCurrentProcess(VOID
)
237 return((HANDLE
)NtCurrentProcess());
245 GetCurrentThread(VOID
)
247 return((HANDLE
)NtCurrentThread());
255 GetCurrentProcessId(VOID
)
257 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
265 GetExitCodeProcess(HANDLE hProcess
,
268 PROCESS_BASIC_INFORMATION ProcessBasic
;
272 Status
= NtQueryInformationProcess(hProcess
,
273 ProcessBasicInformation
,
275 sizeof(PROCESS_BASIC_INFORMATION
),
277 if (!NT_SUCCESS(Status
))
279 SetLastErrorByStatus(Status
);
283 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
293 InternalGetProcessId(HANDLE hProcess
,
296 PROCESS_BASIC_INFORMATION ProcessBasic
;
300 Status
= NtQueryInformationProcess(hProcess
,
301 ProcessBasicInformation
,
303 sizeof(PROCESS_BASIC_INFORMATION
),
305 if (!NT_SUCCESS(Status
))
307 SetLastErrorByStatus(Status
);
311 memcpy(lpProcessId
, &ProcessBasic
.UniqueProcessId
, sizeof(DWORD
));
321 OpenProcess(DWORD dwDesiredAccess
,
322 WINBOOL bInheritHandle
,
326 HANDLE ProcessHandle
;
327 OBJECT_ATTRIBUTES ObjectAttributes
;
330 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
331 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
333 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
334 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
335 ObjectAttributes
.SecurityDescriptor
= NULL
;
336 ObjectAttributes
.SecurityQualityOfService
= NULL
;
337 ObjectAttributes
.ObjectName
= NULL
;
339 if (bInheritHandle
== TRUE
)
340 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
342 ObjectAttributes
.Attributes
= 0;
344 errCode
= NtOpenProcess(&ProcessHandle
,
348 if (!NT_SUCCESS(errCode
))
350 SetLastErrorByStatus (errCode
);
353 return ProcessHandle
;
361 WinExec(LPCSTR lpCmdLine
,
364 STARTUPINFOA StartupInfo
;
365 PROCESS_INFORMATION ProcessInformation
;
369 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
370 StartupInfo
.wShowWindow
= uCmdShow
;
371 StartupInfo
.dwFlags
= 0;
373 hInst
= (HINSTANCE
)CreateProcessA(NULL
,
382 &ProcessInformation
);
385 dosErr
= GetLastError();
388 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
390 lpfnGlobalRegisterWaitForInputIdle (
391 ProcessInformation
.hProcess
,
395 NtClose (ProcessInformation
.hProcess
);
396 NtClose (ProcessInformation
.hThread
);
405 RegisterWaitForInputIdle (
406 WaitForInputIdleType lpfnRegisterWaitForInputIdle
409 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
431 Sleep(DWORD dwMilliseconds
)
433 SleepEx(dwMilliseconds
, FALSE
);
442 SleepEx(DWORD dwMilliseconds
,
448 if (dwMilliseconds
!= INFINITE
)
451 * System time units are 100 nanoseconds (a nanosecond is a billionth of
454 Interval
.QuadPart
= dwMilliseconds
;
455 Interval
.QuadPart
= -(Interval
.QuadPart
* 10000);
459 /* Approximately 292000 years hence */
460 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFF;
463 errCode
= NtDelayExecution (bAlertable
, &Interval
);
464 if (!NT_SUCCESS(errCode
))
466 SetLastErrorByStatus (errCode
);
477 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
479 PRTL_USER_PROCESS_PARAMETERS Params
;
481 if (lpStartupInfo
== NULL
)
483 SetLastError(ERROR_INVALID_PARAMETER
);
487 Params
= NtCurrentPeb()->ProcessParameters
;
489 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
490 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
491 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
492 lpStartupInfo
->dwX
= Params
->dwX
;
493 lpStartupInfo
->dwY
= Params
->dwY
;
494 lpStartupInfo
->dwXSize
= Params
->dwXSize
;
495 lpStartupInfo
->dwYSize
= Params
->dwYSize
;
496 lpStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
497 lpStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
498 lpStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
499 lpStartupInfo
->dwFlags
= Params
->dwFlags
;
500 lpStartupInfo
->wShowWindow
= Params
->wShowWindow
;
501 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
502 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
503 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
505 lpStartupInfo
->hStdInput
= Params
->hStdInput
;
506 lpStartupInfo
->hStdOutput
= Params
->hStdOutput
;
507 lpStartupInfo
->hStdError
= Params
->hStdError
;
515 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
517 PRTL_USER_PROCESS_PARAMETERS Params
;
518 ANSI_STRING AnsiString
;
520 if (lpStartupInfo
== NULL
)
522 SetLastError(ERROR_INVALID_PARAMETER
);
526 Params
= NtCurrentPeb ()->ProcessParameters
;
528 RtlAcquirePebLock ();
530 if (lpLocalStartupInfo
== NULL
)
532 /* create new local startup info (ansi) */
533 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
535 sizeof(STARTUPINFOA
));
537 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
539 /* copy window title string */
540 RtlUnicodeStringToAnsiString (&AnsiString
,
541 &Params
->WindowTitle
,
543 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
545 /* copy desktop info string */
546 RtlUnicodeStringToAnsiString (&AnsiString
,
547 &Params
->DesktopInfo
,
549 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
551 /* copy shell info string */
552 RtlUnicodeStringToAnsiString (&AnsiString
,
555 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
557 lpLocalStartupInfo
->dwX
= Params
->dwX
;
558 lpLocalStartupInfo
->dwY
= Params
->dwY
;
559 lpLocalStartupInfo
->dwXSize
= Params
->dwXSize
;
560 lpLocalStartupInfo
->dwYSize
= Params
->dwYSize
;
561 lpLocalStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
562 lpLocalStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
563 lpLocalStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
564 lpLocalStartupInfo
->dwFlags
= Params
->dwFlags
;
565 lpLocalStartupInfo
->wShowWindow
= Params
->wShowWindow
;
566 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
567 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
569 lpLocalStartupInfo
->hStdInput
= Params
->hStdInput
;
570 lpLocalStartupInfo
->hStdOutput
= Params
->hStdOutput
;
571 lpLocalStartupInfo
->hStdError
= Params
->hStdError
;
574 RtlReleasePebLock ();
576 /* copy local startup info data to external startup info */
577 memcpy (lpStartupInfo
,
579 sizeof(STARTUPINFOA
));
587 FlushInstructionCache (HANDLE hProcess
,
588 LPCVOID lpBaseAddress
,
593 Status
= NtFlushInstructionCache(hProcess
,
594 (PVOID
)lpBaseAddress
,
596 if (!NT_SUCCESS(Status
))
598 SetLastErrorByStatus(Status
);
609 ExitProcess(UINT uExitCode
)
611 CSRSS_API_REQUEST CsrRequest
;
612 CSRSS_API_REPLY CsrReply
;
615 /* unload all dll's */
616 LdrShutdownProcess ();
618 /* notify csrss of process termination */
619 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
620 Status
= CsrClientCallServer(&CsrRequest
,
622 sizeof(CSRSS_API_REQUEST
),
623 sizeof(CSRSS_API_REPLY
));
624 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
626 DbgPrint("Failed to tell csrss about terminating process. "
627 "Expect trouble.\n");
631 NtTerminateProcess (NtCurrentProcess (),
634 /* should never get here */
644 TerminateProcess (HANDLE hProcess
,
649 Status
= NtTerminateProcess (hProcess
, uExitCode
);
650 if (NT_SUCCESS(Status
))
654 SetLastErrorByStatus (Status
);
663 FatalAppExitA (UINT uAction
,
664 LPCSTR lpMessageText
)
666 UNICODE_STRING MessageTextU
;
667 ANSI_STRING MessageText
;
669 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
671 RtlAnsiStringToUnicodeString (&MessageTextU
,
675 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
677 RtlFreeUnicodeString (&MessageTextU
);
685 FatalAppExitW(UINT uAction
,
686 LPCWSTR lpMessageText
)
696 FatalExit (int ExitCode
)
698 ExitProcess(ExitCode
);
706 GetPriorityClass (HANDLE hProcess
)
709 DWORD CsrPriorityClass
= 0; // This tells CSRSS we want to GET it!
713 NtDuplicateObject (GetCurrentProcess(),
717 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
720 if (!NT_SUCCESS(Status
))
722 SetLastErrorByStatus (Status
);
723 return (0); /* ERROR */
725 /* Ask CSRSS to set it */
726 CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
727 NtClose (hProcessTmp
);
728 /* Translate CSR->W32 priorities */
729 switch (CsrPriorityClass
)
731 case CSR_PRIORITY_CLASS_NORMAL
:
732 return (NORMAL_PRIORITY_CLASS
); /* 32 */
733 case CSR_PRIORITY_CLASS_IDLE
:
734 return (IDLE_PRIORITY_CLASS
); /* 64 */
735 case CSR_PRIORITY_CLASS_HIGH
:
736 return (HIGH_PRIORITY_CLASS
); /* 128 */
737 case CSR_PRIORITY_CLASS_REALTIME
:
738 return (REALTIME_PRIORITY_CLASS
); /* 256 */
740 SetLastError (ERROR_ACCESS_DENIED
);
741 return (0); /* ERROR */
749 SetPriorityClass (HANDLE hProcess
,
750 DWORD dwPriorityClass
)
753 DWORD CsrPriorityClass
;
756 switch (dwPriorityClass
)
758 case NORMAL_PRIORITY_CLASS
: /* 32 */
759 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
761 case IDLE_PRIORITY_CLASS
: /* 64 */
762 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
764 case HIGH_PRIORITY_CLASS
: /* 128 */
765 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
767 case REALTIME_PRIORITY_CLASS
: /* 256 */
768 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
771 SetLastError (ERROR_INVALID_PARAMETER
);
775 NtDuplicateObject (GetCurrentProcess(),
779 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
782 if (!NT_SUCCESS(Status
))
784 SetLastErrorByStatus (Status
);
785 return (FALSE
); /* ERROR */
787 /* Ask CSRSS to set it */
788 Status
= CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
789 NtClose (hProcessTmp
);
790 if (!NT_SUCCESS(Status
))
792 SetLastErrorByStatus (Status
);
803 GetProcessVersion (DWORD ProcessId
)
806 PIMAGE_NT_HEADERS NtHeader
= NULL
;
807 PVOID BaseAddress
= NULL
;
810 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
812 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
813 NtHeader
= RtlImageNtHeader (BaseAddress
);
814 if (NULL
!= NtHeader
)
817 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
818 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
821 else /* other process */
823 /* FIXME: open the other process */
824 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);