implemented the ProcessSessionInformation 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 20:26:56 UTC (rev
13137)
+++ trunk/reactos/ntoskrnl/ps/process.c 2005-01-19 20:59:53 UTC (rev
13138)
@@ -1132,7 +1132,10 @@
{
PEPROCESS Process;
NTSTATUS Status;
+ KPROCESSOR_MODE PreviousMode;
+ PreviousMode = ExGetPreviousMode();
+
/*
* TODO: Here we should probably check that ProcessInformationLength
* bytes indeed are writable at address ProcessInformation.
@@ -1141,7 +1144,7 @@
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
- UserMode,
+ PreviousMode,
(PVOID*)&Process,
NULL);
if (Status != STATUS_SUCCESS)
@@ -1228,7 +1231,35 @@
break;
case ProcessSessionInformation:
+ {
+ if (ProcessInformationLength !=
sizeof(PROCESS_SESSION_INFORMATION))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ else
+ {
+ PPROCESS_SESSION_INFORMATION SessionInfo =
(PPROCESS_SESSION_INFORMATION)ProcessInformation;
+
+ _SEH_TRY
+ {
+ SessionInfo->SessionId = Process->SessionId;
+ if (ReturnLength)
+ {
+ *ReturnLength = sizeof(PROCESS_SESSION_INFORMATION);
+ }
+ Status = STATUS_SUCCESS;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+ }
+ break;
+ }
+
case ProcessWow64Information:
+ DPRINT1("We currently don't support the ProcessWow64Information
information class!\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
@@ -1428,11 +1459,14 @@
PEPROCESS Process;
NTSTATUS Status;
PHANDLE ProcessAccessTokenP;
+ KPROCESSOR_MODE PreviousMode;
+ PreviousMode = ExGetPreviousMode();
+
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_SET_INFORMATION,
PsProcessType,
- UserMode,
+ PreviousMode,
(PVOID*)&Process,
NULL);
if (!NT_SUCCESS(Status))
@@ -1477,6 +1511,102 @@
}
break;
}
+
+ case ProcessSessionInformation:
+ {
+ if(ProcessInformationLength != sizeof(UINT))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ }
+ else
+ {
+ PROCESS_SESSION_INFORMATION SessionInfo;
+ Status = STATUS_SUCCESS;
+
+ _SEH_TRY
+ {
+ /* copy the structure to the stack */
+ SessionInfo =
*(PPROCESS_SESSION_INFORMATION)ProcessInformation;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(NT_SUCCESS(Status))
+ {
+ PEPROCESS Process2;
+ /* we successfully copied the structure to the stack,
continue processing */
+
+ /*
+ * setting the session id requires the SeTcbPrivilege!
+ */
+ if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
+ PreviousMode))
+ {
+ /* can't set the session id, bail! */
+ Status = STATUS_PRIVILEGE_NOT_HELD;
+ break;
+ }
+
+ /*
+ * ntinternals documents a PROCESS_SET_SESSIONID flag for
NtOpenProcess,
+ * so we need to open the handle again with this access
flag to make
+ * sure the handle has the required permissions to change
the session id!
+ */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_SET_INFORMATION
| PROCESS_SET_SESSIONID,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process2,
+ NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ /* the handle doesn't have the access rights */
+ break;
+ }
+
+ /* SANITY check, Process2 MUST be the same as Process as
it's the same handle! */
+ ASSERT(Process2 == Process);
+
+ /* FIXME - update the session id for the process token */
+
+ Status = PsLockProcess(Process, TRUE);
+ if(NT_SUCCESS(Status))
+ {
+ Process->SessionId = 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);
+ }
+
+ ObDereferenceObject(Process2);
+ }
+ }
+ break;
+ }
case ProcessLdtInformation:
case ProcessLdtSize:
@@ -2296,11 +2426,18 @@
KernelMode,
FALSE,
Delay);
- if(Status == STATUS_TIMEOUT)
+ if(NT_SUCCESS(Status))
{
+#ifndef NDEBUG
+ if(Status == STATUS_TIMEOUT)
+ {
+ DPRINT1("PsLockProcess(0x%x) timed out!\n", Process);
+ }
+#endif
KeLeaveCriticalRegion();
- break;
+
}
+ break;
}
else
{