How to detect programmatically whether you are running on 64-bit Windows

To detect programmatically whether your 32-bit program is running
on 64-bit Windows, you can use the IsWow64Process function.

Do not do
as some people do and
hard-code the list of 64-bit processors.
You'd think that after the hard-coded list of 64-bit processors
changed the first time (when x64 was added to ia64), people would have
learned their lesson.

But how do you detect programmatically from your 64-bit process
whether you are running on 64-bit Windows? Easy.

BOOL Is64BitProcessRunningOn64BitWindows()
{
return TRUE;
}

The fact that your 64-bit program is running at all
means that you are running on 64-bit Windows!
If it were a 32-bit machine, your program wouldn't be
able to run.

It's like asking the question, "Is the power on?"
If there were no power, your program wouldn't be able to ask the question.

Of course, if you want a single source code base that can be
compiled both as a 32-bit program and as a 64-bit program,
you have a tiny amount of work to do.

It may have been interesting to have the function as an API though to already include a check for the day Win128 ships. Since there’s no such API, we’ll have to recompile. Or is it already known that there will be no Win128 within foreseable future ?

BTW, why would a 32-bits process be interested to know that it runs on Win64 ?

SHTDN_REASON_MINOR_CORDUNPLUGGED might also be the reason code used when "Power failure (cord unplugged)" is selected as the reason for an unexpected shutdown. There’s also "Power failure (environmental)".

Just imagine if Win16 had included a function called something like GetSystemWordSize(). When Win95 came out, half-a-dozen crucial widely-distributed 16-bit apps would have promptly broken because this function was now returning 32. And a dozen more Win32 apps when it went to 64…

Well, one reason would be so that you could go to your online update site, see that there’s a 64-bit version of the DLLs available for download, push them to the user, and then fixup everything to run that instead of the old 32-bit version next time they launch it.

Not to brag or anything, but one of our apps still ships 32/16 thunk DLLs for interop with some 16 bit apps which our customers still use. We haven’t had to rebuild them in a while though. Luckily a couple of 16 bit apps owned by our group were finally EOL’ed last year. Even though I’m a pack rat, I’m ready to get rid of my win31 SDK manuals….

We’ve got a lot of 32-bit processes running on 64-bit Windows, but unfortunately they’re things like WSH that don’t have access to API calls such as IsWow64Process. I wish they did, though, because some of the registry and system directory fakeouts performed by the 64-bit OS causes confusion when we start launching 64-bit utilities (or use something like WMI) that are not subject to the fakeouts. At times like those, I need to know if I’m running on 64-bit Windows so I can tell my 64-bit utility and/or WMI where to look for something.

As well – there can be some kind of crazy BIOS code that will keep track of current time or Wake-on-XXX events. This code definitely requere "IsPowerOn()" method – as there can be several different "Off" states – "Soft Off" and "Mechanical Off".

If the intention was this to be used for powering off in a low battery situation (UPS, laptop) it could be worded a bit better!"

The intention is to prompt the first administrator that logs onto the server after it comes up for the reason that the server was unexpectedly shutdown [how does it know the shutdown was unexpected? by using a heartbeat service]. In this scenario, it’s perfectly reasonable for the [sheepish] administrator to say it was because the cord was unplugged. I suspect that the reason the "reason code" is available for an API initiating a shutdown is just to have all the reason codes listed, even if it doesn’t make sense to say: "I’m trying to shutdown because the cord is about to be unplugged." I would think that the reason code for power failure (environment) would be more likely to be used for UPS/laptop shutdowns than "cord unplugged."

You’re asking people to predict the future; no surprise nobody has taken you up on it.

Besides, even if your program detected 128-bit Windows, what can you do in response? Are you going to start passing undefined flags in the hopes that one of them suddenly means something on 128-bit Windows?

But surely thats the whole purpose of the emulator? You run it saying "Please pretend this program is running in 64bit windows". I would be upset if it didn’t detect 64bit in the emulator… wouldn’t you ?

Yes, it’s the purpose of the emulator, but some people want to know that they are running inside an x86 emulator (for example, maybe they want to pass the REG_WOW64_64KEY flag to RegOpenKeyEx in order to open the 64-bit registry) – that’s the purpose of this exercise.

That’s a function of the architecture, not of Windows. For example, the 80386 DX (I believe the DX was the first 32-bit processor) was fully backwards compatible with it’s 16-bit cousins.

However, Intel’s Itanium 64-bit architecture is not backwards compatible with the x86 architecture and so you can only run 64-bit Windows on it.

AMD’s X64 (and Intel’s copy of that, EM64T) /is/ backwards compatible with x86, and so 32-bit Windows will run fine on it.

Running 32-bit applications on a 64-bit Windows is different again, and is like running a Windows 3.1 app on Windows 2000/XP – it’ll work, but the OS has to pull off a number of tricks to make it to work.

Dean Harding: I’m quite sure the SX was also capable of i386 protected mode, but it had a cheaper 16-bit bus. But, I think the original 386s of all flavors (where I think the DX was introduced first) had some bugs that made them impossible to use in that mode, after all.

wow means "Windows on Windows" afaik. 32bit windows uses wow to run 16bit code on 32bit windows, and 64bit windows uses wow to run 32bit code on 64bit windows. I could be wrong but its kinda like an emulator for the 32bit subsystem on the 64bit operating system.

> You’re asking people to predict the future; no surprise nobody has taken you up on it.

This is not what I initially asked. My original question was:

Is it already known that there will be no Win128 within foreseable future ?

Slightly different ! If the future cannot be predicted in this matter then the answer to the question is : No. And back to the problem at hand: Why then is there no Is64BitProcessRunningOn64BitWindows() API today to ensure further compatibility in non excluded future scenarios ?

What I would do with it if it existed ? I don’t know. Neither do I know what to do with IsWow64Process() today. And Simon Cooke’s suggestion remains valid for a possibly upcoming Win128 as well.

"However, Intel’s Itanium 64-bit architecture is not backwards compatible with the x86 architecture and so you can only run 64-bit Windows on it. "

Not true. Not only does it have x86 emulation performed in hardware (albeit slowly), it also has (in Win2K3SP1 and up) software emulation (which I believe does fancy tricks like profiling and essentially recompile) which runs considerably faster than the hardware support.

> Why then is there no Is64BitProcessRunningOn64BitWindows() API today?

Because until there *is* a 128-bit Windows, then knowing that you’re running on a 128-bit windows in 64-bit emulation mode is meaningless. You only ever need to know you’re a 32-bit process running on 64-bit Windows if you want to take advantage of 64-bit features (e.g. like accessing the 64-bit registry as opposed to the WoW 32-bit registry). So without an actual 128-bit platform to take advantage of, you can’t gain anything by knowing whether you’re running on it or not.

Of course, if 128-bit Windows ever does come out, then you’re going to have to modify your code to take advantage of it’s features anyway, so putting the call to Is64BitRunningOn128Bit is no problem.

CN: Yes, 80386SX was able to run 32-bit protected mode programs, including 3.1 enhanced mode provided sufficient (extended) memory. Of course, it also could execute 32-bit instructions in 16-bit program too.

80386DX was a name put back (much like Win16), originally this processor was simply 80386.

The first released steps of this chip (B1 and prior, that is before 1997-04) had a 32-bit multiply bug, but AFAIK it did not prevent to use 32-bit mode, it "just" requires to replace a 32-bit MUL with (several) 16-bit ones (remember the Pentium bug, anyone?) Of course, it was much easier to explaine the customers they should not install 32-bit softwares and let softwares use 32-bit MUL without worrying!

And a very good problem I have no definitive answer to is how to detect if you are running on a 80286 or a 80386+, if you are in protected mode and do not want/can change the illegal instruction handler (one way to have 99% certainity is to check the upper word of SGDT, it is 0xFF with 80286; but this is a possible yet unlikely value for a 80386 too).

So here again, the solution is to rely to an API, exactly as Raymond highlighted. My best candidate is the DPMI function 0400h.

Btw: Win16 is not supported within Win64/x64, even if the processor allows execution of 16-bit protected mode code in long mode. I conjectured this is because the V86 mode is not available, and far too much Win16 programs may rely on it or on similar DOS-related things (such as allocating ‘real-mode’ memory, or PSP). Any insight?