1 /* $Id: proc.c,v 1.46 2002/09/08 10:22:45 chorns 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 ****************************************************************/
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
);
49 GetProcessAffinityMask (
51 LPDWORD lpProcessAffinityMask
,
52 LPDWORD lpSystemAffinityMask
55 if ( (NULL
== lpProcessAffinityMask
)
56 || (NULL
== lpSystemAffinityMask
)
59 SetLastError(ERROR_BAD_ARGUMENTS
);
62 /* FIXME: check hProcess is actually a process */
63 /* FIXME: query the kernel process object */
64 *lpProcessAffinityMask
= 0x00000001;
65 *lpSystemAffinityMask
= 0x00000001;
72 GetProcessShutdownParameters (
77 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
84 GetProcessWorkingSetSize (
86 LPDWORD lpMinimumWorkingSetSize
,
87 LPDWORD lpMaximumWorkingSetSize
90 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
96 SetProcessShutdownParameters (
101 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
108 SetProcessWorkingSetSize (
110 DWORD dwMinimumWorkingSetSize
,
111 DWORD dwMaximumWorkingSetSize
114 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
120 GetProcessTimes (HANDLE hProcess
,
121 LPFILETIME lpCreationTime
,
122 LPFILETIME lpExitTime
,
123 LPFILETIME lpKernelTime
,
124 LPFILETIME lpUserTime
)
127 KERNEL_USER_TIMES Kut
;
129 Status
= NtQueryInformationProcess (hProcess
,
135 if (!NT_SUCCESS(Status
))
137 SetLastErrorByStatus (Status
);
141 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
142 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
144 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
145 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
147 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
148 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
150 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
151 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
157 HANDLE STDCALL
GetCurrentProcess (VOID
)
159 return((HANDLE
)NtCurrentProcess());
163 HANDLE STDCALL
GetCurrentThread (VOID
)
165 return((HANDLE
)NtCurrentThread());
169 DWORD STDCALL
GetCurrentProcessId (VOID
)
171 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
183 PROCESS_BASIC_INFORMATION ProcessBasic
;
186 errCode
= NtQueryInformationProcess(hProcess
,
187 ProcessBasicInformation
,
189 sizeof(PROCESS_BASIC_INFORMATION
),
191 if (!NT_SUCCESS(errCode
))
193 SetLastErrorByStatus (errCode
);
196 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
209 PROCESS_BASIC_INFORMATION ProcessBasic
;
212 errCode
= NtQueryInformationProcess(hProcess
,
213 ProcessBasicInformation
,
215 sizeof(PROCESS_BASIC_INFORMATION
),
217 if (!NT_SUCCESS(errCode
))
219 SetLastErrorByStatus (errCode
);
222 memcpy( lpProcessId
,&ProcessBasic
.UniqueProcessId
,sizeof(DWORD
));
230 DWORD dwDesiredAccess
,
231 WINBOOL bInheritHandle
,
236 HANDLE ProcessHandle
;
237 OBJECT_ATTRIBUTES ObjectAttributes
;
240 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
241 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
243 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
244 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
245 ObjectAttributes
.SecurityDescriptor
= NULL
;
246 ObjectAttributes
.SecurityQualityOfService
= NULL
;
247 ObjectAttributes
.ObjectName
= NULL
;
249 if (bInheritHandle
== TRUE
)
250 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
252 ObjectAttributes
.Attributes
= 0;
254 errCode
= NtOpenProcess(&ProcessHandle
,
258 if (!NT_SUCCESS(errCode
))
260 SetLastErrorByStatus (errCode
);
263 return ProcessHandle
;
274 STARTUPINFOA StartupInfo
;
275 PROCESS_INFORMATION ProcessInformation
;
279 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
280 StartupInfo
.wShowWindow
= uCmdShow
;
281 StartupInfo
.dwFlags
= 0;
283 hInst
= (HINSTANCE
)CreateProcessA(NULL
,
292 &ProcessInformation
);
295 dosErr
= GetLastError();
298 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
300 lpfnGlobalRegisterWaitForInputIdle (
301 ProcessInformation
.hProcess
,
305 NtClose (ProcessInformation
.hProcess
);
306 NtClose (ProcessInformation
.hThread
);
313 RegisterWaitForInputIdle (
314 WaitForInputIdleType lpfnRegisterWaitForInputIdle
317 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
339 SleepEx (dwMilliseconds
, FALSE
);
345 SleepEx (DWORD dwMilliseconds
,
351 if (dwMilliseconds
!= INFINITE
)
354 * System time units are 100 nanoseconds (a nanosecond is a billionth of
357 Interval
.QuadPart
= dwMilliseconds
;
358 Interval
.QuadPart
= -(Interval
.QuadPart
* 10000);
362 /* Approximately 292000 years hence */
363 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFF;
366 errCode
= NtDelayExecution (bAlertable
, &Interval
);
367 if (!NT_SUCCESS(errCode
))
369 SetLastErrorByStatus (errCode
);
377 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
379 PRTL_USER_PROCESS_PARAMETERS Params
;
381 if (lpStartupInfo
== NULL
)
383 SetLastError(ERROR_INVALID_PARAMETER
);
387 Params
= NtCurrentPeb ()->ProcessParameters
;
389 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
390 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
391 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
392 lpStartupInfo
->dwX
= Params
->StartingX
;
393 lpStartupInfo
->dwY
= Params
->StartingY
;
394 lpStartupInfo
->dwXSize
= Params
->CountX
;
395 lpStartupInfo
->dwYSize
= Params
->CountY
;
396 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
397 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
398 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
399 lpStartupInfo
->dwFlags
= Params
->Flags
;
400 lpStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
401 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
402 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
403 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
405 lpStartupInfo
->hStdInput
= Params
->InputHandle
;
406 lpStartupInfo
->hStdOutput
= Params
->OutputHandle
;
407 lpStartupInfo
->hStdError
= Params
->ErrorHandle
;
412 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
414 PRTL_USER_PROCESS_PARAMETERS Params
;
415 ANSI_STRING AnsiString
;
417 if (lpStartupInfo
== NULL
)
419 SetLastError(ERROR_INVALID_PARAMETER
);
423 Params
= NtCurrentPeb ()->ProcessParameters
;
425 RtlAcquirePebLock ();
427 if (lpLocalStartupInfo
== NULL
)
429 /* create new local startup info (ansi) */
430 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
432 sizeof(STARTUPINFOA
));
434 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
436 /* copy window title string */
437 RtlUnicodeStringToAnsiString (&AnsiString
,
438 &Params
->WindowTitle
,
440 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
442 /* copy desktop info string */
443 RtlUnicodeStringToAnsiString (&AnsiString
,
444 &Params
->DesktopInfo
,
446 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
448 /* copy shell info string */
449 RtlUnicodeStringToAnsiString (&AnsiString
,
452 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
454 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
455 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
456 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
457 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
458 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
459 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
460 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
461 lpLocalStartupInfo
->dwFlags
= Params
->Flags
;
462 lpLocalStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
463 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
464 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
466 lpLocalStartupInfo
->hStdInput
= Params
->InputHandle
;
467 lpLocalStartupInfo
->hStdOutput
= Params
->OutputHandle
;
468 lpLocalStartupInfo
->hStdError
= Params
->ErrorHandle
;
471 RtlReleasePebLock ();
473 /* copy local startup info data to external startup info */
474 memcpy (lpStartupInfo
,
476 sizeof(STARTUPINFOA
));
481 FlushInstructionCache (HANDLE hProcess
,
482 LPCVOID lpBaseAddress
,
487 errCode
= NtFlushInstructionCache (hProcess
,
488 (PVOID
) lpBaseAddress
,
490 if (!NT_SUCCESS(errCode
))
492 SetLastErrorByStatus (errCode
);
500 ExitProcess (UINT uExitCode
)
502 CSRSS_API_REQUEST CsrRequest
;
503 CSRSS_API_REPLY CsrReply
;
506 /* unload all dll's */
507 LdrShutdownProcess ();
509 /* notify csrss of process termination */
510 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
511 Status
= CsrClientCallServer(&CsrRequest
,
513 sizeof(CSRSS_API_REQUEST
),
514 sizeof(CSRSS_API_REPLY
));
515 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
517 DbgPrint("Failed to tell csrss about terminating process. "
518 "Expect trouble.\n");
522 NtTerminateProcess (NtCurrentProcess (),
528 TerminateProcess (HANDLE hProcess
,
531 NTSTATUS Status
= NtTerminateProcess (hProcess
, uExitCode
);
533 if (NT_SUCCESS(Status
))
537 SetLastErrorByStatus (Status
);
543 FatalAppExitA (UINT uAction
,
544 LPCSTR lpMessageText
)
546 UNICODE_STRING MessageTextU
;
547 ANSI_STRING MessageText
;
549 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
551 RtlAnsiStringToUnicodeString (&MessageTextU
,
555 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
557 RtlFreeUnicodeString (&MessageTextU
);
562 FatalAppExitW (UINT uAction
,
563 LPCWSTR lpMessageText
)
570 FatalExit (int ExitCode
)
572 ExitProcess(ExitCode
);
577 GetPriorityClass (HANDLE hProcess
)
580 DWORD CsrPriorityClass
= 0; // This tells CSRSS we want to GET it!
584 NtDuplicateObject (GetCurrentProcess(),
588 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
591 if (!NT_SUCCESS(Status
))
593 SetLastErrorByStatus (Status
);
594 return (0); /* ERROR */
596 /* Ask CSRSS to set it */
597 CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
598 NtClose (hProcessTmp
);
599 /* Translate CSR->W32 priorities */
600 switch (CsrPriorityClass
)
602 case CSR_PRIORITY_CLASS_NORMAL
:
603 return (NORMAL_PRIORITY_CLASS
); /* 32 */
604 case CSR_PRIORITY_CLASS_IDLE
:
605 return (IDLE_PRIORITY_CLASS
); /* 64 */
606 case CSR_PRIORITY_CLASS_HIGH
:
607 return (HIGH_PRIORITY_CLASS
); /* 128 */
608 case CSR_PRIORITY_CLASS_REALTIME
:
609 return (REALTIME_PRIORITY_CLASS
); /* 256 */
611 SetLastError (ERROR_ACCESS_DENIED
);
612 return (0); /* ERROR */
618 SetPriorityClass (HANDLE hProcess
,
619 DWORD dwPriorityClass
)
622 DWORD CsrPriorityClass
;
625 switch (dwPriorityClass
)
627 case NORMAL_PRIORITY_CLASS
: /* 32 */
628 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
630 case IDLE_PRIORITY_CLASS
: /* 64 */
631 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
633 case HIGH_PRIORITY_CLASS
: /* 128 */
634 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
636 case REALTIME_PRIORITY_CLASS
: /* 256 */
637 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
640 SetLastError (ERROR_INVALID_PARAMETER
);
644 NtDuplicateObject (GetCurrentProcess(),
648 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
651 if (!NT_SUCCESS(Status
))
653 SetLastErrorByStatus (Status
);
654 return (FALSE
); /* ERROR */
656 /* Ask CSRSS to set it */
657 Status
= CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
658 NtClose (hProcessTmp
);
659 if (!NT_SUCCESS(Status
))
661 SetLastErrorByStatus (Status
);
669 GetProcessVersion (DWORD ProcessId
)
672 PIMAGE_NT_HEADERS NtHeader
= NULL
;
673 PVOID BaseAddress
= NULL
;
678 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
679 NtHeader
= RtlImageNtHeader (BaseAddress
);
680 if (NULL
!= NtHeader
)
683 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
684 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
687 else /* other process */
689 /* FIXME: open the other process */
690 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);