15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace { 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)typedef BOOL (WINAPI *GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD); 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSInfo* OSInfo::GetInstance() { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: we don't use the Singleton class because it depends on AtExitManager, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and it's convenient for other modules to use this classs without it. This 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pattern is copied from gurl.cc. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static OSInfo* info; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OSInfo* new_info = new OSInfo(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (InterlockedCompareExchangePointer( 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<PVOID*>(&info), new_info, NULL)) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete new_info; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return info; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSInfo::OSInfo() 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : version_(VERSION_PRE_XP), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) architecture_(OTHER_ARCHITECTURE), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OSVERSIONINFOEX version_info = { sizeof version_info }; 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ::GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info)); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_number_.major = version_info.dwMajorVersion; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_number_.minor = version_info.dwMinorVersion; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_number_.build = version_info.dwBuildNumber; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((version_number_.major == 5) && (version_number_.minor > 0)) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_ = (version_number_.minor == 1) ? VERSION_XP : VERSION_SERVER_2003; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (version_number_.major == 6) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (version_number_.minor) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Treat Windows Server 2008 the same as Windows Vista. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_ = VERSION_VISTA; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Treat Windows Server 2008 R2 the same as Windows 7. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_ = VERSION_WIN7; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case 2: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Treat Windows Server 2012 the same as Windows 8. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_ = VERSION_WIN8; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) default: 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(version_number_.minor, 3); 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) version_ = VERSION_WIN8_1; 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (version_number_.major > 6) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_ = VERSION_WIN_LAST; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_pack_.major = version_info.wServicePackMajor; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_pack_.minor = version_info.wServicePackMinor; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYSTEM_INFO system_info = { 0 }; 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ::GetNativeSystemInfo(&system_info); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (system_info.wProcessorArchitecture) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PROCESSOR_ARCHITECTURE_INTEL: architecture_ = X86_ARCHITECTURE; break; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PROCESSOR_ARCHITECTURE_AMD64: architecture_ = X64_ARCHITECTURE; break; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PROCESSOR_ARCHITECTURE_IA64: architecture_ = IA64_ARCHITECTURE; break; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) processors_ = system_info.dwNumberOfProcessors; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocation_granularity_ = system_info.dwAllocationGranularity; 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GetProductInfoPtr get_product_info; 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DWORD os_type; 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (version_info.dwMajorVersion == 6) { 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Only present on Vista+. 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) get_product_info = reinterpret_cast<GetProductInfoPtr>( 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "GetProductInfo")); 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) get_product_info(version_info.dwMajorVersion, version_info.dwMinorVersion, 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 0, 0, &os_type); 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) switch (os_type) { 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_CLUSTER_SERVER: 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_DATACENTER_SERVER: 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_DATACENTER_SERVER_CORE: 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_ENTERPRISE_SERVER: 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_ENTERPRISE_SERVER_CORE: 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_ENTERPRISE_SERVER_IA64: 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_SMALLBUSINESS_SERVER: 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_STANDARD_SERVER: 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_STANDARD_SERVER_CORE: 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_WEB_SERVER: 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_SERVER; 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_PROFESSIONAL: 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_ULTIMATE: 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_ENTERPRISE: 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_BUSINESS: 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_PROFESSIONAL; 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_HOME_BASIC: 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_HOME_PREMIUM: 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case PRODUCT_STARTER: 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) default: 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_HOME; 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (version_info.dwMajorVersion == 5 && 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_info.dwMinorVersion == 2) { 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (version_info.wProductType == VER_NT_WORKSTATION && 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { 125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_PROFESSIONAL; 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (version_info.wSuiteMask & VER_SUITE_WH_SERVER ) { 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_HOME; 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_SERVER; 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (version_info.dwMajorVersion == 5 && 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_info.dwMinorVersion == 1) { 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if(version_info.wSuiteMask & VER_SUITE_PERSONAL) 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_HOME; 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) else 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_PROFESSIONAL; 137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Windows is pre XP so we don't care but pick a safe default. 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) version_type_ = SUITE_HOME; 140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSInfo::~OSInfo() { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string OSInfo::processor_model_name() { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (processor_model_name_.empty()) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t kProcessorNameString[] = 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey key(HKEY_LOCAL_MACHINE, kProcessorNameString, KEY_READ); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 value; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key.ReadValue(L"ProcessorNameString", &value); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) processor_model_name_ = UTF16ToUTF8(value); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return processor_model_name_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process")); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_wow64_process) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WOW64_DISABLED; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL is_wow64 = FALSE; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(*is_wow64_process)(process_handle, &is_wow64)) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WOW64_UNKNOWN; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Version GetVersion() { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OSInfo::GetInstance()->version(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace win 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 177