Added process ids.
[reactos.git] / reactos / ntoskrnl / ps / process.c
index eb363ad..fd4def4 100644 (file)
@@ -3,7 +3,7 @@
  * 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));
 }
@@ -37,7 +104,280 @@ struct _EPROCESS* PsGetCurrentProcess(VOID)
  * 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);
+}