I found some C# code that checks to see if an EXE is LARGE_ADDRESS_AWARE, and if not , it will update its header. I've verified that it works by using VMMAP.
I created a C# console app which is run as a part of my installation program and updates the EXE files found in installation folder as arguments. Anyway, I do not have to rely on third party tools except the .NET framework.
USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
USING System.IO
BEGIN NAMESPACE XSharpMakeLargeAddressAware
#DEFINE IMAGE_FILE_LARGE_ADDRESS_AWARE 0x20
FUNCTION Start() AS VOID
MakeLargeAware("c:somefolderprogramname.exe") // replace with your own exe path
return
function MakeLargeAware(file as string) as logic
LOCAL b AS LOGIC
begin using var fs := File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
b := LargeAware(fs)
fs.Close()
end using
return b
function LargeAware(stream as Stream) as logic
var br := BinaryReader{stream}
var bw := BinaryWriter{stream}
if (br.ReadInt16() != 0x5A4D) //No MZ Header
return false
ENDIF
br:BaseStream:Position := 0x3C
var peloc := br:ReadInt32() //Get the PE header location.
br:BaseStream:Position := peloc
if (br.ReadInt32() != 0x4550) //No PE header
return false
ENDIF
br:BaseStream:Position += 0x12
local nFilePos := (int)br:BaseStream:Position as longint
local nLgaInt := br:ReadInt16() as SHORT
local bIsLGA := (_And(nLgaInt, IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE) AS LOGIC
if (bIsLGA)
RETURN TRUE
ENDIF
nLgaInt |= IMAGE_FILE_LARGE_ADDRESS_AWARE
local nFilePos1 := bw:Seek((int)nFilePos, SeekOrigin.Begin) as int64
bw.Write(nLgaInt)
bw.Flush()
local nFilePos2 := br:BaseStream:Seek(nFilePos, SeekOrigin.Begin) as int64
nLgaInt := br:ReadInt16()
bIsLGA := (nLgaInt & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE
return bIsLGA
END NAMESPACE
Very nice, something what I I was already looking for.
Daniel, the author of the tool Wolfgang had found, has confirmed that he makes the same as the Visual Studio tool.
He also said that on 32-Bit Windows computers the flags will be ignored and do not disturb.
We are making now some beta tests in our company. It looks good until now.
I have tested that it works also with XSharp 32-bit programs. Although the memory management of Dot.net is better I have seen that also in Dotnet we reach quickly the 2 GB limit. And the move from 32 bit to 64 bit is another big challenge after having moved from VO to XSharp.
The first problematic computer:
The program starts shortly with the following message: Processor stack fault
FFF1FF6C
Ok
It seems to be the standard VO error message window.
On my computer the same EXE file works fine.
The other machine is nearly identical (same motherboard, same Windows 10 64Bit)
Does anybody has an idea where this can come from?
5.6 What is an "Unrecoverable Error 650: Processor Stack Fault"? It's a result of infinite recursion, which occurs when a function calls itself, which calls itself, which calls itself, and so on without stopping. Most often this occurs when your error handler has an error, which triggers the error handler
ArneOrtlinghaus wrote:The first problematic computer:
The program starts shortly with the following message: Processor stack fault
FFF1FF6C
Ok
It seems to be the standard VO error message window.
On my computer the same EXE file works fine.
The other machine is nearly identical (same motherboard, same Windows 10 64Bit)
Does anybody has an idea where this can come from?
It is strange. Until now two computers have been found, where the program does not start anymore.
- The error happens in the EXE before the first self written line of code
- It happens in Vo28run!_ConvertResult
- this calls vo28run!_StackErr and then produces the error message on the screen
- It happens exactly with a simple console application.
Can you provide the code for simple console app?
How did you apply the LMA feature?
Jamal
ArneOrtlinghaus wrote:It is strange. Until now two computers have been found, where the program does not start anymore.
- The error happens in the EXE before the first self written line of code
- It happens in Vo28run!_ConvertResult
- this calls vo28run!_StackErr and then produces the error message on the screen
- It happens exactly with a simple console application.