If there is no 16-bit emulation layer in 64-bit Windows, how come certain 16-bit installers are allowed to run?


Troy Martin is puzzled by the remark in this knowledge base article that says

No 16-bit code can run, except for recognized InstallShield and Acme installers (these are hard-coded in Wow64 to allow them to work).

I agree that the sentence is rather confusingly written. It says "No 16-bit code can run, except for this code that runs."

But that's not really what's going on. No 16-bit code running at all.

What the article is trying to say (as briefly as possible) is that Windows has specific knowledge about certain InstallShield and Acme installers that allows it to parse the installer's data files directly. That's what the article is trying to say with the word recognized: When you try to run a 16-bit program, the application compatibility layer looks at the program and says, "Gosh, I wonder if I recognize this program." And maybe the answer is, "Yes, it is InstallShield version 5.0, and I have been taught very specific information about the data files that are used by that version of InstallSheield to the point that I know how to install them without actually invoking InstallShield itself." In that case, instead of playing a sad sound, the kernel hands the request to the application compatibility engine with the instructions, "You take care of this."

The application compatibility engine then substitutes a 32-bit custom installer that knows how to open, parse, and apply the InstallShield data files. Another way of looking at it is that somebody sat down and ported InstallShield to 32-bit Windows, so that when a user tries to run a 16-bit installer, the request is redirected to the 32-bit version.

You can see that installer in your C:\Windows\SysWOW64\Install­Shield directory.

Comments (37)
  1. Karellen says:

    "The application compatibility engine then substitutes a 32-bit custom installer that knows how to open, parse, and apply the InstallShield data files. Another way of looking at it is that somebody sat down and ported InstallShield to 32-bit Windows, so that when a user tries to run a 16-bit installer, the request is redirected to the 32-bit version."

    WTF? Why not port InstallSheild to 64-bit Windows, and redirect to the 64-bit version, seeing as this program isn't even needed on 32-bit Windows?

    Yo, dawg. I heard you like multiarch OS, so I put a 32-bit installer in your 64-bit OS, so you can extract your 16-bit Installshield while you load 3 different runtimes into memory and hope your disk stops thrashing before the complexity makes your brain melt out of your ears.

  2. VinDuv says:

    I don’t really understand why allowing a 16-bit installer to run is useful, since most of them will install useless 16-bit binaries… Or do some 16-bit installers detect that they are running on a 32-bit system and install 32-bit binaries in that case ?

  3. Joshua says:

    @Karellen: Because the 16 bit installer is installing a 32 bit program.

  4. Mark says:

    Because the installer and target programs are actually 32-bit, but it's used a 16-bit bootstrapper forever (back in 1995, it would have been useful to say "this program requires 32-bit Windows). MS or InstallShield have just done the work of finally getting rid of the 16-bit part, which is a good demonstration of why it's taken so long to remove the 16-bit subsystem.

  5. BZ says:

    One company I worked at (9 years ago) used InstallShield Express to install its (very 32-bit) application. Since this version of InstallShield was discontinued in the first 32-bit version, they used a 16-bit installer to install a 32-bit application.

  6. Brian_EE says:

    @Karellen: "WTF? Why not port InstallSheild to 64-bit Windows,…."

    Umm, because Installshield is not a MS product, so MS cannot port the application? That may be the reason. MS also does not control all the 3rd party vendors (many who have gone out of business over the years) to force them to re-release their older SW with an upgraded Installshield.

    So, how else would MS provide a mechanism to allow install of older 32-bit programs (that run just fine on Windows still today) that were shipped with a 16-bit installer?

  7. Karellen says:

    @Joshua, Mark, others: "The new installer is 32-bit because it's installing a 32-bit program"

    So? You're writing a program which will run exclusively on 64-bit systems. Surely it doesn't really matter what it's doing – why not build it to run natively on the OS it's designed for, along with everything else?

    Yes, you might be stuck with some legacy 32-bit binaries that you just can't get rid of for now, but that's because they're legacy and you're stuck with them. Writing new 32-bit-only code is just daft (and has been for many many years now), and writing new 32-bit code for a 64-bit plaform boggles my mind.

    (Why is this apparently not the "obvious" Right Thing(tm) to do? What am I missing?)

    [The ported installer must be 32-bit so that registry and file system redirection kick in. Otherwise it would be writing 32-bit registry keys into the 64-bit registry and copying 32-bit files into the 64-bit system directory. -Raymond]
  8. Karellen says:

    @Brian_EE: Ah, my mistake. I though Raymond was saying that someone at MS reverse-engineered the 16-bit InstallShield data format and MS "ported" a new version as part of their AppCompatibility framework. I didn't realise it was InstallShield that did that.

    That makes more sense, thanks.

  9. Mal DeMer says:

    @Karellen

    There are two programs: the installer and the program to be installed. They are independent of each other, except that the job of one is to install the other. Bit-edness of either probably doesn't come into play. The installer may not need to be a 64-bit program in order to do its work. In other words, it's not broke. So why must we fix it, if porting to 64-bits adds no functionality?

    Aside from that, most people do not write brand new fresh installers just for fun, if at all. We get them from someone else, many times not as buildable source. If the 32-bit version works fine (and Microsoft takes some pains to make that so), then why switch, barring other circumstances?

  10. Brian G. says:

    My personal experience with this problem (it must not have been InstallShield, though) was a number of games from a particular developer/publisher known for a franchise of stellar combat stories. (A mouse just bought them). All of their games in the 32bit era were shipped with 16bit installers and the best way (that I've found) to get the games installed now is to search for a fan-made 32bit installer program that does the same job.

  11. Anonymous Coward says:

    Why can't you just run the 16-bit emulator from 32-bit Windows in the 32-bit emulator on 64-bit Windows?

    [Because that emulator uses v86-mode, which is not supported by 64-bit processors. -Raymond]
  12. Joker_vD says:

    In before "Then why don't you just ship Windows with DOSBOX?".

    Man, switching the architectures is so annoying! Even if it's they are basically the same architecture, just with different word size.

  13. Azarien says:

    I can imagine some kind of DOS/Win16 emulator based on VirtualPC/Hyper-V technology with seamless integration, but I guess the correct answer is: just stay with x86 version of Windows.

  14. Ian Yates says:

    I already knew this, which makes me suspect I learnt about it from this blog some years back (no one else writes about this sort of stuff much anymore).  I suppose I could stop being lazy and search the archive myself :P

    Still, I liked the discussion, particularly Raymond's response about why the installer wasn't ported all the way to 64-bit.  I think Wow6432 redirection isn't all that well understood in the IT community, which is sad.  Although I could just add that to the pile of lots of other things IT pros should know but don't (print queue management, how sessions work in TS, etc).

  15. yuhong2 says:

    "Because the installer and target programs are actually 32-bit, but it's used a 16-bit bootstrapper forever (back in 1995, it would have been useful to say "this program requires 32-bit Windows)."

    Also because non-x86 version of NT4 and older supported emulating 16-bit x86 applications using NTVDM but did not support emulating x86 Win32 apps.

  16. RangerFish says:

    The installer has to be the lowest common denominator in terms of bitness. This is because it needs to be able to check whether the application can run on that system and give an intelligent "um, you can't install Program X because your computer is 16-bit and doesn't  support it" message rather than falling over in a big heap.

  17. Ens says:

    I would argue that running a 64 bit installer to install a 32 bit app is needlessly complex.  Why not have one bitness throughout the stack of an application's installation and operation?

    64 bit apps can work around redirection, but why bother?  That's the sort of inelegant complexity you're arguing against!  You need to describe a concrete advantage of 64 bit, otherwise with just the registry redirection issue we've shown that complexity is increased, not decreased, by writing it in 64 bits.

    It's not like these are 64 bit programs with 16 bit installers (in fact, you might be able to come up with an argument that says that writing it in 32 bit helps prevent that horror from coming to pass).  The problem can't repeat exactly at some future time when 32 bit support is deprecated (I anticipate different problems, but not literally the exact same problem such that there is a code re-use win).  There is no scenario where this is at all useful without a fully-functional 32 bit system in place.  This is inherently a bridging solution, not something that adds to technical debt and cruft.

  18. Myria says:

    Microsoft *could* have implemented NTVDM on Win64 if they wanted.  It seems like it wasn't worthwhile, so they didn't.  Running Win16 programs on x86-64 doesn't require V86 mode – 16-bit protected mode descriptors are allowed in a 64-bit LDT or GDT.  Only DOS gives problems in that regard.

    For DOS programs, which definitely would have required V86 mode, Microsoft could have written an 8086 emulator.  If a DOS program switched to protected mode – say, a DOS/4GW program switched to 32-bit mode – NTVDM could switch to native execution mode.  Returning to V86 mode would instead return to the emulator.

    Supporting Win16 would have had a slight performance penalty on all XP64/2003 and Vista 64-bit versions, however, even when no Win16 programs were running.  Without NTVDM, NT64 has no need for the LDT.  The kernel therefore sets LDTR to 0 at startup and then never bothers to save or restore it during a context switch, saving a bit of time during context switches.  If LDTs could be made, all context switches would need to switch out the LDTR value.

    This changed in Windows 7, when the user-mode scheduler made the LDT necessary again in 64-bit mode.  However, I don't know the details – it's not simply NtSetLdtEntries.

    In case you're curious, this is also why Google's Native Client requires 64-bit executables in 64-bit Windows even when running 32-bit Chrome.  Their security model uses the LDT, and Win64 doesn't allow that.

  19. Karellen says:

    @Mal: "In other words, it's not broke. So why must we fix it?"

    It was broke – that's the point! The program needed porting; new code needed to be written, and tested, and deployed. It shouldn't be any harder to write 64-bit code than it is to write 32-bit code. Heck, it should be 99.99% *the same code*, just built with one different compiler option.

    (Are Win64 apps not capable of reading/writing the redirected WOW64 keys at all? There is even this ulOptions parameter to RegOpenKeyEx() which has a few bits free…)

    "The installer may not need to be a 64-bit program in order to do its work. [… Why bother] if porting to 64-bits adds no functionality?"

    Because! Because you're running a 64-bit system, and running apps native to that system is just more elegant. Because complexity is what will be our undoing in the end, and reducing it whereever we can is always a win. Because we can't rewrite everything from scratch at once, but we can create clean new code one small piece at a time, preventing an increase to our technical debt where we have the opportunity to do so at negligible incremental cost to just piling on more cruft.

  20. Karellen says:

    @Ens: "You need to describe a concrete advantage of 64 bit,"

    OK, this is where I'm lost. How on earth do you come to that conclusion??

    This is for code that will ship and only ever run on 64-bit systems. Surely, in that case, writing 64-bit apps should be the default position, and there ought to be a clear, significant, concrete advantage to justify writing and shipping new 32-bit code. (If not in that case, then when – of all cases – should 64-bit be the default position?)

    "It makes writing to the registry slightly easier" is certainly an advantage in this case. I don't think that advantage is quite big enough in this case, but that's based on a flimsy hunch and I'd certainly be willing to change my position given some data. But that's kind of the point – surely the burden of proof should be required for 32-bit? Shouldn't it?

  21. Anonymous Coward says:

    Myria, running 16-bit Windows *programs* doesn't require v86 mode, but running 16-bit Windows probably does. So based on Raymond's answer, I wouldn't be surprised if the 16-bit emulator is secretly running a customized Windows 3.1 or something.

  22. Richard Russell says:

    @Karellen "It shouldn't be any harder to write 64-bit code than it is to write 32-bit code".  What about assembler code?  That's potentially very difficult to port from 32 to 64 bits (not least because the ABI is so much more intrusive).  I have applications that are partly assembler, and I simply wouldn't attempt it.

  23. Joshua says:

    [Because that emulator uses v86-mode, which is not supported by 64-bit processors. -Raymond]

    But the emulator used in NT4 Alpha doesn't use v86 mode.

    The solution to the widening problem is to not assign windows 16 bit handles until they are enumerated. Very few 16 bit apps enumerate below top level of other processes.

  24. Andy77586 says:

    The advantages and disadvantages of 64 bit apps are here.

    technet.microsoft.com/…/dd630755%28v=office.12%29.aspx

    I don't think there are many apps that take advantage of a 64 bit system.

    I have the hardware to support 64 bit apps.

    I have a dual boot system Windows using XP 32 bit and Puppy Linux 64 bit.

    Linux supports and uses all of my 4 Gb of RAM, while XP only uses about 3 – 3.5 Gb of the RAM.

    I write 32 bit assembler programs and writing 64 bit programs is harder to write.

    This is based on posts where programmers are asking help converting 32 bit programs to 64 bit.

    Take care.

                Andy

  25. Mike Dimmick says:

    Karellen: The point you're missing is that this code *already existed*. It's the 32-bit actual installer that lives alongside the 16-bit installer stub. The only reason Windows has to ship with it is to handle self-extracting single-file installers. Multi-file installers had the 32-bit installer alongside, just without an .EXE extension. In that case, I believe Windows loads the 32-bit installer part from the install source location, rather than from the WindowsSysWOW64_manufacturer_ folder.

    The reason for the 16-bit stub's existence is solely so that, if run on 16-bit Windows, it can throw a message box saying 'You need 32-bit Windows for this application'. This is the same rationale for Windows PE EXEs – 32-bit x86, x86-64, Itanium, ARM, whatever – all starting with a stub of 16-bit code that DOS would be able to execute, which simply outputs "This program cannot be run in DOS mode". (The message is of course embedded in the EXE, so it's up to the compiler/linker author to decide what goes in there.) The same message is embedded in every .NET EXE and DLL as well.

    I don't think it was possible to build a 32-bit PE executable that would be interpreted as a 16-bit NE-format executable by 16-bit Windows. Both formats use the same location for their signature, so a file cannot be both.

  26. Anonymous coward says:

    @Karellen: "Writing new 32-bit-only code is just daft (and has been for many many years now)"

    Going from 16 to 32 bits was a huge improvement, a quantum leap in programming. Nobody wants to go back, but 20 years later there is still a lot of 16-bit code around.

    In contrast, going from 32 to 64 bits yields most of the time absolutely no measurable improvement. Only a tiny fraction of real world applications needs more than 2/4 GB address space; that is why 32-bit code will still be around in 20 years from now. I'll bet it'll be around, and running fine, 50 years from now. There is just no compelling reason to waste time on 64-bit code, unless of course you work on satellite imagery and your client is the NASA…

  27. Edward M. Grant says:

    "There is just no compelling reason to waste time on 64-bit code"

    Exactly what time are you planning to waste on writing 64-bit code, beyond enabling it with a compiler flag?

    I was porting code from 32-bit to 64-bit CPUs back in the mid 90s, and the only things we had to fix were in code which converted pointers to ints and back again (I should add that there were good reasons for the code to do that, it wasn't just for grins). Everything else just worked.

    There is no reason I can see to ever write 32-bit x86 code any more unless you really believe people will be running your software on 32-bit machines. My laptop runs Linux and is 64-bit through and through, so it's kind of sad that my Windows machine is vastly more powerful, yet 90% of the software that runs on it can only use a tiny fraction of its RAM, and games crash due to running out of memory when there are 20+GB free outside that 32-bit straightjacket.

  28. Anonymous coward says:

    @Edward: "yet 90% of the software that runs on it can only use a tiny fraction of its RAM, and games crash due to running out of memory"

    Yet 99% of the software never needs the full 4 GB of a 32-bit OS, and games crash due to horrible design flaws.

  29. smf says:

    >But the emulator used in NT4 Alpha doesn't use v86 mode.

    Yeah, I think if Microsoft thought there was money in it then they would support 16 bit apps in 64 bit operating systems. If you could hook in an exe that got called instead of message boxing to say that 16 bit software isn't supported, then someone would do it for them.

    [There's more to running 16-bit applications than just writing a CPU emulator. You have all the cross-process interactions to deal with, and that's quite nontrivial. -Raymond]
  30. Christopher Painter says:

    Nearly twenty year ago I was writing 16bit InstallShield 3.0 installers for Windows 3.1.  I then moved on to InstallShield 5.0 and started targeting WFW 3.11 and NT 4.0 and eventually W2K only.  I remember there was a workaround for a 32bit machine that had the 16bit NTVDM disabled.  You ran the installer on a machine that ran 16bit code, grabed a file in the temp directory and renamed it to .EXE.  You could then run this EXE on a 16bit disabled machine and it would work.  It's been a good 12 years since I had to use that.

  31. Semi Essessi says:

    Can't let this one go past without a comment…

    "Writing new 32-bit-only code is just daft (and has been for many many years now)"

    Have you seen the last couple of years worth of VS native tools for windows development? They default to this behaviour, you have to go and add x64 yourself… its a small effort, but imo another example of the VS guys picking absolutely the wrong defaults for something.

  32. Gerben Vos says:

    64-bit pointers are a waste of bits (and cache space, and therefore time) if you are writing a program that doesn't need much memory. See www-cs-faculty.stanford.edu/…/news08.html , section "A Flame About 64-bit Pointers". For this reason, Linux has introduced the x32 ABI in their 64-bit OS, so you can use all the new registers but can still use 32-bit pointers. So apparently there is a demand for this. I don't think Windows has an equivalent ABI yet.

  33. nugryhorace says:

    "The reason for the 16-bit stub's existence is solely so that, if run on 16-bit Windows, it can throw a message box saying 'You need 32-bit Windows for this application'"

    Or launch the 16-bit version of the setup engine, if the program it's installing has a version for 16-bit Windows. Judging by the strings in SETUP.EXE, it also checks for MIPS, PPC and Alpha CPU types, and presumably can do the same for them.

  34. ender says:

    > Linux supports and uses all of my 4 Gb of RAM, while XP only uses about 3 – 3.5 Gb of the RAM.

    XP could use up to full 4GB of RAM before SP2 as well, but when DEP support was added in SP2 (which required PAE to be enabled), there were too many incorrectly written drivers (causing BSODs), which is why accessible memory was reduced to only what was mapped below the 4GB barrier.

    eternallybored.org/…/xp4gb.png

  35. Marc K says:

    @Anonymous coward: "…that is why 32-bit code will still be around in 20 years from now."

    We might see 32-bit code forced out.  Newer releases of Windows Server allow WoW64 to be uninstalled.  Dell has already started releasing dual versions of their management tools to support this scenario.

    en.community.dell.com/…/20311509.aspx

  36. Ben says:

    I am sad that 16bit is now in the past for one reason only. VBDos. Nostalgia perhaps; but it was a beautiful simple way to quickly generate a cmd line app with a nice GUI.

  37. RCL says:

    Nowadays the performance bottleneck is mostly memory access, and 64 bit has disadvantages in that regard (halved – at worst – cache utiliziation due to longer registers). For some platforms, e.g. PowerPC, where shortage of registers was never a problem, running 32-bit code makes perfect sense and is actually a better default option, unless your application is likely to use a lot of memory (or fragment its address space by doing multiple small allocations). For x86-64, 64-bit is normally better due to increased number of registers, but there are still cases when 32-bit code wins.

Comments are closed.