Targeting Windows 95 in Visual Studio 2008
If setting up a Virtual PC image with Windows 95 on it isn’t difficult enough, I had the audacity to try and run a application built using Visual Studio 2008 on Windows 95.
To those who are trying to install Windows 95 on Virtual PC 2007, it appears the Windows 95 is no longer supported on Virtual PC. What I had to do is install DOS on the image, copy all the Windows 95 setup files onto the virtual hard disk image (via mounting it in Windows 7), and then running the setup. It won’t work if you try and mount the Windows 95 ISO in Virtual PC because the CD-ROM isn’t recognized when Windows 95 setup restarts.
Virtual PC Guy’s WebLog: Installing Windows 95 under Virtual PC
Virtual PC still has its problems with Windows 95, sometimes it will come up and say “While initializing device IOS: Windows protection error. You need to restart your computer.” That happens if you have hardware virtualization turned on.
Thread: Win 95 install problem, in Virtual PC
I was disappointed to see that Microsoft removed Windows 95 from MSDN. There also isn’t 98/ME/NT4. It has to do with Microsoft settling a lawsuit with Symantec. Suprisingly even Visual C++ 6.0 isn’t on MSDN, but I don’t know if that is for the same reason or not. I had to grab Windows 95 from Mininova.
To get an application to run in Windows 95 you have to make sure that it doesn’t link to any functions that are not available to Windows 95. You can do this by setting the _WIN32_WINNT preprocessor definition variable to 0×0400 (/D “_WIN32_WINNT=0×0400″). That should expose which functions and structures are not available in Windows 95.
If the application you are using uses Unicode function calls you have to implement the Microsoft Layer for Unicode on Windows 95/98/ME Systems. Unicode wasn’t a part of Windows until Windows NT. I had to link with unicows.lib and set unicows.dll as a delay loaded dll in order for it to work.
If that wasn’t difficult enough, whenever you compile your application in Visual Studio 2008 it modifies the PE’s NT Optional Header and sets the MajorSubsystemVersion and MinorSubsystemVersion. These two properties tell Windows whether or not it will be able to support the application. So if Visual Studio 2008, sets it to 0×0500, then when you try and launch the application in Windows 95 (which is 0×0400), it will throw an error that says, “File expects a newer version of Windows – Upgrade your Windows”. To get around this, I found an AWESOME product called LegacyExtender, which includes a utility EditVersion.exe, that modifies the PE’s SubsystemVersion properties. You can setup a post-build operation to call “EditVersion.exe $(TargetPath) 4.0″. LegacyExtender also includes a .lib which links in function wrappers for the most common functions that Windows 95 doesn’t have (IsDebuggerPresent, InitializeCriticalSectionAndSpinCount, etc).
LegacyExtender
PE Disassembly Viewer – NikPEViewer
MSFN Thread: Visual Studio 2008 and Windows 9x
Targeting Windows 95 was a lot of fun, just to see if I could do it. It wasn’t an easy journey. It really makes you search out the bare bone functions that will work in Windows to get a particular job done.







