Signed-off-by: Paul Gofman <pgofman(a)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)
{
--
2.30.2