Here I show how to use the
IsWow64Process2 API to determine whether a Windows process is running under WOW64, and whether Windows
and/or the process are 32 bit or 64 bit.
Let’s dive right in. Below is the completed code.
Code: Here is the Function
Code: Example Usage of the Function
Note: I have verified that the above code works with a 32 bit process running under WOW64, and with a 64 bit process running
natively, both running under 64 bit Windows 10 version 1903 on a 64 bit Intel AMD64 machine.
IsWow64Process2 requirements say
IsWow64Process2 minimum support is Windows 10 version 1511 (client),
and Windows Server 2016 (server).
I do not have a 32 bit machine or 32 bit version of Windows to test, nor an ARM or ARM64 machine. If someone has those capabilities, please consider testing my code and reporting back to me your results. Here is my contact form to get in touch with me.
I hope the code is mostly self-explanatory. However, the below discussion breaks it down well to clarify the code.
Function Return Value and Parameters
The three parameters in the function
getBits are reference types. The passed arguments will be set to
FALSE values after the
appropriate information is extracted in the function. Since the parameters are all reference types, changing them to the appropriate
values in the functions changes the values in the original arguments passed in by the caller so the caller can use them. The function
BOOL which is
TRUE if the function completed successfully,
Local Variables and Call to IsWow64Process2
Above, we note that two local variables,
NativeMachine, are defined. Their addresses are passed in to
and receive the function’s outputs via the pointer parameters
pNativeMachine, respectively (see here).
Their names are a bit confusing because of the word Machine in both: machine is not the physical machine, but the virtual machine architecture
within which the process runs under WOW64 (
ProcessMachine) and the architecture of the host Windows operating system (
IMAGE_FILE_MACHINE_UNKNOWN (at this time,
0), the process is not running under WOW64;
it is either 32 bit running natively under 32 bit Windows, or 64 bit running natively underneath the 64 bit Windows
If it is not
IMAGE_FILE_MACHINE_UNKNOWN, it will be set to a value that reveals the type of the WOW64 process:
see here. There are many different machine type constants, some referring to 64 bit architectures,
and some architectures that are no longer supported by Windows versions that have
Note this qoute from these docs:
WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows. This allows for 32-bit (x86) Windows applications to run seamlessly in 64-bit (x64) Windows, as well as for 32-bit (x86) and 32-bit (ARM) Windows applications to run seamlessly in 64-bit (ARM64) Windows.
It would appear that the only two possible image file machine constants for a process running under WOW64 returnable via
These constants would indicate a 32 bit x86 process or a 32 bit ARM process, respectively. Note that an x86 process can run under either an AMD64 or ARM64 WOW64 emulator, but a 32 bit ARM process can only run under an ARM64 WOW64 emulator.
NativeMachine will return a value indicating the architecture type of the host Windows operating system
That value is also an image file machine constant. As best I can tell from research, the possible values,
which would be for Windows architectures supporting the
IsWow64Process2 API, are:
IMAGE_FILE_MACHINE_I386(32 bit x86)
IMAGE_FILE_MACHINE_ARM(32 bit ARM)
IMAGE_FILE_MACHINE_IA64(64 bit Intel Itanium)
IMAGE_FILE_MACHINE_AMD64(64 bit Intel or AMD)
IMAGE_FILE_MACHINE_ARM64(64 bit ARM)
I am not sure if the above list is indeed exhaustive. If you know differently, please let me know.
GetCurrentProcess (see here) returns a pseudo handle to the current process, so the
ProcessMachine information in my
example will reflect the architecture of the current process.
IsWowProcess2 Function Return Value
IsWow64Process2 will return a nonzero value if it succeeds, otherwise, returning zero. If it fails, I display an error indication that includes the
last-error code returned by
GetLastError giving the reason for the failure (see here and here). I then return
FALSE to indicate failure to the caller, in which case the four returned booleans have undefined values.
Not WOW64 Path
The above code fragment notices the process is not running under WOW64 since
IMAGE_FILE_MACHINE_UNKNOWN is returned (see above).
It immediately sets
FALSE. The following three paths run under this conditional block:
64 Bit Windows Host Path
NativeMachine is any of the possible 64 bit values, indicating the host Windows architecture is 64 bit, I set
FALSE and return success. Since we know Windows is 64 bit, and the process is not running under WOW64,
we know the process is running 64 bit natively on the host OS.
32 Bit Windows Host Path
NativeMachine is any of the possible 32 bit values, indicating the host Windows architecture is 32 bit, I set
TRUE and return success. Since we know Windows is 32 bit, we know the process is running 32 bit natively on the host OS.
A 64 bit process cannot run under 32 bit Windows.
Catch All Error Path
If the returned value is not one known by
getBits, I print out an error statement and return failed.
The WOW64 Path
ProcessMachine did not return
IMAGE_FILE_MACHINE_UNKNOWN, the process is running under WOW64.
windowsIs32Bit is set to
WOW64 is only possible under 64 bit Windows,
isWow64 is set
processIs32Bit is set
TRUE because only a 32 bit process
can run under WOW64.
The usage is quite straightforward. In the example, we define the three
BOOL variables to pass as arguments then call the function
to fill them with the appropriate values. If getBits returns
FALSE, we exit the process with a return from main with the value
to indicate failure.
Otherwise, we print an appropriate output for each returned
BOOL argument, then return 0 to indicate nominal operation of the process.
IsWow64Process2 provides a nice, new API for its supported Windows versions that returns more information than the old
(see here). There is no need to fuss about old architectures no longer supported in the latest versions of Windows,
and it is a great way to figure out what the Windows host machine architecture is.
I have written this to provide hopefully robust, working example code of its usage for the community, which I could not find elsewhere. Even though I researched heavily, I am still unsure of some of the details, which I note above, and could not exercise all code paths. Help and correction are welcome via my contact form. I hope this article serves the community well.
Thanks to Pexels for the free header image.