1 //
2 // Copyright 2023 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // platform_helpers.cpp: implementations for platform identification functions
8 // which require runtime detections.
9
10 #include "common/platform_helpers.h"
11 #include "common/debug.h"
12
13 #include <tuple>
14
15 #ifdef ANGLE_PLATFORM_WINDOWS
16 # include <windows.h>
17 #endif
18
19 namespace angle
20 {
21
22 namespace
23 {
24
25 // Windows version constants, for range check functions
26 constexpr VersionTriple kVersionWindowsXP = VersionTriple(5, 1, 0);
27 constexpr VersionTriple kVersionWindowsVista = VersionTriple(6, 0, 0);
28 constexpr VersionTriple kVersionWindows7 = VersionTriple(6, 1, 0);
29 constexpr VersionTriple kVersionWindows8 = VersionTriple(6, 2, 0);
30 constexpr VersionTriple kVersionWindows10 = VersionTriple(10, 0, 0);
31 constexpr VersionTriple kVersionWindows11 = VersionTriple(10, 0, 22000);
32
IsWindowsVersionOrLater(VersionTriple greaterOrEqual)33 bool IsWindowsVersionOrLater(VersionTriple greaterOrEqual)
34 {
35 #if defined(ANGLE_PLATFORM_WINDOWS)
36 # if defined(ANGLE_ENABLE_WINDOWS_UWP)
37 // Windows UWP does not provide access to the VerifyVersionInfo API, nor
38 // the versionhelpers.h functions. To work around this, always treat UWP
39 // applications as running on Windows 10 (which is when UWP was
40 // introduced).
41 return greaterOrEqual >= kVersionWindows10;
42 # else
43 OSVERSIONINFOEXW osvi;
44 DWORDLONG dwlConditionMask = 0;
45
46 dwlConditionMask = VerSetConditionMask(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
47 dwlConditionMask = VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
48 dwlConditionMask = VerSetConditionMask(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
49
50 osvi = {};
51 osvi.dwOSVersionInfoSize = sizeof(osvi);
52 osvi.dwMajorVersion = greaterOrEqual.majorVersion;
53 osvi.dwMinorVersion = greaterOrEqual.minorVersion;
54 osvi.dwBuildNumber = greaterOrEqual.patchVersion;
55
56 return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER,
57 dwlConditionMask) != FALSE;
58 # endif // ANGLE_ENABLE_WINDOWS_UWP
59 #else
60 return false;
61 #endif // ANGLE_PLATFORM_WINDOWS
62 }
63
IsWindowsVersionInRange(VersionTriple greaterOrEqual,VersionTriple lessThan)64 bool IsWindowsVersionInRange(VersionTriple greaterOrEqual, VersionTriple lessThan)
65 {
66 // This function is checking (greaterOrEqual <= WindowsVersion < lessThan),
67 // for when you need to match a specific Windows release.
68 ASSERT(greaterOrEqual < lessThan);
69 return IsWindowsVersionOrLater(greaterOrEqual) && !IsWindowsVersionOrLater(lessThan);
70 }
71
72 } // namespace
73
operator ==(const VersionTriple & a,const VersionTriple & b)74 bool operator==(const VersionTriple &a, const VersionTriple &b)
75 {
76 return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) ==
77 std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
78 }
operator !=(const VersionTriple & a,const VersionTriple & b)79 bool operator!=(const VersionTriple &a, const VersionTriple &b)
80 {
81 return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) !=
82 std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
83 }
operator <(const VersionTriple & a,const VersionTriple & b)84 bool operator<(const VersionTriple &a, const VersionTriple &b)
85 {
86 return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) <
87 std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
88 }
operator >=(const VersionTriple & a,const VersionTriple & b)89 bool operator>=(const VersionTriple &a, const VersionTriple &b)
90 {
91 return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) >=
92 std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
93 }
94
95 //
96 // Exact Windows version checks
97 //
98
IsWindowsXP()99 bool IsWindowsXP()
100 {
101 return IsWindowsVersionInRange(kVersionWindowsXP, kVersionWindowsVista);
102 }
103
IsWindowsVista()104 bool IsWindowsVista()
105 {
106 return IsWindowsVersionInRange(kVersionWindowsVista, kVersionWindows7);
107 }
108
IsWindows7()109 bool IsWindows7()
110 {
111 return IsWindowsVersionInRange(kVersionWindows7, kVersionWindows8);
112 }
113
IsWindows8()114 bool IsWindows8()
115 {
116 return IsWindowsVersionInRange(kVersionWindows8, kVersionWindows10);
117 }
118
IsWindows10()119 bool IsWindows10()
120 {
121 return IsWindowsVersionInRange(kVersionWindows10, kVersionWindows11);
122 }
123
IsWindows11()124 bool IsWindows11()
125 {
126 // There's no post-Windows 11 release yet, so this is functionally a
127 // "Windows 11 or later" check right now.
128 return IsWindowsVersionOrLater(kVersionWindows11);
129 }
130
131 //
132 // Windows version or later helpers
133 //
134
IsWindowsXPOrLater()135 bool IsWindowsXPOrLater()
136 {
137 return IsWindowsVersionOrLater(kVersionWindowsXP);
138 }
139
IsWindowsVistaOrLater()140 bool IsWindowsVistaOrLater()
141 {
142 return IsWindowsVersionOrLater(kVersionWindowsVista);
143 }
144
IsWindows7OrLater()145 bool IsWindows7OrLater()
146 {
147 return IsWindowsVersionOrLater(kVersionWindows7);
148 }
149
IsWindows8OrLater()150 bool IsWindows8OrLater()
151 {
152 return IsWindowsVersionOrLater(kVersionWindows8);
153 }
154
IsWindows10OrLater()155 bool IsWindows10OrLater()
156 {
157 return IsWindowsVersionOrLater(kVersionWindows10);
158 }
159
IsWindows11OrLater()160 bool IsWindows11OrLater()
161 {
162 return IsWindowsVersionOrLater(kVersionWindows11);
163 }
164
165 } // namespace angle
166