1 /* $Id: proc.c,v 1.59 2004/01/23 21:16:04 ekohl 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 "../include/debug.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
,
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
= -((ULONGLONG
)dwMilliseconds
* 10000);
458 /* Approximately 292000 years hence */
459 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFFLL
;
462 errCode
= NtDelayExecution (bAlertable
, &Interval
);
463 if (!NT_SUCCESS(errCode
))
465 SetLastErrorByStatus (errCode
);
476 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
478 PRTL_USER_PROCESS_PARAMETERS Params
;
480 if (lpStartupInfo
== NULL
)
482 SetLastError(ERROR_INVALID_PARAMETER
);
486 Params
= NtCurrentPeb()->ProcessParameters
;
488 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
489 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
490 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
491 lpStartupInfo
->dwX
= Params
->dwX
;
492 lpStartupInfo
->dwY
= Params
->dwY
;
493 lpStartupInfo
->dwXSize
= Params
->dwXSize
;
494 lpStartupInfo
->dwYSize
= Params
->dwYSize
;
495 lpStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
496 lpStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
497 lpStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
498 lpStartupInfo
->dwFlags
= Params
->dwFlags
;
499 lpStartupInfo
->wShowWindow
= Params
->wShowWindow
;
500 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
501 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
502 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
504 lpStartupInfo
->hStdInput
= Params
->hStdInput
;
505 lpStartupInfo
->hStdOutput
= Params
->hStdOutput
;
506 lpStartupInfo
->hStdError
= Params
->hStdError
;
514 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
516 PRTL_USER_PROCESS_PARAMETERS Params
;
517 ANSI_STRING AnsiString
;
519 if (lpStartupInfo
== NULL
)
521 SetLastError(ERROR_INVALID_PARAMETER
);
525 Params
= NtCurrentPeb ()->ProcessParameters
;
527 RtlAcquirePebLock ();
529 if (lpLocalStartupInfo
== NULL
)
531 /* create new local startup info (ansi) */
532 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
534 sizeof(STARTUPINFOA
));
536 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
538 /* copy window title string */
539 RtlUnicodeStringToAnsiString (&AnsiString
,
540 &Params
->WindowTitle
,
542 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
544 /* copy desktop info string */
545 RtlUnicodeStringToAnsiString (&AnsiString
,
546 &Params
->DesktopInfo
,
548 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
550 /* copy shell info string */
551 RtlUnicodeStringToAnsiString (&AnsiString
,
554 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
556 lpLocalStartupInfo
->dwX
= Params
->dwX
;
557 lpLocalStartupInfo
->dwY
= Params
->dwY
;
558 lpLocalStartupInfo
->dwXSize
= Params
->dwXSize
;
559 lpLocalStartupInfo
->dwYSize
= Params
->dwYSize
;
560 lpLocalStartupInfo
->dwXCountChars
= Params
->dwXCountChars
;
561 lpLocalStartupInfo
->dwYCountChars
= Params
->dwYCountChars
;
562 lpLocalStartupInfo
->dwFillAttribute
= Params
->dwFillAttribute
;
563 lpLocalStartupInfo
->dwFlags
= Params
->dwFlags
;
564 lpLocalStartupInfo
->wShowWindow
= Params
->wShowWindow
;
565 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
566 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
568 lpLocalStartupInfo
->hStdInput
= Params
->hStdInput
;
569 lpLocalStartupInfo
->hStdOutput
= Params
->hStdOutput
;
570 lpLocalStartupInfo
->hStdError
= Params
->hStdError
;
573 RtlReleasePebLock ();
575 /* copy local startup info data to external startup info */
576 memcpy (lpStartupInfo
,
578 sizeof(STARTUPINFOA
));
586 FlushInstructionCache (HANDLE hProcess
,
587 LPCVOID lpBaseAddress
,
592 Status
= NtFlushInstructionCache(hProcess
,
593 (PVOID
)lpBaseAddress
,
595 if (!NT_SUCCESS(Status
))
597 SetLastErrorByStatus(Status
);
608 ExitProcess(UINT uExitCode
)
610 CSRSS_API_REQUEST CsrRequest
;
611 CSRSS_API_REPLY CsrReply
;
614 /* unload all dll's */
615 LdrShutdownProcess ();
617 /* notify csrss of process termination */
618 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
619 Status
= CsrClientCallServer(&CsrRequest
,
621 sizeof(CSRSS_API_REQUEST
),
622 sizeof(CSRSS_API_REPLY
));
623 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
625 DbgPrint("Failed to tell csrss about terminating process. "
626 "Expect trouble.\n");
630 NtTerminateProcess (NtCurrentProcess (),
633 /* should never get here */
643 TerminateProcess (HANDLE hProcess
,
648 Status
= NtTerminateProcess (hProcess
, uExitCode
);
649 if (NT_SUCCESS(Status
))
653 SetLastErrorByStatus (Status
);
662 FatalAppExitA (UINT uAction
,
663 LPCSTR lpMessageText
)
665 UNICODE_STRING MessageTextU
;
666 ANSI_STRING MessageText
;
668 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
670 RtlAnsiStringToUnicodeString (&MessageTextU
,
674 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
676 RtlFreeUnicodeString (&MessageTextU
);
684 FatalAppExitW(UINT uAction
,
685 LPCWSTR lpMessageText
)
695 FatalExit (int ExitCode
)
697 ExitProcess(ExitCode
);
705 GetPriorityClass (HANDLE hProcess
)
708 DWORD CsrPriorityClass
= 0; // This tells CSRSS we want to GET it!
712 NtDuplicateObject (GetCurrentProcess(),
716 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
719 if (!NT_SUCCESS(Status
))
721 SetLastErrorByStatus (Status
);
722 return (0); /* ERROR */
724 /* Ask CSRSS to set it */
725 CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
726 NtClose (hProcessTmp
);
727 /* Translate CSR->W32 priorities */
728 switch (CsrPriorityClass
)
730 case CSR_PRIORITY_CLASS_NORMAL
:
731 return (NORMAL_PRIORITY_CLASS
); /* 32 */
732 case CSR_PRIORITY_CLASS_IDLE
:
733 return (IDLE_PRIORITY_CLASS
); /* 64 */
734 case CSR_PRIORITY_CLASS_HIGH
:
735 return (HIGH_PRIORITY_CLASS
); /* 128 */
736 case CSR_PRIORITY_CLASS_REALTIME
:
737 return (REALTIME_PRIORITY_CLASS
); /* 256 */
739 SetLastError (ERROR_ACCESS_DENIED
);
740 return (0); /* ERROR */
748 SetPriorityClass (HANDLE hProcess
,
749 DWORD dwPriorityClass
)
752 DWORD CsrPriorityClass
;
755 switch (dwPriorityClass
)
757 case NORMAL_PRIORITY_CLASS
: /* 32 */
758 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
760 case IDLE_PRIORITY_CLASS
: /* 64 */
761 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
763 case HIGH_PRIORITY_CLASS
: /* 128 */
764 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
766 case REALTIME_PRIORITY_CLASS
: /* 256 */
767 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
770 SetLastError (ERROR_INVALID_PARAMETER
);
774 NtDuplicateObject (GetCurrentProcess(),
778 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
781 if (!NT_SUCCESS(Status
))
783 SetLastErrorByStatus (Status
);
784 return (FALSE
); /* ERROR */
786 /* Ask CSRSS to set it */
787 Status
= CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
788 NtClose (hProcessTmp
);
789 if (!NT_SUCCESS(Status
))
791 SetLastErrorByStatus (Status
);
802 GetProcessVersion (DWORD ProcessId
)
805 PIMAGE_NT_HEADERS NtHeader
= NULL
;
806 PVOID BaseAddress
= NULL
;
809 if (0 == ProcessId
|| GetCurrentProcessId() == ProcessId
)
811 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
812 NtHeader
= RtlImageNtHeader (BaseAddress
);
813 if (NULL
!= NtHeader
)
816 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
817 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
820 else /* other process */
822 /* FIXME: open the other process */
823 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);