Skip to content

Commit

Permalink
[NTOS:PS] Add query support for QUOTA_LIMITS_EX
Browse files Browse the repository at this point in the history
  • Loading branch information
TAN-Gaming committed Dec 18, 2024
1 parent bf0dbdb commit 1e06829
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 31 deletions.
4 changes: 3 additions & 1 deletion ntoskrnl/include/internal/ps_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
(
QUOTA_LIMITS,
ULONG,
ICIF_QUERY | ICIF_SET | ICIF_SET_SIZE_VARIABLE

/* NOTE: ICIF_SIZE_VARIABLE is for QUOTA_LIMITS_EX support */
ICIF_QUERY | ICIF_SET | ICIF_SIZE_VARIABLE
),

/* ProcessIoCounters */
Expand Down
77 changes: 47 additions & 30 deletions ntoskrnl/ps/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,19 @@ NtQueryInformationProcess(
/* Process quota limits */
case ProcessQuotaLimits:
{
PQUOTA_LIMITS QuotaLimits = (PQUOTA_LIMITS)ProcessInformation;
QUOTA_LIMITS_EX QuotaLimits;
BOOLEAN Extended;

if (ProcessInformationLength != sizeof(QUOTA_LIMITS))
if (ProcessInformationLength != sizeof(QUOTA_LIMITS) &&
ProcessInformationLength != sizeof(QUOTA_LIMITS_EX))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}

Length = sizeof(QUOTA_LIMITS);
/* Set return length */
Length = ProcessInformationLength;
Extended = (Length == sizeof(QUOTA_LIMITS_EX));

/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
Expand All @@ -175,36 +179,49 @@ NtQueryInformationProcess(
/* Indicate success */
Status = STATUS_SUCCESS;

_SEH2_TRY
RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));

/* Get max/min working set sizes */
QuotaLimits.MaximumWorkingSetSize =
Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
QuotaLimits.MinimumWorkingSetSize =
Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;

/* Get default time limits */
QuotaLimits.TimeLimit.QuadPart = -1LL;

/* Is quota block a default one? */
if (Process->QuotaBlock == &PspDefaultQuotaBlock)
{
/* Set max/min working set sizes */
QuotaLimits->MaximumWorkingSetSize =
Process->Vm.MaximumWorkingSetSize << PAGE_SHIFT;
QuotaLimits->MinimumWorkingSetSize =
Process->Vm.MinimumWorkingSetSize << PAGE_SHIFT;
/* Get 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[PsPagedPool].Limit;
QuotaLimits.NonPagedPoolLimit =
Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit;
QuotaLimits.PagefileLimit =
Process->QuotaBlock->QuotaEntry[PsPageFile].Limit;
}

/* Set default time limits */
QuotaLimits->TimeLimit.LowPart = MAXULONG;
QuotaLimits->TimeLimit.HighPart = MAXULONG;
/* Get additional information, if needed */
if (Extended)
{
/* FIXME: Get the correct information */
//QuotaLimits.WorkingSetLimit = (SIZE_T)-1; // Not used on Win2k3, it is set to 0
QuotaLimits.Flags = QUOTA_LIMITS_HARDWS_MIN_DISABLE | QUOTA_LIMITS_HARDWS_MAX_DISABLE;
QuotaLimits.CpuRateLimit.RateData = 0;
}

/* 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[PsPagedPool].Limit;
QuotaLimits->NonPagedPoolLimit =
Process->QuotaBlock->QuotaEntry[PsNonPagedPool].Limit;
QuotaLimits->PagefileLimit =
Process->QuotaBlock->QuotaEntry[PsPageFile].Limit;
}
/* Protect writes with SEH */
_SEH2_TRY
{
RtlCopyMemory(ProcessInformation, &QuotaLimits, Length);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Expand Down

0 comments on commit 1e06829

Please sign in to comment.