Long time ago, somebody at Microsoft gazed into the future and they saw that some day we will have the need for a 64-bit OS. They were smart people and they thought that it would be easier if the system directory would reflect the kind of system binaries it would keep and created a directory called c:\windows\system32\. You know, for the 32-bit binaries. The new subsystem was called appropriately - Win32 and so were some of the system files - regsvr32.exe, kernel32.dll, user32.dll, etc, etc, etc.
Years flew by and that future they saw has arrived on the wings of Intel and AMD architecture and it was the time to reap the benefits of the smart choice made long ago. Right?
Well, not quite. Let's see what the followers of those smart people have brought us. On a 64-bit Windows 2003 Server, the system directory, namely c:\windows\system32\ is where all of the 64-bit binaries are stored. Yes, kernel32.dll is really a 64-bit DLL and so are many other libraries and executables in this directory.
So, where is the 32-bit compatibility stuff? Surely it's kept somewhere clearly marked as such. Right? Guess again - all of the 32-bit binaries are stashed away in c:\windows\SysWOW64\. That's short for for Windows-32-On-Windows-64. Apparently, the 32 was in the way to WOW and had to be dropped.
Let's take a look at c:\Program Files\. Finally, one directory where there is no confusion - this is where 64-bit files are kept on a 64-bit OS. Sounds logical, but where are the 32-bit programs are installed? Where is it - may be some other name with a 32 or a 64 in it? Again, not quite. It's in c:\Program Files (x86)\, for all of the processors in the existing Intel's 16- and 32-bit line, like 8086, 386, 468, that kind of stuff.
Naturally, this 32-64-86 numeric soup lead to much confusion among developers and IT professionals.
For example, Microsoft's database access technology, MS ADO, requires developers to import ADO type library. The latest one is msado27.tlb located under c:\Program Files\. This is the 64-bit directory, remember? Well, think again - importing this library with #import in the C/C++ code, you will crash your application because the library will instruct your code to pass in a pointer to long, where a pointer to a 64-bit number is expected when the number of affected rows is returned by ADO. Instead, you have to import msado15.dll. Version number sounds confusing? Shouldn't be at this point in the post. Really.
What about the latest and greatest .Net technology. Surely, this technology is designed with the 64-bit architecture in mind! You would hope. The good news is that a .Net application is capable of running on either 32-bit or 64-bit system. As long as you don't have to mix it in with non-.Net binaries, that is. If you would like to access a 32-bit COM component from your .Net application running on a 64-bit OS, you are in for a surprise. The loader will try to load what it thinks the best way for your new and shiny 64-bit OS and will load your .Net application as a 64-bit process. Try loading your 32-bit COM component in the 64-bit application now! Fortunately, you can use a utility that comes with .Net to mark a .Net application as a 32-bit binary, so it can load your 32-bit COM component (corflags.exe).
Now, you are thinking that it would be great to compile 32-bit and 64-bit .Net binaries separately and package them appropriately, right? It's just getting more and more hilarious. Not quite. Visual Studio 2005 doesn't quite support invoking the 64-bit C# compiler from c:\Microsoft.Net\Framework64\. That's right, there is no configuration property anywhere in Visual Studio to tell it which version of the compiler it should use [edit: there is, but it's not obvious]. C++, even managed C++ is fine - there are global project settings that allow developers to point to 64-bit binaries, libraries and include files. Working with C#? You are on your own. Microsoft didn't even bother adding configuration selection to half of C# property pages!
Of course, one could say that the beauty of .Net applications is that they can run on any platform, as they are stored in intermediate byte codes. Think again, if you need to register your .Net binary as a COM component - 32-bit C# compiler will launch the 32-bit .Net COM registration utility (regasm.exe), which will fail to register a .Net component built as a 64-bit binary.
I just can't wait when they release a 128-bit OS. That should be twice as much fun!