Based on a patch by Qian Hong.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44812
-- v4: ntdll: Add NtQueryInformationProcess(ProcessQuotaLimits) tests. ntdll: Add NtQueryInformationProcess(ProcessQuotaLimits) stub.
From: Vijay Kiran Kamuju infyquest@gmail.com
Based on a patch by Qian Hong.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44812 Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/ntdll/unix/process.c | 30 +++++++++++++++++++++++++++++- dlls/wow64/process.c | 1 + 2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 2c6dc1b43cc..09e38572cf2 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1124,7 +1124,6 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class
switch (class) { - UNIMPLEMENTED_INFO_CLASS(ProcessQuotaLimits); UNIMPLEMENTED_INFO_CLASS(ProcessBasePriority); UNIMPLEMENTED_INFO_CLASS(ProcessRaisePriority); UNIMPLEMENTED_INFO_CLASS(ProcessExceptionPort); @@ -1580,6 +1579,35 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class else ret = STATUS_INVALID_PARAMETER; break;
+ case ProcessQuotaLimits: + { + QUOTA_LIMITS qlimits; + + FIXME( "ProcessQuotaLimits (%p,%p,0x%08x,%p) stub\n", handle, info, (int)size, ret_len ); + + len = sizeof(QUOTA_LIMITS); + if (size == len) + { + if (!info || !handle) ret = STATUS_INVALID_HANDLE; + else + { + /* FIXME: SetProcessWorkingSetSize can also set the quota values. + Quota Limits should be stored inside the process. */ + qlimits.PagedPoolLimit = (SIZE_T)-1; + qlimits.NonPagedPoolLimit = (SIZE_T)-1; + /* Default minimum working set size is 204800 bytes (50 Pages) */ + qlimits.MinimumWorkingSetSize = 204800; + /* Default maximum working set size is 1413120 bytes (345 Pages) */ + qlimits.MaximumWorkingSetSize = 1413120; + qlimits.PagefileLimit = (SIZE_T)-1; + qlimits.TimeLimit.QuadPart = -1; + memcpy(info, &qlimits, len); + } + } + else ret = STATUS_INFO_LENGTH_MISMATCH; + break; + } + default: FIXME("(%p,info_class=%d,%p,0x%08x,%p) Unknown information class\n", handle, class, info, (int)size, ret_len ); diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 8b543d2a859..679281dedcb 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -563,6 +563,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationProcess( UINT *args ) case ProcessExecuteFlags: /* ULONG */ case ProcessCookie: /* ULONG */ case ProcessCycleTime: /* PROCESS_CYCLE_TIME_INFORMATION */ + case ProcessQuotaLimits: /* QUOTA_LIMITS */ /* FIXME: check buffer alignment */ return NtQueryInformationProcess( handle, class, ptr, len, retlen );
From: Vijay Kiran Kamuju infyquest@gmail.com
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/ntdll/tests/info.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 6771bbe4e3f..6151bb02800 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -2677,6 +2677,59 @@ static void test_query_process_debug_flags(int argc, char **argv) } }
+static void test_query_process_quota_limits(void) +{ + QUOTA_LIMITS qlimits; + NTSTATUS status; + HANDLE process; + ULONG ret_len; + + status = NtQueryInformationProcess(NULL, ProcessQuotaLimits, NULL, sizeof(qlimits), NULL); + ok(status == STATUS_INVALID_HANDLE, "NtQueryInformationProcess failed, status %#lx.\n", status); + + status = NtQueryInformationProcess(NULL, ProcessQuotaLimits, &qlimits, sizeof(qlimits), NULL); + ok(status == STATUS_INVALID_HANDLE, "NtQueryInformationProcess failed, status %#lx.\n", status); + + process = GetCurrentProcess(); + status = NtQueryInformationProcess( process, ProcessQuotaLimits, &qlimits, 2, &ret_len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationProcess failed, status %#lx.\n", status); + + memset(&qlimits, 0, sizeof(qlimits)); + status = NtQueryInformationProcess( process, ProcessQuotaLimits, &qlimits, sizeof(qlimits), &ret_len); + ok(status == STATUS_SUCCESS, "NtQueryInformationProcess failed, status %#lx.\n", status); + ok(sizeof(qlimits) == ret_len, "len set to %lx\n", ret_len); + ok(qlimits.MinimumWorkingSetSize == 204800,"Expected MinimumWorkingSetSize = 204800, got %s\n", + wine_dbgstr_longlong(qlimits.MinimumWorkingSetSize)); + ok(qlimits.MaximumWorkingSetSize == 1413120,"Expected MaximumWorkingSetSize = 1413120, got %s\n", + wine_dbgstr_longlong(qlimits.MaximumWorkingSetSize)); + ok(qlimits.PagefileLimit == ~0,"Expected PagefileLimit = ~0, got %s\n", + wine_dbgstr_longlong(qlimits.PagefileLimit)); + ok(qlimits.TimeLimit.QuadPart == ~0,"Expected TimeLimit = ~0, got %s\n", + wine_dbgstr_longlong(qlimits.TimeLimit.QuadPart)); + + if (winetest_debug > 1) + { + trace("Quota Limits:\n"); + trace("PagedPoolLimit: %s\n", wine_dbgstr_longlong(qlimits.PagedPoolLimit)); + trace("NonPagedPoolLimit: %s\n", wine_dbgstr_longlong(qlimits.NonPagedPoolLimit)); + } + + memset(&qlimits, 0, sizeof(qlimits)); + status = NtQueryInformationProcess( process, ProcessQuotaLimits, &qlimits, sizeof(qlimits) * 2, &ret_len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationProcess failed, status %#lx.\n", status); + ok(sizeof(qlimits) == ret_len, "len set to %lx\n", ret_len); + + memset(&qlimits, 0, sizeof(qlimits)); + status = NtQueryInformationProcess( process, ProcessQuotaLimits, &qlimits, sizeof(qlimits) - 1, &ret_len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationProcess failed, status %#lx.\n", status); + ok(sizeof(qlimits) == ret_len, "len set to %lx\n", ret_len); + + memset(&qlimits, 0, sizeof(qlimits)); + status = NtQueryInformationProcess( process, ProcessQuotaLimits, &qlimits, sizeof(qlimits) + 1, &ret_len); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationProcess failed, status %#lx.\n", status); + ok(sizeof(qlimits) == ret_len, "len set to %lx\n", ret_len); +} + static void test_readvirtualmemory(void) { HANDLE process; @@ -3886,6 +3939,7 @@ START_TEST(info) test_query_process_debug_object_handle(argc, argv); test_query_process_debug_flags(argc, argv); test_query_process_image_info(); + test_query_process_quota_limits(); test_mapprotection(); test_threadstack();
On Sun Mar 24 18:31:54 2024 +0000, Alexandre Julliard wrote:
This will need a corresponding mapping in wow64_NtQueryInformationProcess.
Done.
Nikolay Sivov (@nsivov) commented about dlls/wow64/process.c:
case ProcessExecuteFlags: /* ULONG */ case ProcessCookie: /* ULONG */ case ProcessCycleTime: /* PROCESS_CYCLE_TIME_INFORMATION */
- case ProcessQuotaLimits: /* QUOTA_LIMITS */ /* FIXME: check buffer alignment */ return NtQueryInformationProcess( handle, class, ptr, len, retlen );
I don't think it's enough, because of the SIZE_T fields in the structure.
On Sun Mar 24 18:48:15 2024 +0000, Nikolay Sivov wrote:
I don't think it's enough, because of the SIZE_T fields in the structure.
Let me elaborate:
`SIZE_T` fields depends on bitness. The Wow64 translation layer is responsible for translating **64-bit** structure returned by native syscall, to **32-bit** structure usable by the application.
We don't run new-style wow64 tests on GitLab CI yet, but I think this MR will fail those if `QUOTA_LIMITS` indeed has `SIZE_T` fields (haven't checked).
On Wed Mar 27 09:05:11 2024 +0000, Jinoh Kang wrote:
Let me elaborate: `SIZE_T` fields depends on bitness. The Wow64 translation layer is responsible for translating **64-bit** structure returned by native syscall, to **32-bit** structure usable by the application. We don't run new-style wow64 tests on GitLab CI yet, but I think this MR will fail those if `QUOTA_LIMITS` indeed has `SIZE_T` fields (haven't checked).
We need a 32bit structure in struct32.h for QUOTA_LIMITS and function to convert the values. I have created a patch for it, so you can squash it in. But we may have to test and implement for QUOTA_LIMITS_EX as well (that might be for future)[wow64_quota.diff](/uploads/7f6e62e72778bb3af8b1e89fe3004009/wow64_quota.diff).
On Sat Apr 6 21:06:30 2024 +0000, Vijay Kiran Kamuju wrote:
We need a 32bit structure in struct32.h for QUOTA_LIMITS and function to convert the values. I have created a patch for it, so you can squash it in. But we may have to test and implement for QUOTA_LIMITS_EX as well (that might be for future)[wow64_quota.diff](/uploads/7f6e62e72778bb3af8b1e89fe3004009/wow64_quota.diff).
Sorry, it seems I missed this comment and I havent' had the time to look at this further. Superseeded by !5501.
This merge request was closed by Gijs Vermeulen.