[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