Paul Gofman : kernel32: Do not impose 32 bit limits on Win64 in GlobalMemoryStatus().

Alexandre Julliard julliard at winehq.org
Tue Apr 27 16:08:58 CDT 2021


Module: wine
Branch: master
Commit: 72c562ce9c481e73a01f50e17b624095aab11bdc
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=72c562ce9c481e73a01f50e17b624095aab11bdc

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Wed Apr 21 17:58:26 2021 +0300

kernel32: Do not impose 32 bit limits on Win64 in GlobalMemoryStatus().

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/heap.c       | 21 +++++++++++----------
 dlls/kernel32/tests/heap.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index b7bd6f5f91d..02f4587d43b 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -543,7 +543,9 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
 {
     MEMORYSTATUSEX memstatus;
     OSVERSIONINFOW osver;
+#ifndef _WIN64
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( GetModuleHandleW(0) );
+#endif
 
     /* Because GlobalMemoryStatus is identical to GlobalMemoryStatusEX save
        for one extra field in the struct, and the lack of a bug, we simply
@@ -561,6 +563,14 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
     osver.dwOSVersionInfoSize = sizeof(osver);
     GetVersionExW(&osver);
 
+    lpBuffer->dwTotalPhys = memstatus.ullTotalPhys;
+    lpBuffer->dwAvailPhys = memstatus.ullAvailPhys;
+    lpBuffer->dwTotalPageFile = memstatus.ullTotalPageFile;
+    lpBuffer->dwAvailPageFile = memstatus.ullAvailPageFile;
+    lpBuffer->dwTotalVirtual = memstatus.ullTotalVirtual;
+    lpBuffer->dwAvailVirtual = memstatus.ullAvailVirtual;
+
+#ifndef _WIN64
     if ( osver.dwMajorVersion >= 5 || osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
     {
         lpBuffer->dwTotalPhys = min( memstatus.ullTotalPhys, MAXDWORD );
@@ -570,16 +580,6 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
         lpBuffer->dwAvailPageFile = min( memstatus.ullAvailPageFile, MAXDWORD );
         lpBuffer->dwTotalVirtual = min( memstatus.ullTotalVirtual, MAXDWORD );
         lpBuffer->dwAvailVirtual = min( memstatus.ullAvailVirtual, MAXDWORD );
-
-    }
-    else /* duplicate NT bug */
-    {
-        lpBuffer->dwTotalPhys = memstatus.ullTotalPhys;
-        lpBuffer->dwAvailPhys = memstatus.ullAvailPhys;
-        lpBuffer->dwTotalPageFile = memstatus.ullTotalPageFile;
-        lpBuffer->dwAvailPageFile = memstatus.ullAvailPageFile;
-        lpBuffer->dwTotalVirtual = memstatus.ullTotalVirtual;
-        lpBuffer->dwAvailVirtual = memstatus.ullAvailVirtual;
     }
 
     /* values are limited to 2Gb unless the app has the IMAGE_FILE_LARGE_ADDRESS_AWARE flag */
@@ -603,6 +603,7 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
         if (lpBuffer->dwTotalPageFile > MAXLONG) lpBuffer->dwTotalPageFile = MAXLONG;
         if (lpBuffer->dwAvailPageFile > MAXLONG) lpBuffer->dwAvailPageFile = MAXLONG;
     }
+#endif
 
     TRACE("Length %u, MemoryLoad %u, TotalPhys %lx, AvailPhys %lx,"
           " TotalPageFile %lx, AvailPageFile %lx, TotalVirtual %lx, AvailVirtual %lx\n",
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)
     {




More information about the wine-cvs mailing list