How to tell if program is running on 32 or 64bit windows?

  • Thread starter Thread starter Phil Tomson
  • Start date Start date
P

Phil Tomson

Is there a way to _reliably_ tell if you're program or script is
running on 32 or 64 bit WindowsXP?

I've seen some suggestions that you could check for the processor in:
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0

but even if it reports that you've got an IA64 processor, you might
still be running 32-bit windows.

I would have thought that I might find it in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

....but of course, that would be too logical.

Any ideas? There must be some way that Microsoft apps determine this
(for example, when you need to download a security patch).

Phil
 
HOW TO: Determine Whether Your Computer Is Running a 32-Bit Version or
64-Bit Version of Windows XP
http://support.microsoft.com/default.aspx?scid=kb;en-us;827218&Product=winxp

--
Carey Frisch
Microsoft MVP
Windows XP - Shell/User

Be Smart! Protect your PC!
http://www.microsoft.com/security/protect/

--------------------------------------------------------------------------------------------------------


| Is there a way to _reliably_ tell if you're program or script is
| running on 32 or 64 bit WindowsXP?
|
| I've seen some suggestions that you could check for the processor in:
| HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0
|
| but even if it reports that you've got an IA64 processor, you might
| still be running 32-bit windows.
|
| I would have thought that I might find it in:
| HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
|
| ...but of course, that would be too logical.
|
| Any ideas? There must be some way that Microsoft apps determine this
| (for example, when you need to download a security patch).
|
| Phil
 
-----Original Message-----
Is there a way to _reliably_ tell if you're program or script is
running on 32 or 64 bit WindowsXP?

I've seen some suggestions that you could check for the processor in:
HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralPro cessor\0

but even if it reports that you've got an IA64 processor, you might
still be running 32-bit windows.

I would have thought that I might find it in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVers ion

....but of course, that would be too logical.

Any ideas? There must be some way that Microsoft apps determine this
(for example, when you need to download a security patch).

Phil
.
Unless you paid 3 or 4 grand for your computer it's 32
bit
 
Raymond Chen said:
IsWow64Process()

This sounds like probably the best way that I've seen so far, except
what happens if the program gets run on Win2K or even Win98? I
suspect that the dll's on those older machines won't have reference to
this newer function.
....well, I suppose I could put some exception handling around it.

Thanks.

Phil
 
Phil Tomson said:
This sounds like probably the best way that I've seen so far, except
what happens if the program gets run on Win2K or even Win98? I
suspect that the dll's on those older machines won't have reference to
this newer function.
...well, I suppose I could put some exception handling around it.

Read the note on the MSDN page for IsWow64Process: use GetProcAddress to
retrieve a pointer to this function to allow your program to run on versions
of Windows before XP.
 
Raymond Chen said:
IsWow64Process()

It looks like I need a newer version of Windows.h that declares
IsWow64Process().
I can't get my program to compile with a call to this function (and
yes, I did try setting _WIN32_WINNT>=0x0501 WINVER>=0x0501). I've got
VC7 is the correct header file included somewhere or is there
someplace I can download it from?

Phil
 
Raymond Chen said:
IsWow64Process()

A bit more info as a followup to my previous query:

I have Visual Studio .NET 2003/VC7 May 2003 edition. The microsoft
site (http://msdn.microsoft.com/library/d...winprog/winprog/using_the_windows_headers.asp
) seems to imply that you have to buy the Platform SDK cd to get these
updated headers. However, the latest one they have is from Feb 2003,
so I would think that VC7 May 2003 edition would have this already,
but a complete search of my system fails to find anything any header
file that declares IsWOW64Process().

Phil
 
It looks like I need a newer version of Windows.h that declares
IsWow64Process().
I can't get my program to compile with a call to this function (and
yes, I did try setting _WIN32_WINNT>=0x0501 WINVER>=0x0501). I've got
VC7 is the correct header file included somewhere or is there
someplace I can download it from?

OK, I was able to get things to compile by adding
-D_WIN32_WINNT=0x0501 to my makefile. Now there are other oddities
with calling IsWow64Process() from XP.

I'm running my program on XP and when it comes to the call to
IsWow64Process()an exception is thrown. Here's the code:

//begin C++ code:
typedef BOOL (*ISWOW64PROC) (HANDLE,PBOOL);
REGSAM CRegistry::check_64bit(REGSAM read_permissions)
{
ISWOW64PROC iswow64proc;
PBOOL is64bit = FALSE;
try {
iswow64proc= (ISWOW64PROC)
GetProcAddress(GetModuleHandle("KERNEL32\0"),"IsWow64Process\0");
//if(GetProcAddress(GetModuleHandle("kernel32\0"),"IsWow64Process\0")
!= NULL)
if(NULL != iswow64proc )
{
HANDLE this_process;
this_process = GetCurrentProcess();
printf("Do we get here? (we shouldn't on Win2k)\n");
if (this_process != NULL){
printf("this_process seems to be valid\n");
}else{
printf("this_process is NULL!\n");
}
//the offending call:
(iswow64proc)(this_process,is64bit);
printf("after call to iswow64proc\n");
if(*is64bit == TRUE)
{
read_permissions |= (KEY_WOW64_64KEY | KEY_WOW64_32KEY );
printf("...running on 64bit XP...\n");
}else{
printf("...running on 32bit XP...\n");
}
}else{
printf("...running on 32bit Windows (probably Win9*, Win2k,
WinME)...\n");
}
}
catch(...)
{
printf("...caught exception: probably running on 32bit
windows...\n");
return read_permissions;
}
return read_permissions;
}
//end of code

What happens on both XP 32 and 64bit is that it prints:
Do we get here? (we shouldn't on Win2k)
...caught exception: probably running on 32bit windows...

On Win2K it correctly determines that it cannot call IsWow64Process
and prints:
...running on 32bit Windows (probably Win9*, Win2k, WinME)...

Interestingly enough, I got this working initially in Ruby (using the
Win32API module).... Here's the (working) Ruby code (just the
relevant bits):

#begin Ruby code:
require 'Win32API'

module Win32
class Registry
module Constants
begin
IsWow64Process=Win32API.new("kernel32","IsWow64Process",['L','P'],'L')
rescue
puts "you're not on XP" if $DEBUG
isXP = false
else
puts "you're on XP: could be 32 or 64 bit" if $DEBUG
isXP = true
end
GetCurrentProcess =
Win32API.new("kernel32","GetCurrentProcess",[],'L')

<snip a lot of constants>

key_read = STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY
if isXP
is64 = "\0" * 4
result = IsWow64Process.call(GetCurrentProcess.call(),is64)
is64 = is64.unpack("L")[0].to_i
if is64 > 0
puts "64bit XP" if $DEBUG
key_read |= (KEY_WOW64_64KEY | KEY_WOW64_32KEY )
else
puts "32bit XP" if $DEBUG
end
end
KEY_READ = key_read

<snip more non-relevant code>
end
end
end #of Ruby code

....The Ruby version works great, but I've got to get this working in
C++.
Any ideas?

Phil
 
typedef BOOL (*ISWOW64PROC) (HANDLE,PBOOL);

The declaration is wrong. It should be

typedef BOOL (WINAPI *ISWOW64PROC) (HANDLE,PBOOL);

The WINAPI is important. I discuss the consequences of mismatched
calling conventions here

http://weblogs.asp.net/oldnewthing/archive/2004/01/15/58973.aspx

but it looks like you discovered it on your own...
IsWow64Process=Win32API.new("kernel32","IsWow64Process",['L','P'],'L')

Ruby probably knows that Windows uses the __stdcall (aka WINAPI)
calling convention for most functions, so it got the calling
convention right when thunking to IsWow64Process.
 
Raymond Chen said:
The declaration is wrong. It should be

typedef BOOL (WINAPI *ISWOW64PROC) (HANDLE,PBOOL);

The WINAPI is important. I discuss the consequences of mismatched
calling conventions here

http://weblogs.asp.net/oldnewthing/archive/2004/01/15/58973.aspx

Thanks for the info. Even the example code on MSDN didn't show this.
However, after making the change to match your typedef, it still
didn't work. I still got the exception.

Phil
 
For those playing along at home, the bug was here:

PBOOL is64bit = FALSE;
....
(iswow64proc)(this_process,is64bit);
if(*is64bit == TRUE)

It should have been

BOOL is64bit = FALSE;
....
(iswow64proc)(this_process,&is64bit);
if(is64bit == TRUE)
 
Raymond Chen said:
For those playing along at home, the bug was here:

PBOOL is64bit = FALSE;
...
(iswow64proc)(this_process,is64bit);
if(*is64bit == TRUE)

It should have been

BOOL is64bit = FALSE;
...
(iswow64proc)(this_process,&is64bit);
if(is64bit == TRUE)

Yes indeed. My bad.

For the record, I attach the final version of the method in case
anyone needs to do this sort of thing 'at home':

//.h file declaration:
class CRegistry {
//...
REGSAM get_read_perm(REGSAM read_permissions = KEY_READ);
//...
};

//.cpp file code:
typedef BOOL (WINAPI *ISWOW64PROC) (HANDLE,PBOOL);
REGSAM CRegistry::get_read_perm(REGSAM read_permissions)
{
ISWOW64PROC iswow64proc;
BOOL is64bit = FALSE;
try {
iswow64proc= (ISWOW64PROC)
GetProcAddress(GetModuleHandle("KERNEL32\0"),"IsWow64Process\0");
if(NULL != iswow64proc ){
HANDLE this_process;
this_process = GetCurrentProcess();
//printf("Do we get here? (we shouldn't on Win2k)\n");
if (this_process != NULL){
//printf("this_process seems to be valid\n");
(iswow64proc)(this_process,&is64bit);
//printf("after call to iswow64proc\n");
}else{
//printf("this_process is NULL!\n");
}
if(is64bit == TRUE){
read_permissions |= (KEY_WOW64_64KEY | KEY_WOW64_32KEY );
//printf("...running on 64bit XP...\n");
}else{
//printf("...running on 32bit XP...\n");
}
}else{
//printf("...running on 32bit Windows (probably Win9*, Win2k,
WinME)...\n");
}

}
catch(...)
{
printf("...caught exception: probably running on 32bit
windows...\n");
return read_permissions;
}
return read_permissions;
}
//end C++ code

Note that if you try to do:

read_permissions |= (KEY_WOW64_64KEY | KEY_WOW64_32KEY );

...and then call a registry access function

on Win[2k|ME|98|95] the program will crash (I found this to be the
case on Win2K, anyway, and I suspect it would be true for the others).
That's why you have to call IsWow64Process() first in order to
determine that you're on XP and it's safe to OR the 64bit permissions
to the KEY_READ.

Basically, you just call get_read_perm() wherever you were using
KEY_READ in registry access functions and then your 32bit program
which accesses the registry should work on both 32bit and 64bit
Windows variants.

Phil

...now I'll be getting back to Linux.
 
Back
Top