mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 01:35:43 +00:00
- Formatting cleanup and optimizations to NtSetInformationProcess.
svn path=/trunk/; revision=23176
This commit is contained in:
parent
2278c2914f
commit
6e8d8b5e84
1 changed files with 160 additions and 186 deletions
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue