[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