1 /* $Id: proc.c,v 1.39 2001/03/13 16:25:51 dwelch 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
);
48 GetProcessTimes (HANDLE hProcess
,
49 LPFILETIME lpCreationTime
,
50 LPFILETIME lpExitTime
,
51 LPFILETIME lpKernelTime
,
52 LPFILETIME lpUserTime
)
55 KERNEL_USER_TIMES Kut
;
57 Status
= NtQueryInformationProcess (hProcess
,
63 if (!NT_SUCCESS(Status
))
65 SetLastErrorByStatus (Status
);
69 lpCreationTime
->dwLowDateTime
= Kut
.CreateTime
.u
.LowPart
;
70 lpCreationTime
->dwHighDateTime
= Kut
.CreateTime
.u
.HighPart
;
72 lpExitTime
->dwLowDateTime
= Kut
.ExitTime
.u
.LowPart
;
73 lpExitTime
->dwHighDateTime
= Kut
.ExitTime
.u
.HighPart
;
75 lpKernelTime
->dwLowDateTime
= Kut
.KernelTime
.u
.LowPart
;
76 lpKernelTime
->dwHighDateTime
= Kut
.KernelTime
.u
.HighPart
;
78 lpUserTime
->dwLowDateTime
= Kut
.UserTime
.u
.LowPart
;
79 lpUserTime
->dwHighDateTime
= Kut
.UserTime
.u
.HighPart
;
85 HANDLE STDCALL
GetCurrentProcess (VOID
)
87 return((HANDLE
)NtCurrentProcess());
91 HANDLE STDCALL
GetCurrentThread (VOID
)
93 return((HANDLE
)NtCurrentThread());
97 DWORD STDCALL
GetCurrentProcessId (VOID
)
99 return((DWORD
)GetTeb()->Cid
.UniqueProcess
);
111 PROCESS_BASIC_INFORMATION ProcessBasic
;
114 errCode
= NtQueryInformationProcess(hProcess
,
115 ProcessBasicInformation
,
117 sizeof(PROCESS_BASIC_INFORMATION
),
119 if (!NT_SUCCESS(errCode
))
121 SetLastErrorByStatus (errCode
);
124 memcpy(lpExitCode
, &ProcessBasic
.ExitStatus
, sizeof(DWORD
));
137 PROCESS_BASIC_INFORMATION ProcessBasic
;
140 errCode
= NtQueryInformationProcess(hProcess
,
141 ProcessBasicInformation
,
143 sizeof(PROCESS_BASIC_INFORMATION
),
145 if (!NT_SUCCESS(errCode
))
147 SetLastErrorByStatus (errCode
);
150 memcpy( lpProcessId
,&ProcessBasic
.UniqueProcessId
,sizeof(DWORD
));
158 DWORD dwDesiredAccess
,
159 WINBOOL bInheritHandle
,
164 HANDLE ProcessHandle
;
165 OBJECT_ATTRIBUTES ObjectAttributes
;
168 ClientId
.UniqueProcess
= (HANDLE
)dwProcessId
;
169 ClientId
.UniqueThread
= INVALID_HANDLE_VALUE
;
171 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
172 ObjectAttributes
.RootDirectory
= (HANDLE
)NULL
;
173 ObjectAttributes
.SecurityDescriptor
= NULL
;
174 ObjectAttributes
.SecurityQualityOfService
= NULL
;
175 ObjectAttributes
.ObjectName
= NULL
;
177 if (bInheritHandle
== TRUE
)
178 ObjectAttributes
.Attributes
= OBJ_INHERIT
;
180 ObjectAttributes
.Attributes
= 0;
182 errCode
= NtOpenProcess(&ProcessHandle
,
186 if (!NT_SUCCESS(errCode
))
188 SetLastErrorByStatus (errCode
);
191 return ProcessHandle
;
202 STARTUPINFOA StartupInfo
;
203 PROCESS_INFORMATION ProcessInformation
;
207 StartupInfo
.cb
= sizeof(STARTUPINFOA
);
208 StartupInfo
.wShowWindow
= uCmdShow
;
209 StartupInfo
.dwFlags
= 0;
211 hInst
= (HINSTANCE
)CreateProcessA(NULL
,
220 &ProcessInformation
);
223 dosErr
= GetLastError();
226 if (NULL
!= lpfnGlobalRegisterWaitForInputIdle
)
228 lpfnGlobalRegisterWaitForInputIdle (
229 ProcessInformation
.hProcess
,
233 NtClose (ProcessInformation
.hProcess
);
234 NtClose (ProcessInformation
.hThread
);
241 RegisterWaitForInputIdle (
242 WaitForInputIdleType lpfnRegisterWaitForInputIdle
245 lpfnGlobalRegisterWaitForInputIdle
= lpfnRegisterWaitForInputIdle
;
267 SleepEx (dwMilliseconds
, FALSE
);
273 SleepEx (DWORD dwMilliseconds
,
279 if (dwMilliseconds
!= INFINITE
)
282 * System time units are 100 nanoseconds (a nanosecond is a billionth of
285 Interval
.QuadPart
= dwMilliseconds
;
286 Interval
.QuadPart
= -(Interval
.QuadPart
* 10000);
290 /* Approximately 292000 years hence */
291 Interval
.QuadPart
= -0x7FFFFFFFFFFFFFFF;
294 errCode
= NtDelayExecution (bAlertable
, &Interval
);
295 if (!NT_SUCCESS(errCode
))
297 SetLastErrorByStatus (errCode
);
305 GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo
)
307 PRTL_USER_PROCESS_PARAMETERS Params
;
309 if (lpStartupInfo
== NULL
)
311 SetLastError(ERROR_INVALID_PARAMETER
);
315 Params
= NtCurrentPeb ()->ProcessParameters
;
317 lpStartupInfo
->cb
= sizeof(STARTUPINFOW
);
318 lpStartupInfo
->lpDesktop
= Params
->DesktopInfo
.Buffer
;
319 lpStartupInfo
->lpTitle
= Params
->WindowTitle
.Buffer
;
320 lpStartupInfo
->dwX
= Params
->StartingX
;
321 lpStartupInfo
->dwY
= Params
->StartingY
;
322 lpStartupInfo
->dwXSize
= Params
->CountX
;
323 lpStartupInfo
->dwYSize
= Params
->CountY
;
324 lpStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
325 lpStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
326 lpStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
327 lpStartupInfo
->dwFlags
= Params
->Flags
;
328 lpStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
329 lpStartupInfo
->lpReserved
= Params
->ShellInfo
.Buffer
;
330 lpStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
331 lpStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
333 lpStartupInfo
->hStdInput
= Params
->InputHandle
;
334 lpStartupInfo
->hStdOutput
= Params
->OutputHandle
;
335 lpStartupInfo
->hStdError
= Params
->ErrorHandle
;
340 GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo
)
342 PRTL_USER_PROCESS_PARAMETERS Params
;
343 ANSI_STRING AnsiString
;
345 if (lpStartupInfo
== NULL
)
347 SetLastError(ERROR_INVALID_PARAMETER
);
351 Params
= NtCurrentPeb ()->ProcessParameters
;
353 RtlAcquirePebLock ();
355 if (lpLocalStartupInfo
== NULL
)
357 /* create new local startup info (ansi) */
358 lpLocalStartupInfo
= RtlAllocateHeap (RtlGetProcessHeap (),
360 sizeof(STARTUPINFOA
));
362 lpLocalStartupInfo
->cb
= sizeof(STARTUPINFOA
);
364 /* copy window title string */
365 RtlUnicodeStringToAnsiString (&AnsiString
,
366 &Params
->WindowTitle
,
368 lpLocalStartupInfo
->lpTitle
= AnsiString
.Buffer
;
370 /* copy desktop info string */
371 RtlUnicodeStringToAnsiString (&AnsiString
,
372 &Params
->DesktopInfo
,
374 lpLocalStartupInfo
->lpDesktop
= AnsiString
.Buffer
;
376 /* copy shell info string */
377 RtlUnicodeStringToAnsiString (&AnsiString
,
380 lpLocalStartupInfo
->lpReserved
= AnsiString
.Buffer
;
382 lpLocalStartupInfo
->dwX
= Params
->StartingX
;
383 lpLocalStartupInfo
->dwY
= Params
->StartingY
;
384 lpLocalStartupInfo
->dwXSize
= Params
->CountX
;
385 lpLocalStartupInfo
->dwYSize
= Params
->CountY
;
386 lpLocalStartupInfo
->dwXCountChars
= Params
->CountCharsX
;
387 lpLocalStartupInfo
->dwYCountChars
= Params
->CountCharsY
;
388 lpLocalStartupInfo
->dwFillAttribute
= Params
->FillAttribute
;
389 lpLocalStartupInfo
->dwFlags
= Params
->Flags
;
390 lpLocalStartupInfo
->wShowWindow
= Params
->ShowWindowFlags
;
391 lpLocalStartupInfo
->cbReserved2
= Params
->RuntimeInfo
.Length
;
392 lpLocalStartupInfo
->lpReserved2
= (LPBYTE
)Params
->RuntimeInfo
.Buffer
;
394 lpLocalStartupInfo
->hStdInput
= Params
->InputHandle
;
395 lpLocalStartupInfo
->hStdOutput
= Params
->OutputHandle
;
396 lpLocalStartupInfo
->hStdError
= Params
->ErrorHandle
;
399 RtlReleasePebLock ();
401 /* copy local startup info data to external startup info */
402 memcpy (lpStartupInfo
,
404 sizeof(STARTUPINFOA
));
410 FlushInstructionCache (
412 LPCVOID lpBaseAddress
,
418 errCode
= NtFlushInstructionCache (
420 (PVOID
) lpBaseAddress
,
422 if (!NT_SUCCESS(errCode
))
424 SetLastErrorByStatus (errCode
);
437 /* unload all dll's */
438 LdrShutdownProcess ();
440 /* FIXME: notify csrss of process termination */
442 NtTerminateProcess (NtCurrentProcess (),
456 errCode
= NtTerminateProcess (hProcess
, uExitCode
);
457 if (!NT_SUCCESS(errCode
))
459 SetLastErrorByStatus (errCode
);
473 UNICODE_STRING MessageTextU
;
474 ANSI_STRING MessageText
;
476 RtlInitAnsiString (& MessageText
,
477 (LPSTR
) lpMessageText
);
479 RtlAnsiStringToUnicodeString (& MessageTextU
,
483 FatalAppExitW (uAction
,
484 MessageTextU
.Buffer
);
486 RtlFreeUnicodeString (&MessageTextU
);
494 LPCWSTR lpMessageText
507 ExitProcess(ExitCode
);
518 DWORD CsrPriorityClass
;
521 Status
= NtDuplicateObject (
526 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
530 if (!NT_SUCCESS(Status
))
532 SetLastErrorByStatus (Status
);
533 return (0); /* ERROR */
535 /* Ask CSRSS to set it */
536 CsrSetPriorityClass (
540 NtClose (hProcessTmp
);
541 /* Translate CSR->W32 priorities */
542 switch (CsrPriorityClass
)
544 case CSR_PRIORITY_CLASS_NORMAL
:
545 return (NORMAL_PRIORITY_CLASS
); /* 32 */
546 case CSR_PRIORITY_CLASS_IDLE
:
547 return (IDLE_PRIORITY_CLASS
); /* 64 */
548 case CSR_PRIORITY_CLASS_HIGH
:
549 return (HIGH_PRIORITY_CLASS
); /* 128 */
550 case CSR_PRIORITY_CLASS_REALTIME
:
551 return (REALTIME_PRIORITY_CLASS
); /* 256 */
553 SetLastError (ERROR_ACCESS_DENIED
);
554 return (0); /* ERROR */
563 DWORD dwPriorityClass
567 DWORD CsrPriorityClass
;
570 switch (dwPriorityClass
)
572 case NORMAL_PRIORITY_CLASS
: /* 32 */
573 CsrPriorityClass
= CSR_PRIORITY_CLASS_NORMAL
;
575 case IDLE_PRIORITY_CLASS
: /* 64 */
576 CsrPriorityClass
= CSR_PRIORITY_CLASS_IDLE
;
578 case HIGH_PRIORITY_CLASS
: /* 128 */
579 CsrPriorityClass
= CSR_PRIORITY_CLASS_HIGH
;
581 case REALTIME_PRIORITY_CLASS
: /* 256 */
582 CsrPriorityClass
= CSR_PRIORITY_CLASS_REALTIME
;
585 SetLastError (ERROR_INVALID_PARAMETER
);
588 Status
= NtDuplicateObject (
593 (PROCESS_SET_INFORMATION
| PROCESS_QUERY_INFORMATION
),
597 if (!NT_SUCCESS(Status
))
599 SetLastErrorByStatus (Status
);
600 return (FALSE
); /* ERROR */
602 /* Ask CSRSS to set it */
603 Status
= CsrSetPriorityClass (
607 NtClose (hProcessTmp
);
608 if (!NT_SUCCESS(Status
))
610 SetLastErrorByStatus (Status
);
624 PIMAGE_NT_HEADERS NtHeader
= NULL
;
625 PVOID BaseAddress
= NULL
;
630 BaseAddress
= (PVOID
) NtCurrentPeb()->ImageBaseAddress
;
631 NtHeader
= RtlImageNtHeader (BaseAddress
);
632 if (NULL
!= NtHeader
)
635 (NtHeader
->OptionalHeader
.MajorOperatingSystemVersion
<< 16)
636 | (NtHeader
->OptionalHeader
.MinorOperatingSystemVersion
);
639 else /* other process */
641 /* FIXME: open the other process */
642 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);