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 if ((NULL == lpProcessAffinityMask)
42 || (NULL == lpSystemAffinityMask))
44 SetLastError(ERROR_BAD_ARGUMENTS);
48 /* FIXME: check hProcess is actually a process */
49 /* FIXME: query the kernel process object */
50 *lpProcessAffinityMask = 0x00000001;
51 *lpSystemAffinityMask = 0x00000001;
58 SetProcessAffinityMask(HANDLE hProcess,
59 DWORD dwProcessAffinityMask)
66 GetProcessShutdownParameters(LPDWORD lpdwLevel,
69 CSRSS_API_REQUEST CsrRequest;
70 CSRSS_API_REPLY CsrReply;
73 CsrRequest.Type = CSRSS_GET_SHUTDOWN_PARAMETERS;
74 Status = CsrClientCallServer(&CsrRequest,
76 sizeof(CSRSS_API_REQUEST),
77 sizeof(CSRSS_API_REPLY));
78 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
84 *lpdwLevel = CsrReply.Data.GetShutdownParametersReply.Level;
85 *lpdwFlags = CsrReply.Data.GetShutdownParametersReply.Flags;
92 SetProcessShutdownParameters(DWORD dwLevel,
95 CSRSS_API_REQUEST CsrRequest;
96 CSRSS_API_REPLY CsrReply;
99 CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
100 CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
102 CsrRequest.Type = CSRSS_SET_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);
118 GetProcessWorkingSetSize(HANDLE hProcess,
119 LPDWORD lpMinimumWorkingSetSize,
120 LPDWORD lpMaximumWorkingSetSize)
122 QUOTA_LIMITS QuotaLimits;
125 Status = NtQueryInformationProcess(hProcess,
128 sizeof(QUOTA_LIMITS),
130 if (!NT_SUCCESS(Status))
132 SetLastErrorByStatus(Status);
136 *lpMinimumWorkingSetSize = (DWORD)QuotaLimits.MinimumWorkingSetSize;
137 *lpMaximumWorkingSetSize = (DWORD)QuotaLimits.MaximumWorkingSetSize;
144 SetProcessWorkingSetSize(HANDLE hProcess,
145 DWORD dwMinimumWorkingSetSize,
146 DWORD dwMaximumWorkingSetSize)
148 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
154 GetProcessTimes(HANDLE hProcess,
155 LPFILETIME lpCreationTime,
156 LPFILETIME lpExitTime,
157 LPFILETIME lpKernelTime,
158 LPFILETIME lpUserTime)
160 KERNEL_USER_TIMES Kut;
163 Status = NtQueryInformationProcess(hProcess,
168 if (!NT_SUCCESS(Status))
170 SetLastErrorByStatus(Status);
174 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
175 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
177 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
178 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
180 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
181 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
183 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
184 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
191 GetCurrentProcess(VOID)
193 return((HANDLE)NtCurrentProcess());
198 GetCurrentThread(VOID)
200 return((HANDLE)NtCurrentThread());
205 GetCurrentProcessId(VOID)
207 return((DWORD)GetTeb()->Cid.UniqueProcess);
212 GetExitCodeProcess(HANDLE hProcess,
215 PROCESS_BASIC_INFORMATION ProcessBasic;
219 Status = NtQueryInformationProcess(hProcess,
220 ProcessBasicInformation,
222 sizeof(PROCESS_BASIC_INFORMATION),
224 if (!NT_SUCCESS(Status))
226 SetLastErrorByStatus(Status);
230 memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
237 GetProcessId(HANDLE hProcess,
240 PROCESS_BASIC_INFORMATION ProcessBasic;
244 Status = NtQueryInformationProcess(hProcess,
245 ProcessBasicInformation,
247 sizeof(PROCESS_BASIC_INFORMATION),
249 if (!NT_SUCCESS(Status))
251 SetLastErrorByStatus(Status);
255 memcpy(lpProcessId, &ProcessBasic.UniqueProcessId, sizeof(DWORD));
262 OpenProcess(DWORD dwDesiredAccess,
263 WINBOOL bInheritHandle,
267 HANDLE ProcessHandle;
268 OBJECT_ATTRIBUTES ObjectAttributes;
271 ClientId.UniqueProcess = (HANDLE)dwProcessId;
272 ClientId.UniqueThread = INVALID_HANDLE_VALUE;
274 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
275 ObjectAttributes.RootDirectory = (HANDLE)NULL;
276 ObjectAttributes.SecurityDescriptor = NULL;
277 ObjectAttributes.SecurityQualityOfService = NULL;
278 ObjectAttributes.ObjectName = NULL;
280 if (bInheritHandle == TRUE)
281 ObjectAttributes.Attributes = OBJ_INHERIT;
283 ObjectAttributes.Attributes = 0;
285 errCode = NtOpenProcess(&ProcessHandle,
289 if (!NT_SUCCESS(errCode))
291 SetLastErrorByStatus (errCode);
294 return ProcessHandle;
299 WinExec(LPCSTR lpCmdLine,
302 STARTUPINFOA StartupInfo;
303 PROCESS_INFORMATION ProcessInformation;
307 StartupInfo.cb = sizeof(STARTUPINFOA);
308 StartupInfo.wShowWindow = uCmdShow;
309 StartupInfo.dwFlags = 0;
311 hInst = (HINSTANCE)CreateProcessA(NULL,
320 &ProcessInformation);
323 dosErr = GetLastError();
326 if (NULL != lpfnGlobalRegisterWaitForInputIdle)
328 lpfnGlobalRegisterWaitForInputIdle (
329 ProcessInformation.hProcess,
333 NtClose (ProcessInformation.hProcess);
334 NtClose (ProcessInformation.hThread);
340 RegisterWaitForInputIdle (
341 WaitForInputIdleType lpfnRegisterWaitForInputIdle
344 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
360 Sleep(DWORD dwMilliseconds)
362 SleepEx(dwMilliseconds, FALSE);
368 SleepEx(DWORD dwMilliseconds,
374 if (dwMilliseconds != INFINITE)
377 * System time units are 100 nanoseconds (a nanosecond is a billionth of
380 Interval.QuadPart = dwMilliseconds;
381 Interval.QuadPart = -(Interval.QuadPart * 10000);
385 /* Approximately 292000 years hence */
386 Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
389 errCode = NtDelayExecution (bAlertable, &Interval);
390 if (!NT_SUCCESS(errCode))
392 SetLastErrorByStatus (errCode);
400 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
402 PRTL_USER_PROCESS_PARAMETERS Params;
404 if (lpStartupInfo == NULL)
406 SetLastError(ERROR_INVALID_PARAMETER);
410 Params = NtCurrentPeb()->ProcessParameters;
412 lpStartupInfo->cb = sizeof(STARTUPINFOW);
413 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
414 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
415 lpStartupInfo->dwX = Params->dwX;
416 lpStartupInfo->dwY = Params->dwY;
417 lpStartupInfo->dwXSize = Params->dwXSize;
418 lpStartupInfo->dwYSize = Params->dwYSize;
419 lpStartupInfo->dwXCountChars = Params->dwXCountChars;
420 lpStartupInfo->dwYCountChars = Params->dwYCountChars;
421 lpStartupInfo->dwFillAttribute = Params->dwFillAttribute;
422 lpStartupInfo->dwFlags = Params->dwFlags;
423 lpStartupInfo->wShowWindow = Params->wShowWindow;
424 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
425 lpStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
426 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
428 lpStartupInfo->hStdInput = Params->hStdInput;
429 lpStartupInfo->hStdOutput = Params->hStdOutput;
430 lpStartupInfo->hStdError = Params->hStdError;
435 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
437 PRTL_USER_PROCESS_PARAMETERS Params;
438 ANSI_STRING AnsiString;
440 if (lpStartupInfo == NULL)
442 SetLastError(ERROR_INVALID_PARAMETER);
446 Params = NtCurrentPeb ()->ProcessParameters;
448 RtlAcquirePebLock ();
450 if (lpLocalStartupInfo == NULL)
452 /* create new local startup info (ansi) */
453 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
455 sizeof(STARTUPINFOA));
457 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
459 /* copy window title string */
460 RtlUnicodeStringToAnsiString (&AnsiString,
461 &Params->WindowTitle,
463 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
465 /* copy desktop info string */
466 RtlUnicodeStringToAnsiString (&AnsiString,
467 &Params->DesktopInfo,
469 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
471 /* copy shell info string */
472 RtlUnicodeStringToAnsiString (&AnsiString,
475 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
477 lpLocalStartupInfo->dwX = Params->dwX;
478 lpLocalStartupInfo->dwY = Params->dwY;
479 lpLocalStartupInfo->dwXSize = Params->dwXSize;
480 lpLocalStartupInfo->dwYSize = Params->dwYSize;
481 lpLocalStartupInfo->dwXCountChars = Params->dwXCountChars;
482 lpLocalStartupInfo->dwYCountChars = Params->dwYCountChars;
483 lpLocalStartupInfo->dwFillAttribute = Params->dwFillAttribute;
484 lpLocalStartupInfo->dwFlags = Params->dwFlags;
485 lpLocalStartupInfo->wShowWindow = Params->wShowWindow;
486 lpLocalStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
487 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
489 lpLocalStartupInfo->hStdInput = Params->hStdInput;
490 lpLocalStartupInfo->hStdOutput = Params->hStdOutput;
491 lpLocalStartupInfo->hStdError = Params->hStdError;
494 RtlReleasePebLock ();
496 /* copy local startup info data to external startup info */
497 memcpy (lpStartupInfo,
499 sizeof(STARTUPINFOA));
504 FlushInstructionCache (HANDLE hProcess,
505 LPCVOID lpBaseAddress,
510 Status = NtFlushInstructionCache(hProcess,
511 (PVOID)lpBaseAddress,
513 if (!NT_SUCCESS(Status))
515 SetLastErrorByStatus(Status);
523 ExitProcess(UINT uExitCode)
525 CSRSS_API_REQUEST CsrRequest;
526 CSRSS_API_REPLY CsrReply;
529 /* unload all dll's */
530 LdrShutdownProcess ();
532 /* notify csrss of process termination */
533 CsrRequest.Type = CSRSS_TERMINATE_PROCESS;
534 Status = CsrClientCallServer(&CsrRequest,
536 sizeof(CSRSS_API_REQUEST),
537 sizeof(CSRSS_API_REPLY));
538 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
540 DbgPrint("Failed to tell csrss about terminating process. "
541 "Expect trouble.\n");
545 NtTerminateProcess (NtCurrentProcess (),
551 TerminateProcess (HANDLE hProcess,
556 Status = NtTerminateProcess (hProcess, uExitCode);
557 if (NT_SUCCESS(Status))
561 SetLastErrorByStatus (Status);
567 FatalAppExitA (UINT uAction,
568 LPCSTR lpMessageText)
570 UNICODE_STRING MessageTextU;
571 ANSI_STRING MessageText;
573 RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
575 RtlAnsiStringToUnicodeString (&MessageTextU,
579 FatalAppExitW (uAction, MessageTextU.Buffer);
581 RtlFreeUnicodeString (&MessageTextU);
586 FatalAppExitW(UINT uAction,
587 LPCWSTR lpMessageText)
594 FatalExit (int ExitCode)
596 ExitProcess(ExitCode);
601 GetPriorityClass (HANDLE hProcess)
604 DWORD CsrPriorityClass = 0; // This tells CSRSS we want to GET it!
608 NtDuplicateObject (GetCurrentProcess(),
612 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
615 if (!NT_SUCCESS(Status))
617 SetLastErrorByStatus (Status);
618 return (0); /* ERROR */
620 /* Ask CSRSS to set it */
621 CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
622 NtClose (hProcessTmp);
623 /* Translate CSR->W32 priorities */
624 switch (CsrPriorityClass)
626 case CSR_PRIORITY_CLASS_NORMAL:
627 return (NORMAL_PRIORITY_CLASS); /* 32 */
628 case CSR_PRIORITY_CLASS_IDLE:
629 return (IDLE_PRIORITY_CLASS); /* 64 */
630 case CSR_PRIORITY_CLASS_HIGH:
631 return (HIGH_PRIORITY_CLASS); /* 128 */
632 case CSR_PRIORITY_CLASS_REALTIME:
633 return (REALTIME_PRIORITY_CLASS); /* 256 */
635 SetLastError (ERROR_ACCESS_DENIED);
636 return (0); /* ERROR */
642 SetPriorityClass (HANDLE hProcess,
643 DWORD dwPriorityClass)
646 DWORD CsrPriorityClass;
649 switch (dwPriorityClass)
651 case NORMAL_PRIORITY_CLASS: /* 32 */
652 CsrPriorityClass = CSR_PRIORITY_CLASS_NORMAL;
654 case IDLE_PRIORITY_CLASS: /* 64 */
655 CsrPriorityClass = CSR_PRIORITY_CLASS_IDLE;
657 case HIGH_PRIORITY_CLASS: /* 128 */
658 CsrPriorityClass = CSR_PRIORITY_CLASS_HIGH;
660 case REALTIME_PRIORITY_CLASS: /* 256 */
661 CsrPriorityClass = CSR_PRIORITY_CLASS_REALTIME;
664 SetLastError (ERROR_INVALID_PARAMETER);
668 NtDuplicateObject (GetCurrentProcess(),
672 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
675 if (!NT_SUCCESS(Status))
677 SetLastErrorByStatus (Status);
678 return (FALSE); /* ERROR */
680 /* Ask CSRSS to set it */
681 Status = CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
682 NtClose (hProcessTmp);
683 if (!NT_SUCCESS(Status))
685 SetLastErrorByStatus (Status);
693 GetProcessVersion (DWORD ProcessId)
696 PIMAGE_NT_HEADERS NtHeader = NULL;
697 PVOID BaseAddress = NULL;
702 BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
703 NtHeader = RtlImageNtHeader (BaseAddress);
704 if (NULL != NtHeader)
707 (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
708 (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
711 else /* other process */
713 /* FIXME: open the other process */
714 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);