Windows 95 defenses against installers that overwrite a file with an older one (devblogs.microsoft.com)

by michelangelo 100 comments 168 points
Read article View on HN

100 comments

[−] chihuahua 44d ago
It must have been difficult and frustrating to work as part of the Windows team back in those days.

You see all the wacky software that doesn't follow the rules properly, does whatever it wants, breaks things. And you have to figure out how Windows can accommodate all that software, keep it from breaking, and also prevent it from messing up a computer or undo the damage.

They did not have the option of saying "this app developer wrote shitty software, sucks to be them, not my problem."

I wonder how much of this problem was caused by lack of adequate documentation describing how an installer should behave, and how much was developers not reading that documentation and being content when it works on their machine.

[−] MarkSweep 44d ago

> I wonder how much of this problem was caused by lack of adequate documentation describing how an installer should behave, and how much was developers not reading that documentation and being content when it works on their machine.

There is a third option: the developers knew the rules and chose to ignore them for some reason. A modern example of this is the Zig language’s decision to reverse engineer and use undocumented APIs in Windows in preference of using documented APIs.

https://codeberg.org/ziglang/zig/issues/31131

[−] kaashif 44d ago
This comment is pretty wild:

> In addition to what @The-King-of-Toasters said, the worst case scenario is really mild: A new version of windows comes out, breaking ntdll compatibility. Zig project adds a fix to the std lib. Application developer recompiles their zig project from source, and ships an update to their users.

Uh so what if the application developer isn't around any more?

The fact that they consider the worst case to be one where the application is still actively supported and the developer is willing to put up with this nonsense is pretty surprising. Not sure how anyone could believe that.

[−] throwA29B 44d ago

>ignore them for some reason

The reasons are clearly stated in the issue you have linked.

[−] MarkSweep 37d ago
I understand the stated reasons and disagree with their conclusions. It seems like a lot of extra work on the part of the Zig developers to have to reverse engineer undocumented interfaces. There is potentially extra work for the Windows developers if they want to change their private implementation details that Zig programs are now relying on. And in the case where the lower level APIs are missing features implemented higher level APIs, Zig has to either reimplment the functionality themselves or not have the same level of support for Windows features that normal Win32 apps have. A concrete example is looks like Zig programs can't open serial devices:

https://codeberg.org/ziglang/zig/src/commit/6193470ceea89a98...

All this to save a little memory CPU and memory usage? The juice does not seem worth the squeeze.

[−] guenthert 44d ago
"As Zig has evolved, it has become a target to avoid calling Win32 APIs from kernel32.dll etc., instead using lower-level ones in ntdll.dll."

If we needed an example of why we should avoid using passive voice, this is it.

[−] loevborg 44d ago
This sentence doesn't include examples of the passive voice.
[−] MForster 43d ago
The sentence that you quoted is more generic. The Zig issue is only one example of "some reason".
[−] gzread 44d ago
Wow! What a mind-bogglingly stupid idea. I will cancel my plans to learn Zig.
[−] iknowstuff 44d ago
Kinda wild
[−] bigstrat2003 44d ago
One of the craziest Raymond Chen stories is one where a Windows API call would return a pointer to a data structure the OS had allocated for the operation. The programmers at Microsoft made the data structure bigger than they needed, for future expansion. But some third party devs noticed the extra space, and started to use it to store data for their program. Then when Windows tried to start using the extra space, those applications would crash.

Reasonable people can disagree on a lot of things in programming. But I still do not understand how one can consider writing to memory the OS owns to be ok. It's sheer professional malpractice to do that kind of thing. With stuff like that, I don't think that any amount of documentation would have helped. The issue was that those programmers simply did not care about anything except getting their own program working, and did whatever the most expedient method was to get there.

[−] RiverCrochet 44d ago
Before Windows 95/3.x, there was DOS.

There were no rules in DOS, or r_x permissions like Unix.

The DOS kernel itself didn't really impose any structure on the filesystem. All that mattered was:

- The two files that comprised DOS itself (MSDOS.SYS, IO.SYS) had to be "inode" 0 and 1 on the disk in early versions,

- the kernel parsed \CONFIG.SYS on boot, and I think looked for \COMMAND.COM if you didn't specify a different shell with COMSPEC= in CONFIG.SYS. There were defaults if \CONFIG.SYS didn't exist, but of course all your DEVICE= stuff won't load and you'll probably not have a working mouse, CD-ROM, etc.

\AUTOEXEC.BAT was optional. That's it. Any other files could be anywhere else. I think the MS-DOS installer disk put files in C:\DOS by convention but that was just a convention. As long as COMMAND.COM was findable DOS would boot and be useable-and if you mucked something up you just grab your DOS boot floppy with A:\COMMAND.COM on it and fix it.

From what I recall most installers-if provided-made a directory in \ and put all their files there, mixing executables with read-write data. There was no central registry of programs or anything unless you were using a third party front-end.

Windows 3.x and 95 inherited the DOS legacy there.

[−] layer8 44d ago

> I wonder how much of this problem was caused by lack of adequate documentation describing how an installer should behave, and how much was developers not reading that documentation and being content when it works on their machine.

It was mostly the latter. And when Windows broke, people would blame it on Microsoft, not on the software they installed. The same if the software broke. And you didn’t have online updates at the time that could retroactively add fixes. So Microsoft had to do everything they could to ensure broken software would still work, while also keeping Windows working, the best they could.

[−] topspin 44d ago
One workaround Microsoft has done for use-after-free is detecting when an application is prone to this and using an allocator that doesn't actually free RAM immediately. It believe that lovely bit of fun is a function of "Heap Quarantine".

Yes, the real, can't say no world of system software is not what one might wish.

[−] eviks 44d ago
The biggest cause for this problem isn't lack of docs, but poor OS design. Like, why would you let apps change anything without restrictions to begin with? Of course, then you have to have some dumb hidden folder wasting space to restore the changes, and this "waste space for no good reason because we can't architect properly" is still a common issue
[−] wmf 44d ago
They could have had file permissions. They could have had a package manager instead of third-party installers.

Also note that Microsoft Office has a long history of not following Windows rules. Microsoft didn't even set a good example.

[−] hulitu 44d ago

>back in those days.

> You see all the wacky software that doesn't follow the rules properly, does whatever it wants, breaks things.

Just like today. Software is hard, software engineering even harder.

[−] AgentME 44d ago
When I was a kid, I released a small GUI program online that I made with either VB6 or VB.NET. The program used the standard open-file dialog. When I created the installer for my program through VB's release wizard, there was a page where it pointed out that my program depended on a certain system library (because of the open-file dialog) and it asked me if I wanted to include that library in the installer. I think the default answer was yes, or maybe it wasn't but it sounded like an obvious thing to enable so I did it. Apparently this screwed over and broke open-file dialogs globally across Windows for everyone who wasn't on the same version of Windows as me. Whoops! It's too bad that VB had such a foot-gun in it, and that the article's workaround didn't save those users.
[−] akdev1l 44d ago

>Windows 95 worked around this by keeping a backup copy of commonly-overwritten files in a hidden C:\Windows\SYSBCKUP directory. Whenever an installer finished, Windows went and checked whether any of these commonly-overwritten files had indeed been overwritten.

This is truly unhinged. I wonder if running an installer under wine in win95 mode will do this.

[−] Lammy 44d ago

> Whenever an installer finished, Windows went and checked whether any of these commonly-overwritten files had indeed been overwritten.

> Basically, Windows 95 waited for each installer to finish

How could it tell that a particular process was an installer? Just anything that writes to the PROGRA~1 or WINDOWS folders?

[−] ruevs 44d ago
And 6-7 years later the WinSxS directory was born and these days it is tens of gigabytes.

Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase

In an administrator command prompt. You can thank me when it's finished ;-)

[−] Macha 43d ago
I find articles like this a good counter to the idea that typical software used to be better in the past (usually with an appeal to an idea that people were “real programmers” in those days and anything other than C as used in the 90s is a modern extravagance)
[−] Grom_PE 44d ago
In my 25 years of using Windows I've grown so much disdain towards annoying, broken, slow installers that I started to instead extract them like zip archives, using various tools: 7-Zip, UniExtract, Observer plugin for Far Manager, sometimes even manual carving.

Most things just worked after being extracted like that. Some things needed a few registry entries, or regsvr32 some dll files.

[−] iamcalledrob 44d ago
I love the naiveté of this approach.

Unlike , it's so easy to reason about. I wish this kind of approach was still viable.

[−] 1970-01-01 44d ago
The sad lesson is to be both proactive and reactive if you want a clean environment. Trust, verify, and stick around to clean up someone else's mess after the fact.
[−] phendrenad2 44d ago
Windows, especially old versions, were beautifully pragmatic. Think about the things that would need to exist on an open-source OS to match this functionality. You'd need to:

1. Convince people to distribute programs via installers.

2. Provide some way that installers can tell the OS that they're an installer (and not invent 5 different ways to do this!)

3. Convince the creators of installers to actually use that function.

4. Convince library creators to maintain backward compatibility (big ask).

5. Convince people to not fork said libraries, creating ambiguous upgrade paths.

6. If there are multiple distros, convince them all to use the same backup/restore format for libraries (and not treat their own favorite libraries as "special")

[−] forkerenok 44d ago
OMG, is this the reason why every other installer would get stuck at 99% forever? :D
[−] uxp100 43d ago

> Some components addressed this problem by providing their own installer for the component, and telling installers, “You are not allowed to install these component file directly. Instead, you must run our custom installer.

Aha, that’s why they do that.

[−] intensifier 43d ago
This existed until Windows XP but with different name and behavior. Only from Vista, they added permissions to restrict user and third party programs to modify system files easily.
[−] thecaio 43d ago
wow. this is insane. never new such mechanic was ever remotely considered or possible. pretty neat