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 ****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <ntdll/rtl.h>
17 #include <kernel32/proc.h>
18 #include <kernel32/thread.h>
19 #include <kernel32/error.h>
22 #include <napi/i386/segment.h>
24 #include <ntdll/csr.h>
25 #include <ntdll/ldr.h>
29 #include <kernel32/kernel32.h>
32 /* GLOBALS *******************************************************************/
34 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
36 LPSTARTUPINFO lpLocalStartupInfo = NULL;
39 RegisterWaitForInputIdle (WaitForInputIdleType lpfnRegisterWaitForInputIdle);
42 /* FUNCTIONS ****************************************************************/
45 GetProcessId (HANDLE hProcess, LPDWORD lpProcessId);
48 GetProcessAffinityMask(HANDLE hProcess,
49 LPDWORD lpProcessAffinityMask,
50 LPDWORD lpSystemAffinityMask)
52 if ((NULL == lpProcessAffinityMask)
53 || (NULL == lpSystemAffinityMask))
55 SetLastError(ERROR_BAD_ARGUMENTS);
59 /* FIXME: check hProcess is actually a process */
60 /* FIXME: query the kernel process object */
61 *lpProcessAffinityMask = 0x00000001;
62 *lpSystemAffinityMask = 0x00000001;
69 GetProcessShutdownParameters(LPDWORD lpdwLevel,
72 CSRSS_API_REQUEST CsrRequest;
73 CSRSS_API_REPLY CsrReply;
76 CsrRequest.Type = CSRSS_GET_SHUTDOWN_PARAMETERS;
77 Status = CsrClientCallServer(&CsrRequest,
79 sizeof(CSRSS_API_REQUEST),
80 sizeof(CSRSS_API_REPLY));
81 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
87 *lpdwLevel = CsrReply.Data.GetShutdownParametersReply.Level;
88 *lpdwFlags = CsrReply.Data.GetShutdownParametersReply.Flags;
95 SetProcessShutdownParameters(DWORD dwLevel,
98 CSRSS_API_REQUEST CsrRequest;
99 CSRSS_API_REPLY CsrReply;
102 CsrRequest.Data.SetShutdownParametersRequest.Level = dwLevel;
103 CsrRequest.Data.SetShutdownParametersRequest.Flags = dwFlags;
105 CsrRequest.Type = CSRSS_SET_SHUTDOWN_PARAMETERS;
106 Status = CsrClientCallServer(&CsrRequest,
108 sizeof(CSRSS_API_REQUEST),
109 sizeof(CSRSS_API_REPLY));
110 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
112 SetLastError(Status);
121 GetProcessWorkingSetSize(HANDLE hProcess,
122 LPDWORD lpMinimumWorkingSetSize,
123 LPDWORD lpMaximumWorkingSetSize)
125 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
131 SetProcessWorkingSetSize(HANDLE hProcess,
132 DWORD dwMinimumWorkingSetSize,
133 DWORD dwMaximumWorkingSetSize)
135 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
141 GetProcessTimes(HANDLE hProcess,
142 LPFILETIME lpCreationTime,
143 LPFILETIME lpExitTime,
144 LPFILETIME lpKernelTime,
145 LPFILETIME lpUserTime)
147 KERNEL_USER_TIMES Kut;
150 Status = NtQueryInformationProcess(hProcess,
155 if (!NT_SUCCESS(Status))
157 SetLastErrorByStatus(Status);
161 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
162 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
164 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
165 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
167 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
168 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
170 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
171 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
178 GetCurrentProcess(VOID)
180 return((HANDLE)NtCurrentProcess());
185 GetCurrentThread(VOID)
187 return((HANDLE)NtCurrentThread());
192 GetCurrentProcessId(VOID)
194 return((DWORD)GetTeb()->Cid.UniqueProcess);
199 GetExitCodeProcess(HANDLE hProcess,
202 PROCESS_BASIC_INFORMATION ProcessBasic;
206 Status = NtQueryInformationProcess(hProcess,
207 ProcessBasicInformation,
209 sizeof(PROCESS_BASIC_INFORMATION),
211 if (!NT_SUCCESS(Status))
213 SetLastErrorByStatus(Status);
217 memcpy(lpExitCode, &ProcessBasic.ExitStatus, sizeof(DWORD));
224 GetProcessId(HANDLE hProcess,
228 PROCESS_BASIC_INFORMATION ProcessBasic;
231 errCode = NtQueryInformationProcess(hProcess,
232 ProcessBasicInformation,
234 sizeof(PROCESS_BASIC_INFORMATION),
236 if (!NT_SUCCESS(errCode))
238 SetLastErrorByStatus (errCode);
241 memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
247 OpenProcess(DWORD dwDesiredAccess,
248 WINBOOL bInheritHandle,
252 HANDLE ProcessHandle;
253 OBJECT_ATTRIBUTES ObjectAttributes;
256 ClientId.UniqueProcess = (HANDLE)dwProcessId;
257 ClientId.UniqueThread = INVALID_HANDLE_VALUE;
259 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
260 ObjectAttributes.RootDirectory = (HANDLE)NULL;
261 ObjectAttributes.SecurityDescriptor = NULL;
262 ObjectAttributes.SecurityQualityOfService = NULL;
263 ObjectAttributes.ObjectName = NULL;
265 if (bInheritHandle == TRUE)
266 ObjectAttributes.Attributes = OBJ_INHERIT;
268 ObjectAttributes.Attributes = 0;
270 errCode = NtOpenProcess(&ProcessHandle,
274 if (!NT_SUCCESS(errCode))
276 SetLastErrorByStatus (errCode);
279 return ProcessHandle;
284 WinExec(LPCSTR lpCmdLine,
287 STARTUPINFOA StartupInfo;
288 PROCESS_INFORMATION ProcessInformation;
292 StartupInfo.cb = sizeof(STARTUPINFOA);
293 StartupInfo.wShowWindow = uCmdShow;
294 StartupInfo.dwFlags = 0;
296 hInst = (HINSTANCE)CreateProcessA(NULL,
305 &ProcessInformation);
308 dosErr = GetLastError();
311 if (NULL != lpfnGlobalRegisterWaitForInputIdle)
313 lpfnGlobalRegisterWaitForInputIdle (
314 ProcessInformation.hProcess,
318 NtClose (ProcessInformation.hProcess);
319 NtClose (ProcessInformation.hThread);
325 RegisterWaitForInputIdle (
326 WaitForInputIdleType lpfnRegisterWaitForInputIdle
329 lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
345 Sleep(DWORD dwMilliseconds)
347 SleepEx(dwMilliseconds, FALSE);
353 SleepEx(DWORD dwMilliseconds,
359 if (dwMilliseconds != INFINITE)
362 * System time units are 100 nanoseconds (a nanosecond is a billionth of
365 Interval.QuadPart = dwMilliseconds;
366 Interval.QuadPart = -(Interval.QuadPart * 10000);
370 /* Approximately 292000 years hence */
371 Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
374 errCode = NtDelayExecution (bAlertable, &Interval);
375 if (!NT_SUCCESS(errCode))
377 SetLastErrorByStatus (errCode);
385 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
387 PRTL_USER_PROCESS_PARAMETERS Params;
389 if (lpStartupInfo == NULL)
391 SetLastError(ERROR_INVALID_PARAMETER);
395 Params = NtCurrentPeb()->ProcessParameters;
397 lpStartupInfo->cb = sizeof(STARTUPINFOW);
398 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
399 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
400 lpStartupInfo->dwX = Params->dwX;
401 lpStartupInfo->dwY = Params->dwY;
402 lpStartupInfo->dwXSize = Params->dwXSize;
403 lpStartupInfo->dwYSize = Params->dwYSize;
404 lpStartupInfo->dwXCountChars = Params->dwXCountChars;
405 lpStartupInfo->dwYCountChars = Params->dwYCountChars;
406 lpStartupInfo->dwFillAttribute = Params->dwFillAttribute;
407 lpStartupInfo->dwFlags = Params->dwFlags;
408 lpStartupInfo->wShowWindow = Params->wShowWindow;
409 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
410 lpStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
411 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
413 lpStartupInfo->hStdInput = Params->hStdInput;
414 lpStartupInfo->hStdOutput = Params->hStdOutput;
415 lpStartupInfo->hStdError = Params->hStdError;
420 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
422 PRTL_USER_PROCESS_PARAMETERS Params;
423 ANSI_STRING AnsiString;
425 if (lpStartupInfo == NULL)
427 SetLastError(ERROR_INVALID_PARAMETER);
431 Params = NtCurrentPeb ()->ProcessParameters;
433 RtlAcquirePebLock ();
435 if (lpLocalStartupInfo == NULL)
437 /* create new local startup info (ansi) */
438 lpLocalStartupInfo = RtlAllocateHeap (RtlGetProcessHeap (),
440 sizeof(STARTUPINFOA));
442 lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);
444 /* copy window title string */
445 RtlUnicodeStringToAnsiString (&AnsiString,
446 &Params->WindowTitle,
448 lpLocalStartupInfo->lpTitle = AnsiString.Buffer;
450 /* copy desktop info string */
451 RtlUnicodeStringToAnsiString (&AnsiString,
452 &Params->DesktopInfo,
454 lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;
456 /* copy shell info string */
457 RtlUnicodeStringToAnsiString (&AnsiString,
460 lpLocalStartupInfo->lpReserved = AnsiString.Buffer;
462 lpLocalStartupInfo->dwX = Params->dwX;
463 lpLocalStartupInfo->dwY = Params->dwY;
464 lpLocalStartupInfo->dwXSize = Params->dwXSize;
465 lpLocalStartupInfo->dwYSize = Params->dwYSize;
466 lpLocalStartupInfo->dwXCountChars = Params->dwXCountChars;
467 lpLocalStartupInfo->dwYCountChars = Params->dwYCountChars;
468 lpLocalStartupInfo->dwFillAttribute = Params->dwFillAttribute;
469 lpLocalStartupInfo->dwFlags = Params->dwFlags;
470 lpLocalStartupInfo->wShowWindow = Params->wShowWindow;
471 lpLocalStartupInfo->cbReserved2 = Params->RuntimeInfo.Length;
472 lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeInfo.Buffer;
474 lpLocalStartupInfo->hStdInput = Params->hStdInput;
475 lpLocalStartupInfo->hStdOutput = Params->hStdOutput;
476 lpLocalStartupInfo->hStdError = Params->hStdError;
479 RtlReleasePebLock ();
481 /* copy local startup info data to external startup info */
482 memcpy (lpStartupInfo,
484 sizeof(STARTUPINFOA));
489 FlushInstructionCache (HANDLE hProcess,
490 LPCVOID lpBaseAddress,
495 Status = NtFlushInstructionCache(hProcess,
496 (PVOID)lpBaseAddress,
498 if (!NT_SUCCESS(Status))
500 SetLastErrorByStatus(Status);
508 ExitProcess(UINT uExitCode)
510 CSRSS_API_REQUEST CsrRequest;
511 CSRSS_API_REPLY CsrReply;
514 /* unload all dll's */
515 LdrShutdownProcess ();
517 /* notify csrss of process termination */
518 CsrRequest.Type = CSRSS_TERMINATE_PROCESS;
519 Status = CsrClientCallServer(&CsrRequest,
521 sizeof(CSRSS_API_REQUEST),
522 sizeof(CSRSS_API_REPLY));
523 if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrReply.Status))
525 DbgPrint("Failed to tell csrss about terminating process. "
526 "Expect trouble.\n");
530 NtTerminateProcess (NtCurrentProcess (),
536 TerminateProcess (HANDLE hProcess,
541 Status = NtTerminateProcess (hProcess, uExitCode);
542 if (NT_SUCCESS(Status))
546 SetLastErrorByStatus (Status);
552 FatalAppExitA (UINT uAction,
553 LPCSTR lpMessageText)
555 UNICODE_STRING MessageTextU;
556 ANSI_STRING MessageText;
558 RtlInitAnsiString (&MessageText, (LPSTR) lpMessageText);
560 RtlAnsiStringToUnicodeString (&MessageTextU,
564 FatalAppExitW (uAction, MessageTextU.Buffer);
566 RtlFreeUnicodeString (&MessageTextU);
571 FatalAppExitW(UINT uAction,
572 LPCWSTR lpMessageText)
579 FatalExit (int ExitCode)
581 ExitProcess(ExitCode);
586 GetPriorityClass (HANDLE hProcess)
589 DWORD CsrPriorityClass = 0; // This tells CSRSS we want to GET it!
593 NtDuplicateObject (GetCurrentProcess(),
597 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
600 if (!NT_SUCCESS(Status))
602 SetLastErrorByStatus (Status);
603 return (0); /* ERROR */
605 /* Ask CSRSS to set it */
606 CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
607 NtClose (hProcessTmp);
608 /* Translate CSR->W32 priorities */
609 switch (CsrPriorityClass)
611 case CSR_PRIORITY_CLASS_NORMAL:
612 return (NORMAL_PRIORITY_CLASS); /* 32 */
613 case CSR_PRIORITY_CLASS_IDLE:
614 return (IDLE_PRIORITY_CLASS); /* 64 */
615 case CSR_PRIORITY_CLASS_HIGH:
616 return (HIGH_PRIORITY_CLASS); /* 128 */
617 case CSR_PRIORITY_CLASS_REALTIME:
618 return (REALTIME_PRIORITY_CLASS); /* 256 */
620 SetLastError (ERROR_ACCESS_DENIED);
621 return (0); /* ERROR */
627 SetPriorityClass (HANDLE hProcess,
628 DWORD dwPriorityClass)
631 DWORD CsrPriorityClass;
634 switch (dwPriorityClass)
636 case NORMAL_PRIORITY_CLASS: /* 32 */
637 CsrPriorityClass = CSR_PRIORITY_CLASS_NORMAL;
639 case IDLE_PRIORITY_CLASS: /* 64 */
640 CsrPriorityClass = CSR_PRIORITY_CLASS_IDLE;
642 case HIGH_PRIORITY_CLASS: /* 128 */
643 CsrPriorityClass = CSR_PRIORITY_CLASS_HIGH;
645 case REALTIME_PRIORITY_CLASS: /* 256 */
646 CsrPriorityClass = CSR_PRIORITY_CLASS_REALTIME;
649 SetLastError (ERROR_INVALID_PARAMETER);
653 NtDuplicateObject (GetCurrentProcess(),
657 (PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION),
660 if (!NT_SUCCESS(Status))
662 SetLastErrorByStatus (Status);
663 return (FALSE); /* ERROR */
665 /* Ask CSRSS to set it */
666 Status = CsrSetPriorityClass (hProcessTmp, &CsrPriorityClass);
667 NtClose (hProcessTmp);
668 if (!NT_SUCCESS(Status))
670 SetLastErrorByStatus (Status);
678 GetProcessVersion (DWORD ProcessId)
681 PIMAGE_NT_HEADERS NtHeader = NULL;
682 PVOID BaseAddress = NULL;
687 BaseAddress = (PVOID) NtCurrentPeb()->ImageBaseAddress;
688 NtHeader = RtlImageNtHeader (BaseAddress);
689 if (NULL != NtHeader)
692 (NtHeader->OptionalHeader.MajorOperatingSystemVersion << 16) |
693 (NtHeader->OptionalHeader.MinorOperatingSystemVersion);
696 else /* other process */
698 /* FIXME: open the other process */
699 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);