[ros-diffs] [ion] 23176: - Formatting cleanup and optimizations to NtSetInformationProcess.

ion at svn.reactos.org ion at svn.reactos.org
Thu Jul 20 05:05:46 CEST 2006


Author: ion
Date: Thu Jul 20 07:05:46 2006
New Revision: 23176

URL: http://svn.reactos.org/svn/reactos?rev=23176&view=rev
Log:
- Formatting cleanup and optimizations to NtSetInformationProcess.

Modified:
    trunk/reactos/ntoskrnl/ps/query.c

Modified: trunk/reactos/ntoskrnl/ps/query.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/query.c?rev=23176&r1=23175&r2=23176&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ps/query.c (original)
+++ trunk/reactos/ntoskrnl/ps/query.c Thu Jul 20 07:05:46 2006
@@ -465,7 +465,7 @@
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 NTAPI
@@ -477,7 +477,11 @@
     PEPROCESS Process;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
     ACCESS_MASK Access;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
+    HANDLE PortHandle = NULL;
+    HANDLE TokenHandle = NULL;
+    PROCESS_SESSION_INFORMATION SessionInfo;
+    PEPORT ExceptionPort;
     PAGED_CODE();
 
     /* Verify Information Class validity */
@@ -487,234 +491,200 @@
                                        ProcessInformation,
                                        ProcessInformationLength,
                                        PreviousMode);
-    if(!NT_SUCCESS(Status))
-    {
-        DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status);
-        return Status;
-    }
-
-    switch(ProcessInformationClass)
-    {
-        case ProcessSessionInformation:
-            Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID;
-            break;
-        case ProcessExceptionPort:
-            Access = PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME;
-            break;
-
-        default:
-            Access = PROCESS_SET_INFORMATION;
-            break;
-    }
-
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Check what class this is */
+    Access = PROCESS_SET_INFORMATION;
+    if (ProcessInformationClass == ProcessSessionInformation)
+    {
+        /* Setting the Session ID needs a special mask */
+        Access |= PROCESS_SET_SESSIONID;
+    }
+    else if (ProcessInformationClass == ProcessExceptionPort)
+    {
+        /* Setting the exception port needs a special mask */
+        Access |= PROCESS_SUSPEND_RESUME;
+    }
+
+    /* Reference the process */
     Status = ObReferenceObjectByHandle(ProcessHandle,
                                        Access,
                                        PsProcessType,
                                        PreviousMode,
                                        (PVOID*)&Process,
                                        NULL);
-    if (!NT_SUCCESS(Status)) return(Status);
-
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Check what kind of information class this is */
     switch (ProcessInformationClass)
     {
+        /* Quotas and priorities: not implemented */
         case ProcessQuotaLimits:
         case ProcessBasePriority:
         case ProcessRaisePriority:
             Status = STATUS_NOT_IMPLEMENTED;
             break;
 
+        /* Error/Exception Port */
         case ProcessExceptionPort:
-            {
-                HANDLE PortHandle = NULL;
-
-                /* make a safe copy of the buffer on the stack */
+
+            /* Use SEH for capture */
+            _SEH_TRY
+            {
+                /* Capture the handle */
+                PortHandle = *(PHANDLE)ProcessInformation;
+            }
+            _SEH_HANDLE
+            {
+                /* Get the exception code */
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Get the LPC Port */
+            Status = ObReferenceObjectByHandle(PortHandle,
+                                               0,
+                                               LpcPortObjectType,
+                                               PreviousMode,
+                                               (PVOID)&ExceptionPort,
+                                               NULL);
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Lock the process to be thread-safe! */
+            Status = PsLockProcess(Process, FALSE);
+            if(NT_SUCCESS(Status))
+            {
+                /* Make sure we don't already have a port */
+                if (!Process->ExceptionPort)
+                {
+                    /* Save the exception port */
+                    Process->ExceptionPort = ExceptionPort;
+                }
+                else
+                {
+                    /* We already have one, fail */
+                    ObDereferenceObject(ExceptionPort);
+                    Status = STATUS_PORT_ALREADY_SET;
+                }
+
+                /* Unlock the process */
+                PsUnlockProcess(Process);
+            }
+            else
+            {
+                /* Locking failed, dereference the port */
+                ObDereferenceObject(ExceptionPort);
+            }
+            break;
+
+        /* Security Token */
+        case ProcessAccessToken:
+
+            /* Use SEH for capture */
+            _SEH_TRY
+            {
+                /* Save the token handle */
+                TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
+                               Token;
+            }
+            _SEH_HANDLE
+            {
+                /* Get the exception code */
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Assign the actual token */
+            Status = PspAssignPrimaryToken(Process, TokenHandle);
+            break;
+
+        /* Hard error processing */
+        case ProcessDefaultHardErrorMode:
+
+            /* Enter SEH for direct buffer read */
+            _SEH_TRY
+            {
+                /* Update the current mode abd return the previous one */
+                InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
+                                    *(PLONG)ProcessInformation);
+            }
+            _SEH_HANDLE
+            {
+                /* Get exception code */
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+            break;
+
+        /* Session ID */
+        case ProcessSessionInformation:
+
+            /* Enter SEH for capture */
+            _SEH_TRY
+            {
+                /* Capture the caller's buffer */
+                SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
+            }
+            _SEH_HANDLE
+            {
+                /* Get the exception code */
+                Status = _SEH_GetExceptionCode();
+            }
+            _SEH_END;
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Setting the session id requires the SeTcbPrivilege */
+            if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+            {
+                /* Can't set the session ID, bail out. */
+                Status = STATUS_PRIVILEGE_NOT_HELD;
+                break;
+            }
+
+            /* FIXME - update the session id for the process token */
+            Status = PsLockProcess(Process, FALSE);
+            if (!NT_SUCCESS(Status)) break;
+
+            /* Write the session ID in the EPROCESS */
+            Process->Session = SessionInfo.SessionId;
+
+            /* Check if the process also has a PEB */
+            if (Process->Peb)
+            {
+                /*
+                 * Attach to the process to make sure we're in the right
+                 * context to access the PEB structure
+                 */
+                KeAttachProcess(&Process->Pcb);
+
+                /* Enter SEH for write to user-mode PEB */
                 _SEH_TRY
                 {
-                    PortHandle = *(PHANDLE)ProcessInformation;
-                    Status = STATUS_SUCCESS;
+                    /* Write the session ID */
+                    Process->Peb->SessionId = SessionInfo.SessionId;
                 }
                 _SEH_HANDLE
                 {
+                    /* Get exception code */
                     Status = _SEH_GetExceptionCode();
                 }
                 _SEH_END;
 
-                if(NT_SUCCESS(Status))
-                {
-                    PEPORT ExceptionPort;
-
-                    /* in case we had success reading from the buffer, verify the provided
-                    * LPC port handle
-                    */
-                    Status = ObReferenceObjectByHandle(PortHandle,
-                        0,
-                        LpcPortObjectType,
-                        PreviousMode,
-                        (PVOID)&ExceptionPort,
-                        NULL);
-                    if(NT_SUCCESS(Status))
-                    {
-                        /* lock the process to be thread-safe! */
-
-                        Status = PsLockProcess(Process, FALSE);
-                        if(NT_SUCCESS(Status))
-                        {
-                            /*
-                            * according to "NT Native API" documentation, setting the exception
-                            * port is only permitted once!
-                            */
-                            if(Process->ExceptionPort == NULL)
-                            {
-                                /* keep the reference to the handle! */
-                                Process->ExceptionPort = ExceptionPort;
-                                Status = STATUS_SUCCESS;
-                            }
-                            else
-                            {
-                                ObDereferenceObject(ExceptionPort);
-                                Status = STATUS_PORT_ALREADY_SET;
-                            }
-                            PsUnlockProcess(Process);
-                        }
-                        else
-                        {
-                            ObDereferenceObject(ExceptionPort);
-                        }
-                    }
-                }
-                break;
-            }
-
-        case ProcessAccessToken:
-            {
-                HANDLE TokenHandle = NULL;
-
-                /* make a safe copy of the buffer on the stack */
-                _SEH_TRY
-                {
-                    TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token;
-                    Status = STATUS_SUCCESS;
-                }
-                _SEH_HANDLE
-                {
-                    Status = _SEH_GetExceptionCode();
-                }
-                _SEH_END;
-
-                if(NT_SUCCESS(Status))
-                {
-                    /* in case we had success reading from the buffer, perform the actual task */
-                    Status = PspAssignPrimaryToken(Process, TokenHandle);
-                }
-                break;
-            }
-
-        case ProcessDefaultHardErrorMode:
-            {
-                _SEH_TRY
-                {
-                    InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
-                        *(PLONG)ProcessInformation);
-                    Status = STATUS_SUCCESS;
-                }
-                _SEH_HANDLE
-                {
-                    Status = _SEH_GetExceptionCode();
-                }
-                _SEH_END;
-                break;
-            }
-
-        case ProcessSessionInformation:
-            {
-                PROCESS_SESSION_INFORMATION SessionInfo;
-                Status = STATUS_SUCCESS;
-
-                RtlZeroMemory(&SessionInfo, sizeof(SessionInfo));
-
-                _SEH_TRY
-                {
-                    /* copy the structure to the stack */
-                    SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
-                }
-                _SEH_HANDLE
-                {
-                    Status = _SEH_GetExceptionCode();
-                }
-                _SEH_END;
-
-                if(NT_SUCCESS(Status))
-                {
-                    /* we successfully copied the structure to the stack, continue processing */
-
-                    /*
-                    * setting the session id requires the SeTcbPrivilege!
-                    */
-                    if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
-                        PreviousMode))
-                    {
-                        DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
-                        /* can't set the session id, bail! */
-                        Status = STATUS_PRIVILEGE_NOT_HELD;
-                        break;
-                    }
-
-                    /* FIXME - update the session id for the process token */
-
-                    Status = PsLockProcess(Process, FALSE);
-                    if(NT_SUCCESS(Status))
-                    {
-                        Process->Session = SessionInfo.SessionId;
-
-                        /* Update the session id in the PEB structure */
-                        if(Process->Peb != NULL)
-                        {
-                            /* we need to attach to the process to make sure we're in the right
-                            context to access the PEB structure */
-                            KeAttachProcess(&Process->Pcb);
-
-                            _SEH_TRY
-                            {
-                                /* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
-
-                                Status = STATUS_SUCCESS;
-                            }
-                            _SEH_HANDLE
-                            {
-                                Status = _SEH_GetExceptionCode();
-                            }
-                            _SEH_END;
-
-                            KeDetachProcess();
-                        }
-
-                        PsUnlockProcess(Process);
-                    }
-                }
-                break;
-            }
-
+                /* Detach from the process */
+                KeDetachProcess();
+            }
+
+            /* Unlock the process */
+            PsUnlockProcess(Process);
+            break;
+
+        /* Priority class: HACK! */
         case ProcessPriorityClass:
-            {
-                PROCESS_PRIORITY_CLASS ppc;
-
-                _SEH_TRY
-                {
-                    ppc = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
-                }
-                _SEH_HANDLE
-                {
-                    Status = _SEH_GetExceptionCode();
-                }
-                _SEH_END;
-
-                if(NT_SUCCESS(Status))
-                {
-                }
-
-                break;
-            }
-
+            break;
+
+        /* We currently don't implement any of these */
         case ProcessLdtInformation:
         case ProcessLdtSize:
         case ProcessIoPortHandlers:
@@ -725,6 +695,7 @@
             Status = STATUS_NOT_IMPLEMENTED;
             break;
 
+        /* Supposedly these are invalid...!? verify! */
         case ProcessBasicInformation:
         case ProcessIoCounters:
         case ProcessTimes:
@@ -736,8 +707,10 @@
         default:
             Status = STATUS_INVALID_INFO_CLASS;
     }
+
+    /* Dereference and return status */
     ObDereferenceObject(Process);
-    return(Status);
+    return Status;
 }
 
 /*
@@ -907,4 +880,5 @@
     ObDereferenceObject(Thread);
     return(Status);
 }
+
 /* EOF */




More information about the Ros-diffs mailing list