Windows Confidential16-Bit Icons Are So Passé

Raymond Chen

As I noted in the February 2008 Windows Confidential column, features do disappear from Windows®. They typically do so slowly and largely imperceptibly, with a product team quietly celebrating the event each time it occurs. Another feature that vanished in Windows Vista® is the ability for 32-bit code to access icons stored in 16-bit modules—mostly 16-bit EXEs and 16-bit DLLs.

Before you get all worked up, bear in mind that 16-bit code can access icons stored in 16-bit modules just fine; that all happens inside the 16-bit emulation layer. What is gone is the ability to access those icons from 32-bit code, or more specifically the ability for 32-bit icon extraction functions like the ExtractIcon function to load those icons from your 16-bit DLL.

The 32-bit code that extracts icons from 16-bit modules doesn't have the luxury of using kernel functions such as FindResource to locate the icon in the file. Instead, the code must implement its own mini-loader that parses the 16-bit module header, seeks to the resource table, and then parses the resource table looking for the desired icon resource. Only after doing all that can the 32-bit code finally convert the pixels into an icon.

  (Click the image for a larger view)

As you can imagine, the code that does this is very old and fragile. There are plenty of opportunities for error when parsing binaries that could be corrupted, either by mistake or with malicious intent. The performance team will ask for changes to the way the file is opened in order to improve the performance over networks, since different open and sharing modes have different consequences for network caching effects. And the reliability team may ask for the parsing code to be rewritten to avoid using memory-mapped files. Eventually, the cost of maintaining this kind of code starts to exceed the value it offered. I mean, really, who writes 16-bit programs anymore, right?

Now, your 16-bit programs will still run as long as the 16-bit emulation layer is there. (Yes, 64-bit Windows Vista does not have a 16-bit emulation layer, but this isn't a step backward from Windows XP; 64-bit Windows XP didn't have a 16-bit emulation layer either. It didn't get better, but it didn't get any worse.)

All that you're losing on Windows Vista is the ability to do an ExtractIcon from your 32-bit program and obtain an icon from a 16-bit DLL. If you have a shortcut to a 16-bit program on your Start menu, the icon for that shortcut will now come up as a generic program icon since Windows Explorer can no longer extract the 16-bit program's icon from its main EXE. No big loss. But if this really bothers you, you can edit the shortcut's properties and give it an icon from a 32-bit module.

The only place I've seen this lost feature become a problem is in icon libraries that are produced by one particular icon editing tool. For some reason, that program defaults to saving its icons as resources in 16-bit DLLs, which means that you can't access those icons from 32-bit code anymore. The easy workaround, of course, is to resave those icon libraries as resources in 32-bit DLLs.

I'm sure that eventually—if not already—somebody will write a little program to extract all the icons from a 16-bit DLL and then create a 32-bit resource-only DLL with those icons, just so people who have old icons lying around in 16-bit DLLs can continue to use them in shortcuts on their Start menu. But I have to admit, if you write this program, you probably won't find anybody who actually needs it. The number of requests for such a program that have come to the Windows user interface team: zero.

Raymond Chen's Web site, The Old New Thing, and identically titled book deal with Windows history and Win32 programming. He stands clear of the closing doors.