- Formatting cleanup and optimizations to NtSetInformationProcess.

svn path=/trunk/; revision=23176
This commit is contained in:
Alex Ionescu 2006-07-20 03:05:46 +00:00
parent 2278c2914f
commit 6e8d8b5e84

View file

@ -465,7 +465,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
} }
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -477,7 +477,11 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
PEPROCESS Process; PEPROCESS Process;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
ACCESS_MASK Access; ACCESS_MASK Access;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status;
HANDLE PortHandle = NULL;
HANDLE TokenHandle = NULL;
PROCESS_SESSION_INFORMATION SessionInfo;
PEPORT ExceptionPort;
PAGED_CODE(); PAGED_CODE();
/* Verify Information Class validity */ /* Verify Information Class validity */
@ -487,234 +491,200 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
ProcessInformation, ProcessInformation,
ProcessInformationLength, ProcessInformationLength,
PreviousMode); PreviousMode);
if(!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return Status;
/* Check what class this is */
Access = PROCESS_SET_INFORMATION;
if (ProcessInformationClass == ProcessSessionInformation)
{ {
DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status); /* Setting the Session ID needs a special mask */
return Status; Access |= PROCESS_SET_SESSIONID;
} }
else if (ProcessInformationClass == ProcessExceptionPort)
switch(ProcessInformationClass) {
{ /* Setting the exception port needs a special mask */
case ProcessSessionInformation: Access |= PROCESS_SUSPEND_RESUME;
Access = PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID;
break;
case ProcessExceptionPort:
Access = PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME;
break;
default:
Access = PROCESS_SET_INFORMATION;
break;
} }
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle, Status = ObReferenceObjectByHandle(ProcessHandle,
Access, Access,
PsProcessType, PsProcessType,
PreviousMode, PreviousMode,
(PVOID*)&Process, (PVOID*)&Process,
NULL); NULL);
if (!NT_SUCCESS(Status)) return(Status); if (!NT_SUCCESS(Status)) return Status;
/* Check what kind of information class this is */
switch (ProcessInformationClass) switch (ProcessInformationClass)
{ {
/* Quotas and priorities: not implemented */
case ProcessQuotaLimits: case ProcessQuotaLimits:
case ProcessBasePriority: case ProcessBasePriority:
case ProcessRaisePriority: case ProcessRaisePriority:
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
break; break;
/* Error/Exception Port */
case ProcessExceptionPort: case ProcessExceptionPort:
/* Use SEH for capture */
_SEH_TRY
{ {
HANDLE PortHandle = NULL; /* Capture the handle */
PortHandle = *(PHANDLE)ProcessInformation;
/* make a safe copy of the buffer on the stack */
_SEH_TRY
{
PortHandle = *(PHANDLE)ProcessInformation;
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
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;
} }
_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: case ProcessAccessToken:
/* Use SEH for capture */
_SEH_TRY
{ {
HANDLE TokenHandle = NULL; /* Save the token handle */
TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->
/* make a safe copy of the buffer on the stack */ Token;
_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;
} }
_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: case ProcessDefaultHardErrorMode:
{
_SEH_TRY
{
InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
*(PLONG)ProcessInformation);
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
break;
}
/* 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: case ProcessSessionInformation:
/* Enter SEH for capture */
_SEH_TRY
{ {
PROCESS_SESSION_INFORMATION SessionInfo; /* Capture the caller's buffer */
Status = STATUS_SUCCESS; SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
}
_SEH_HANDLE
{
/* Get the exception code */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) break;
RtlZeroMemory(&SessionInfo, sizeof(SessionInfo)); /* 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 _SEH_TRY
{ {
/* copy the structure to the stack */ /* Write the session ID */
SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation; Process->Peb->SessionId = SessionInfo.SessionId;
} }
_SEH_HANDLE _SEH_HANDLE
{ {
/* Get exception code */
Status = _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
} }
_SEH_END; _SEH_END;
if(NT_SUCCESS(Status)) /* Detach from the process */
{ KeDetachProcess();
/* 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;
} }
/* Unlock the process */
PsUnlockProcess(Process);
break;
/* Priority class: HACK! */
case ProcessPriorityClass: case ProcessPriorityClass:
{ break;
PROCESS_PRIORITY_CLASS ppc;
_SEH_TRY
{
ppc = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(NT_SUCCESS(Status))
{
}
break;
}
/* We currently don't implement any of these */
case ProcessLdtInformation: case ProcessLdtInformation:
case ProcessLdtSize: case ProcessLdtSize:
case ProcessIoPortHandlers: case ProcessIoPortHandlers:
@ -725,6 +695,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
break; break;
/* Supposedly these are invalid...!? verify! */
case ProcessBasicInformation: case ProcessBasicInformation:
case ProcessIoCounters: case ProcessIoCounters:
case ProcessTimes: case ProcessTimes:
@ -736,8 +707,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
default: default:
Status = STATUS_INVALID_INFO_CLASS; Status = STATUS_INVALID_INFO_CLASS;
} }
/* Dereference and return status */
ObDereferenceObject(Process); ObDereferenceObject(Process);
return(Status); return Status;
} }
/* /*
@ -907,4 +880,5 @@ NtQueryInformationThread(IN HANDLE ThreadHandle,
ObDereferenceObject(Thread); ObDereferenceObject(Thread);
return(Status); return(Status);
} }
/* EOF */ /* EOF */