/* FIXME: From winbase.h... what to do? */
#define SEM_NOALIGNMENTFAULTEXCEPT 0x04
-/* Include Information Class Tables */
-#include "internal/ps_i.h"
-
/* Debugging Level */
ULONG PspTraceLevel = 0;
_SEH2_END;
}
- if((ProcessInformationClass == ProcessCookie) &&
+ if (((ProcessInformationClass == ProcessCookie) ||
+ (ProcessInformationClass == ProcessImageInformation)) &&
(ProcessHandle != NtCurrentProcess()))
{
/*
ProcessBasicInfo->UniqueProcessId = (ULONG_PTR)Process->
UniqueProcessId;
ProcessBasicInfo->InheritedFromUniqueProcessId =
- (ULONG)Process->InheritedFromUniqueProcessId;
+ (ULONG_PTR)Process->InheritedFromUniqueProcessId;
ProcessBasicInfo->BasePriority = Process->Pcb.BasePriority;
}
_SEH2_TRY
{
/* Write back the Session ID */
- SessionInfo->SessionId = PtrToUlong(PsGetProcessSessionId(Process));
+ SessionInfo->SessionId = PsGetProcessSessionId(Process);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
VmCounters->PagefileUsage = Process->QuotaUsage[2] << PAGE_SHIFT;
VmCounters->PeakPagefileUsage = Process->QuotaPeak[2] << PAGE_SHIFT;
//VmCounters->PrivateUsage = Process->CommitCharge << PAGE_SHIFT;
- //
-
+ //
+
/* Set the return length */
Length = ProcessInformationLength;
}
}
/* Free the image path */
- ExFreePool(ImageName);
+ ExFreePoolWithTag(ImageName, TAG_SEPA);
}
/* Dereference the process */
ObDereferenceObject(Process);
break;
case ProcessImageInformation:
- DPRINT1("Image Information Query Not implemented: %lx\n", ProcessInformationClass);
- Status = STATUS_NOT_IMPLEMENTED;
+
+ /* Set the length required and validate it */
+ Length = sizeof(SECTION_IMAGE_INFORMATION);
+ if (ProcessInformationLength != Length)
+ {
+ /* Break out */
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Enter SEH to protect write */
+ _SEH2_TRY
+ {
+ MmGetImageInformation((PSECTION_IMAGE_INFORMATION)ProcessInformation);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Get the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Indicate success */
+ Status = STATUS_SUCCESS;
break;
case ProcessDebugObjectHandle:
/* 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:
/* 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;
- break;
+
+ return PspSetQuotaLimits(ProcessHandle,
+ 1,
+ ProcessInformation,
+ ProcessInformationLength,
+ PreviousMode);
case ProcessWorkingSetWatch:
DPRINT1("WS watch not implemented\n");
/* 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: