One thing not to do lightly in a Wow64 app is to disable the file system redirection that causes accesses to the System32 folder to be routed to the SysWOW64 folder. In new native code projects, you may be able to get away with it as all the code is under your purview. In a C++/CLI module or pinvoked in a .net app however, it really is a bad idea, not least because you never know which managed calls will load an additional assemembly. Take the following code, which is a simplified version of something I wrote:
using System; using System.Runtime.InteropServices; using System.Data.OleDb; namespace App { static class Win32 { [DllImport("kernel32.dll", SetLastError=true)] public static extern int Wow64DisableWow64FsRedirection(ref IntPtr ptr); static void Main(string[] args) { OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=myfile.mdb"); IntPtr val; Wow64DisableWow64FsRedirection(ref val); conn.Open(); } } }
The program in question was the collector program for the newly enhanced Window Platform Changes. There’s no reason why it couldn’t process the 64-bit dlls in \Windows\System32 (I now have an x64 system), so as part of initialization I disabled the redirection. On the next test run, the program crashed with the error:
Needless to say I was utterly confused by this. While the error message is direct, the program worked just fine the day before and I hadn’t (un)installed anything. Nevertheless I installed MDAC 2.8 SP1 and tried the program again, same error; repaired Office 2003 in case something in there was corrupt, same error. Then I decided to take notice of the exception details, particularly the System.BadImageFormatException innerexception which highlighted the cause of the error:
Retrieving the COM class factory for component with CLSID {2206CDB2-19C1-11D1-89E0-00C04FD7A829} failed due to the following error: 800700c1.
Well, HRESULT 800700c1 is HRESULT_FROM_WIN32(ERROR_BAD_EXE_FORMAT) so the exception type wasn’t lying and made the cause fairly obvious. When conn.Open() was called, the 32-bit .Net program was trying to load a native dll from System32. Because the WoW64 redirection wasn’t enabled it got exactly what it asked for, a 64-bit version of the dll in lieu of its SysWow64 counterpart. We all know that a 32-bit process can’t load a 64-bit dll thus it went bang, and lesson learned.