2005-01-06 13:58:04 +00:00
|
|
|
/* $Id$
|
2000-06-03 21:36:32 +00:00
|
|
|
*
|
2005-01-26 13:58:37 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/ps/psmgr.c
|
|
|
|
* PURPOSE: Process management
|
2005-05-09 01:38:29 +00:00
|
|
|
*
|
2005-01-26 13:58:37 +00:00
|
|
|
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
1998-08-25 04:27:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES **************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2001-05-01 23:08:21 +00:00
|
|
|
#define NDEBUG
|
1999-11-24 11:51:55 +00:00
|
|
|
#include <internal/debug.h>
|
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
extern LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
|
2005-04-18 04:46:06 +00:00
|
|
|
extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
|
2005-04-18 02:12:30 +00:00
|
|
|
|
|
|
|
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 |
|
2005-05-09 01:38:29 +00:00
|
|
|
PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
|
2005-04-29 16:41:52 +00:00
|
|
|
PROCESS_SUSPEND_RESUME,
|
2005-04-18 02:12:30 +00:00
|
|
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
|
|
|
PROCESS_ALL_ACCESS};
|
|
|
|
|
2005-04-18 04:46:06 +00:00
|
|
|
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};
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 05:47:13 +00:00
|
|
|
extern ULONG NtBuildNumber;
|
|
|
|
extern ULONG NtMajorVersion;
|
|
|
|
extern ULONG NtMinorVersion;
|
2005-08-05 03:44:24 +00:00
|
|
|
extern PVOID KeUserApcDispatcher;
|
|
|
|
extern PVOID KeUserCallbackDispatcher;
|
|
|
|
extern PVOID KeUserExceptionDispatcher;
|
|
|
|
extern PVOID KeRaiseUserExceptionDispatcher;
|
|
|
|
|
|
|
|
PVOID PspSystemDllBase = NULL;
|
|
|
|
PVOID PspSystemDllSection = NULL;
|
|
|
|
PVOID PspSystemDllEntryPoint = NULL;
|
2005-04-18 05:47:13 +00:00
|
|
|
|
2005-05-09 01:38:29 +00:00
|
|
|
VOID
|
2005-04-18 02:12:30 +00:00
|
|
|
INIT_FUNCTION
|
|
|
|
PsInitClientIDManagment(VOID);
|
|
|
|
|
|
|
|
VOID STDCALL PspKillMostProcesses();
|
2005-04-22 12:52:25 +00:00
|
|
|
|
1998-08-25 04:27:26 +00:00
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
1999-11-24 11:51:55 +00:00
|
|
|
VOID PiShutdownProcessManager(VOID)
|
|
|
|
{
|
2004-08-10 07:25:49 +00:00
|
|
|
DPRINT("PiShutdownProcessManager()\n");
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
PspKillMostProcesses();
|
1999-11-24 11:51:55 +00:00
|
|
|
}
|
|
|
|
|
2003-10-12 17:05:50 +00:00
|
|
|
VOID INIT_FUNCTION
|
|
|
|
PiInitProcessManager(VOID)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2004-09-22 22:31:46 +00:00
|
|
|
PsInitJobManagment();
|
1998-09-13 15:55:55 +00:00
|
|
|
PsInitProcessManagment();
|
1998-08-25 04:27:26 +00:00
|
|
|
PsInitThreadManagment();
|
1998-09-05 17:34:23 +00:00
|
|
|
PsInitIdleThread();
|
2003-07-23 19:13:37 +00:00
|
|
|
PsInitialiseW32Call();
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
2000-06-03 21:36:32 +00:00
|
|
|
|
2005-05-09 01:38:29 +00:00
|
|
|
VOID
|
2005-04-18 04:46:06 +00:00
|
|
|
INIT_FUNCTION
|
|
|
|
PsInitThreadManagment(VOID)
|
|
|
|
/*
|
|
|
|
* FUNCTION: Initialize thread managment
|
|
|
|
*/
|
|
|
|
{
|
2005-05-15 17:59:33 +00:00
|
|
|
UNICODE_STRING Name;
|
|
|
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
2005-04-18 04:46:06 +00:00
|
|
|
PETHREAD FirstThread;
|
|
|
|
ULONG i;
|
|
|
|
|
|
|
|
for (i=0; i < MAXIMUM_PRIORITY; i++)
|
|
|
|
{
|
|
|
|
InitializeListHead(&PriorityListHead[i]);
|
|
|
|
}
|
|
|
|
|
2005-05-21 16:33:23 +00:00
|
|
|
DPRINT("Creating Thread Object Type\n");
|
2005-05-15 17:59:33 +00:00
|
|
|
|
|
|
|
/* Initialize the Thread type */
|
|
|
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
|
|
|
RtlInitUnicodeString(&Name, L"Thread");
|
|
|
|
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
|
|
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETHREAD);
|
|
|
|
ObjectTypeInitializer.GenericMapping = PiThreadMapping;
|
|
|
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
|
|
|
ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
|
|
|
|
ObjectTypeInitializer.DeleteProcedure = PspDeleteThread;
|
|
|
|
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &PsThreadType);
|
2005-04-18 04:46:06 +00:00
|
|
|
|
2005-04-22 12:52:25 +00:00
|
|
|
PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE);
|
2005-04-18 15:49:57 +00:00
|
|
|
FirstThread->Tcb.State = Running;
|
2005-04-18 04:46:06 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
|
|
|
|
}
|
|
|
|
|
2005-05-09 01:38:29 +00:00
|
|
|
VOID
|
2005-04-18 02:12:30 +00:00
|
|
|
INIT_FUNCTION
|
|
|
|
PsInitProcessManagment(VOID)
|
|
|
|
{
|
|
|
|
PKPROCESS KProcess;
|
|
|
|
NTSTATUS Status;
|
2005-05-15 17:59:33 +00:00
|
|
|
UNICODE_STRING Name;
|
|
|
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
ShortPsLockDelay.QuadPart = -100LL;
|
|
|
|
PsLockTimeout.QuadPart = -10000000LL; /* one second */
|
|
|
|
/*
|
|
|
|
* Register the process object type
|
|
|
|
*/
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-05-21 16:33:23 +00:00
|
|
|
DPRINT("Creating Process Object Type\n");
|
2005-05-15 17:59:33 +00:00
|
|
|
|
2005-08-01 11:20:44 +00:00
|
|
|
/* Initialize the Process type */
|
|
|
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
|
|
|
RtlInitUnicodeString(&Name, L"Process");
|
|
|
|
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
|
|
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EPROCESS);
|
|
|
|
ObjectTypeInitializer.GenericMapping = PiProcessMapping;
|
|
|
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
|
|
|
ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
|
|
|
|
ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess;
|
|
|
|
ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &PsProcessType);
|
2005-04-18 02:12:30 +00:00
|
|
|
|
|
|
|
InitializeListHead(&PsActiveProcessHead);
|
|
|
|
ExInitializeFastMutex(&PspActiveProcessMutex);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-08-01 11:20:44 +00:00
|
|
|
/*
|
|
|
|
* Initialize the default quota block.
|
|
|
|
*/
|
|
|
|
|
|
|
|
RtlZeroMemory(&PspDefaultQuotaBlock, sizeof(PspDefaultQuotaBlock));
|
|
|
|
PspDefaultQuotaBlock.QuotaEntry[PagedPool].Limit = (SIZE_T)-1;
|
|
|
|
PspDefaultQuotaBlock.QuotaEntry[NonPagedPool].Limit = (SIZE_T)-1;
|
|
|
|
PspDefaultQuotaBlock.QuotaEntry[2].Limit = (SIZE_T)-1; /* Page file */
|
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/*
|
|
|
|
* 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));
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
|
|
|
|
PsIdleProcess->Pcb.IopmOffset = 0xffff;
|
|
|
|
PsIdleProcess->Pcb.BasePriority = PROCESS_PRIO_IDLE;
|
2005-05-05 22:40:05 +00:00
|
|
|
PsIdleProcess->Pcb.QuantumReset = 6;
|
2005-04-18 02:12:30 +00:00
|
|
|
InitializeListHead(&PsIdleProcess->Pcb.ThreadListHead);
|
|
|
|
InitializeListHead(&PsIdleProcess->ThreadListHead);
|
2005-05-06 22:54:40 +00:00
|
|
|
InitializeListHead(&PsIdleProcess->ActiveProcessLinks);
|
2005-05-05 22:40:05 +00:00
|
|
|
KeInitializeDispatcherHeader(&PsIdleProcess->Pcb.Header,
|
2005-04-18 02:12:30 +00:00
|
|
|
ProcessObject,
|
|
|
|
sizeof(EPROCESS),
|
|
|
|
FALSE);
|
2005-06-21 23:42:58 +00:00
|
|
|
PsIdleProcess->Pcb.DirectoryTableBase.QuadPart = (ULONG_PTR)MmGetPageDirectory();
|
2005-04-18 02:12:30 +00:00
|
|
|
strcpy(PsIdleProcess->ImageFileName, "Idle");
|
2005-08-01 11:20:44 +00:00
|
|
|
PspInheritQuota(PsIdleProcess, NULL);
|
2000-06-03 21:36:32 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* System threads may run on any processor. */
|
2005-05-05 22:40:05 +00:00
|
|
|
RtlZeroMemory(PsInitialSystemProcess, sizeof(EPROCESS));
|
2005-04-18 02:12:30 +00:00
|
|
|
PsInitialSystemProcess->Pcb.Affinity = 0xFFFFFFFF;
|
|
|
|
PsInitialSystemProcess->Pcb.IopmOffset = 0xffff;
|
|
|
|
PsInitialSystemProcess->Pcb.BasePriority = PROCESS_PRIO_NORMAL;
|
2005-05-05 22:40:05 +00:00
|
|
|
PsInitialSystemProcess->Pcb.QuantumReset = 6;
|
2005-04-18 02:12:30 +00:00
|
|
|
InitializeListHead(&PsInitialSystemProcess->Pcb.ThreadListHead);
|
2005-05-05 22:40:05 +00:00
|
|
|
KeInitializeDispatcherHeader(&PsInitialSystemProcess->Pcb.Header,
|
2005-04-18 02:12:30 +00:00
|
|
|
ProcessObject,
|
|
|
|
sizeof(EPROCESS),
|
|
|
|
FALSE);
|
|
|
|
KProcess = &PsInitialSystemProcess->Pcb;
|
2005-08-01 11:20:44 +00:00
|
|
|
PspInheritQuota(PsInitialSystemProcess, NULL);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
MmInitializeAddressSpace(PsInitialSystemProcess,
|
|
|
|
&PsInitialSystemProcess->AddressSpace);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
2005-05-09 01:38:29 +00:00
|
|
|
KProcess->DirectoryTableBase =
|
2005-04-18 02:12:30 +00:00
|
|
|
(LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
LARGE_INTEGER dummy;
|
|
|
|
dummy.QuadPart = (LONGLONG)(ULONG)MmGetPageDirectory();
|
|
|
|
KProcess->DirectoryTableBase = dummy;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
strcpy(PsInitialSystemProcess->ImageFileName, "System");
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
InsertHeadList(&PsActiveProcessHead,
|
2005-05-06 22:54:40 +00:00
|
|
|
&PsInitialSystemProcess->ActiveProcessLinks);
|
2005-04-18 02:12:30 +00:00
|
|
|
InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
#ifndef SCHED_REWRITE
|
2005-06-21 23:42:58 +00:00
|
|
|
{
|
2005-04-18 02:12:30 +00:00
|
|
|
PTOKEN BootToken;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* No parent, this is the Initial System Process. Assign Boot Token */
|
|
|
|
BootToken = SepCreateSystemProcessToken();
|
|
|
|
BootToken->TokenInUse = TRUE;
|
2005-05-06 22:54:40 +00:00
|
|
|
PsInitialSystemProcess->Token.Object = BootToken; /* FIXME */
|
2005-04-18 02:12:30 +00:00
|
|
|
ObReferenceObject(BootToken);
|
2005-06-21 23:42:58 +00:00
|
|
|
}
|
2005-04-18 02:12:30 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
PspPostInitSystemProcess(VOID)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
/* 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();
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
|
|
|
|
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-18 02:12:30 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2005-08-05 03:44:24 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
INIT_FUNCTION
|
|
|
|
PspLookupKernelUserEntryPoints(VOID)
|
|
|
|
{
|
|
|
|
ANSI_STRING ProcedureName;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Retrieve ntdll's startup address */
|
|
|
|
DPRINT("Getting Entrypoint: %p\n", PspSystemDllBase);
|
|
|
|
RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk");
|
|
|
|
Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase,
|
|
|
|
&ProcedureName,
|
|
|
|
0,
|
|
|
|
&PspSystemDllEntryPoint);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get User APC Dispatcher */
|
|
|
|
DPRINT("Getting Entrypoint\n");
|
|
|
|
RtlInitAnsiString(&ProcedureName, "KiUserApcDispatcher");
|
|
|
|
Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase,
|
|
|
|
&ProcedureName,
|
|
|
|
0,
|
|
|
|
&KeUserApcDispatcher);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get Exception Dispatcher */
|
|
|
|
DPRINT("Getting Entrypoint\n");
|
|
|
|
RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher");
|
|
|
|
Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase,
|
|
|
|
&ProcedureName,
|
|
|
|
0,
|
|
|
|
&KeUserExceptionDispatcher);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get Callback Dispatcher */
|
|
|
|
DPRINT("Getting Entrypoint\n");
|
|
|
|
RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher");
|
|
|
|
Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase,
|
|
|
|
&ProcedureName,
|
|
|
|
0,
|
|
|
|
&KeUserCallbackDispatcher);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get Raise Exception Dispatcher */
|
|
|
|
DPRINT("Getting Entrypoint\n");
|
|
|
|
RtlInitAnsiString(&ProcedureName, "KiRaiseUserExceptionDispatcher");
|
|
|
|
Status = LdrGetProcedureAddress((PVOID)PspSystemDllBase,
|
|
|
|
&ProcedureName,
|
|
|
|
0,
|
|
|
|
&KeRaiseUserExceptionDispatcher);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
PspMapSystemDll(PEPROCESS Process,
|
|
|
|
PVOID *DllBase)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG ViewSize = 0;
|
|
|
|
PVOID ImageBase = 0;
|
|
|
|
|
|
|
|
/* Map the System DLL */
|
|
|
|
DPRINT("Mapping System DLL\n");
|
|
|
|
Status = MmMapViewOfSection(PspSystemDllSection,
|
|
|
|
Process,
|
|
|
|
(PVOID*)&ImageBase,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
&ViewSize,
|
|
|
|
0,
|
|
|
|
MEM_COMMIT,
|
|
|
|
PAGE_READWRITE);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1("Failed to map System DLL Into Process\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DllBase) *DllBase = ImageBase;
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
INIT_FUNCTION
|
|
|
|
PsLocateSystemDll(VOID)
|
|
|
|
{
|
|
|
|
UNICODE_STRING DllPathname = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll");
|
|
|
|
OBJECT_ATTRIBUTES FileObjectAttributes;
|
|
|
|
IO_STATUS_BLOCK Iosb;
|
|
|
|
HANDLE FileHandle;
|
|
|
|
HANDLE NTDllSectionHandle;
|
|
|
|
NTSTATUS Status;
|
|
|
|
CHAR BlockBuffer[1024];
|
|
|
|
PIMAGE_DOS_HEADER DosHeader;
|
|
|
|
PIMAGE_NT_HEADERS NTHeaders;
|
|
|
|
|
|
|
|
/* Locate and open NTDLL to determine ImageBase and LdrStartup */
|
|
|
|
InitializeObjectAttributes(&FileObjectAttributes,
|
|
|
|
&DllPathname,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
DPRINT("Opening NTDLL\n");
|
|
|
|
Status = ZwOpenFile(&FileHandle,
|
|
|
|
FILE_READ_ACCESS,
|
|
|
|
&FileObjectAttributes,
|
|
|
|
&Iosb,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
DPRINT1("NTDLL open failed (Status %x)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load NTDLL is valid */
|
|
|
|
DPRINT("Reading NTDLL\n");
|
|
|
|
Status = ZwReadFile(FileHandle,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&Iosb,
|
|
|
|
BlockBuffer,
|
|
|
|
sizeof(BlockBuffer),
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) {
|
|
|
|
|
|
|
|
DPRINT1("NTDLL header read failed (Status %x)\n", Status);
|
|
|
|
ZwClose(FileHandle);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if it's valid */
|
|
|
|
DosHeader = (PIMAGE_DOS_HEADER)BlockBuffer;
|
|
|
|
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
|
|
|
|
|
|
|
|
if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) ||
|
|
|
|
(DosHeader->e_lfanew == 0L) ||
|
|
|
|
(*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE)) {
|
|
|
|
|
|
|
|
DPRINT1("NTDLL format invalid\n");
|
|
|
|
ZwClose(FileHandle);
|
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a section for NTDLL */
|
|
|
|
DPRINT("Creating section\n");
|
|
|
|
Status = ZwCreateSection(&NTDllSectionHandle,
|
|
|
|
SECTION_ALL_ACCESS,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
PAGE_READONLY,
|
|
|
|
SEC_IMAGE | SEC_COMMIT,
|
|
|
|
FileHandle);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1("NTDLL create section failed (Status %x)\n", Status);
|
|
|
|
ZwClose(FileHandle);
|
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
ZwClose(FileHandle);
|
|
|
|
|
|
|
|
/* Reference the Section */
|
|
|
|
DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle);
|
|
|
|
Status = ObReferenceObjectByHandle(NTDllSectionHandle,
|
|
|
|
SECTION_ALL_ACCESS,
|
|
|
|
MmSectionObjectType,
|
|
|
|
KernelMode,
|
|
|
|
(PVOID*)&PspSystemDllSection,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
|
|
|
|
DPRINT1("NTDLL section reference failed (Status %x)\n", Status);
|
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Map it */
|
|
|
|
PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase);
|
|
|
|
DPRINT("LdrpSystemDllBase: %x\n", PspSystemDllBase);
|
|
|
|
|
|
|
|
/* Now get the Entrypoints */
|
|
|
|
PspLookupKernelUserEntryPoints();
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-03 21:36:32 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* 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
|
2003-07-11 01:23:16 +00:00
|
|
|
*
|
2005-04-18 05:47:13 +00:00
|
|
|
* @implemented
|
2000-06-03 21:36:32 +00:00
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
2005-04-18 05:47:13 +00:00
|
|
|
PsGetVersion(PULONG MajorVersion OPTIONAL,
|
|
|
|
PULONG MinorVersion OPTIONAL,
|
|
|
|
PULONG BuildNumber OPTIONAL,
|
|
|
|
PUNICODE_STRING CSDVersion OPTIONAL)
|
2000-06-03 21:36:32 +00:00
|
|
|
{
|
2005-04-18 05:47:13 +00:00
|
|
|
if (MajorVersion)
|
|
|
|
*MajorVersion = NtMajorVersion;
|
2000-06-03 21:36:32 +00:00
|
|
|
|
2005-04-18 05:47:13 +00:00
|
|
|
if (MinorVersion)
|
|
|
|
*MinorVersion = NtMinorVersion;
|
2000-06-03 21:36:32 +00:00
|
|
|
|
2005-04-18 05:47:13 +00:00
|
|
|
if (BuildNumber)
|
|
|
|
*BuildNumber = NtBuildNumber;
|
2000-06-03 21:36:32 +00:00
|
|
|
|
2005-04-18 05:47:13 +00:00
|
|
|
if (CSDVersion)
|
|
|
|
{
|
|
|
|
CSDVersion->Length = 0;
|
|
|
|
CSDVersion->MaximumLength = 0;
|
|
|
|
CSDVersion->Buffer = NULL;
|
2000-06-03 21:36:32 +00:00
|
|
|
#if 0
|
2005-04-18 05:47:13 +00:00
|
|
|
CSDVersion->Length = CmCSDVersionString.Length;
|
|
|
|
CSDVersion->MaximumLength = CmCSDVersionString.Maximum;
|
|
|
|
CSDVersion->Buffer = CmCSDVersionString.Buffer;
|
2000-06-03 21:36:32 +00:00
|
|
|
#endif
|
2005-04-18 05:47:13 +00:00
|
|
|
}
|
2000-06-03 21:36:32 +00:00
|
|
|
|
2005-04-18 05:47:13 +00:00
|
|
|
/* Check the High word */
|
|
|
|
return (NtBuildNumber >> 28) == 0xC;
|
2000-06-03 21:36:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|