Do always dereference the section object if it was created (in PspCreateProcess).
[reactos.git] / reactos / ntoskrnl / ps / process.c
index d78ada4..df3993d 100644 (file)
@@ -30,6 +30,7 @@ LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
 /* INTERNAL FUNCTIONS *****************************************************************/
 
 NTSTATUS
+NTAPI
 PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
 {
   ULONG Attempts = 0;
@@ -88,6 +89,7 @@ PsLockProcess(PEPROCESS Process, BOOLEAN Timeout)
 }
 
 VOID
+NTAPI
 PsUnlockProcess(PEPROCESS Process)
 {
   PAGED_CODE();
@@ -181,8 +183,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
                  IN HANDLE ExceptionPort  OPTIONAL)
 {
     HANDLE hProcess;
-    PEPROCESS Process;
-    PEPROCESS pParentProcess;
+    PEPROCESS Process = NULL;
+    PEPROCESS pParentProcess = NULL;
     PEPORT pDebugPort = NULL;
     PEPORT pExceptionPort = NULL;
     PSECTION_OBJECT SectionObject = NULL;
@@ -192,6 +194,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     KAFFINITY Affinity;
     HANDLE_TABLE_ENTRY CidEntry;
     DirectoryTableBase.QuadPart = (ULONGLONG)0;
+    BOOLEAN ProcessCreated = FALSE;
 
     DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
 
@@ -208,7 +211,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
-            return(Status);
+            goto Cleanup;
         }
 
         /* Inherit Parent process's Affinity. */
@@ -218,7 +221,14 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     else
     {
         pParentProcess = NULL;
+#ifdef CONFIG_SMP        
+   /* FIXME:
+    *   Only the boot cpu is initialized in the early boot phase. 
+    */
+        Affinity = 0xffffffff;
+#else
         Affinity = KeActiveProcessors;
+#endif
     }
 
     /* Add the debug port */
@@ -233,7 +243,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
         if (!NT_SUCCESS(Status))
         {
                 DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
-                goto exitdereferenceobjects;
+                goto Cleanup;
         }
     }
 
@@ -250,7 +260,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
-            goto exitdereferenceobjects;
+            goto Cleanup;
         }
     }
 
@@ -258,7 +268,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     if (SectionHandle != NULL)
     {
         Status = ObReferenceObjectByHandle(SectionHandle,
-                                           0,
+                                           SECTION_MAP_EXECUTE,
                                            MmSectionObjectType,
                                            PreviousMode,
                                            (PVOID*)&SectionObject,
@@ -266,7 +276,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to reference process image section: Status: 0x%x\n", Status);
-            goto exitdereferenceobjects;
+            goto Cleanup;
         }
     }
 
@@ -285,7 +295,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
-        goto exitdereferenceobjects;
+        goto Cleanup;
     }
 
     /* Clean up the Object */
@@ -331,7 +341,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     /* Now initialize the Kernel Process */
     DPRINT("Initialzing Kernel Process\n");
     KeInitializeProcess(&Process->Pcb,
-                        PROCESS_PRIO_NORMAL,
+                        PROCESS_PRIORITY_NORMAL,
                         Affinity,
                         DirectoryTableBase);
 
@@ -341,8 +351,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     if (!NT_SUCCESS(Status))
     {
         DbgPrint("PspInitializeProcessSecurity failed (Status %x)\n", Status);
-        ObDereferenceObject(Process);
-        goto exitdereferenceobjects;
+        goto Cleanup;
     }
 
     /* Create the Process' Address Space */
@@ -351,8 +360,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to create Address Space\n");
-        ObDereferenceObject(Process);
-        goto exitdereferenceobjects;
+        goto Cleanup;
     }
 
     if (SectionObject)
@@ -371,8 +379,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     if(!Process->UniqueProcessId)
     {
         DPRINT1("Failed to create CID handle\n");
-        ObDereferenceObject(Process);
-        goto exitdereferenceobjects;
+        Status = STATUS_UNSUCCESSFUL; /* FIXME - what error should we return? */
+        goto Cleanup;
     }
 
     /* FIXME: Insert into Job Object */
@@ -385,13 +393,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
         if (!NT_SUCCESS(Status))
         {
             DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
-            ObDereferenceObject(Process);
-            goto exitdereferenceobjects;
+            goto Cleanup;
         }
-
-        /* Let's take advantage of this time to kill the reference too */
-        ObDereferenceObject(pParentProcess);
-        pParentProcess = NULL;
     }
 
     /* W00T! The process can now be activated */
@@ -399,6 +402,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
     ExAcquireFastMutex(&PspActiveProcessMutex);
     InsertTailList(&PsActiveProcessHead, &Process->ActiveProcessLinks);
     ExReleaseFastMutex(&PspActiveProcessMutex);
+    
+    ProcessCreated = TRUE;
 
     /* FIXME: SeCreateAccessStateEx */
 
@@ -410,37 +415,35 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
                             0,
                             NULL,
                             &hProcess);
-    if (!NT_SUCCESS(Status))
+    if (NT_SUCCESS(Status))
     {
-       DPRINT1("Could not get a handle to the Process Object\n");
-       ObDereferenceObject(Process);
-       goto exitdereferenceobjects;
-    }
+        /* Set the Creation Time */
+        KeQuerySystemTime(&Process->CreateTime);
 
-    /* Set the Creation Time */
-    KeQuerySystemTime(&Process->CreateTime);
+        DPRINT("Done. Returning handle: %x\n", hProcess);
+        _SEH_TRY
+        {
+           *ProcessHandle = hProcess;
+        }
+        _SEH_HANDLE
+        {
+           Status = _SEH_GetExceptionCode();
+        } _SEH_END;
+        /* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
+                  SeAccessCheck
+        */
+    }
 
-    DPRINT("Done. Returning handle: %x\n", hProcess);
-    _SEH_TRY
+Cleanup:
+    if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
+    if(SectionObject != NULL) ObDereferenceObject(SectionObject);
+    if (!ProcessCreated)
     {
-       *ProcessHandle = hProcess;
+        if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
+        if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
+        if(Process != NULL) ObDereferenceObject(Process);
     }
-    _SEH_HANDLE
-    {
-       Status = _SEH_GetExceptionCode();
-    } _SEH_END;
 
-    /* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
-              SeAccessCheck
-    */
-    ObDereferenceObject(Process);
-    return Status;
-
-exitdereferenceobjects:
-    if(SectionObject != NULL) ObDereferenceObject(SectionObject);
-    if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
-    if(pDebugPort != NULL) ObDereferenceObject(pDebugPort);
-    if(pParentProcess != NULL) ObDereferenceObject(pParentProcess);
     return Status;
 }
 
@@ -477,6 +480,8 @@ PsLookupProcessByProcessId(IN HANDLE ProcessId,
     PEPROCESS FoundProcess;
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
     PAGED_CODE();
+    
+    KeEnterCriticalRegion();
 
     /* Get the CID Handle Entry */
     if ((CidEntry = ExMapHandleToPointer(PspCidTable,
@@ -497,6 +502,8 @@ PsLookupProcessByProcessId(IN HANDLE ProcessId,
         /* Unlock the Entry */
         ExUnlockHandleTableEntry(PspCidTable, CidEntry);
     }
+    
+    KeLeaveCriticalRegion();
 
     /* Return to caller */
     return Status;
@@ -515,6 +522,8 @@ PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
     PETHREAD FoundThread;
     NTSTATUS Status = STATUS_INVALID_CID;
     PAGED_CODE();
+    
+    KeEnterCriticalRegion();
 
     /* Get the CID Handle Entry */
     if ((CidEntry = ExMapHandleToPointer(PspCidTable,
@@ -544,6 +553,8 @@ PsLookupProcessThreadByCid(IN PCLIENT_ID Cid,
         /* Unlock the Entry */
         ExUnlockHandleTableEntry(PspCidTable, CidEntry);
     }
+    
+    KeLeaveCriticalRegion();
 
     /* Return to caller */
     return Status;
@@ -872,9 +883,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
     {
         _SEH_TRY
         {
-            ProbeForWrite(ProcessHandle,
-                          sizeof(HANDLE),
-                          sizeof(ULONG));
+            ProbeForWriteHandle(ProcessHandle);
         }
         _SEH_HANDLE
         {
@@ -918,21 +927,67 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
               IN  POBJECT_ATTRIBUTES ObjectAttributes,
               IN  PCLIENT_ID ClientId)
 {
-    KPROCESSOR_MODE PreviousMode  = ExGetPreviousMode();
-    NTSTATUS Status = STATUS_INVALID_PARAMETER;
-    PEPROCESS Process;
+    KPROCESSOR_MODE PreviousMode;
+    CLIENT_ID SafeClientId;
+    ULONG Attributes = 0;
+    HANDLE hProcess;
+    BOOLEAN HasObjectName = FALSE;
     PETHREAD Thread = NULL;
-
-    DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
-           "ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
-           ProcessHandle, DesiredAccess, ObjectAttributes, ClientId,
-           ClientId->UniqueProcess, ClientId->UniqueThread);
+    PEPROCESS Process = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     PAGED_CODE();
 
+    PreviousMode = KeGetPreviousMode();
+
+    /* Probe the paraemeters */
+    if(PreviousMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            ProbeForWriteHandle(ProcessHandle);
+
+            if(ClientId != NULL)
+            {
+                ProbeForRead(ClientId,
+                             sizeof(CLIENT_ID),
+                             sizeof(ULONG));
+
+                SafeClientId = *ClientId;
+                ClientId = &SafeClientId;
+            }
+
+            /* just probe the object attributes structure, don't capture it
+               completely. This is done later if necessary */
+            ProbeForRead(ObjectAttributes,
+                         sizeof(OBJECT_ATTRIBUTES),
+                         sizeof(ULONG));
+            HasObjectName = (ObjectAttributes->ObjectName != NULL);
+            Attributes = ObjectAttributes->Attributes;
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    else
+    {
+        HasObjectName = (ObjectAttributes->ObjectName != NULL);
+        Attributes = ObjectAttributes->Attributes;
+    }
+
+    if (HasObjectName && ClientId != NULL)
+    {
+        /* can't pass both, n object name and a client id */
+        return STATUS_INVALID_PARAMETER_MIX;
+    }
+
     /* Open by name if one was given */
     DPRINT("Checking type\n");
-    if (ObjectAttributes->ObjectName)
+    if (HasObjectName)
     {
         /* Open it */
         DPRINT("Opening by name\n");
@@ -942,18 +997,14 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
                                     PreviousMode,
                                     DesiredAccess,
                                     NULL,
-                                    ProcessHandle);
+                                    &hProcess);
 
-        if (Status != STATUS_SUCCESS)
+        if (!NT_SUCCESS(Status))
         {
             DPRINT1("Could not open object by name\n");
         }
-
-        /* Return Status */
-        DPRINT("Found: %x\n", ProcessHandle);
-        return(Status);
     }
-    else if (ClientId)
+    else if (ClientId != NULL)
     {
         /* Open by Thread ID */
         if (ClientId->UniqueThread)
@@ -963,7 +1014,6 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
             Status = PsLookupProcessThreadByCid(ClientId,
                                                 &Process,
                                                 &Thread);
-            DPRINT("Found: %x\n", Process);
         }
         else
         {
@@ -971,7 +1021,6 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
             DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess);
             Status = PsLookupProcessByProcessId(ClientId->UniqueProcess,
                                                 &Process);
-            DPRINT("Found: %x\n", Process);
         }
 
         if(!NT_SUCCESS(Status))
@@ -982,12 +1031,12 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
 
         /* Open the Process Object */
         Status = ObOpenObjectByPointer(Process,
-                                       ObjectAttributes->Attributes,
+                                       Attributes,
                                        NULL,
                                        DesiredAccess,
                                        PsProcessType,
                                        PreviousMode,
-                                       ProcessHandle);
+                                       &hProcess);
         if(!NT_SUCCESS(Status))
         {
             DPRINT1("Failure to open process\n");
@@ -999,6 +1048,25 @@ NtOpenProcess(OUT PHANDLE ProcessHandle,
         /* Dereference the Process */
         ObDereferenceObject(Process);
     }
+    else
+    {
+        /* neither an object name nor a client id was passed */
+        return STATUS_INVALID_PARAMETER_MIX;
+    }
+
+    /* Write back the handle */
+    if(NT_SUCCESS(Status))
+    {
+        _SEH_TRY
+        {
+            *ProcessHandle = hProcess;
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+    }
 
     return Status;
 }