# HG changeset patch # User Chris Cannam # Date 1169740512 0 # Node ID 07a96a1931c0a1ed9cc885447f983e17ae339b12 # Parent e08cb0158e811f48cebf866e0af3eb250588e142 ... diff -r e08cb0158e81 -r 07a96a1931c0 system/System.cpp --- a/system/System.cpp Thu Jan 25 15:26:15 2007 +0000 +++ b/system/System.cpp Thu Jan 25 15:55:12 2007 +0000 @@ -81,6 +81,24 @@ #endif } +#ifdef _WIN32 +/* MEMORYSTATUSEX is missing from older Windows headers, so define a + local replacement. This trick from MinGW source code. Ugh */ +typedef struct +{ + DWORD dwLength; + DWORD dwMemoryLoad; + DWORDLONG ullTotalPhys; + DWORDLONG ullAvailPhys; + DWORDLONG ullTotalPageFile; + DWORDLONG ullAvailPageFile; + DWORDLONG ullTotalVirtual; + DWORDLONG ullAvailVirtual; + DWORDLONG ullAvailExtendedVirtual; +} lMEMORYSTATUSEX; +typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*); +#endif + void GetRealMemoryMBAvailable(int &available, int &total) { @@ -89,18 +107,54 @@ #ifdef _WIN32 - MEMORYSTATUSEX status; - status.dwLength = sizeof(status); - if (!GlobalMemoryStatusEx(&status)) { - std::cerr << "WARNING: GetDiskFreeSpaceEx failed: error code " - << GetLastError() << std::endl; - return; + static bool checked = false; + static bool exFound = false; + static PFN_MS_EX ex; + + if (!checked) { + + HMODULE h = GetModuleHandle("kernel32.dll"); + + if (h) { + if ((ex = (PFN_MS_EX)GetProcAddress(h, "GlobalMemoryStatusEx"))) { + exFound = true; + } + } + + checked = true; } - DWORDLONG size = status.ullAvailPhys / 1048576; + + DWORDLONG avail = 0; + DWORDLONG total = 0; + + if (exFound) { + + lMEMORYSTATUSEX lms; + lms.dwLength = sizeof(lms); + if (!ex(&lms)) { + std::cerr << "WARNING: GlobalMemoryStatusEx failed: error code " + << GetLastError() << std::endl; + return; + } + avail = lms.ullAvailPhys; + total = lms.ullTotalPhys; + + } else { + + /* Fall back to GlobalMemoryStatus which is always available. + but returns wrong results for physical memory > 4GB */ + + MEMORYSTATUS ms; + GlobalMemoryStatus(&ms); + avail = ms.dwAvailPhys; + total = ms.dwTotalPhys; + } + + DWORDLONG size = avail / 1048576; if (size > INT_MAX) size = INT_MAX; available = int(size); - size = status.ullTotalPhys / 1048576; + size = total / 1048576; if (size > INT_MAX) size = INT_MAX; total = int(size);