Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - fix random test failures which are due to exact available memory sizes changing between GlobalMemoryStatus() and GlobalMemoryStatusEx() calls (by performing approximate comparison).
Fixes computer configuration detection in Forza Horizon 4 (avoids the complain about the system falling below minimum requirements).
dlls/kernel32/heap.c | 7 +++--- dlls/kernel32/tests/heap.c | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c index b7bd6f5f91d..c8ae9f5a943 100644 --- a/dlls/kernel32/heap.c +++ b/dlls/kernel32/heap.c @@ -44,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(globalmem);
static HANDLE systemHeap; /* globally shared heap */
+static BOOL is_win64 = sizeof(void *) == 8;
/*********************************************************************** * HEAP_CreateSystemHeap @@ -561,7 +562,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer ) osver.dwOSVersionInfoSize = sizeof(osver); GetVersionExW(&osver);
- if ( osver.dwMajorVersion >= 5 || osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) + if ( !is_win64 && (osver.dwMajorVersion >= 5 || osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ) { lpBuffer->dwTotalPhys = min( memstatus.ullTotalPhys, MAXDWORD ); lpBuffer->dwAvailPhys = min( memstatus.ullAvailPhys, MAXDWORD ); @@ -572,7 +573,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer ) lpBuffer->dwAvailVirtual = min( memstatus.ullAvailVirtual, MAXDWORD );
} - else /* duplicate NT bug */ + else /* 64 bit case, or duplicate NT bug */ { lpBuffer->dwTotalPhys = memstatus.ullTotalPhys; lpBuffer->dwAvailPhys = memstatus.ullAvailPhys; @@ -593,7 +594,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer ) }
/* work around for broken photoshop 4 installer */ - if ( lpBuffer->dwAvailPhys + lpBuffer->dwAvailPageFile >= 2U*1024*1024*1024) + if ( !is_win64 && lpBuffer->dwAvailPhys + lpBuffer->dwAvailPageFile >= 2U*1024*1024*1024 ) lpBuffer->dwAvailPageFile = 2U*1024*1024*1024 - lpBuffer->dwAvailPhys - 1;
/* limit page file size for really old binaries */ diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index fa372b14e21..0a4e3367f60 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -1213,6 +1213,51 @@ static void test_GetPhysicallyInstalledSystemMemory(void) "expected total_memory >= memstatus.ullTotalPhys / 1024\n"); }
+static BOOL compare_ulong64(ULONG64 v1, ULONG64 v2, ULONG64 max_diff) +{ + ULONG64 diff = v1 > v2 ? v1 - v2 : v2 - v1; + + return diff <= max_diff; +} + +static void test_GlobalMemoryStatus(void) +{ + static const ULONG64 max_diff = 0x200000; + MEMORYSTATUSEX memex; + MEMORYSTATUS mem; + SIZE_T size; + + mem.dwLength = sizeof(mem); + GlobalMemoryStatus(&mem); + memex.dwLength = sizeof(memex); + GlobalMemoryStatusEx(&memex); + + /* Compare values approximately as the available memory may change between + * GlobalMemoryStatus() and GlobalMemoryStatusEx() calls. */ + + size = min(memex.ullTotalPhys, ~(SIZE_T)0 >> 1); + ok(compare_ulong64(mem.dwTotalPhys, size, max_diff), "Got unexpected dwTotalPhys %s, size %s.\n", + wine_dbgstr_longlong(mem.dwTotalPhys), wine_dbgstr_longlong(size)); + size = min(memex.ullAvailPhys, ~(SIZE_T)0 >> 1); + ok(compare_ulong64(mem.dwAvailPhys, size, max_diff), "Got unexpected dwAvailPhys %s, size %s.\n", + wine_dbgstr_longlong(mem.dwAvailPhys), wine_dbgstr_longlong(size)); + + size = min(memex.ullTotalPageFile, ~(SIZE_T)0); + ok(compare_ulong64(mem.dwTotalPageFile, size, max_diff), + "Got unexpected dwTotalPageFile %s, size %s.\n", + wine_dbgstr_longlong(mem.dwTotalPageFile), wine_dbgstr_longlong(size)); + size = min(memex.ullAvailPageFile, ~(SIZE_T)0); + ok(compare_ulong64(mem.dwAvailPageFile, size, max_diff), "Got unexpected dwAvailPageFile %s, size %s.\n", + wine_dbgstr_longlong(mem.dwAvailPageFile), wine_dbgstr_longlong(size)); + + ok(compare_ulong64(mem.dwTotalVirtual, memex.ullTotalVirtual, max_diff), + "Got unexpected dwTotalVirtual %s, ullTotalVirtual %s.\n", + wine_dbgstr_longlong(mem.dwTotalVirtual), wine_dbgstr_longlong(memex.ullTotalVirtual)); + ok(compare_ulong64(mem.dwAvailVirtual, memex.ullAvailVirtual, max_diff), + "Got unexpected dwAvailVirtual %s, ullAvailVirtual %s.\n", + wine_dbgstr_longlong(mem.dwAvailVirtual), wine_dbgstr_longlong(memex.ullAvailVirtual)); +} + START_TEST(heap) { int argc; @@ -1246,6 +1291,7 @@ START_TEST(heap)
test_HeapQueryInformation(); test_GetPhysicallyInstalledSystemMemory(); + test_GlobalMemoryStatus();
if (pRtlGetNtGlobalFlags) {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=89156
Your paranoid android.
=== debiant2 (32 bit report) ===
kernel32: comm.c:728: Test failed: Still pending 2070003979 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue
=== debiant2 (32 bit WoW report) ===
kernel32: comm.c:728: Test failed: Still pending 2070003979 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue comm.c:728: Test failed: Still pending 5677407 characters in OutQueue
=== debiant2 (64 bit WoW report) ===
kernel32: comm.c:727: Test failed: Unexpected 2070004009 chars in InQueue comm.c:996: Test failed: Unexpected 13335381 chars in OutQueue comm.c:997: Test failed: ClearCommErrors: Unexpected error 0x0057ad0f comm.c:729: Test failed: Unexpected errors 0x00cb7b55 comm.c:2011: Test failed: expected 0, got 13335381 bytes in OutQueue comm.c:2012: Test failed: expected errors 0, got 0x57ad0f comm.c:727: Test failed: Unexpected 5515760 chars in InQueue comm.c:729: Test failed: Unexpected errors 0x0053fa37
On Wed, 21 Apr 2021, Paul Gofman wrote: [...]
- size = min(memex.ullTotalPhys, ~(SIZE_T)0 >> 1);
- ok(compare_ulong64(mem.dwTotalPhys, size, max_diff), "Got unexpected dwTotalPhys %s, size %s.\n",
wine_dbgstr_longlong(mem.dwTotalPhys), wine_dbgstr_longlong(size));
- size = min(memex.ullAvailPhys, ~(SIZE_T)0 >> 1);
- ok(compare_ulong64(mem.dwAvailPhys, size, max_diff), "Got unexpected dwAvailPhys %s, size %s.\n",
wine_dbgstr_longlong(mem.dwAvailPhys), wine_dbgstr_longlong(size));
This does not seem to work on Windows <= 8.1 when there is more than 4GB of RAM:
https://test.winehq.org/data/patterns.html#kernel32:heap
heap.c:1239: Test failed: Got unexpected dwTotalPhys ffffffff, size 7fffffff. heap.c:1242: Test failed: Got unexpected dwAvailPhys ffffffff, size 7fffffff.
The available memory is probably why this was not detected by the TestBot VMs since they all have less than 4GB.
Could you adjust the test?