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=23…
==============================================================================
--- 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 */