1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_WIN_WINDOWS_VERSION_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_WIN_WINDOWS_VERSION_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <string> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/version.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker using DWORD = unsigned long; // NOLINT(runtime/int) 17*6777b538SAndroid Build Coastguard Worker using HANDLE = void*; 18*6777b538SAndroid Build Coastguard Worker struct _OSVERSIONINFOEXW; 19*6777b538SAndroid Build Coastguard Worker struct _SYSTEM_INFO; 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker namespace base { 22*6777b538SAndroid Build Coastguard Worker namespace test { 23*6777b538SAndroid Build Coastguard Worker class ScopedOSInfoOverride; 24*6777b538SAndroid Build Coastguard Worker } // namespace test 25*6777b538SAndroid Build Coastguard Worker } // namespace base 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker namespace base { 28*6777b538SAndroid Build Coastguard Worker namespace win { 29*6777b538SAndroid Build Coastguard Worker 30*6777b538SAndroid Build Coastguard Worker // The running version of Windows. This is declared outside OSInfo for 31*6777b538SAndroid Build Coastguard Worker // syntactic sugar reasons; see the declaration of GetVersion() below. 32*6777b538SAndroid Build Coastguard Worker // NOTE: Keep these in order so callers can do things like 33*6777b538SAndroid Build Coastguard Worker // "if (base::win::GetVersion() >= base::win::Version::VISTA) ...". 34*6777b538SAndroid Build Coastguard Worker enum class Version { 35*6777b538SAndroid Build Coastguard Worker PRE_XP = 0, // Not supported. 36*6777b538SAndroid Build Coastguard Worker XP = 1, 37*6777b538SAndroid Build Coastguard Worker SERVER_2003 = 2, // Also includes XP Pro x64 and Server 2003 R2. 38*6777b538SAndroid Build Coastguard Worker VISTA = 3, // Also includes Windows Server 2008. 39*6777b538SAndroid Build Coastguard Worker WIN7 = 4, // Also includes Windows Server 2008 R2. 40*6777b538SAndroid Build Coastguard Worker WIN8 = 5, // Also includes Windows Server 2012. 41*6777b538SAndroid Build Coastguard Worker WIN8_1 = 6, // Also includes Windows Server 2012 R2. 42*6777b538SAndroid Build Coastguard Worker WIN10 = 7, // Threshold 1: Version 1507, Build 10240. 43*6777b538SAndroid Build Coastguard Worker WIN10_TH2 = 8, // Threshold 2: Version 1511, Build 10586. 44*6777b538SAndroid Build Coastguard Worker WIN10_RS1 = 9, // Redstone 1: Version 1607, Build 14393. 45*6777b538SAndroid Build Coastguard Worker // Also includes Windows Server 2016 46*6777b538SAndroid Build Coastguard Worker WIN10_RS2 = 10, // Redstone 2: Version 1703, Build 15063. 47*6777b538SAndroid Build Coastguard Worker WIN10_RS3 = 11, // Redstone 3: Version 1709, Build 16299. 48*6777b538SAndroid Build Coastguard Worker WIN10_RS4 = 12, // Redstone 4: Version 1803, Build 17134. 49*6777b538SAndroid Build Coastguard Worker WIN10_RS5 = 13, // Redstone 5: Version 1809, Build 17763. 50*6777b538SAndroid Build Coastguard Worker // Also includes Windows Server 2019 51*6777b538SAndroid Build Coastguard Worker WIN10_19H1 = 14, // 19H1: Version 1903, Build 18362. 52*6777b538SAndroid Build Coastguard Worker WIN10_19H2 = 15, // 19H2: Version 1909, Build 18363. 53*6777b538SAndroid Build Coastguard Worker WIN10_20H1 = 16, // 20H1: Build 19041. 54*6777b538SAndroid Build Coastguard Worker WIN10_20H2 = 17, // 20H2: Build 19042. 55*6777b538SAndroid Build Coastguard Worker WIN10_21H1 = 18, // 21H1: Build 19043. 56*6777b538SAndroid Build Coastguard Worker WIN10_21H2 = 19, // Win10 21H2: Build 19044. 57*6777b538SAndroid Build Coastguard Worker WIN10_22H2 = 20, // Win10 21H2: Build 19045. 58*6777b538SAndroid Build Coastguard Worker SERVER_2022 = 21, // Server 2022: Build 20348. 59*6777b538SAndroid Build Coastguard Worker WIN11 = 22, // Win11 21H2: Build 22000. 60*6777b538SAndroid Build Coastguard Worker WIN11_22H2 = 23, // Win11 22H2: Build 22621. 61*6777b538SAndroid Build Coastguard Worker WIN11_23H2 = 24, // Win11 23H2: Build 22631. 62*6777b538SAndroid Build Coastguard Worker WIN_LAST, // Indicates error condition. 63*6777b538SAndroid Build Coastguard Worker }; 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker // A rough bucketing of the available types of versions of Windows. This is used 66*6777b538SAndroid Build Coastguard Worker // to distinguish enterprise enabled versions from home versions and potentially 67*6777b538SAndroid Build Coastguard Worker // server versions. Keep these values in the same order, since they are used as 68*6777b538SAndroid Build Coastguard Worker // is for metrics histogram ids. 69*6777b538SAndroid Build Coastguard Worker enum VersionType { 70*6777b538SAndroid Build Coastguard Worker SUITE_HOME = 0, 71*6777b538SAndroid Build Coastguard Worker SUITE_PROFESSIONAL, 72*6777b538SAndroid Build Coastguard Worker SUITE_SERVER, 73*6777b538SAndroid Build Coastguard Worker SUITE_ENTERPRISE, 74*6777b538SAndroid Build Coastguard Worker SUITE_EDUCATION, 75*6777b538SAndroid Build Coastguard Worker SUITE_EDUCATION_PRO, 76*6777b538SAndroid Build Coastguard Worker SUITE_LAST, 77*6777b538SAndroid Build Coastguard Worker }; 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker // A singleton that can be used to query various pieces of information about the 80*6777b538SAndroid Build Coastguard Worker // OS and process state. Note that this doesn't use the base Singleton class, so 81*6777b538SAndroid Build Coastguard Worker // it can be used without an AtExitManager. 82*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT OSInfo { 83*6777b538SAndroid Build Coastguard Worker public: 84*6777b538SAndroid Build Coastguard Worker struct VersionNumber { 85*6777b538SAndroid Build Coastguard Worker uint32_t major; 86*6777b538SAndroid Build Coastguard Worker uint32_t minor; 87*6777b538SAndroid Build Coastguard Worker uint32_t build; 88*6777b538SAndroid Build Coastguard Worker uint32_t patch; 89*6777b538SAndroid Build Coastguard Worker }; 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker struct ServicePack { 92*6777b538SAndroid Build Coastguard Worker int major; 93*6777b538SAndroid Build Coastguard Worker int minor; 94*6777b538SAndroid Build Coastguard Worker }; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // The processor architecture this copy of Windows natively uses. For 97*6777b538SAndroid Build Coastguard Worker // example, given an x64-capable processor, we have three possibilities: 98*6777b538SAndroid Build Coastguard Worker // 32-bit Chrome running on 32-bit Windows: X86_ARCHITECTURE 99*6777b538SAndroid Build Coastguard Worker // 32-bit Chrome running on 64-bit Windows via WOW64: X64_ARCHITECTURE 100*6777b538SAndroid Build Coastguard Worker // 64-bit Chrome running on 64-bit Windows: X64_ARCHITECTURE 101*6777b538SAndroid Build Coastguard Worker enum WindowsArchitecture { 102*6777b538SAndroid Build Coastguard Worker X86_ARCHITECTURE, 103*6777b538SAndroid Build Coastguard Worker X64_ARCHITECTURE, 104*6777b538SAndroid Build Coastguard Worker IA64_ARCHITECTURE, 105*6777b538SAndroid Build Coastguard Worker ARM64_ARCHITECTURE, 106*6777b538SAndroid Build Coastguard Worker OTHER_ARCHITECTURE, 107*6777b538SAndroid Build Coastguard Worker }; 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker static OSInfo* GetInstance(); 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker OSInfo(const OSInfo&) = delete; 112*6777b538SAndroid Build Coastguard Worker OSInfo& operator=(const OSInfo&) = delete; 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker // Separate from the rest of OSInfo so they can be used during early process 115*6777b538SAndroid Build Coastguard Worker // initialization. 116*6777b538SAndroid Build Coastguard Worker static WindowsArchitecture GetArchitecture(); 117*6777b538SAndroid Build Coastguard Worker // This is necessary because GetArchitecture doesn't return correct OS 118*6777b538SAndroid Build Coastguard Worker // architectures for x86/x64 binaries running on ARM64 - it says the OS is 119*6777b538SAndroid Build Coastguard Worker // x86/x64. This function returns true if the process is an x86 or x64 process 120*6777b538SAndroid Build Coastguard Worker // running emulated on ARM64. 121*6777b538SAndroid Build Coastguard Worker static bool IsRunningEmulatedOnArm64(); 122*6777b538SAndroid Build Coastguard Worker 123*6777b538SAndroid Build Coastguard Worker // Returns the OS Version as returned from a call to GetVersionEx(). version()124*6777b538SAndroid Build Coastguard Worker const Version& version() const { return version_; } 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker // Returns detailed version info containing major, minor, build and patch. version_number()127*6777b538SAndroid Build Coastguard Worker const VersionNumber& version_number() const { return version_number_; } 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker // The Kernel32* set of functions return the OS version as determined by a 130*6777b538SAndroid Build Coastguard Worker // call to VerQueryValue() on kernel32.dll. This avoids any running App Compat 131*6777b538SAndroid Build Coastguard Worker // shims from manipulating the version reported. 132*6777b538SAndroid Build Coastguard Worker static Version Kernel32Version(); 133*6777b538SAndroid Build Coastguard Worker static VersionNumber Kernel32VersionNumber(); 134*6777b538SAndroid Build Coastguard Worker static base::Version Kernel32BaseVersion(); 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker // These helper functions return information about common scenarios of 137*6777b538SAndroid Build Coastguard Worker // interest in regards to WOW emulation. 138*6777b538SAndroid Build Coastguard Worker bool IsWowDisabled() const; // Chrome bitness matches OS bitness. 139*6777b538SAndroid Build Coastguard Worker bool IsWowX86OnAMD64() const; // Chrome x86 on an AMD64 host machine. 140*6777b538SAndroid Build Coastguard Worker bool IsWowX86OnARM64() const; // Chrome x86 on an ARM64 host machine. 141*6777b538SAndroid Build Coastguard Worker bool IsWowAMD64OnARM64() 142*6777b538SAndroid Build Coastguard Worker const; // Chrome AMD64 build on an ARM64 host machine. 143*6777b538SAndroid Build Coastguard Worker bool IsWowX86OnOther() const; // Chrome x86 on some other x64 host machine. 144*6777b538SAndroid Build Coastguard Worker 145*6777b538SAndroid Build Coastguard Worker // Functions to determine Version Type (e.g. Enterprise/Home) and Service Pack 146*6777b538SAndroid Build Coastguard Worker // value. See above for definitions of these values. version_type()147*6777b538SAndroid Build Coastguard Worker const VersionType& version_type() const { return version_type_; } service_pack()148*6777b538SAndroid Build Coastguard Worker const ServicePack& service_pack() const { return service_pack_; } service_pack_str()149*6777b538SAndroid Build Coastguard Worker const std::string& service_pack_str() const { return service_pack_str_; } 150*6777b538SAndroid Build Coastguard Worker 151*6777b538SAndroid Build Coastguard Worker // Returns the number of processors on the system. processors()152*6777b538SAndroid Build Coastguard Worker const int& processors() const { return processors_; } 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker // Returns the allocation granularity. See 155*6777b538SAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info. allocation_granularity()156*6777b538SAndroid Build Coastguard Worker const size_t& allocation_granularity() const { 157*6777b538SAndroid Build Coastguard Worker return allocation_granularity_; 158*6777b538SAndroid Build Coastguard Worker } 159*6777b538SAndroid Build Coastguard Worker 160*6777b538SAndroid Build Coastguard Worker // Processor name as read from registry. 161*6777b538SAndroid Build Coastguard Worker std::string processor_model_name(); 162*6777b538SAndroid Build Coastguard Worker 163*6777b538SAndroid Build Coastguard Worker // Returns the "ReleaseId" (Windows 10 release number) from the registry. release_id()164*6777b538SAndroid Build Coastguard Worker const std::string& release_id() const { return release_id_; } 165*6777b538SAndroid Build Coastguard Worker 166*6777b538SAndroid Build Coastguard Worker // It returns true if the Windows SKU is N edition. 167*6777b538SAndroid Build Coastguard Worker bool IsWindowsNSku() const; 168*6777b538SAndroid Build Coastguard Worker 169*6777b538SAndroid Build Coastguard Worker private: 170*6777b538SAndroid Build Coastguard Worker friend class base::test::ScopedOSInfoOverride; 171*6777b538SAndroid Build Coastguard Worker FRIEND_TEST_ALL_PREFIXES(OSInfo, MajorMinorBuildToVersion); 172*6777b538SAndroid Build Coastguard Worker 173*6777b538SAndroid Build Coastguard Worker // This enum contains a variety of 32-bit process types that could be 174*6777b538SAndroid Build Coastguard Worker // running with consideration towards WOW64. 175*6777b538SAndroid Build Coastguard Worker enum class WowProcessMachine { 176*6777b538SAndroid Build Coastguard Worker kDisabled, // Chrome bitness matches OS bitness. 177*6777b538SAndroid Build Coastguard Worker kX86, // 32-bit (x86) Chrome. 178*6777b538SAndroid Build Coastguard Worker kARM32, // 32-bit (arm32) Chrome. 179*6777b538SAndroid Build Coastguard Worker kOther, // all other 32-bit Chrome. 180*6777b538SAndroid Build Coastguard Worker kUnknown, 181*6777b538SAndroid Build Coastguard Worker }; 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker // This enum contains a variety of 64-bit host machine architectures that 184*6777b538SAndroid Build Coastguard Worker // could be running with consideration towards WOW64. 185*6777b538SAndroid Build Coastguard Worker enum class WowNativeMachine { 186*6777b538SAndroid Build Coastguard Worker kARM64, // 32-bit Chrome running on ARM64 Windows. 187*6777b538SAndroid Build Coastguard Worker kAMD64, // 32-bit Chrome running on AMD64 Windows. 188*6777b538SAndroid Build Coastguard Worker kOther, // 32-bit Chrome running on all other 64-bit Windows. 189*6777b538SAndroid Build Coastguard Worker kUnknown, 190*6777b538SAndroid Build Coastguard Worker }; 191*6777b538SAndroid Build Coastguard Worker 192*6777b538SAndroid Build Coastguard Worker // This is separate from GetInstance() so that ScopedOSInfoOverride 193*6777b538SAndroid Build Coastguard Worker // can override it in tests. 194*6777b538SAndroid Build Coastguard Worker static OSInfo** GetInstanceStorage(); 195*6777b538SAndroid Build Coastguard Worker 196*6777b538SAndroid Build Coastguard Worker OSInfo(const _OSVERSIONINFOEXW& version_info, 197*6777b538SAndroid Build Coastguard Worker const _SYSTEM_INFO& system_info, 198*6777b538SAndroid Build Coastguard Worker DWORD os_type); 199*6777b538SAndroid Build Coastguard Worker ~OSInfo(); 200*6777b538SAndroid Build Coastguard Worker 201*6777b538SAndroid Build Coastguard Worker // Returns a Version value for a given OS version tuple. 202*6777b538SAndroid Build Coastguard Worker static Version MajorMinorBuildToVersion(uint32_t major, 203*6777b538SAndroid Build Coastguard Worker uint32_t minor, 204*6777b538SAndroid Build Coastguard Worker uint32_t build); 205*6777b538SAndroid Build Coastguard Worker 206*6777b538SAndroid Build Coastguard Worker // Returns the architecture of the process machine within the WOW emulator. 207*6777b538SAndroid Build Coastguard Worker WowProcessMachine GetWowProcessMachineArchitecture(const int process_machine); 208*6777b538SAndroid Build Coastguard Worker 209*6777b538SAndroid Build Coastguard Worker // Returns the architecture of the native (host) machine using the WOW 210*6777b538SAndroid Build Coastguard Worker // emulator. 211*6777b538SAndroid Build Coastguard Worker WowNativeMachine GetWowNativeMachineArchitecture(const int native_machine); 212*6777b538SAndroid Build Coastguard Worker 213*6777b538SAndroid Build Coastguard Worker void InitializeWowStatusValuesFromLegacyApi(HANDLE process_handle); 214*6777b538SAndroid Build Coastguard Worker 215*6777b538SAndroid Build Coastguard Worker void InitializeWowStatusValuesForProcess(HANDLE process_handle); 216*6777b538SAndroid Build Coastguard Worker 217*6777b538SAndroid Build Coastguard Worker Version version_; 218*6777b538SAndroid Build Coastguard Worker VersionNumber version_number_; 219*6777b538SAndroid Build Coastguard Worker VersionType version_type_; 220*6777b538SAndroid Build Coastguard Worker ServicePack service_pack_; 221*6777b538SAndroid Build Coastguard Worker 222*6777b538SAndroid Build Coastguard Worker // Represents the version of the OS associated to a release of 223*6777b538SAndroid Build Coastguard Worker // Windows 10. Each version may have different releases (such as patch 224*6777b538SAndroid Build Coastguard Worker // updates). This is the identifier of the release. 225*6777b538SAndroid Build Coastguard Worker // Example: 226*6777b538SAndroid Build Coastguard Worker // Windows 10 Version 1809 (OS build 17763) has multiple releases 227*6777b538SAndroid Build Coastguard Worker // (i.e. build 17763.1, build 17763.195, build 17763.379, ...). 228*6777b538SAndroid Build Coastguard Worker // See https://docs.microsoft.com/en-us/windows/windows-10/release-information 229*6777b538SAndroid Build Coastguard Worker // for more information. 230*6777b538SAndroid Build Coastguard Worker std::string release_id_; 231*6777b538SAndroid Build Coastguard Worker 232*6777b538SAndroid Build Coastguard Worker // A string, such as "Service Pack 3", that indicates the latest Service Pack 233*6777b538SAndroid Build Coastguard Worker // installed on the system. If no Service Pack has been installed, the string 234*6777b538SAndroid Build Coastguard Worker // is empty. 235*6777b538SAndroid Build Coastguard Worker std::string service_pack_str_; 236*6777b538SAndroid Build Coastguard Worker int processors_; 237*6777b538SAndroid Build Coastguard Worker size_t allocation_granularity_; 238*6777b538SAndroid Build Coastguard Worker WowProcessMachine wow_process_machine_; 239*6777b538SAndroid Build Coastguard Worker WowNativeMachine wow_native_machine_; 240*6777b538SAndroid Build Coastguard Worker std::string processor_model_name_; 241*6777b538SAndroid Build Coastguard Worker DWORD os_type_; 242*6777b538SAndroid Build Coastguard Worker }; 243*6777b538SAndroid Build Coastguard Worker 244*6777b538SAndroid Build Coastguard Worker // Because this is by far the most commonly-requested value from the above 245*6777b538SAndroid Build Coastguard Worker // singleton, we add a global-scope accessor here as syntactic sugar. 246*6777b538SAndroid Build Coastguard Worker BASE_EXPORT Version GetVersion(); 247*6777b538SAndroid Build Coastguard Worker 248*6777b538SAndroid Build Coastguard Worker } // namespace win 249*6777b538SAndroid Build Coastguard Worker } // namespace base 250*6777b538SAndroid Build Coastguard Worker 251*6777b538SAndroid Build Coastguard Worker #endif // BASE_WIN_WINDOWS_VERSION_H_ 252