[PATCH 11/11] kernel32/heap: Add registry caps for reported memory.

Adam Martinson amartinson at codeweavers.com
Wed May 25 16:03:34 CDT 2011


This is a workaround for some broken installers which don't understand
large amounts of memory.  eg, the Photoshop 4 installer is broken on
Windows on systems with modern amounts of memory due to a bug in
Macromedia Director.  Macromedia's suggested solution is to reduce the
pagefile size to 200MB or less.  This gives us a similar course of action,
setting HKLM\Software\Wine\GlobalMemory\TotalPageFileMax = "200" fixes the
installer in Win98 mode.
---
 dlls/kernel32/heap.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index b70c755..5bb4cd8 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -61,6 +61,7 @@
 #include "winerror.h"
 #include "winnt.h"
 #include "winternl.h"
+#include "winreg.h"
 #include "wine/exception.h"
 #include "wine/debug.h"
 
@@ -1140,6 +1141,9 @@ BOOL WINAPI GlobalMemoryStatusEx( LPMEMORYSTATUSEX lpmemex )
 {
     static MEMORYSTATUSEX	cached_memstatus;
     static int cache_lastchecked = 0;
+    static DWORDLONG ullTotalPhysMax = ~((DWORDLONG)0);
+    static DWORDLONG ullTotalPageFileMax = ~((DWORDLONG)0);
+    static DWORDLONG ullTotalVirtualMax = ~((DWORDLONG)0);
     SYSTEM_INFO si;
     OSVERSIONINFOW osver;
 #ifdef linux
@@ -1164,6 +1168,37 @@ BOOL WINAPI GlobalMemoryStatusEx( LPMEMORYSTATUSEX lpmemex )
         return FALSE;
     }
 
+    /* Only check this once */
+    if (!cache_lastchecked)
+    {
+        HMODULE hadvapi32 = LoadLibraryA("advapi32.dll");
+#define ADVAPI32_GET_PROC(func) typeof(func) * p ## func = (void*)GetProcAddress(hadvapi32, #func)
+        ADVAPI32_GET_PROC(RegOpenKeyExA);
+        ADVAPI32_GET_PROC(RegCloseKey);
+        ADVAPI32_GET_PROC(RegGetValueA);
+
+        HKEY hkey;
+        if (pRegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\GlobalMemory", 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
+        {
+            char buf[64];
+            DWORD bufsize = 64;
+
+            if (pRegGetValueA(hkey, NULL, "TotalPhysMax", RRF_RT_REG_SZ, NULL, buf, &bufsize) == ERROR_SUCCESS)
+                ullTotalPhysMax = strtouq(buf, NULL, 0) * 1024 * 1024;
+
+            bufsize = 64;
+            if (pRegGetValueA(hkey, NULL, "TotalPageFileMax", RRF_RT_REG_SZ, NULL, buf, &bufsize) == ERROR_SUCCESS)
+                ullTotalPageFileMax = strtouq(buf, NULL, 0) * 1024 * 1024;
+
+            bufsize = 64;
+            if (pRegGetValueA(hkey, NULL, "TotalVirtualMax", RRF_RT_REG_SZ, NULL, buf, &bufsize) == ERROR_SUCCESS)
+                ullTotalVirtualMax = strtouq(buf, NULL, 0) * 1024 * 1024;
+
+            pRegCloseKey(hkey);
+        }
+        FreeLibrary(hadvapi32);
+    }
+
     if (time(NULL)==cache_lastchecked) {
 	*lpmemex = cached_memstatus;
 	return TRUE;
@@ -1260,6 +1295,20 @@ BOOL WINAPI GlobalMemoryStatusEx( LPMEMORYSTATUSEX lpmemex )
                                   / (lpmemex->ullTotalPhys / 100);
     }
 
+    if (lpmemex->ullTotalPhys > ullTotalPhysMax)
+    {
+        lpmemex->ullTotalPhys = ullTotalPhysMax;
+        if (lpmemex->ullAvailPhys > ullTotalPhysMax)
+            lpmemex->ullAvailPhys = ullTotalPhysMax;
+    }
+
+    if (lpmemex->ullTotalPageFile > ullTotalPageFileMax)
+    {
+        lpmemex->ullTotalPageFile = ullTotalPageFileMax;
+        if (lpmemex->ullAvailPageFile > ullTotalPageFileMax)
+            lpmemex->ullAvailPageFile = ullTotalPageFileMax;
+    }
+
     /* Win98 returns only the swapsize in ullTotalPageFile/ullAvailPageFile,
        WinXP returns the size of physical memory + swapsize;
        Note: Project2k refuses to start if it sees less than 1Mb of free swap.
@@ -1279,7 +1328,7 @@ BOOL WINAPI GlobalMemoryStatusEx( LPMEMORYSTATUSEX lpmemex )
 
     /* FIXME: should do something for other systems */
     GetSystemInfo(&si);
-    lpmemex->ullTotalVirtual  = (ULONG_PTR)si.lpMaximumApplicationAddress-(ULONG_PTR)si.lpMinimumApplicationAddress;
+    lpmemex->ullTotalVirtual  = min((ULONG_PTR)si.lpMaximumApplicationAddress-(ULONG_PTR)si.lpMinimumApplicationAddress, ullTotalVirtualMax);
     /* FIXME: we should track down all the already allocated VM pages and subtract them, for now arbitrarily remove 64KB so that it matches NT */
     lpmemex->ullAvailVirtual  = lpmemex->ullTotalVirtual-64*1024;
 
-- 
1.7.1


--------------030509010600050309010609--



More information about the wine-devel mailing list