Marking NE binaries compatible

07 May 2017

I previously wrote about Win32 binaries using a PE header subsystem version to indicate support for a new version of Windows. But what happens when a binary needs to run on an old version but the new version is sufficiently different to require indicating compatibility?

The transition from Windows 2.x to Windows 3.0 was a very large step. Although the executable format was the same - the New Executable format, aka NE - Windows 3.0 would launch binaries in protected mode with far more available memory by default. Not all programs could handle this; most non-trivial ones would not. Although Windows 3.0 supported a real mode runtime in order to ensure compatibility, it couldn't dynamically switch between modes, so if a user tried to run a Windows 2.0 application on Windows 3.0, it needed to decide what to do. So if asked to run a Windows 2.0 application from protected mode that didn't indicate support, it gave a very descriptive warning:

In order to allow an application to run on both real mode Windows 2.0 and protected mode Windows 3.0 without the warning, two bits were used in the executable format to indicate support for protected mode memory and proportional fonts. The tool to set these bits was distributed with the Windows 3.0 SDK - not exactly convenient, because any application requiring this treatment must have been compiled with the Windows 2.x SDK.

Microsoft (R) Windows Executable Marker  Version 1.0
Copyright (C) Microsoft Corp 1990.  All rights reserved.

usage: MARK [-q] [MEMORY [FONT]] filename

-q   indicates to MARK.EXE to suppress the listing of major operations.
MEMORY indicates the application is well-behaved in its use of memory
   so that it can run safely in protect mode.
FONT indicates the application will be given the proportional system font,
   instead of the fixed-pitch font used in Windows 2.x.
Application cannot be marked FONT without also being marked MEMORY.

Having marked an application in this way, Windows no longer displays a warning. It's possible to set these bits on any binary - they're in offset 37h from the NE header - but note that if the application really isn't designed for protected memory, it's likely to crash.

Since Windows 2.0 wasn't a very popular platform for developers, there aren't many applications that were marked in this way. One prominent exception is Word for Windows 1.1, which runs on Windows 2.x and 3.x protected mode correctly.