#define NDEBUG
#include <debug.h>
-/* FIXME: From winbase.h... what to do? */
-#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
-
/* Debugging Level */
ULONG PspTraceLevel = 0;
PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
(PPROCESS_BASIC_INFORMATION)ProcessInformation;
PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
+ ULONG UserTime, KernelTime;
PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
ULONG HandleCount;
PPROCESS_SESSION_INFORMATION SessionInfo =
(ProcessHandle != NtCurrentProcess()))
{
/*
- * Retreiving the process cookie is only allowed for the calling process
- * itself! XP only allowes NtCurrentProcess() as process handles even if
+ * Retrieving the process cookie is only allowed for the calling process
+ * itself! XP only allows NtCurrentProcess() as process handles even if
* a real handle actually represents the current process.
*/
return STATUS_INVALID_PARAMETER;
ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
UniqueProcessId;
ProcessBasicInfo->InheritedFromUniqueProcessId =
- (ULONG)Process->InheritedFromUniqueProcessId;
+ (ULONG_PTR)Process->InheritedFromUniqueProcessId;
ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
}
_SEH2_TRY
{
/* Copy time information from EPROCESS/KPROCESS */
- /* FIXME: Call KeQueryRuntimeProcess */
+ KernelTime = KeQueryRuntimeProcess(&Process->Pcb, &UserTime);
ProcessTime->CreateTime = Process->CreateTime;
- ProcessTime->UserTime.QuadPart = Process->Pcb.UserTime *
- KeMaximumIncrement;
- ProcessTime->KernelTime.QuadPart = Process->Pcb.KernelTime *
- KeMaximumIncrement;
+ ProcessTime->UserTime.QuadPart = (LONGLONG)UserTime * KeMaximumIncrement;
+ ProcessTime->KernelTime.QuadPart = (LONGLONG)KernelTime * KeMaximumIncrement;
ProcessTime->ExitTime = Process->ExitTime;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
_SEH2_TRY
{
/* Write back the Session ID */
- SessionInfo->SessionId = PtrToUlong(PsGetProcessSessionId(Process));
+ SessionInfo->SessionId = PsGetProcessSessionId(Process);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Length = sizeof(ULONG_PTR);
if (ProcessInformationLength != Length)
{
+ Length = 0;
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
/* Getting VDM powers requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Bail out */
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
DPRINT1("Need TCB privilege\n");
break;
/* Setting the error port requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Can't set the session ID, bail out. */
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
/* Setting the session id requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Can't set the session ID, bail out. */
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
+#if 0 // OLD AND DEPRECATED CODE!!!!
+
/* FIXME - update the session id for the process token */
//Status = PsLockProcess(Process, FALSE);
if (!NT_SUCCESS(Status)) break;
/* Unlock the process */
//PsUnlockProcess(Process);
+
+#endif
+
+ /*
+ * Since we cannot change the session ID of the given
+ * process anymore because it is set once and for all
+ * at process creation time and because it is stored
+ * inside the Process->Session structure managed by MM,
+ * we fake changing it: we just return success if the
+ * user-defined value is the same as the session ID of
+ * the process, and otherwise we fail.
+ */
+ if (SessionInfo.SessionId == PsGetProcessSessionId(Process))
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = STATUS_ACCESS_DENIED;
+ }
+
break;
case ProcessPriorityClass:
/* Validate the number */
if ((BasePriority > HIGH_PRIORITY) || (BasePriority <= LOW_PRIORITY))
{
+ ObDereferenceObject(Process);
return STATUS_INVALID_PARAMETER;
}
/* Setting 'break on termination' requires the SeDebugPrivilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
{
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
/* Only TCB can do this */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{
- /* Fail */
+ /* We don't hold the privilege, bail out */
DPRINT1("Need TCB to set IOPL\n");
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
break;
case ProcessQuotaLimits:
- DPRINT1("Quota Limits not implemented\n");
- Status = STATUS_NOT_IMPLEMENTED;
+
+ Status = PspSetQuotaLimits(Process,
+ 1,
+ ProcessInformation,
+ ProcessInformationLength,
+ PreviousMode);
break;
case ProcessWorkingSetWatch:
/* Setting 'break on termination' requires the SeDebugPrivilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
{
+ /* We don't hold the privilege, bail out */
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
(PTHREAD_BASIC_INFORMATION)ThreadInformation;
PKERNEL_USER_TIMES ThreadTime = (PKERNEL_USER_TIMES)ThreadInformation;
KIRQL OldIrql;
+ ULONG ThreadTerminated;
PAGED_CODE();
/* Check if we were called from user mode */
_SEH2_END;
break;
+ case ThreadIsTerminated:
+
+ /* Set the return length*/
+ Length = sizeof(ThreadTerminated);
+
+ if (ThreadInformationLength != Length)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ ThreadTerminated = PsIsThreadTerminating(Thread);
+
+ _SEH2_TRY
+ {
+ *(PULONG)ThreadInformation = ThreadTerminated ? 1 : 0;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ break;
+
/* Anything else */
default: