Based on a patch by Qian Hong.
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 | 40 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 4342ac8ac45..005f4054821 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,45 @@ 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 ); + + if (size >= sizeof(QUOTA_LIMITS)) + { + if (!info) + ret = STATUS_ACCESS_VIOLATION; + else if (!handle) + ret = STATUS_INVALID_HANDLE; + else + { + /* FIXME : SetProcessWorkingSetSize can also set the quota values + Quota Limits should be stored inside 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, sizeof(QUOTA_LIMITS)); + len = sizeof(qlimits); + } + + if (size > sizeof(QUOTA_LIMITS)) + ret = STATUS_INFO_LENGTH_MISMATCH; + } + else + { + len = sizeof(qlimits); + 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 );
From: Vijay Kiran Kamuju infyquest@gmail.com
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/ntdll/tests/info.c | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 5028dd11e99..9cf12646b46 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -2677,6 +2677,60 @@ static void test_query_process_debug_flags(int argc, char **argv) } }
+static void test_query_process_qlimits(void) +{ + QUOTA_LIMITS qlimits; + NTSTATUS status; + HANDLE process; + ULONG ret_len; + + status = NtQueryInformationProcess(NULL, ProcessQuotaLimits, NULL, sizeof(qlimits), NULL); + ok(status == STATUS_ACCESS_VIOLATION || 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; @@ -3885,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_qlimits(); test_mapprotection(); test_threadstack();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143923
Your paranoid android.
=== w11pro64 (32 bit report) ===
ntdll: info.c:599: Test failed: extended 1: i 110 (L"UsoClient.exe"): Got unexpected status 0xc000000b, pid 00001410. info.c:599: Test failed: extended 1: i 112 (L"UsoClient.exe"): Got unexpected status 0xc000000b, pid 00001D30.
This merge request was approved by Gijs Vermeulen.
Jinoh Kang (@iamahuman) commented about dlls/ntdll/tests/info.c:
}
}
+static void test_query_process_qlimits(void) +{
- QUOTA_LIMITS qlimits;
- NTSTATUS status;
- HANDLE process;
- ULONG ret_len;
- status = NtQueryInformationProcess(NULL, ProcessQuotaLimits, NULL, sizeof(qlimits), NULL);
- ok(status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
One of this is not latest Windows behavior and should be marked broken() I think.
Jinoh Kang (@iamahuman) commented about dlls/ntdll/unix/process.c:
else if (!handle)
ret = STATUS_INVALID_HANDLE;
else
{
/* FIXME : SetProcessWorkingSetSize can also set the quota values
Quota Limits should be stored inside 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, sizeof(QUOTA_LIMITS));
len = sizeof(qlimits);
Why not set `len` unconditionally, just like `case ProcessCycleTime`?
On Tue Mar 19 09:20:21 2024 +0000, Jinoh Kang wrote:
One of this is not latest Windows behavior and should be marked broken() I think.
Everything after WinXP seems to return `STATUS_INVALID_HANDLE`. Wine, however, still returns STATUS_ACCESS_VIOLATION consistently in this case for other classes. It's also done like this in other tests in this file, so maybe we should leave it as-is?