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 LPSTARTUPINFO lpLocalStartupInfo = NULL;
28 RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
31 GetProcessId (HANDLE hProcess, LPDWORD lpProcessId);
34 /* FUNCTIONS ****************************************************************/
37 GetProcessAffinityMask (HANDLE hProcess,
38 LPDWORD lpProcessAffinityMask,
39 LPDWORD lpSystemAffinityMask)
41 PROCESS_BASIC_INFORMATION ProcessInfo;
45 Status = NtQueryInformationProcess (hProcess,
46 ProcessBasicInformation,
48 sizeof(PROCESS_BASIC_INFORMATION),
50 if (!NT_SUCCESS(Status))
52 SetLastError (Status);
56 *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
59 *lpSystemAffinityMask = 0x00000001;
66 SetProcessAffinityMask (HANDLE hProcess,
67 DWORD dwProcessAffinityMask)
71 Status = NtSetInformationProcess (hProcess,
73 (PVOID)&dwProcessAffinityMask,
75 if (!NT_SUCCESS(Status))
77 SetLastError (Status);
86 GetProcessShutdownParameters (LPDWORD lpdwLevel,
89 CSRSS_API_REQUEST CsrRequest;
90 CSRSS_API_REPLY CsrReply;
93 CsrRequest.Type = CSRSS_GET_SHUTDOWN_PARAMETERS;
94 Status = CsrClientCallServer(&CsrRequest,
96 sizeof(CSRSS_API_REQUEST),
97 sizeof(CSRSS_API_REPLY));
98 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
100 SetLastError(Status);
104 *lpdwLevel = CsrReply.Data.GetShutdownParametersReply.Level;
105 *lpdwFlags = CsrReply.Data.GetShutdownParametersReply.Flags;
112 SetProcessShutdownParameters (DWORD dwLevel,
115 CSRSS_API_REQUEST CsrRequest;
116 CSRSS_API_REPLY CsrReply;
119 CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
120 CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
122 CsrRequest.Type = CSRSS_SET_SHUTDOWN_PARAMETERS;
123 Status = CsrClientCallServer(&CsrRequest,
125 sizeof(CSRSS_API_REQUEST),
126 sizeof(CSRSS_API_REPLY));
127 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
129 SetLastError(Status);
138 GetProcessWorkingSetSize (HANDLE hProcess,
139 LPDWORD lpMinimumWorkingSetSize,
140 LPDWORD lpMaximumWorkingSetSize)
142 QUOTA_LIMITS QuotaLimits;
145 Status = NtQueryInformationProcess(hProcess,
148 sizeof(QUOTA_LIMITS),
150 if (!NT_SUCCESS(Status))
152 SetLastErrorByStatus(Status);
156 *lpMinimumWorkingSetSize = (DWORD)QuotaLimits.MinimumWorkingSetSize;
157 *lpMaximumWorkingSetSize = (DWORD)QuotaLimits.MaximumWorkingSetSize;
164 SetProcessWorkingSetSize(HANDLE hProcess,
165 DWORD dwMinimumWorkingSetSize,
166 DWORD dwMaximumWorkingSetSize)
168 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
174 GetProcessTimes(HANDLE hProcess,
175 LPFILETIME lpCreationTime,
176 LPFILETIME lpExitTime,
177 LPFILETIME lpKernelTime,
178 LPFILETIME lpUserTime)
180 KERNEL_USER_TIMES Kut;
183 Status = NtQueryInformationProcess(hProcess,
188 if (!NT_SUCCESS(Status))
190 SetLastErrorByStatus(Status);
194 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
195 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
197 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
198 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
200 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
201 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
203 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
204 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
211 GetCurrentProcess(VOID)
213 return((HANDLE)NtCurrentProcess());
218 GetCurrentThread(VOID)
220 return((HANDLE)NtCurrentThread());
225 GetCurrentProcessId(VOID)
227 return((DWORD)GetTeb()->Cid.UniqueProcess);
232 GetExitCodeProcess(HANDLE hProcess,
235 PROCESS_BASIC_INFORMATION ProcessBasic;
239 Status = NtQueryInformationProcess(hProcess,
240 ProcessBasicInformation,
242 sizeof(PROCESS_BASIC_INFORMATION),
244 if (!NT_SUCCESS(Status))
246 SetLastErrorByStatus(Status);
250 memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
257 GetProcessId(HANDLE hProcess,
260 PROCESS_BASIC_INFORMATION ProcessBasic;
264 Status = NtQueryInformationProcess(hProcess,
265 ProcessBasicInformation,
267 sizeof(PROCESS_BASIC_INFORMATION),
269 if (!NT_SUCCESS(Status))
271 SetLastErrorByStatus(Status);
275 memcpy(lpProcessId, &ProcessBasic.UniqueProcessId, sizeof(DWORD));
282 OpenProcess(DWORD dwDesiredAccess,
283 WINBOOL bInheritHandle,
287 HANDLE ProcessHandle;
288 OBJECT_ATTRIBUTES ObjectAttributes;
291 ClientId.UniqueProcess = (HANDLE)dwProcessId;
292 ClientId.UniqueThread = INVALID_HANDLE_VALUE;
294 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
295 ObjectAttributes.RootDirectory = (HANDLE)NULL;
296 ObjectAttributes.SecurityDescriptor = NULL;
297 ObjectAttributes.SecurityQualityOfService = NULL;
298 ObjectAttributes.ObjectName = NULL;
300 if (bInheritHandle == TRUE)
301 ObjectAttributes.Attributes = OBJ_INHERIT;
303 ObjectAttributes.Attributes = 0;
305 errCode = NtOpenProcess(&ProcessHandle,
309 if (!NT_SUCCESS(errCode))
311 SetLastErrorByStatus (errCode);
314 return ProcessHandle;
319 WinExec(LPCSTR lpCmdLine,
322 STARTUPINFOA StartupInfo;
323 PROCESS_INFORMATION ProcessInformation;
327 StartupInfo.cb = sizeof(STARTUPINFOA);
328 StartupInfo.wShowWindow = uCmdShow;
329 StartupInfo.dwFlags = 0;
331 hInst = (HINSTANCE)CreateProcessA(NULL,
340 &ProcessInformation);
343 dosErr = GetLastError();
346 if (NULL != lpfnGlobalRegisterWaitForInputIdle)
348 lpfnGlobalRegisterWaitForInputIdle (
349 ProcessInformation.hProcess,
353 NtClose (ProcessInformation.hProcess);
354 NtClose (ProcessInformation.hThread);
360 RegisterWaitForInputIdle (
361 WaitForInputIdleType lpfnRegisterWaitForInputIdle
364 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
380 Sleep(DWORD dwMilliseconds)
382 SleepEx(dwMilliseconds, FALSE);
388 SleepEx(DWORD dwMilliseconds,
394 if (dwMilliseconds != INFINITE)
397 * System time units are 100 nanoseconds (a nanosecond is a billionth of
400 Interval.QuadPart = dwMilliseconds;
401 Interval.QuadPart = -(Interval.QuadPart * 10000);
405 /* Approximately 292000 years hence */
406 Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
409 errCode = NtDelayExecution (bAlertable, &Interval);
410 if (!NT_SUCCESS(errCode))
412 SetLastErrorByStatus (errCode);
420 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
422 PRTL_USER_PROCESS_PARAMETERS Params;
424 if (lpStartupInfo == NULL)
426 SetLastError(ERROR_INVALID_PARAMETER);
430 Params = NtCurrentPeb()->ProcessParameters;
432 lpStartupInfo->cb = sizeof(STARTUPINFOW);
433 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
434 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
435 lpStartupInfo->dwX = Params->dwX;
436 lpStartupInfo->dwY = Params->dwY;
437 lpStartupInfo->dwXSize = Params->dwXSize;
438 lpStartupInfo->dwYSize = Params->dwYSize;
439 lpStartupInfo->dwXCountChars = Params->dwXCountChars;
440 lpStartupInfo->dwYCountChars = Params->dwYCountChars;
441 lpStartupInfo->dwFillAttribute = Params->dwFillAttribute;
442 lpStartupInfo->dwFlags = Params->dwFlags;
443 lpStartupInfo->wShowWindow = Params->wShowWindow;
444 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
445 lpStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
446 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
448 lpStartupInfo->hStdInput = Params->hStdInput;
449 lpStartupInfo->hStdOutput = Params->hStdOutput;
450 lpStartupInfo->hStdError = Params->hStdError;
455 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
457 PRTL_USER_PROCESS_PARAMETERS Params;
458 ANSI_STRING AnsiString;
460 if (lpStartupInfo == NULL)
462 SetLastError(ERROR_INVALID_PARAMETER);
466 Params = NtCurrentPeb ()->ProcessParameters;
468 RtlAcquirePebLock ();
470 if (lpLocalStartupInfo == NULL)
472 /* create new local startup info (ansi) */
473 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
475 sizeof(STARTUPINFOA));
477 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
479 /* copy window title string */
480 RtlUnicodeStringToAnsiString (&AnsiString,
481 &Params->WindowTitle,
483 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
485 /* copy desktop info string */
486 RtlUnicodeStringToAnsiString (&AnsiString,
487 &Params->DesktopInfo,
489 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
491 /* copy shell info string */
492 RtlUnicodeStringToAnsiString (&AnsiString,
495 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
497 lpLocalStartupInfo->dwX = Params->dwX;
498 lpLocalStartupInfo->dwY = Params->dwY;
499 lpLocalStartupInfo->dwXSize = Params->dwXSize;
500 lpLocalStartupInfo->dwYSize = Params->dwYSize;
501 lpLocalStartupInfo->dwXCountChars = Params->dwXCountChars;
502 lpLocalStartupInfo->dwYCountChars = Params->dwYCountChars;
503 lpLocalStartupInfo->dwFillAttribute = Params->dwFillAttribute;
504 lpLocalStartupInfo->dwFlags = Params->dwFlags;
505 lpLocalStartupInfo->wShowWindow = Params->wShowWindow;
506 lpLocalStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
507 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
509 lpLocalStartupInfo->hStdInput = Params->hStdInput;
510 lpLocalStartupInfo->hStdOutput = Params->hStdOutput;
511 lpLocalStartupInfo->hStdError = Params->hStdError;
514 RtlReleasePebLock ();
516 /* copy local startup info data to external startup info */
517 memcpy (lpStartupInfo,
519 sizeof(STARTUPINFOA));
524 FlushInstructionCache (HANDLE hProcess,
525 LPCVOID lpBaseAddress,
530 Status = NtFlushInstructionCache(hProcess,
531 (PVOID)lpBaseAddress,
533 if (!NT_SUCCESS(Status))
535 SetLastErrorByStatus(Status);
543 ExitProcess(UINT uExitCode)
545 CSRSS_API_REQUEST CsrRequest;
546 CSRSS_API_REPLY CsrReply;
549 /* unload all dll's */
550 LdrShutdownProcess ();
552 /* notify csrss of process termination */
553 CsrRequest.Type = CSRSS_TERMINATE_PROCESS;
554 Status = CsrClientCallServer(&CsrRequest,
556 sizeof(CSRSS_API_REQUEST),
557 sizeof(CSRSS_API_REPLY));
558 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
560 DbgPrint("Failed to tell csrss about terminating process. "
561 "Expect trouble.\n");
565 NtTerminateProcess (NtCurrentProcess (),
568 /* should never get here */
575 TerminateProcess (HANDLE hProcess,
580 Status = NtTerminateProcess (hProcess, uExitCode);
581 if (NT_SUCCESS(Status))
585 SetLastErrorByStatus (Status);
591 FatalAppExitA (UINT uAction,
592 LPCSTR lpMessageText)
594 UNICODE_STRING MessageTextU;
595 ANSI_STRING MessageText;
597 RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
599 RtlAnsiStringToUnicodeString (&MessageTextU,
603 FatalAppExitW (uAction, MessageTextU.Buffer);
605 RtlFreeUnicodeString (&MessageTextU);
610 FatalAppExitW(UINT uAction,
611 LPCWSTR lpMessageText)
618 FatalExit (int ExitCode)
620 ExitProcess(ExitCode);
625 GetPriorityClass (HANDLE hProcess)
628 DWORD CsrPriorityClass = 0; // This tells CSRSS we want to GET it!
632 NtDuplicateObject (GetCurrentProcess(),
636 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
639 if (!NT_SUCCESS(Status))
641 SetLastErrorByStatus (Status);
642 return (0); /* ERROR */
644 /* Ask CSRSS to set it */
645 CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
646 NtClose (hProcessTmp);
647 /* Translate CSR->W32 priorities */
648 switch (CsrPriorityClass)
650 case CSR_PRIORITY_CLASS_NORMAL:
651 return (NORMAL_PRIORITY_CLASS); /* 32 */
652 case CSR_PRIORITY_CLASS_IDLE:
653 return (IDLE_PRIORITY_CLASS); /* 64 */
654 case CSR_PRIORITY_CLASS_HIGH:
655 return (HIGH_PRIORITY_CLASS); /* 128 */
656 case CSR_PRIORITY_CLASS_REALTIME:
657 return (REALTIME_PRIORITY_CLASS); /* 256 */
659 SetLastError (ERROR_ACCESS_DENIED);
660 return (0); /* ERROR */
666 SetPriorityClass (HANDLE hProcess,
667 DWORD dwPriorityClass)
670 DWORD CsrPriorityClass;
673 switch (dwPriorityClass)
675 case NORMAL_PRIORITY_CLASS: /* 32 */
676 CsrPriorityClass = CSR_PRIORITY_CLASS_NORMAL;
678 case IDLE_PRIORITY_CLASS: /* 64 */
679 CsrPriorityClass = CSR_PRIORITY_CLASS_IDLE;
681 case HIGH_PRIORITY_CLASS: /* 128 */
682 CsrPriorityClass = CSR_PRIORITY_CLASS_HIGH;
684 case REALTIME_PRIORITY_CLASS: /* 256 */
685 CsrPriorityClass = CSR_PRIORITY_CLASS_REALTIME;
688 SetLastError (ERROR_INVALID_PARAMETER);
692 NtDuplicateObject (GetCurrentProcess(),
696 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
699 if (!NT_SUCCESS(Status))
701 SetLastErrorByStatus (Status);
702 return (FALSE); /* ERROR */
704 /* Ask CSRSS to set it */
705 Status = CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
706 NtClose (hProcessTmp);
707 if (!NT_SUCCESS(Status))
709 SetLastErrorByStatus (Status);
717 GetProcessVersion (DWORD ProcessId)
720 PIMAGE_NT_HEADERS NtHeader = NULL;
721 PVOID BaseAddress = NULL;
724 if (0 == ProcessId || GetCurrentProcessId() == ProcessId)
726 BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
727 NtHeader = RtlImageNtHeader (BaseAddress);
728 if (NULL != NtHeader)
731 (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
732 (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
735 else /* other process */
737 /* FIXME: open the other process */
738 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);