PPROCESS_BASIC_INFORMATION ProcessBasicInfo =
(PPROCESS_BASIC_INFORMATION)ProcessInformation;
PKERNEL_USER_TIMES ProcessTime = (PKERNEL_USER_TIMES)ProcessInformation;
+ PPROCESS_PRIORITY_CLASS PsPriorityClass = (PPROCESS_PRIORITY_CLASS)ProcessInformation;
ULONG HandleCount;
PPROCESS_SESSION_INFORMATION SessionInfo =
(PPROCESS_SESSION_INFORMATION)ProcessInformation;
PVM_COUNTERS VmCounters = (PVM_COUNTERS)ProcessInformation;
+ PIO_COUNTERS IoCounters = (PIO_COUNTERS)ProcessInformation;
+ PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation;
PROCESS_DEVICEMAP_INFORMATION DeviceMap;
PUNICODE_STRING ImageName;
ULONG Cookie;
ObDereferenceObject(Process);
break;
- /* Quote limits and I/O Counters: not implemented */
+ /* Process quota limits */
case ProcessQuotaLimits:
+
+ Length = sizeof(QUOTA_LIMITS);
+ if (ProcessInformationLength != Length)
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Reference the process */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Indicate success */
+ Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ /* Set max/min working set sizes */
+ QuotaLimits->MaximumWorkingSetSize =
+ Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
+ QuotaLimits->MinimumWorkingSetSize =
+ Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
+
+ /* Set default time limits */
+ QuotaLimits->TimeLimit.LowPart = (ULONG)-1;
+ QuotaLimits->TimeLimit.HighPart = (ULONG)-1;
+
+ /* Is quota block a default one? */
+ if (Process->QuotaBlock == &PspDefaultQuotaBlock)
+ {
+ /* Set default pools and pagefile limits */
+ QuotaLimits->PagedPoolLimit = (SIZE_T)-1;
+ QuotaLimits->NonPagedPoolLimit = (SIZE_T)-1;
+ QuotaLimits->PagefileLimit = (SIZE_T)-1;
+ }
+ else
+ {
+ /* Get limits from non-default quota block */
+ QuotaLimits->PagedPoolLimit =
+ Process->QuotaBlock->QuotaEntry[PagedPool].Limit;
+ QuotaLimits->NonPagedPoolLimit =
+ Process->QuotaBlock->QuotaEntry[NonPagedPool].Limit;
+ QuotaLimits->PagefileLimit =
+ Process->QuotaBlock->QuotaEntry[2].Limit;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Get exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Dereference the process */
+ ObDereferenceObject(Process);
+ break;
+
case ProcessIoCounters:
Length = sizeof(IO_COUNTERS);
NULL);
if (!NT_SUCCESS(Status)) break;
- Status = STATUS_NOT_IMPLEMENTED;
+ _SEH2_TRY
+ {
+ IoCounters->ReadOperationCount = Process->ReadOperationCount.QuadPart;
+ IoCounters->ReadTransferCount = Process->ReadTransferCount.QuadPart;
+ IoCounters->WriteOperationCount = Process->WriteOperationCount.QuadPart;
+ IoCounters->WriteTransferCount = Process->WriteTransferCount.QuadPart;
+ IoCounters->OtherOperationCount = Process->OtherOperationCount.QuadPart;
+ IoCounters->OtherTransferCount = Process->OtherTransferCount.QuadPart;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Ignore exception */
+ }
+ _SEH2_END;
+
+ /* Set status to success in any case */
+ Status = STATUS_SUCCESS;
+
/* Dereference the process */
ObDereferenceObject(Process);
break;
case ProcessLdtInformation:
case ProcessWorkingSetWatch:
case ProcessWx86Information:
+
+ /* Reference the process */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status)) break;
+
+ DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
+
+ /* Dereference the process */
+ ObDereferenceObject(Process);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessPriorityClass:
/* Set the return length*/
- Length = sizeof(USHORT);
+ Length = sizeof(PROCESS_PRIORITY_CLASS);
if (ProcessInformationLength != Length)
{
_SEH2_TRY
{
/* Return current priority class */
- *(PUSHORT)ProcessInformation = Process->PriorityClass;
+ PsPriorityClass->PriorityClass = Process->PriorityClass;
+ PsPriorityClass->Foreground = FALSE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
case ProcessAffinityMask:
case ProcessForegroundInformation:
default:
+ DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
}
HANDLE PortHandle = NULL;
HANDLE TokenHandle = NULL;
PROCESS_SESSION_INFORMATION SessionInfo = {0};
+ PROCESS_PRIORITY_CLASS PriorityClass = {0};
PVOID ExceptionPort;
PAGED_CODE();
/* Check what kind of information class this is */
switch (ProcessInformationClass)
{
- /* Quotas and priorities: not implemented */
- case ProcessQuotaLimits:
- case ProcessBasePriority:
- case ProcessRaisePriority:
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
/* Error/Exception Port */
case ProcessExceptionPort:
+ /* Check buffer length */
+ if (ProcessInformationLength != sizeof(HANDLE))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
/* Security Token */
case ProcessAccessToken:
+ /* Check buffer length */
+ if (ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
/* Hard error processing */
case ProcessDefaultHardErrorMode:
+ /* Check buffer length */
+ if (ProcessInformationLength != sizeof(ULONG))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Enter SEH for direct buffer read */
_SEH2_TRY
{
/* Session ID */
case ProcessSessionInformation:
+ /* Check buffer length */
+ if (ProcessInformationLength != sizeof(PROCESS_SESSION_INFORMATION))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Enter SEH for capture */
_SEH2_TRY
{
//PsUnlockProcess(Process);
break;
- /* Priority class: HACK! */
case ProcessPriorityClass:
+
+ /* Check buffer length */
+ if (ProcessInformationLength != sizeof(PROCESS_PRIORITY_CLASS))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ /* Enter SEH for capture */
+ _SEH2_TRY
+ {
+ /* Capture the caller's buffer */
+ PriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Get the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ if (!NT_SUCCESS(Status)) break;
+
+ /* Check for invalid PriorityClass value */
+ if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* TODO: Check privileges */
+
+ /* Check if we have a job */
+ if (Process->Job)
+ {
+ DPRINT1("Jobs not yet supported\n");
+ }
+
+ /* Set process priority class */
+ Process->PriorityClass = PriorityClass.PriorityClass;
+
+ /* Set process priority mode (foreground or background) */
+ PsSetProcessPriorityByClass(Process,
+ !PriorityClass.Foreground ? PsProcessPriorityBackground :
+ PsProcessPriorityForeground);
+
+ Status = STATUS_SUCCESS;
break;
/* We currently don't implement any of these */
+ case ProcessQuotaLimits:
+ case ProcessBasePriority:
+ case ProcessRaisePriority:
case ProcessLdtInformation:
case ProcessLdtSize:
case ProcessIoPortHandlers:
case ProcessUserModeIOPL:
case ProcessEnableAlignmentFaultFixup:
case ProcessAffinityMask:
+ DPRINT1("Not implemented: %lx\n", ProcessInformationClass);
Status = STATUS_NOT_IMPLEMENTED;
break;
case ProcessWow64Information:
case ProcessDebugPort:
default:
+ DPRINT1("Unsupported or unimplemented: %lx\n", ProcessInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
}
/* Thread priority */
case ThreadPriority:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(KPRIORITY))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadBasePriority:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(LONG))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadAffinityMask:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(ULONG_PTR))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadImpersonationToken:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(HANDLE))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadQuerySetWin32StartAddress:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(ULONG_PTR))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadIdealProcessor:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(ULONG_PTR))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadPriorityBoost:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(ULONG_PTR))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{
case ThreadZeroTlsCell:
+ /* Check buffer length */
+ if (ThreadInformationLength != sizeof(ULONG_PTR))
+ {
+ Status = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
/* Use SEH for capture */
_SEH2_TRY
{