[PATCH 10/11] kernel32/heap: Fix some hacks in GlobalMemoryStatus().

Adam Martinson amartinson at codeweavers.com
Wed May 25 16:32:30 CDT 2011


Fixes bugs 10844 + 11627 + 15708.
Breaks the Photoshop 4 installer on systems where it's also broken on
Windows.
---
 dlls/kernel32/heap.c |  107 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 93 insertions(+), 14 deletions(-)

diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c
index 9234b3b..b70c755 100644
--- a/dlls/kernel32/heap.c
+++ b/dlls/kernel32/heap.c
@@ -1302,6 +1302,96 @@ BOOL WINAPI GlobalMemoryStatusEx( LPMEMORYSTATUSEX lpmemex )
     return TRUE;
 }
 
+/* Check the current process and all ancestors.  Some apps run sub-processes that
+ * have the IMAGE_FILE_LARGE_ADDRESS_AWARE flag set, but the parent process doesn't.
+ * (eg, Dragon NaturallySpeaking 7 setup runs Install Shield 6).
+ * If any don't have IMAGE_FILE_LARGE_ADDRESS_AWARE, return FALSE. */
+static BOOL isProcessLAAware(void)
+{
+    WCHAR img_path[MAX_PATH + 1];
+    DWORD pid;
+    IMAGE_NT_HEADERS *nt = NULL;
+    PROCESS_BASIC_INFORMATION pbi;
+    BOOL la_aware;
+
+    nt = RtlImageNtHeader(GetModuleHandleW(0));
+    if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
+    {
+        la_aware = FALSE;
+    }
+    else
+    {
+
+        la_aware = TRUE;
+        img_path[MAX_PATH] = 0;
+        NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
+        pid = pbi.InheritedFromUniqueProcessId;
+    }
+
+    while (la_aware && pid)
+    {
+        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
+        if (!SUCCEEDED(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL)))
+        {
+            FIXME("NtQueryInformationProcess(%p) failed (pid %04x)\n", hProcess, pid);
+            pid = 0;
+        }
+        else
+        {
+            DWORD len = MAX_PATH;
+            if (QueryFullProcessImageNameW(hProcess, 0, img_path, &len) && len)
+            {
+
+                HMODULE hModule = GetModuleHandleW(img_path);
+                HANDLE  hFile = INVALID_HANDLE_VALUE, hMap = NULL;
+                img_path[len] = 0;
+
+                if (hModule)
+                {
+                    nt = RtlImageNtHeader(hModule);
+                }
+                else
+                {
+                    void*   mapping;
+
+                    hFile = CreateFileW(img_path, GENERIC_READ, FILE_SHARE_READ, NULL,
+                                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+                    if (hFile == INVALID_HANDLE_VALUE)
+                    {
+                        FIXME("Failed to open %s for pid %04x\n", wine_dbgstr_wn(img_path, len), pid);
+                    }
+                    else if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
+                    {
+                        if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
+                            nt = RtlImageNtHeader(mapping);
+                    }
+                }
+
+                if (!nt)
+                {
+                    FIXME("RtlImageNtHeader() failed\n");
+                }
+                else
+                {
+                    if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
+                    {
+                        la_aware = FALSE;
+                    }
+                }
+
+                if (hModule) CloseHandle(hModule);
+                if (hMap) UnmapViewOfFile(hMap);
+                if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
+            }
+            pid = pbi.InheritedFromUniqueProcessId;
+        }
+        CloseHandle(hProcess);
+    }
+
+    TRACE("() => %s\n", la_aware? "TRUE" : "FALSE");
+    return la_aware;
+}
+
 /***********************************************************************
  *           GlobalMemoryStatus   (KERNEL32.@)
  * Provides information about the status of the memory, so apps can tell
@@ -1314,7 +1404,6 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
 {
     MEMORYSTATUSEX memstatus;
     OSVERSIONINFOW osver;
-    IMAGE_NT_HEADERS *nt = RtlImageNtHeader( GetModuleHandleW(0) );
 
     /* Because GlobalMemoryStatus is identical to GlobalMemoryStatusEX save
        for one extra field in the struct, and the lack of a bug, we simply
@@ -1353,24 +1442,14 @@ VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
     }
 
     /* values are limited to 2Gb unless the app has the IMAGE_FILE_LARGE_ADDRESS_AWARE flag */
-    /* page file sizes are not limited (Adobe Illustrator 8 depends on this) */
-    if (!(nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
+    if (!isProcessLAAware())
     {
         if (lpBuffer->dwTotalPhys > MAXLONG) lpBuffer->dwTotalPhys = MAXLONG;
         if (lpBuffer->dwAvailPhys > MAXLONG) lpBuffer->dwAvailPhys = MAXLONG;
-        if (lpBuffer->dwTotalVirtual > MAXLONG) lpBuffer->dwTotalVirtual = MAXLONG;
-        if (lpBuffer->dwAvailVirtual > MAXLONG) lpBuffer->dwAvailVirtual = MAXLONG;
-    }
-
-    /* work around for broken photoshop 4 installer */
-    if ( 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 */
-    if (nt->OptionalHeader.MajorSubsystemVersion < 4)
-    {
         if (lpBuffer->dwTotalPageFile > MAXLONG) lpBuffer->dwTotalPageFile = MAXLONG;
         if (lpBuffer->dwAvailPageFile > MAXLONG) lpBuffer->dwAvailPageFile = MAXLONG;
+        if (lpBuffer->dwTotalVirtual > MAXLONG) lpBuffer->dwTotalVirtual = MAXLONG;
+        if (lpBuffer->dwAvailVirtual > MAXLONG) lpBuffer->dwAvailVirtual = MAXLONG;
     }
 
     TRACE("Length %u, MemoryLoad %u, TotalPhys %lx, AvailPhys %lx,"
-- 
1.7.1


--------------030509010600050309010609
Content-Type: text/x-patch;
 name="0011-kernel32-heap-Add-registry-caps-for-reported-memory.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0011-kernel32-heap-Add-registry-caps-for-reported-memory.pat";
 filename*1="ch"



More information about the wine-devel mailing list