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);