Home | History | Annotate | Download | only in win
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/win/windows_version.h"
      6 
      7 #include <windows.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "base/win/registry.h"
     12 
     13 namespace base {
     14 namespace win {
     15 
     16 // static
     17 OSInfo* OSInfo::GetInstance() {
     18   // Note: we don't use the Singleton class because it depends on AtExitManager,
     19   // and it's convenient for other modules to use this classs without it. This
     20   // pattern is copied from gurl.cc.
     21   static OSInfo* info;
     22   if (!info) {
     23     OSInfo* new_info = new OSInfo();
     24     if (InterlockedCompareExchangePointer(
     25         reinterpret_cast<PVOID*>(&info), new_info, NULL)) {
     26       delete new_info;
     27     }
     28   }
     29   return info;
     30 }
     31 
     32 OSInfo::OSInfo()
     33     : version_(VERSION_PRE_XP),
     34       architecture_(OTHER_ARCHITECTURE),
     35       wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) {
     36   OSVERSIONINFOEX version_info = { sizeof version_info };
     37   GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
     38   version_number_.major = version_info.dwMajorVersion;
     39   version_number_.minor = version_info.dwMinorVersion;
     40   version_number_.build = version_info.dwBuildNumber;
     41   if ((version_number_.major == 5) && (version_number_.minor > 0)) {
     42     // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
     43     version_ = (version_number_.minor == 1) ? VERSION_XP : VERSION_SERVER_2003;
     44   } else if (version_number_.major == 6) {
     45     switch (version_number_.minor) {
     46       case 0:
     47         // Treat Windows Server 2008 the same as Windows Vista.
     48         version_ = VERSION_VISTA;
     49         break;
     50       case 1:
     51         // Treat Windows Server 2008 R2 the same as Windows 7.
     52         version_ = VERSION_WIN7;
     53         break;
     54       default:
     55         DCHECK_EQ(version_number_.minor, 2);
     56         // Treat Windows Server 2012 the same as Windows 8.
     57         version_ = VERSION_WIN8;
     58         break;
     59     }
     60   } else if (version_number_.major > 6) {
     61     NOTREACHED();
     62     version_ = VERSION_WIN_LAST;
     63   }
     64   service_pack_.major = version_info.wServicePackMajor;
     65   service_pack_.minor = version_info.wServicePackMinor;
     66 
     67   SYSTEM_INFO system_info = { 0 };
     68   GetNativeSystemInfo(&system_info);
     69   switch (system_info.wProcessorArchitecture) {
     70     case PROCESSOR_ARCHITECTURE_INTEL: architecture_ = X86_ARCHITECTURE; break;
     71     case PROCESSOR_ARCHITECTURE_AMD64: architecture_ = X64_ARCHITECTURE; break;
     72     case PROCESSOR_ARCHITECTURE_IA64:  architecture_ = IA64_ARCHITECTURE; break;
     73   }
     74   processors_ = system_info.dwNumberOfProcessors;
     75   allocation_granularity_ = system_info.dwAllocationGranularity;
     76 }
     77 
     78 OSInfo::~OSInfo() {
     79 }
     80 
     81 std::string OSInfo::processor_model_name() {
     82   if (processor_model_name_.empty()) {
     83     const wchar_t kProcessorNameString[] =
     84         L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
     85     base::win::RegKey key(HKEY_LOCAL_MACHINE, kProcessorNameString, KEY_READ);
     86     string16 value;
     87     key.ReadValue(L"ProcessorNameString", &value);
     88     processor_model_name_ = UTF16ToUTF8(value);
     89   }
     90   return processor_model_name_;
     91 }
     92 
     93 // static
     94 OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) {
     95   typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
     96   IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
     97       GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
     98   if (!is_wow64_process)
     99     return WOW64_DISABLED;
    100   BOOL is_wow64 = FALSE;
    101   if (!(*is_wow64_process)(process_handle, &is_wow64))
    102     return WOW64_UNKNOWN;
    103   return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
    104 }
    105 
    106 Version GetVersion() {
    107   return OSInfo::GetInstance()->version();
    108 }
    109 
    110 }  // namespace win
    111 }  // namespace base
    112