* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/process.c
* PURPOSE: Process managment
- * PROGRAMMER: David Welch (welch@mcmail.com)
+ * PROGRAMMER: David Welch (welch@cwcom.net)
* REVISION HISTORY:
* 21/07/98: Created
*/
/* INCLUDES ******************************************************************/
#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <internal/mm.h>
+#include <internal/ke.h>
+#include <internal/ps.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/id.h>
#define NDEBUG
#include <internal/debug.h>
/* GLOBALS ******************************************************************/
-EPROCESS SystemProcess = {{0},};
+PEPROCESS SystemProcess = NULL;
HANDLE SystemProcessHandle = NULL;
+POBJECT_TYPE PsProcessType = NULL;
+
+static ULONG NextUniqueProcessId = 0;
+
/* FUNCTIONS *****************************************************************/
VOID PsInitProcessManagment(VOID)
{
- InitializeListHead(&(SystemProcess.Pcb.MemoryAreaList));
+ ANSI_STRING AnsiString;
+ PKPROCESS KProcess;
+
+ /*
+ * Register the process object type
+ */
+
+ PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+
+ PsProcessType->TotalObjects = 0;
+ PsProcessType->TotalHandles = 0;
+ PsProcessType->MaxObjects = ULONG_MAX;
+ PsProcessType->MaxHandles = ULONG_MAX;
+ PsProcessType->PagedPoolCharge = 0;
+ PsProcessType->NonpagedPoolCharge = sizeof(EPROCESS);
+ PsProcessType->Dump = NULL;
+ PsProcessType->Open = NULL;
+ PsProcessType->Close = NULL;
+ PsProcessType->Delete = PiDeleteProcess;
+ PsProcessType->Parse = NULL;
+ PsProcessType->Security = NULL;
+ PsProcessType->QueryName = NULL;
+ PsProcessType->OkayToClose = NULL;
+
+ RtlInitAnsiString(&AnsiString,"Process");
+ RtlAnsiStringToUnicodeString(&PsProcessType->TypeName,&AnsiString,TRUE);
+
+ /*
+ * Initialize the system process
+ */
+ SystemProcess = ObCreateObject(NULL,
+ PROCESS_ALL_ACCESS,
+ NULL,
+ PsProcessType);
+ KeInitializeDispatcherHeader(&SystemProcess->Pcb.DispatcherHeader,
+ ID_PROCESS_OBJECT,
+ sizeof(EPROCESS),
+ FALSE);
+ DPRINT("SystemProcess->Pcb.Type %x\n",
+ SystemProcess->Pcb.Type);
+ KProcess = &SystemProcess->Pcb;
+
+ InitializeListHead(&(KProcess->MemoryAreaList));
+ ObCreateHandleTable(NULL,FALSE,SystemProcess);
+ KProcess->PageTableDirectory = get_page_directory();
+
+ SystemProcess->UniqueProcessId = NextUniqueProcessId;
+ SystemProcess->InheritedFromUniqueProcessId = NextUniqueProcessId;
+
+ ObCreateHandle(SystemProcess,
+ SystemProcess,
+ PROCESS_ALL_ACCESS,
+ FALSE,
+ &SystemProcessHandle);
}
PKPROCESS KeGetCurrentProcess(VOID)
+/*
+ * FUNCTION: Returns a pointer to the current process
+ */
{
return(&(PsGetCurrentProcess()->Pcb));
}
* FUNCTION: Returns a pointer to the current process
*/
{
- DPRINT("PsGetCurrentProcess() = %x\n",PsGetCurrentThread()->ThreadsProcess);
- return(PsGetCurrentThread()->ThreadsProcess);
+ if (PsGetCurrentThread() == NULL ||
+ PsGetCurrentThread()->ThreadsProcess == NULL)
+ {
+ return(SystemProcess);
+ }
+ else
+ {
+ return(PsGetCurrentThread()->ThreadsProcess);
+ }
+}
+
+NTSTATUS STDCALL NtCreateProcess(
+ OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN HANDLE ParentProcessHandle,
+ IN BOOLEAN InheritObjectTable,
+ IN HANDLE SectionHandle OPTIONAL,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL)
+{
+ return(ZwCreateProcess(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ParentProcessHandle,
+ InheritObjectTable,
+ SectionHandle,
+ DebugPort,
+ ExceptionPort));
+}
+
+NTSTATUS STDCALL ZwCreateProcess(
+ OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
+ IN HANDLE ParentProcessHandle,
+ IN BOOLEAN InheritObjectTable,
+ IN HANDLE SectionHandle OPTIONAL,
+ IN HANDLE DebugPort OPTIONAL,
+ IN HANDLE ExceptionPort OPTIONAL)
+/*
+ * FUNCTION: Creates a process.
+ * ARGUMENTS:
+ * ProcessHandle (OUT) = Caller supplied storage for the resulting
+ * handle
+ * DesiredAccess = Specifies the allowed or desired access to the
+ * process can be a combination of
+ * STANDARD_RIGHTS_REQUIRED| ..
+ * ObjectAttribute = Initialized attributes for the object, contains
+ * the rootdirectory and the filename
+ * ParentProcess = Handle to the parent process.
+ * InheritObjectTable = Specifies to inherit the objects of the parent
+ * process if true.
+ * SectionHandle = Handle to a section object to back the image file
+ * DebugPort = Handle to a DebugPort if NULL the system default debug
+ * port will be used.
+ * ExceptionPort = Handle to a exception port.
+ * REMARKS:
+ * This function maps to the win32 CreateProcess.
+ * RETURNS: Status
+ */
+{
+ PEPROCESS Process;
+ PEPROCESS ParentProcess;
+ PKPROCESS KProcess;
+ NTSTATUS Status;
+
+ DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
+
+ Status = ObReferenceObjectByHandle(ParentProcessHandle,
+ PROCESS_CREATE_PROCESS,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&ParentProcess,
+ NULL);
+
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT("ZwCreateProcess() = %x\n",Status);
+ return(Status);
+ }
+
+ Process = ObCreateObject(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ PsProcessType);
+ KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader,
+ ID_PROCESS_OBJECT,
+ sizeof(EPROCESS),
+ FALSE);
+ KProcess = &(Process->Pcb);
+
+ InitializeListHead(&(KProcess->MemoryAreaList));
+ Process->UniqueProcessId = InterlockedIncrement(&NextUniqueProcessId);
+ Process->InheritedFromUniqueProcessId = ParentProcess->UniqueProcessId;
+ ObCreateHandleTable(ParentProcess,
+ InheritObjectTable,
+ Process);
+ MmCopyMmInfo(ParentProcess, Process);
+
+ /*
+ * FIXME: I don't what I'm supposed to know with a section handle
+ */
+ if (SectionHandle != NULL)
+ {
+ DbgPrint("ZwCreateProcess() non-NULL SectionHandle\n");
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ Process->Pcb.ProcessState = PROCESS_STATE_ACTIVE;
+ ObDereferenceObject(Process);
+ ObDereferenceObject(ParentProcess);
+ return(STATUS_SUCCESS);
}
+
+NTSTATUS STDCALL NtOpenProcess (OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
+{
+ return(ZwOpenProcess(ProcessHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ClientId));
+}
+
+NTSTATUS STDCALL ZwOpenProcess (OUT PHANDLE ProcessHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtQueryInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength)
+{
+ return(ZwQueryInformationProcess(ProcessHandle,
+ ProcessInformationClass,
+ ProcessInformation,
+ ProcessInformationLength,
+ ReturnLength));
+}
+
+NTSTATUS STDCALL ZwQueryInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength)
+{
+ PEPROCESS Process;
+ NTSTATUS Status;
+ PPROCESS_BASIC_INFORMATION ProcessBasicInformationP;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_SET_INFORMATION,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&Process,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ switch (ProcessInformationClass)
+ {
+ case ProcessBasicInformation:
+ ProcessBasicInformationP = (PPROCESS_BASIC_INFORMATION)
+ ProcessInformation;
+ memset(ProcessBasicInformationP, 0, sizeof(PROCESS_BASIC_INFORMATION));
+ ProcessBasicInformationP->AffinityMask = Process->Pcb.Affinity;
+ ProcessBasicInformationP->UniqueProcessId =
+ Process->UniqueProcessId;
+ ProcessBasicInformationP->InheritedFromUniqueProcessId =
+ Process->InheritedFromUniqueProcessId;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case ProcessQuotaLimits:
+ case ProcessIoCounters:
+ case ProcessVmCounters:
+ case ProcessTimes:
+ case ProcessBasePriority:
+ case ProcessRaisePriority:
+ case ProcessDebugPort:
+ case ProcessExceptionPort:
+ case ProcessAccessToken:
+ case ProcessLdtInformation:
+ case ProcessLdtSize:
+ case ProcessDefaultHardErrorMode:
+ case ProcessIoPortHandlers:
+ case ProcessWorkingSetWatch:
+ case ProcessUserModeIOPL:
+ case ProcessEnableAlignmentFaultFixup:
+ case ProcessPriorityClass:
+ case ProcessWx86Information:
+ case ProcessHandleCount:
+ case ProcessAffinityMask:
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ ObDereferenceObject(Process);
+ return(Status);
+}
+
+NTSTATUS STDCALL NtSetInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength)
+{
+ return(ZwSetInformationProcess(ProcessHandle,
+ ProcessInformationClass,
+ ProcessInformation,
+ ProcessInformationLength));
+}
+
+NTSTATUS STDCALL ZwSetInformationProcess(IN HANDLE ProcessHandle,
+ IN CINT ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength)
+{
+ PEPROCESS Process;
+ NTSTATUS Status;
+ PPROCESS_BASIC_INFORMATION ProcessBasicInformationP;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_SET_INFORMATION,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&Process,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ switch (ProcessInformationClass)
+ {
+ case ProcessBasicInformation:
+ ProcessBasicInformationP = (PPROCESS_BASIC_INFORMATION)
+ ProcessInformation;
+ memset(ProcessBasicInformationP, 0, sizeof(PROCESS_BASIC_INFORMATION));
+ Process->Pcb.Affinity = ProcessBasicInformationP->AffinityMask;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case ProcessQuotaLimits:
+ case ProcessIoCounters:
+ case ProcessVmCounters:
+ case ProcessTimes:
+ case ProcessBasePriority:
+ case ProcessRaisePriority:
+ case ProcessDebugPort:
+ case ProcessExceptionPort:
+ case ProcessAccessToken:
+ case ProcessLdtInformation:
+ case ProcessLdtSize:
+ case ProcessDefaultHardErrorMode:
+ case ProcessIoPortHandlers:
+ case ProcessWorkingSetWatch:
+ case ProcessUserModeIOPL:
+ case ProcessEnableAlignmentFaultFixup:
+ case ProcessPriorityClass:
+ case ProcessWx86Information:
+ case ProcessHandleCount:
+ case ProcessAffinityMask:
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ ObDereferenceObject(Process);
+ return(Status);
+}