mirror of
https://github.com/reactos/reactos.git
synced 2025-06-03 08:20:27 +00:00

- the ProcessDebugPort information class is read-only on NT5.1+ svn path=/trunk/; revision=14862
352 lines
10 KiB
C
352 lines
10 KiB
C
/* $Id$
|
|
*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* FILE: ntoskrnl/ps/psmgr.c
|
|
* PURPOSE: Process management
|
|
*
|
|
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
|
*/
|
|
|
|
/* INCLUDES **************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
#define NDEBUG
|
|
#include <internal/debug.h>
|
|
|
|
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
|
|
extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
|
|
|
|
static GENERIC_MAPPING PiProcessMapping = {
|
|
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
|
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
|
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
|
|
PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
|
|
PROCESS_SUSPEND_RESUME,
|
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
|
PROCESS_ALL_ACCESS};
|
|
|
|
static GENERIC_MAPPING PiThreadMapping = {
|
|
STANDARD_RIGHTS_READ | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
|
|
STANDARD_RIGHTS_WRITE | THREAD_TERMINATE | THREAD_SUSPEND_RESUME |
|
|
THREAD_ALERT | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT,
|
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
|
THREAD_ALL_ACCESS};
|
|
|
|
BOOLEAN DoneInitYet = FALSE;
|
|
|
|
extern ULONG NtBuildNumber;
|
|
extern ULONG NtMajorVersion;
|
|
extern ULONG NtMinorVersion;
|
|
|
|
VOID
|
|
INIT_FUNCTION
|
|
PsInitClientIDManagment(VOID);
|
|
|
|
VOID STDCALL PspKillMostProcesses();
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
VOID PiShutdownProcessManager(VOID)
|
|
{
|
|
DPRINT("PiShutdownProcessManager()\n");
|
|
|
|
PspKillMostProcesses();
|
|
}
|
|
|
|
VOID INIT_FUNCTION
|
|
PiInitProcessManager(VOID)
|
|
{
|
|
PsInitJobManagment();
|
|
PsInitProcessManagment();
|
|
PsInitThreadManagment();
|
|
PsInitIdleThread();
|
|
PsInitialiseW32Call();
|
|
}
|
|
|
|
VOID
|
|
INIT_FUNCTION
|
|
PsInitThreadManagment(VOID)
|
|
/*
|
|
* FUNCTION: Initialize thread managment
|
|
*/
|
|
{
|
|
PETHREAD FirstThread;
|
|
ULONG i;
|
|
|
|
for (i=0; i < MAXIMUM_PRIORITY; i++)
|
|
{
|
|
InitializeListHead(&PriorityListHead[i]);
|
|
}
|
|
|
|
PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
|
|
|
|
PsThreadType->Tag = TAG('T', 'H', 'R', 'T');
|
|
PsThreadType->TotalObjects = 0;
|
|
PsThreadType->TotalHandles = 0;
|
|
PsThreadType->PeakObjects = 0;
|
|
PsThreadType->PeakHandles = 0;
|
|
PsThreadType->PagedPoolCharge = 0;
|
|
PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);
|
|
PsThreadType->Mapping = &PiThreadMapping;
|
|
PsThreadType->Dump = NULL;
|
|
PsThreadType->Open = NULL;
|
|
PsThreadType->Close = NULL;
|
|
PsThreadType->Delete = PspDeleteThread;
|
|
PsThreadType->Parse = NULL;
|
|
PsThreadType->Security = NULL;
|
|
PsThreadType->QueryName = NULL;
|
|
PsThreadType->OkayToClose = NULL;
|
|
PsThreadType->Create = NULL;
|
|
PsThreadType->DuplicationNotify = NULL;
|
|
|
|
RtlInitUnicodeString(&PsThreadType->TypeName, L"Thread");
|
|
|
|
ObpCreateTypeObject(PsThreadType);
|
|
|
|
PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE);
|
|
FirstThread->Tcb.State = Running;
|
|
FirstThread->Tcb.FreezeCount = 0;
|
|
FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */
|
|
FirstThread->Tcb.Affinity = (1 << 0);
|
|
KeGetCurrentPrcb()->CurrentThread = (PVOID)FirstThread;
|
|
|
|
DPRINT("FirstThread %x\n",FirstThread);
|
|
|
|
DoneInitYet = TRUE;
|
|
|
|
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
|
|
}
|
|
|
|
VOID
|
|
INIT_FUNCTION
|
|
PsInitProcessManagment(VOID)
|
|
{
|
|
PKPROCESS KProcess;
|
|
NTSTATUS Status;
|
|
|
|
ShortPsLockDelay.QuadPart = -100LL;
|
|
PsLockTimeout.QuadPart = -10000000LL; /* one second */
|
|
/*
|
|
* Register the process object type
|
|
*/
|
|
|
|
PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
|
|
|
PsProcessType->Tag = TAG('P', 'R', 'O', 'C');
|
|
PsProcessType->TotalObjects = 0;
|
|
PsProcessType->TotalHandles = 0;
|
|
PsProcessType->PeakObjects = 0;
|
|
PsProcessType->PeakHandles = 0;
|
|
PsProcessType->PagedPoolCharge = 0;
|
|
PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
|
|
PsProcessType->Mapping = &PiProcessMapping;
|
|
PsProcessType->Dump = NULL;
|
|
PsProcessType->Open = NULL;
|
|
PsProcessType->Close = NULL;
|
|
PsProcessType->Delete = PspDeleteProcess;
|
|
PsProcessType->Parse = NULL;
|
|
PsProcessType->Security = NULL;
|
|
PsProcessType->QueryName = NULL;
|
|
PsProcessType->OkayToClose = NULL;
|
|
PsProcessType->Create = NULL;
|
|
PsProcessType->DuplicationNotify = NULL;
|
|
|
|
RtlInitUnicodeString(&PsProcessType->TypeName, L"Process");
|
|
|
|
ObpCreateTypeObject(PsProcessType);
|
|
|
|
InitializeListHead(&PsActiveProcessHead);
|
|
ExInitializeFastMutex(&PspActiveProcessMutex);
|
|
|
|
/*
|
|
* Initialize the idle process
|
|
*/
|
|
Status = ObCreateObject(KernelMode,
|
|
PsProcessType,
|
|
NULL,
|
|
KernelMode,
|
|
NULL,
|
|
sizeof(EPROCESS),
|
|
0,
|
|
0,
|
|
(PVOID*)&PsIdleProcess);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Failed to create the idle process object, Status: 0x%x\n", Status);
|
|
KEBUGCHECK(0);
|
|
return;
|
|
}
|
|
|
|
RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
|
|
|
|
PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
|
|
PsIdleProcess->Pcb.IopmOffset = 0xffff;
|
|
PsIdleProcess->Pcb.LdtDescriptor[0] = 0;
|
|
PsIdleProcess->Pcb.LdtDescriptor[1] = 0;
|
|
PsIdleProcess->Pcb.BasePriority = PROCESS_PRIO_IDLE;
|
|
PsIdleProcess->Pcb.ThreadQuantum = 6;
|
|
InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead);
|
|
InitializeListHead(&PsIdleProcess->ThreadListHead);
|
|
InitializeListHead(&PsIdleProcess->ProcessListEntry);
|
|
KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.DispatcherHeader,
|
|
ProcessObject,
|
|
sizeof(EPROCESS),
|
|
FALSE);
|
|
PsIdleProcess->Pcb.DirectoryTableBase =
|
|
(LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
|
|
strcpy(PsIdleProcess->ImageFileName, "Idle");
|
|
|
|
/*
|
|
* Initialize the system process
|
|
*/
|
|
Status = ObCreateObject(KernelMode,
|
|
PsProcessType,
|
|
NULL,
|
|
KernelMode,
|
|
NULL,
|
|
sizeof(EPROCESS),
|
|
0,
|
|
0,
|
|
(PVOID*)&PsInitialSystemProcess);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Failed to create the system process object, Status: 0x%x\n", Status);
|
|
KEBUGCHECK(0);
|
|
return;
|
|
}
|
|
|
|
/* System threads may run on any processor. */
|
|
PsInitialSystemProcess->Pcb.Affinity = 0xFFFFFFFF;
|
|
PsInitialSystemProcess->Pcb.IopmOffset = 0xffff;
|
|
PsInitialSystemProcess->Pcb.LdtDescriptor[0] = 0;
|
|
PsInitialSystemProcess->Pcb.LdtDescriptor[1] = 0;
|
|
PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIO_NORMAL;
|
|
PsInitialSystemProcess->Pcb.ThreadQuantum = 6;
|
|
InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead);
|
|
KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.DispatcherHeader,
|
|
ProcessObject,
|
|
sizeof(EPROCESS),
|
|
FALSE);
|
|
KProcess = &PsInitialSystemProcess->Pcb;
|
|
|
|
MmInitializeAddressSpace(PsInitialSystemProcess,
|
|
&PsInitialSystemProcess->AddressSpace);
|
|
|
|
KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
|
|
PsInitialSystemProcess->LockCount = 0;
|
|
PsInitialSystemProcess->LockOwner = NULL;
|
|
|
|
#if defined(__GNUC__)
|
|
KProcess->DirectoryTableBase =
|
|
(LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
|
|
#else
|
|
{
|
|
LARGE_INTEGER dummy;
|
|
dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory();
|
|
KProcess->DirectoryTableBase = dummy;
|
|
}
|
|
#endif
|
|
|
|
strcpy(PsInitialSystemProcess->ImageFileName, "System");
|
|
|
|
PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
|
|
|
|
InsertHeadList(&PsActiveProcessHead,
|
|
&PsInitialSystemProcess->ProcessListEntry);
|
|
InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
|
|
|
|
#ifndef SCHED_REWRITE
|
|
PTOKEN BootToken;
|
|
|
|
/* No parent, this is the Initial System Process. Assign Boot Token */
|
|
BootToken = SepCreateSystemProcessToken();
|
|
BootToken->TokenInUse = TRUE;
|
|
PsInitialSystemProcess->Token = BootToken;
|
|
ObReferenceObject(BootToken);
|
|
#endif
|
|
}
|
|
|
|
VOID
|
|
PspPostInitSystemProcess(VOID)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
/* this routine is called directly after the exectuive handle tables were
|
|
initialized. We'll set up the Client ID handle table and assign the system
|
|
process a PID */
|
|
PsInitClientIDManagment();
|
|
|
|
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
|
|
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
|
|
|
|
Status = PsCreateCidHandle(PsInitialSystemProcess,
|
|
PsProcessType,
|
|
&PsInitialSystemProcess->UniqueProcessId);
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Failed to create CID handle (unique process id) for the system process!\n");
|
|
KEBUGCHECK(0);
|
|
}
|
|
}
|
|
/**********************************************************************
|
|
* NAME EXPORTED
|
|
* PsGetVersion
|
|
*
|
|
* DESCRIPTION
|
|
* Retrieves the current OS version.
|
|
*
|
|
* ARGUMENTS
|
|
* MajorVersion Pointer to a variable that will be set to the
|
|
* major version of the OS. Can be NULL.
|
|
*
|
|
* MinorVersion Pointer to a variable that will be set to the
|
|
* minor version of the OS. Can be NULL.
|
|
*
|
|
* BuildNumber Pointer to a variable that will be set to the
|
|
* build number of the OS. Can be NULL.
|
|
*
|
|
* CSDVersion Pointer to a variable that will be set to the
|
|
* CSD string of the OS. Can be NULL.
|
|
*
|
|
* RETURN VALUE
|
|
* TRUE OS is a checked build.
|
|
* FALSE OS is a free build.
|
|
*
|
|
* NOTES
|
|
*
|
|
* @implemented
|
|
*/
|
|
BOOLEAN
|
|
STDCALL
|
|
PsGetVersion(PULONG MajorVersion OPTIONAL,
|
|
PULONG MinorVersion OPTIONAL,
|
|
PULONG BuildNumber OPTIONAL,
|
|
PUNICODE_STRING CSDVersion OPTIONAL)
|
|
{
|
|
if (MajorVersion)
|
|
*MajorVersion = NtMajorVersion;
|
|
|
|
if (MinorVersion)
|
|
*MinorVersion = NtMinorVersion;
|
|
|
|
if (BuildNumber)
|
|
*BuildNumber = NtBuildNumber;
|
|
|
|
if (CSDVersion)
|
|
{
|
|
CSDVersion->Length = 0;
|
|
CSDVersion->MaximumLength = 0;
|
|
CSDVersion->Buffer = NULL;
|
|
#if 0
|
|
CSDVersion->Length = CmCSDVersionString.Length;
|
|
CSDVersion->MaximumLength = CmCSDVersionString.Maximum;
|
|
CSDVersion->Buffer = CmCSDVersionString.Buffer;
|
|
#endif
|
|
}
|
|
|
|
/* Check the High word */
|
|
return (NtBuildNumber >> 28) == 0xC;
|
|
}
|
|
|
|
/* EOF */
|