[Bug 44931] Macromedia Director Player 5.0/6.0 based games fail to run: " This program requires at least 3MB of free virtual memory to run" (Nine: The last Resort)
wine-bugs at winehq.org
wine-bugs at winehq.org
Sat Apr 7 11:40:57 CDT 2018
https://bugs.winehq.org/show_bug.cgi?id=44931
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|-unknown |kernel32
--- Comment #2 from Anastasius Focht <focht at gmx.net> ---
Hello again,
I found a "backup" of 'Macromedia Director 5' on Internet to play with.
Even the installer has the same problem.
--- quote ---
Macromedia Director 5
Released in 1996 by Macromedia
For Windows 3.1 with Win32s and Windows 95
Director is a multimedia authoring tool, and is used to create
Macromedia Shockwave content.
This archive contains an ISO image with both a 16-bit Windows 3.1
version and a 32-bit Windows 95 version.
--- quote ---
On my system:
--- snip ---
$ WINEDEBUG=+seh,+relay,+globalmem wine ./d5acce32.exe >>log.txt 2>&1
...
0009:Call KERNEL32.GlobalMemoryStatus(0032f81c) ret=00469cfb
0009:trace:globalmem:GlobalMemoryStatusEx <-- LPMEMORYSTATUSEX: dwLength 64,
dwMemoryLoad 13, ullTotalPhys 3e32a9000, ullAvailPhys 35c7a0000,
ullTotalPageFile 5d92a8000, ullAvailPageFile 55279f000, ullTotalVirtual
7ffdffff, ullAvailVirtual 7ffcffff
0009:trace:globalmem:GlobalMemoryStatus Length 32, MemoryLoad 13, TotalPhys
7fffffff, AvailPhys 7fffffff, TotalPageFile 7fffffff, AvailPageFile 7fffffff,
TotalVirtual 7ffdffff, AvailVirtual 7ffcffff
0009:Ret KERNEL32.GlobalMemoryStatus() retval=000000c7 ret=00469cfb
0009:Call user32.LoadStringA(00400000,00000880,0032f88c,00000080) ret=00469d2b
0009:Ret user32.LoadStringA() retval=00000013 ret=00469d2b
0009:Call user32.LoadStringA(00400000,0000000f,0032f90c,00000080) ret=00469d42
0009:Ret user32.LoadStringA() retval=00000042 ret=00469d42
0009:Call user32.MessageBoxA(00000000,0032f98c "This program requires at least
3MB of free virtual memory to run.",0032f88c "Director Player 5.0",00000000)
ret=00469d7b
...
--- snip ---
Disassembly of installer show the same brain damaged sequence as from the link
I posted earlier:
--- snip ---
00469CE0 SUB ESP,29C
00469CE6 LEA EAX,[LOCAL.156]
00469CEA PUSH ESI
00469CEB MOV DWORD PTR SS:[LOCAL.156],20
00469CF3 PUSH EDI
00469CF4 PUSH EAX ; pMemorystatus => OFFSET LOCAL.156
00469CF5 CALL DWORD PTR DS:[<&KERNEL32.GlobalMemoryStatus>]
00469CFB MOV EAX,DWORD PTR SS:[LOCAL.151] ; AvailPageFile = 0x7FFFFFFF
00469CFF ADD EAX,DWORD PTR SS:[LOCAL.153] ; AvailPhys = 0x7FFFFFFF
; 2GB AvailPageFile + 2GB AvailPhys = overflow
00469D03 CMP EAX,387520 ; >= 3700000 Bytes?
00469D08 JGE SHORT 00469D88
00469D0A LEA EAX,[LOCAL.128]
00469D11 PUSH 80
00469D16 PUSH EAX
00469D17 MOV ECX,DWORD PTR DS:[514350]
00469D1D PUSH 880 ; StringID = 2176. => 'Director Player 5.01'
00469D22 MOV ESI,DWORD PTR DS:[<&USER32.LoadStringA>]
00469D28 PUSH ECX
00469D29 CALL ESI ; USER32.LoadStringA
00469D2B LEA ECX,[LOCAL.96]
00469D32 PUSH 80
00469D37 PUSH ECX
00469D38 MOV EAX,DWORD PTR DS:[514350]
00469D3D PUSH 0F ; StringID = 15. => 'This program requires at
least %dMB of free virtual memory to run.'
00469D3F PUSH EAX
00469D40 CALL ESI ; USER32.LoadStringA
00469D42 LEA ECX,[LOCAL.96]
00469D49 PUSH 3
00469D4B LEA EDX,[LOCAL.64]
00469D52 PUSH ECX
00469D53 PUSH 100
00469D58 PUSH EDX
00469D59 CALL 004FFA7F
00469D5E LEA ECX,[LOCAL.128]
00469D65 LEA EDX,[LOCAL.64]
00469D6C ADD ESP,10
00469D6F PUSH 0 ; Type = MB_OK|MB_DEFBUTTON1|MB_APPLMODAL
00469D71 PUSH ECX ; Caption => OFFSET LOCAL.128
00469D72 PUSH EDX ; Text => OFFSET LOCAL.64
00469D73 PUSH 0 ; hOwner = NULL
00469D75 CALL DWORD PTR DS:[<&USER32.MessageBoxA>]
00469D7B XOR EAX,EAX
00469D7D POP EDI
00469D7E POP ESI
00469D7F ADD ESP,29C
00469D85 RETN 8
00469D88 CALL 004676C0
00469D8D TEST EAX,EAX
00469D8F JZ SHORT 00469D9E
00469D91 XOR EAX,EAX
00469D93 POP EDI
00469D94 POP ESI
00469D95 ADD ESP,29C
00469D9B RETN 8
--- snip ---
You basically need to ensure dwAvailPageFile+dwAvailPhys <= 0x7FFFFFFF (2GB)
Wine source:
https://source.winehq.org/git/wine.git/blob/fe09e2dba66095f1494946226c911a2acc65c9c6:/dlls/kernel32/heap.c#l1373
--- snip ---
1373 VOID WINAPI GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer )
1374 {
1375 MEMORYSTATUSEX memstatus;
1376 OSVERSIONINFOW osver;
1377 IMAGE_NT_HEADERS *nt = RtlImageNtHeader( GetModuleHandleW(0) );
1378
1379 /* Because GlobalMemoryStatus is identical to GlobalMemoryStatusEX
save
1380 for one extra field in the struct, and the lack of a bug, we simply
1381 call GlobalMemoryStatusEx and copy the values across. */
1382 memstatus.dwLength = sizeof(memstatus);
1383 GlobalMemoryStatusEx(&memstatus);
1384
1385 lpBuffer->dwLength = sizeof(*lpBuffer);
1386 lpBuffer->dwMemoryLoad = memstatus.dwMemoryLoad;
...
1416 /* values are limited to 2Gb unless the app has the
IMAGE_FILE_LARGE_ADDRESS_AWARE flag */
1417 /* page file sizes are not limited (Adobe Illustrator 8 depends on
this) */
1418 if (!(nt->FileHeader.Characteristics &
IMAGE_FILE_LARGE_ADDRESS_AWARE))
1419 {
1420 if (lpBuffer->dwTotalPhys > MAXLONG) lpBuffer->dwTotalPhys =
MAXLONG;
1421 if (lpBuffer->dwAvailPhys > MAXLONG) lpBuffer->dwAvailPhys =
MAXLONG;
1422 if (lpBuffer->dwTotalVirtual > MAXLONG) lpBuffer->dwTotalVirtual =
MAXLONG;
1423 if (lpBuffer->dwAvailVirtual > MAXLONG) lpBuffer->dwAvailVirtual =
MAXLONG;
1424 }
1425
1426 /* work around for broken photoshop 4 installer */
1427 if ( lpBuffer->dwAvailPhys + lpBuffer->dwAvailPageFile >=
2U*1024*1024*1024)
1428 lpBuffer->dwAvailPageFile = 2U*1024*1024*1024 -
lpBuffer->dwAvailPhys - 1;
1429
1430 /* limit page file size for really old binaries */
1431 if (nt->OptionalHeader.MajorSubsystemVersion < 4 ||
1432 nt->OptionalHeader.MajorOperatingSystemVersion < 4)
1433 {
1434 if (lpBuffer->dwTotalPageFile > MAXLONG) lpBuffer->dwTotalPageFile
= MAXLONG;
1435 if (lpBuffer->dwAvailPageFile > MAXLONG) lpBuffer->dwAvailPageFile
= MAXLONG;
1436 }
...
1443 }
--- snip ---
"work around for broken photoshop 4 installer" -> Line 1427 looks pretty much
what we want. The change was introduced by Alexandre himself in year 2004:
https://source.winehq.org/git/wine.git/commitdiff/2130f613102c46aaa643336ff4f5595a104c7151
("In GlobalMemoryStatus, also cap the sum of dwAvailPhys and")
The problem with that code is the test for < 2 GB range (MAXLONG).
GCC emits this code:
--- snip ---
...
addl %edx,%eax
testl %eax,%eax
jns no_need_to_cap_2gb
...
--- snip ---
'test' will set the sign flag based on the most significant bit of %eax.
Consider two cases:
dwAvailPageFile(0x7fffffff) + dwAvailPhys(0x7fffffff) = 0xfffffffe, causes a
signed overflow, but not an unsigned overflow (or carry) -> 'S' flag set, 'C'
flag not set.
dwAvailPageFile(0xffffffff) + dwAvailPhys(0x7fffffff) = 0x7ffffffe, causes an
unsigned overflow (with carry) -> 'C' flag set, 'S' flag not set.
The latter case is actually the default for non-IMAGE_FILE_LARGE_ADDRESS_AWARE
apps. The unsigned overflow is not detected hence no 2GB cap handling.
I've modified the expression to take potential unsigned integer overflow into
account and the app works correctly.
This will likely fix a lot of old Adobe installers/apps from Win9X era.
Regards
--
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.
More information about the wine-bugs
mailing list