1 /* $Id: proc.c,v 1.45 2002/09/07 15:12:27 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 ****************************************************************/
15 #define NTOS_USER_MODE
17 #include <kernel32/proc.h>
18 #include <kernel32/thread.h>
19 #include <kernel32/error.h>
24 #include <kernel32/kernel32.h>
27 /* GLOBALS *******************************************************************/
29 WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle
;
31 LPSTARTUPINFO lpLocalStartupInfo
= NULL
;
34 RegisterWaitForInputIdle (WaitForInputIdleType lpfnRegisterWaitForInputIdle
);
37 /* FUNCTIONS ****************************************************************/
40 GetProcessId (HANDLE hProcess
, LPDWORD lpProcessId
);
44 GetProcessAffinityMask (
46 LPDWORD lpProcessAffinityMask
,
47 LPDWORD lpSystemAffinityMask
50 if ( (NULL
== lpProcessAffinityMask
)
51 || (NULL
== lpSystemAffinityMask
)
54 SetLastError(ERROR_BAD_ARGUMENTS
);
57 /* FIXME: check hProcess is actually a process */
58 /* FIXME: query the kernel process object */
59 *lpProcessAffinityMask
= 0x00000001;
60 *lpSystemAffinityMask
= 0x00000001;
67 GetProcessShutdownParameters (
72 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
79 GetProcessWorkingSetSize (
81 LPDWORD lpMinimumWorkingSetSize
,
82 LPDWORD lpMaximumWorkingSetSize
85 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
91 SetProcessShutdownParameters (
96 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
103 SetProcessWorkingSetSize (
105 DWORD dwMinimumWorkingSetSize
,
106 DWORD dwMaximumWorkingSetSize
109 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
115 GetProcessTimes (HANDLE hProcess
,
116 LPFILETIME lpCreationTime
,
117 LPFILETIME lpExitTime
,
118 LPFILETIME lpKernelTime
,
119 LPFILETIME lpUserTime
)
122 KERNEL_USER_TIMES Kut
;
124 Status
= NtQueryInformationProcess (hProcess
,
130 if (!NT_SUCCESS(Status
))
132 SetLastErrorByStatus (Status
);
136 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
137 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
139 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
140 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
142 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
143 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
145 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
146 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
152 HANDLE STDCALL
GetCurrentProcess (VOID
)
154 return((HANDLE
)NtCurrentProcess());
158 HANDLE STDCALL
GetCurrentThread (VOID
)
160 return((HANDLE
)NtCurrentThread());
164 DWORD STDCALL
GetCurrentProcessId (VOID
)
166 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
178 PROCESS_BASIC_INFORMATION ProcessBasic
;
181 errCode
= NtQueryInformationProcess(hProcess
,
182 ProcessBasicInformation
,
184 sizeof(PROCESS_BASIC_INFORMATION
),
186 if (!NT_SUCCESS(errCode
))
188 SetLastErrorByStatus (errCode
);
191 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
204 PROCESS_BASIC_INFORMATION ProcessBasic
;
207 errCode
= NtQueryInformationProcess(hProcess
,
208 ProcessBasicInformation
,
210 sizeof(PROCESS_BASIC_INFORMATION
),
212 if (!NT_SUCCESS(errCode
))
214 SetLastErrorByStatus (errCode
);
217 memcpy( lpProcessId
,&ProcessBasic
.UniqueProcessId
,sizeof(DWORD
));
225 DWORD dwDesiredAccess
,
226 WINBOOL bInheritHandle
,
231 HANDLE ProcessHandle
;
232 OBJECT_ATTRIBUTES ObjectAttributes
;
235 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
236 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
238 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
239 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
240 ObjectAttributes
.SecurityDescriptor
= NULL
;
241 ObjectAttributes
.SecurityQualityOfService
= NULL
;
242 ObjectAttributes
.ObjectName
= NULL
;
244 if (bInheritHandle
== TRUE
)
245 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
247 ObjectAttributes
.Attributes
= 0;
249 errCode
= NtOpenProcess(&ProcessHandle
,
253 if (!NT_SUCCESS(errCode
))
255 SetLastErrorByStatus (errCode
);
258 return ProcessHandle
;
269 STARTUPINFOA StartupInfo
;
270 PROCESS_INFORMATION ProcessInformation
;
274 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
275 StartupInfo
.wShowWindow
= uCmdShow
;
276 StartupInfo
.dwFlags
= 0;
278 hInst
= (HINSTANCE
)CreateProcessA(NULL
,
287 &ProcessInformation
);
290 dosErr
= GetLastError();
293 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
295 lpfnGlobalRegisterWaitForInputIdle (
296 ProcessInformation
.hProcess
,
300 NtClose (ProcessInformation
.hProcess
);
301 NtClose (ProcessInformation
.hThread
);
308 RegisterWaitForInputIdle (
309 WaitForInputIdleType lpfnRegisterWaitForInputIdle
312 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
334 SleepEx (dwMilliseconds
, FALSE
);
340 SleepEx (DWORD dwMilliseconds
,
346 if (dwMilliseconds
!= INFINITE
)
349 * System time units are 100 nanoseconds (a nanosecond is a billionth of
352 Interval
.QuadPart
= dwMilliseconds
;
353 Interval
.QuadPart
= -(Interval
.QuadPart
* 10000);
357 /* Approximately 292000 years hence */
358 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFF;
361 errCode
= NtDelayExecution (bAlertable
, &Interval
);
362 if (!NT_SUCCESS(errCode
))
364 SetLastErrorByStatus (errCode
);
372 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
374 PRTL_ROS_USER_PROCESS_PARAMETERS Params
;
376 if (lpStartupInfo
== NULL
)
378 SetLastError(ERROR_INVALID_PARAMETER
);
382 Params
= NtCurrentPeb ()->ProcessParameters
;
384 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
385 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
386 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
387 lpStartupInfo
->dwX
= Params
->StartingX
;
388 lpStartupInfo
->dwY
= Params
->StartingY
;
389 lpStartupInfo
->dwXSize
= Params
->CountX
;
390 lpStartupInfo
->dwYSize
= Params
->CountY
;
391 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
392 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
393 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
394 lpStartupInfo
->dwFlags
= Params
->Flags
;
395 lpStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
396 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
397 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
398 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
400 lpStartupInfo
->hStdInput
= Params
->InputHandle
;
401 lpStartupInfo
->hStdOutput
= Params
->OutputHandle
;
402 lpStartupInfo
->hStdError
= Params
->ErrorHandle
;
407 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
409 PRTL_ROS_USER_PROCESS_PARAMETERS Params
;
410 ANSI_STRING AnsiString
;
412 if (lpStartupInfo
== NULL
)
414 SetLastError(ERROR_INVALID_PARAMETER
);
418 Params
= NtCurrentPeb ()->ProcessParameters
;
420 RtlAcquirePebLock ();
422 if (lpLocalStartupInfo
== NULL
)
424 /* create new local startup info (ansi) */
425 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
427 sizeof(STARTUPINFOA
));
429 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
431 /* copy window title string */
432 RtlUnicodeStringToAnsiString (&AnsiString
,
433 &Params
->WindowTitle
,
435 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
437 /* copy desktop info string */
438 RtlUnicodeStringToAnsiString (&AnsiString
,
439 &Params
->DesktopInfo
,
441 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
443 /* copy shell info string */
444 RtlUnicodeStringToAnsiString (&AnsiString
,
447 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
449 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
450 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
451 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
452 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
453 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
454 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
455 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
456 lpLocalStartupInfo
->dwFlags
= Params
->Flags
;
457 lpLocalStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
458 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
459 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
461 lpLocalStartupInfo
->hStdInput
= Params
->InputHandle
;
462 lpLocalStartupInfo
->hStdOutput
= Params
->OutputHandle
;
463 lpLocalStartupInfo
->hStdError
= Params
->ErrorHandle
;
466 RtlReleasePebLock ();
468 /* copy local startup info data to external startup info */
469 memcpy (lpStartupInfo
,
471 sizeof(STARTUPINFOA
));
476 FlushInstructionCache (HANDLE hProcess
,
477 LPCVOID lpBaseAddress
,
482 errCode
= NtFlushInstructionCache (hProcess
,
483 (PVOID
) lpBaseAddress
,
485 if (!NT_SUCCESS(errCode
))
487 SetLastErrorByStatus (errCode
);
495 ExitProcess (UINT uExitCode
)
497 CSRSS_API_REQUEST CsrRequest
;
498 CSRSS_API_REPLY CsrReply
;
501 /* unload all dll's */
502 LdrShutdownProcess ();
504 /* notify csrss of process termination */
505 CsrRequest
.Type
= CSRSS_TERMINATE_PROCESS
;
506 Status
= CsrClientCallServer(&CsrRequest
,
508 sizeof(CSRSS_API_REQUEST
),
509 sizeof(CSRSS_API_REPLY
));
510 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(CsrReply
.Status
))
512 DbgPrint("Failed to tell csrss about terminating process. "
513 "Expect trouble.\n");
517 NtTerminateProcess (NtCurrentProcess (),
523 TerminateProcess (HANDLE hProcess
,
526 NTSTATUS Status
= NtTerminateProcess (hProcess
, uExitCode
);
528 if (NT_SUCCESS(Status
))
532 SetLastErrorByStatus (Status
);
538 FatalAppExitA (UINT uAction
,
539 LPCSTR lpMessageText
)
541 UNICODE_STRING MessageTextU
;
542 ANSI_STRING MessageText
;
544 RtlInitAnsiString (&MessageText
, (LPSTR
) lpMessageText
);
546 RtlAnsiStringToUnicodeString (&MessageTextU
,
550 FatalAppExitW (uAction
, MessageTextU
.Buffer
);
552 RtlFreeUnicodeString (&MessageTextU
);
557 FatalAppExitW (UINT uAction
,
558 LPCWSTR lpMessageText
)
565 FatalExit (int ExitCode
)
567 ExitProcess(ExitCode
);
572 GetPriorityClass (HANDLE hProcess
)
575 DWORD CsrPriorityClass
= 0; // This tells CSRSS we want to GET it!
579 NtDuplicateObject (GetCurrentProcess(),
583 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
586 if (!NT_SUCCESS(Status
))
588 SetLastErrorByStatus (Status
);
589 return (0); /* ERROR */
591 /* Ask CSRSS to set it */
592 CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
593 NtClose (hProcessTmp
);
594 /* Translate CSR->W32 priorities */
595 switch (CsrPriorityClass
)
597 case CSR_PRIORITY_CLASS_NORMAL
:
598 return (NORMAL_PRIORITY_CLASS
); /* 32 */
599 case CSR_PRIORITY_CLASS_IDLE
:
600 return (IDLE_PRIORITY_CLASS
); /* 64 */
601 case CSR_PRIORITY_CLASS_HIGH
:
602 return (HIGH_PRIORITY_CLASS
); /* 128 */
603 case CSR_PRIORITY_CLASS_REALTIME
:
604 return (REALTIME_PRIORITY_CLASS
); /* 256 */
606 SetLastError (ERROR_ACCESS_DENIED
);
607 return (0); /* ERROR */
613 SetPriorityClass (HANDLE hProcess
,
614 DWORD dwPriorityClass
)
617 DWORD CsrPriorityClass
;
620 switch (dwPriorityClass
)
622 case NORMAL_PRIORITY_CLASS
: /* 32 */
623 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
625 case IDLE_PRIORITY_CLASS
: /* 64 */
626 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
628 case HIGH_PRIORITY_CLASS
: /* 128 */
629 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
631 case REALTIME_PRIORITY_CLASS
: /* 256 */
632 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
635 SetLastError (ERROR_INVALID_PARAMETER
);
639 NtDuplicateObject (GetCurrentProcess(),
643 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
646 if (!NT_SUCCESS(Status
))
648 SetLastErrorByStatus (Status
);
649 return (FALSE
); /* ERROR */
651 /* Ask CSRSS to set it */
652 Status
= CsrSetPriorityClass (hProcessTmp
, &CsrPriorityClass
);
653 NtClose (hProcessTmp
);
654 if (!NT_SUCCESS(Status
))
656 SetLastErrorByStatus (Status
);
664 GetProcessVersion (DWORD ProcessId
)
667 PIMAGE_NT_HEADERS NtHeader
= NULL
;
668 PVOID BaseAddress
= NULL
;
673 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
674 NtHeader
= RtlImageNtHeader (BaseAddress
);
675 if (NULL
!= NtHeader
)
678 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16) |
679 (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
682 else /* other process */
684 /* FIXME: open the other process */
685 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);