Click here to Skip to main content
Click here to Skip to main content

32-Bit or 64-bit OS ??

, 21 Sep 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple way to detect bitness of an OS Programatically. (C# and C++ examples given)
There's always been a fight over an optimal way to detect bitness of an OS. Most of the time, getting system information is considered to be solved using interop services or P/Invoke. For this, the methodology followed is as shown below:
 
public enum Platform
    {
      X86,
      X64,
      Unknown
    }
 
    internal const ushort PROCESSOR_ARCHITECTURE_INTEL = 0;
    internal const ushort PROCESSOR_ARCHITECTURE_IA64 = 6;
    internal const ushort PROCESSOR_ARCHITECTURE_AMD64 = 9;
    internal const ushort PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;
 
    [StructLayout(LayoutKind.Sequential)]
    internal struct SYSTEM_INFO
    {
      public ushort wProcessorArchitecture;
      public ushort wReserved;
      public uint dwPageSize;
      public IntPtr lpMinimumApplicationAddress;
      public IntPtr lpMaximumApplicationAddress;
      public UIntPtr dwActiveProcessorMask;
      public uint dwNumberOfProcessors;
      public uint dwProcessorType;
      public uint dwAllocationGranularity;
      public ushort wProcessorLevel;
      public ushort wProcessorRevision;
    };
 
    [DllImport("kernel32.dll")]
    internal static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);
 
    [DllImport("kernel32.dll")]
    internal static extern void GetSystemInfo(ref SYSTEM_INFO lpSystemInfo);
 
    public static Platform GetPlatform()
    {
      SYSTEM_INFO sysInfo = new SYSTEM_INFO();
 
      if(System.Environment.OSVersion.Version.Major > 5 ||
    (System.Environment.OSVersion.Version.Major == 5 && System.Environment.OSVersion.Version.Minor >= 1))
      {
         GetNativeSystemInfo(ref sysInfo);
      }
      else
      {
         GetSystemInfo(ref sysInfo);
      }
 
      switch(sysInfo.wProcessorArchitecture)
      {
    case PROCESSOR_ARCHITECTURE_IA64:
    case PROCESSOR_ARCHITECTURE_AMD64:
      return Platform.X64;
 
    case PROCESSOR_ARCHITECTURE_INTEL:
      return Platform.X86;
 
    default:
      return Platform.Unknown;
      }
    }
 
Actually there's a simple way to do that in C#. C# provides a very useful struct IntPtr.
 

64-Bit Vs 32-Bit w.r.t Pointer

We all know that the size of an Pointer on a 32-bit machine compiled program is 4-Bytes. The size changes on a 64-Bit compiled program and becomes 8-bytes. Then why not compare the size of Integer. Pointer is nothing but an Integer and IntPtr serves the same for us in C#.
 
The following example shows the simple usage of IntPtr.
(UPDATE: As Win64 follows LLP64 Model (For more informarion on LLP64 model please follow Technet Article[^]) as corrected by codeproject member Ajay Vijayvargiya[^])
 
if(IntPtr.size == 4)
{
   //Your logic for 32-Bit.
}
else
{
  // Your logic for 64-Bit.
}
Previous code checks whether the program is running in 32-bit or 64-bit mode. This doesn't inform OS bitness.
 
If using C++/Win32:
IntPtr is not available in C++. Rather sizeof(int) does the same.
 
BOOL Is64BitOS()
{
	BOOL bIs64Bit = FALSE;
 
	#if defined(_WIN64)
 
	bIs64Bit = TRUE;  // 64-bit programs run only on Win64

	#elif defined(_WIN32)
 
	// Note that 32-bit programs run on both 32-bit and 64-bit Windows

	typedef BOOL (WINAPI *LPFNISWOW64PROCESS) (HANDLE, PBOOL);
	LPFNISWOW64PROCESS pfnIsWow64Process = (LPFNISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process");
 
	if (pfnIsWow64Process)
		pfnIsWow64Process(GetCurrentProcess(), &bIs64Bit);
 
	#endif
 
	return bIs64Bit;
}
 
There's one more distinctive feature a 64-Bit OS supports: "Virtualization".
 

Virtualization (Windows Vista and 7 x64 Platform only)

 
Virtualization technologies are used by Windows Vista and 7 x64 platform only. These act like virtual machines just like VMWare or similar apps. The advantage here is to run legacy apps such s 32-bit apps. Running 32-Bit apps on 64-Bit OS becomes difficult without virtualization as such applications are usually not written to co-exist within a single execution environment.
 
64-Bit applications are never run virtualized, nor do 32 or 64-Bit services and drivers. Virtualization becomes active when running legacy 32-bit interactive apps under WOW64.
 
So if the OS supports virtualization, then it got to be 64-Bit.
 
You can use the following code to check whether the app is running as virtualized:
 
[DllImport("advapi32.dll", EntryPoint = "GetTokenInformation",
SetLastError = true)]
static extern bool GetTokenInformationNative(
IntPtr TokenHandle,
int TokenInformationClass,
ref int  TokenInformation,
int TokenInformationLength,
out int ReturnLength);
 
public bool IsVirtualized(IntPtr token)
{
    bool virtualized = false;
    int len = 4;
    int info = 0;
    if (!GetTokenInformationNative(token, 24, ref info, len, out
    len)) // 24 = TokenVirtualizationEnabled
    {
       string s = "Win32 error " +
       Marshal.GetLastWin32Error().ToString();
       throw new Exception(s);
    }
    if(info != 0)
       virtualized = true;
    return virtualized;
}
 
// usage...

if(IsVirtualized(WindowsIdentity.GetCurrent().Toke  n))
// better add a manifest to your application if you end here ;-)
 

Thanks to Luc Pattyn[^] and Ajay Vijayvargiya[^] to point out the errors. Smile | :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

GPUToaster™
Other
India India
http://gputoaster.wordpress.com/about
Follow on   Twitter

Comments and Discussions

 
GeneralReason for my vote of 5 You are right, I hadn't read with en... PinmemberSauro Viti21-Oct-10 21:32 
GeneralReason for my vote of 3 Good start, but some mistakes. PinmemberToli Cuturicu11-Oct-10 12:39 
GeneralIf using C++: IntPtr is not available in C++. Rather sizeof(... PinmemberAjay Vijayvargiya19-Sep-10 11:56 
If using C++: IntPtr is not available in C++. Rather sizeof(int) does the same.
 
Nonsense, int is always 4-bytes, on 32-bit AND on 64-bit. Windows implements LLP64 model for 64-bit architecture.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411028.1 | Last Updated 21 Sep 2010
Article Copyright 2010 by GPUToaster™
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid