5

I'm writing a program in Visual Studio C++ which needs to run natively as a 32-bit process on any computer running Windows XP 32-bit, or any later Windows operating system. This program needs to be able to access the C:\Windows\system32\ folder on a computer, regardless of whether the program is running on a 64-bit or 32-bit system. To do this, I was using Wow64DisableWow64FsRedirection to disable the redirection that Windows typically does to 32-bit processes, sending them to C:\Windows\syswow64. Unfortunately, this breaks compatibility -- though my program can run on Server 2003 and XP x64 edition, the program fails whenever it runs on a 32-bit XP RTM system, giving me this error:

[Program Name] - Entry Point Not Found
  The procedure entry point Wow64DisableWow64FsRedirection could not be located
  in the dynamic link library KERNEL32.dll.

Since the system is 32-bit, the call is obviously superfluous, but I can't figure out a way to determine at runtime whether a system is 64-bit or not, and therefore whether or not to skip the call, without adding another call that itself breaks compatibility, such as IsWow64Process(), which requires XP Service Pack 2.

tl;dr: How can I determine whether a system is 64-bit or 32-bit without using any of the calls that were introduced after the advent of consumer 64-bit Windows.

  • 2
    As in something like `GetProcAddress`, then test if the function is there? – Niall Aug 20 '14 at 20:15
  • 2
    test for the presence of a syswow64 directory? it obviously wouldn't be present on a 32bit windows. – Marc B Aug 20 '14 at 20:15
  • 2
    @Marc-b That's clever, but I have no guarantee that the user won't create one. It would be dumb, but users can be dumb. – The name's Bob. MS Bob. Aug 20 '14 at 20:16
  • @Niall That's probably what I'm looking for. – The name's Bob. MS Bob. Aug 20 '14 at 20:17
  • 1
    Bunch of ideas here: http://stackoverflow.com/questions/7011071/detect-32-bit-or-64-bit-of-windows – Marc B Aug 20 '14 at 20:18
  • @MarcB The problem with `IsWow64Process()`, which most of the people there are suggesting, is as I say in my question, that it was not implemented until SP2. There are some other clever answers there though. – The name's Bob. MS Bob. Aug 20 '14 at 20:21
  • 1
    @dr_andonuts: You do realize that having `if (magic_is_64bit()) Wow64DisableWow64FsRedirection();` in your code will not stop Windows from trying to resolve the `Wow64DisableWow64FsRedirection` import on a 32-bit system, right? – Ben Voigt Aug 20 '14 at 20:37

1 Answers1

7

Go ahead and use Wow64DisableWow64FsRedirection, but don't import it statically. Instead use either dynamic binding (GetProcAddress) or delay-loading, either of which allow you to handle a missing function without crashing (or worse, not even starting, which is the current case).

And just don't worry about the system bitness. If the function is present, call it.

typedef BOOL WINAPI fntype_Wow64DisableWow64FsRedirection(PVOID *OldValue);
auto pfnWow64DisableWow64FsRedirection = (fntype_Wow64DisableWow64FsRedirection*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "Wow64DisableWow64FsRedirection");

if (pfnWow64DisableWow64FsRedirection) {
   // function found, call it via pointer
   PVOID arg;
   (*pfnWow64DisableWow64FsRedirection)(&arg);
}
else {
   // function was missing
}

Now the linker won't find an unresolved symbol named Wow64DisableWow64FsRedirection, so it won't put that function in the import table, and Windows won't go looking for it during process startup.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Unfortunately, statically linking my program would lend itself to another slew of problems, as my program uses the VC++ runtime library, which needs to be statically linked for other reasons. Is there a way in VC++ to keep static linking, but force dynamic linking at that one instance? – The name's Bob. MS Bob. Aug 20 '14 at 20:45
  • 1
    @dr_andonuts: I didn't say to change how you import the C++ runtime. Just this one function. Don't call it by name. Instead get a pointer from `GetProcAddress`, and call it by pointer. – Ben Voigt Aug 20 '14 at 20:49