From b1f27287aeaacbdf24e7853c8f6328b8623b863c Mon Sep 17 00:00:00 2001 From: Thamatip Chitpong Date: Thu, 12 Dec 2024 02:37:42 +0700 Subject: [PATCH] [NTDLL_APITEST] NtQueryInformationProcess: Add tests for ProcessQuotaLimits/Ex --- .../ntdll/NtQueryInformationProcess.c | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) diff --git a/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c b/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c index a8cc3250597..43ac4c7f424 100644 --- a/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c +++ b/modules/rostests/apitests/ntdll/NtQueryInformationProcess.c @@ -305,6 +305,226 @@ Test_ProcessBasicInformation(void) trace("[2] BasicInfo.InheritedFromUniqueProcessId = %Iu\n", BasicInfo.InheritedFromUniqueProcessId); } +static +void +Test_ProcessQuotaLimits(void) +{ + NTSTATUS Status; + ULONG Length; + QUOTA_LIMITS QuotaLimits; + + /* Everything is NULL */ + Status = NtQueryInformationProcess(NULL, + ProcessQuotaLimits, + NULL, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right size, invalid process handle */ + Status = NtQueryInformationProcess(NULL, + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* Valid process handle, no buffer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Unaligned buffer, wrong size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + (PVOID)2, + 0, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Unaligned buffer, correct size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + (PVOID)2, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); + + /* Buffer too small */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits) - 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right buffer size but NULL pointer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + /* Buffer too large */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits) + 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Buffer too small, ask for length */ + Length = 0x55555555; + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimits) - 1, + &Length); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + ok_dec(Length, 0x55555555); + + /* Valid parameters, no return length */ + RtlFillMemory(&QuotaLimits, sizeof(QuotaLimits), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QuotaLimits), + NULL); + ok_hex(Status, STATUS_SUCCESS); + + /* Trace the returned data (1) */ + trace("[1] QuotaLimits.PagedPoolLimit = %Iu\n", QuotaLimits.PagedPoolLimit); + trace("[1] QuotaLimits.NonPagedPoolLimit = %Iu\n", QuotaLimits.NonPagedPoolLimit); + trace("[1] QuotaLimits.MinimumWorkingSetSize = %Iu\n", QuotaLimits.MinimumWorkingSetSize); + trace("[1] QuotaLimits.MaximumWorkingSetSize = %Iu\n", QuotaLimits.MaximumWorkingSetSize); + trace("[1] QuotaLimits.PagefileLimit = %Iu\n", QuotaLimits.PagefileLimit); + trace("[1] QuotaLimits.TimeLimit = %I64d\n", QuotaLimits.TimeLimit.QuadPart); + + /* Again, this time with a return length */ + Length = 0x55555555; + RtlFillMemory(&QuotaLimits, sizeof(QuotaLimits), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimits, + sizeof(QuotaLimits), + &Length); + ok_hex(Status, STATUS_SUCCESS); + ok_dec(Length, sizeof(QuotaLimits)); + + /* Trace the returned data (2) */ + trace("[2] QuotaLimits.PagedPoolLimit = %Iu\n", QuotaLimits.PagedPoolLimit); + trace("[2] QuotaLimits.NonPagedPoolLimit = %Iu\n", QuotaLimits.NonPagedPoolLimit); + trace("[2] QuotaLimits.MinimumWorkingSetSize = %Iu\n", QuotaLimits.MinimumWorkingSetSize); + trace("[2] QuotaLimits.MaximumWorkingSetSize = %Iu\n", QuotaLimits.MaximumWorkingSetSize); + trace("[2] QuotaLimits.PagefileLimit = %Iu\n", QuotaLimits.PagefileLimit); + trace("[2] QuotaLimits.TimeLimit = %I64d\n", QuotaLimits.TimeLimit.QuadPart); +} + +static +void +Test_ProcessQuotaLimitsEx(void) +{ + NTSTATUS Status; + ULONG Length; + QUOTA_LIMITS_EX QuotaLimitsEx; + + /* Right size, invalid process handle */ + Status = NtQueryInformationProcess(NULL, + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_INVALID_HANDLE); + + /* Unaligned buffer, correct size */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + (PVOID)2, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_DATATYPE_MISALIGNMENT); + + /* Buffer too small */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx) - 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Right buffer size but NULL pointer */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_ACCESS_VIOLATION); + + /* Buffer too large */ + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx) + 1, + NULL); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + + /* Buffer too small, ask for length */ + Length = 0x55555555; + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + NULL, + sizeof(QuotaLimitsEx) - 1, + &Length); + ok_hex(Status, STATUS_INFO_LENGTH_MISMATCH); + ok_dec(Length, 0x55555555); + + /* Valid parameters, no return length */ + RtlFillMemory(&QuotaLimitsEx, sizeof(QuotaLimitsEx), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimitsEx, + sizeof(QuotaLimitsEx), + NULL); + ok_hex(Status, STATUS_SUCCESS); + + /* Trace the returned data (1) */ + trace("[1] QuotaLimitsEx.PagedPoolLimit = %Iu\n", QuotaLimitsEx.PagedPoolLimit); + trace("[1] QuotaLimitsEx.NonPagedPoolLimit = %Iu\n", QuotaLimitsEx.NonPagedPoolLimit); + trace("[1] QuotaLimitsEx.MinimumWorkingSetSize = %Iu\n", QuotaLimitsEx.MinimumWorkingSetSize); + trace("[1] QuotaLimitsEx.MaximumWorkingSetSize = %Iu\n", QuotaLimitsEx.MaximumWorkingSetSize); + trace("[1] QuotaLimitsEx.PagefileLimit = %Iu\n", QuotaLimitsEx.PagefileLimit); + trace("[1] QuotaLimitsEx.TimeLimit = %I64d\n", QuotaLimitsEx.TimeLimit.QuadPart); + //trace("[1] QuotaLimitsEx.WorkingSetLimit = %Iu\n", QuotaLimitsEx.WorkingSetLimit); // Not used on Win2k3 + trace("[1] QuotaLimitsEx.Flags = %lx\n", QuotaLimitsEx.Flags); + trace("[1] QuotaLimitsEx.CpuRateLimit.RateData = %lx\n", QuotaLimitsEx.CpuRateLimit.RateData); + + /* Again, this time with a return length */ + Length = 0x55555555; + RtlFillMemory(&QuotaLimitsEx, sizeof(QuotaLimitsEx), 0x55); + Status = NtQueryInformationProcess(NtCurrentProcess(), + ProcessQuotaLimits, + &QuotaLimitsEx, + sizeof(QuotaLimitsEx), + &Length); + ok_hex(Status, STATUS_SUCCESS); + ok_dec(Length, sizeof(QuotaLimitsEx)); + + /* Trace the returned data (2) */ + trace("[2] QuotaLimitsEx.PagedPoolLimit = %Iu\n", QuotaLimitsEx.PagedPoolLimit); + trace("[2] QuotaLimitsEx.NonPagedPoolLimit = %Iu\n", QuotaLimitsEx.NonPagedPoolLimit); + trace("[2] QuotaLimitsEx.MinimumWorkingSetSize = %Iu\n", QuotaLimitsEx.MinimumWorkingSetSize); + trace("[2] QuotaLimitsEx.MaximumWorkingSetSize = %Iu\n", QuotaLimitsEx.MaximumWorkingSetSize); + trace("[2] QuotaLimitsEx.PagefileLimit = %Iu\n", QuotaLimitsEx.PagefileLimit); + trace("[2] QuotaLimitsEx.TimeLimit = %I64d\n", QuotaLimitsEx.TimeLimit.QuadPart); + //trace("[2] QuotaLimitsEx.WorkingSetLimit = %Iu\n", QuotaLimitsEx.WorkingSetLimit); // Not used on Win2k3 + trace("[2] QuotaLimitsEx.Flags = %lx\n", QuotaLimitsEx.Flags); + trace("[2] QuotaLimitsEx.CpuRateLimit.RateData = %lx\n", QuotaLimitsEx.CpuRateLimit.RateData); +} + static void Test_ProcessPriorityClassAlignment(void) @@ -496,6 +716,8 @@ START_TEST(NtQueryInformationProcess) Test_ProcessTimes(); Test_ProcessBasicInformation(); + Test_ProcessQuotaLimits(); + Test_ProcessQuotaLimitsEx(); Test_ProcessPriorityClassAlignment(); Test_ProcessWx86Information(); Test_ProcQueryAlignmentProbe();