tags:

views:

86

answers:

3

The silent redirection of 64-bit system files to their 32-bit equivalents can be turned off and reverted with Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection. We use this for certain file identity checks in our application.

The problem is that in performing some of theses tasks, we might call a framework or Windows API, which subsequently calls another API in a DLL that has not yet been loaded. If redirection is enabled at that time, the wrong version of the dll may be loaded resulting in a XXX is not a valid Win32 application error.

I've identified the few API calls in question and what I'd like to do force the redirection on for the duration of that call then revert it back - just the opposite of the provided Win32 APIs. Unfortunately these calls do not provide any sort of WOW64 compatibility flag like some of the registry methods do.

The obvious alternative is to use Wow64EnableWow64FsRedirection, pass TRUE for Wow64FsEanbledRedirection. However there are a variety of warnings about the use of this method and a note that it is not compatible with Disable/Revert combo methods that have replaced it.

Is there a safe way to force redirection on for a give Win32 call?

The docs state the redirection is thread specific so I've considered spinning up a new thread for the specific call with appropriate locks and waits, but I was hoping for a simpler solution.

A: 

Why not use SHGetKnownFolderPath or SHGetFolderPath and look up FOLDERID_SystemX86/CSIDL_SYSTEMX86 to get your base path for loading DLLs? That should get you the correct folder independent of filesystem redirection.

afrazier
@afrazier: We're aren't loading the DLLs, they are being loaded indirectly by the Windows APIs we are calling
Paul Alexander
A: 

stab in the dark. Could you turn on redirection, call all the API methods you need, but ignore the results. This will load all relevant dlls. Then turn off the redirection and redo the method calls, using the results this time?

Sam Holder
Thanks Sam, that's exactly what I'm trying to accomplish. However if you read through the problem description there is no way to do this. The only methods provided by the Windows API are to _disable_ and _restore_ the redirection state. The Wow64EnableWow64FsRedirection method is deprecated and cannot be mixed with the disable/restore methods.
Paul Alexander
ok, I thought I'd check. Maybe its just me missing something but why can't you call all the methods before you disable the redirection state to load all the dlls that you'll need, then enable redirection to check your dlls. As I say I'm probably not understanding something fundamental.
Sam Holder
I've tried this as well, but sadly the call path isn't predictable enough. The DLLs that Windows tries to load also depends on the application state at the time of the call so calling them at, say application startup might not load all the dependent DLLs.
Paul Alexander
A: 

So I finally went the new thread route, which turned out to be easier than anticipated. The docs state that redirection is thread specific, so a new thread will always have redirection enabled.

var t = new Thread(() => 
    SafeNativeMethods.LoadLibraryExW("NTMARTA.DLL", IntPtr.Zero, 0) );
t.Start();
t.Join();
Paul Alexander