Ensuring that older software continues to function on newer versions of Windows has been a challenge shadowing Microsoft since the operating system’s earliest days. Compatibility has always been one of the principal conditions of its success: if familiar applications cease to run, users refuse to migrate. Yet the path toward keeping legacy programs alive has been long — and at times rather peculiar.
In the era of Windows 3.1, everything seemed far simpler. The system performed almost nothing automatically, and it was the user’s responsibility to tell Windows which application they intended to run when two files shared the same name. Microsoft veteran Raymond Chen recalls a classic example: C:\MAIL\MAIL.EXE. This could be Microsoft Mail, the company’s own client, or cc:Mail for MS-DOS. The system could not guess, so the necessary information was written manually into the APPS.INF file, guiding Windows on how to handle the program. At the time, such a solution was considered both modern and convenient.
The arrival of Windows 95 changed the situation dramatically. User improvisation had to be set aside: Microsoft decided to embed a fully fledged mechanism into the operating system to adjust its behaviour for specific applications. A compatibility database was introduced, containing special flags for different programs. These flags could alter Windows’ response to various system calls or quirks in legacy code. In extreme cases, the Windows team even shipped automated “patches” for third-party applications when ordinary adjustments could not resolve the issue.
Chen explains that this approach was risky. For that reason, the Windows 95 team always obtained formal written permission from the software vendor before modifying their executable file. The correspondence included a detailed description of the bug, an exact explanation of the forthcoming fix, and a list of affected versions. In return, Microsoft asked the vendor to send those versions for analysis and to commit to correcting the issue in the next release — because future versions of Windows were not required to carry the same patch.
Another question arose: how could the system determine which programs had built-in fixes? Here Windows 95 made a leap forward by abandoning manual identification. Instead of asking the user, the system automatically detected applications using so-called detection strings stored in the registry. When a 16-bit module intended for pre-4.0 Windows was loaded, the kernel iterated through these strings to see whether any matched the application.
These were not simple checksums. Each string was transformed into a sequence of bytes, with the first byte indicating the comparison algorithm that followed. In practice, file-size checks were the most common — they were quick and inexpensive. Content comparison was rare, as it required extra disk reads and consumed too much time.
Chen notes that a dedicated utility for generating detection strings eventually emerged, but early strings were written manually — byte by byte — making the process laborious. If a string matched a particular program, the system proceeded to the next step: in the corresponding registry subkeys, Windows stored information on which segments to modify, and the values themselves were binary data that the system wrote directly into the memory of the executable as it loaded. This allowed Windows to apply necessary fixes on the fly.
The names of these fixes were unimportant, though a convention existed: added data was labelled Add, modified segments were labelled Change, and multiple entries received numerical suffixes — Add1, Add2, Change1, Change2, and so forth.
This flexibility enabled Windows to preserve compatibility with an enormous number of legacy programs — a key factor behind its dominance in the late 1990s and early 2000s. Users could upgrade without fearing that their essential corporate applications would cease to function.
Chen invites us to reflect on how the engineers of the Windows 95 era might view today’s landscape: millions of devices will soon fall out of support after Windows 10 reaches end-of-life, and no compatibility database or handcrafted patches will be waiting for them. For those who built one of the most intricate backward-compatibility systems three decades ago, such a shift would likely feel like a true cultural upheaval.