1. fixed the ProcessAccessToken information class to properly check buffers 2. implemented the ProcessExceptionPort information class Modified: trunk/reactos/ntoskrnl/ps/process.c _____
Modified: trunk/reactos/ntoskrnl/ps/process.c --- trunk/reactos/ntoskrnl/ps/process.c 2005-01-19 21:05:26 UTC (rev 13140) +++ trunk/reactos/ntoskrnl/ps/process.c 2005-01-19 21:47:51 UTC (rev 13141) @@ -1458,7 +1458,6 @@
{ PEPROCESS Process; NTSTATUS Status; - PHANDLE ProcessAccessTokenP; KPROCESSOR_MODE PreviousMode;
PreviousMode = ExGetPreviousMode(); @@ -1480,14 +1479,104 @@ case ProcessBasePriority: case ProcessRaisePriority: case ProcessDebugPort: - case ProcessExceptionPort: Status = STATUS_NOT_IMPLEMENTED; break;
+ case ProcessExceptionPort: + { + if(ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + HANDLE PortHandle; + + /* 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) + { + Process->ExceptionPort = ExceptionPort; + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_PORT_ALREADY_SET; + } + PsUnlockProcess(Process); + } + + ObDereferenceObject(ExceptionPort); + } + } + } + break; + } + case ProcessAccessToken: - ProcessAccessTokenP = (PHANDLE)ProcessInformation; - Status = PspAssignPrimaryToken(Process, *ProcessAccessTokenP); + { + if(ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + HANDLE TokenHandle; + + /* 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: { @@ -1572,7 +1661,7 @@
/* FIXME - update the session id for the process token */
- Status = PsLockProcess(Process, TRUE); + Status = PsLockProcess(Process, FALSE); if(NT_SUCCESS(Status)) { Process->SessionId = SessionInfo.SessionId;