/work/obj-fuzz/dist/include/GfxDriverInfo.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #ifndef __mozilla_widget_GfxDriverInfo_h__ |
7 | | #define __mozilla_widget_GfxDriverInfo_h__ |
8 | | |
9 | | #include "nsString.h" |
10 | | |
11 | | // Macros for adding a blocklist item to the static list. |
12 | | #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion) \ |
13 | | sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion)) |
14 | | #define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId) \ |
15 | | sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId)) |
16 | | |
17 | | #define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, suggestedVersion) \ |
18 | | do { \ |
19 | | MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \ |
20 | | driverComparator == DRIVER_BETWEEN_INCLUSIVE || \ |
21 | | driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \ |
22 | | GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion); \ |
23 | | info.mDriverVersionMax = driverVersionMax; \ |
24 | | sDriverInfo->AppendElement(info); \ |
25 | | } while (false) |
26 | | |
27 | | #define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, suggestedVersion) \ |
28 | | do { \ |
29 | | MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \ |
30 | | driverComparator == DRIVER_BETWEEN_INCLUSIVE || \ |
31 | | driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \ |
32 | | GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion, false, true); \ |
33 | | info.mDriverVersionMax = driverVersionMax; \ |
34 | | sDriverInfo->AppendElement(info); \ |
35 | | } while (false) |
36 | | |
37 | | |
38 | | namespace mozilla { |
39 | | namespace widget { |
40 | | |
41 | | enum class OperatingSystem { |
42 | | Unknown, |
43 | | Windows, |
44 | | WindowsXP, |
45 | | WindowsServer2003, |
46 | | WindowsVista, |
47 | | Windows7, |
48 | | Windows8, |
49 | | Windows8_1, |
50 | | Windows10, |
51 | | Linux, |
52 | | OSX, |
53 | | OSX10_5, |
54 | | OSX10_6, |
55 | | OSX10_7, |
56 | | OSX10_8, |
57 | | OSX10_9, |
58 | | OSX10_10, |
59 | | OSX10_11, |
60 | | OSX10_12, |
61 | | OSX10_13, |
62 | | Android, |
63 | | Ios |
64 | | }; |
65 | | |
66 | | enum VersionComparisonOp { |
67 | | DRIVER_LESS_THAN, // driver < version |
68 | | DRIVER_BUILD_ID_LESS_THAN, // driver build id < version |
69 | | DRIVER_LESS_THAN_OR_EQUAL, // driver <= version |
70 | | DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version |
71 | | DRIVER_GREATER_THAN, // driver > version |
72 | | DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version |
73 | | DRIVER_EQUAL, // driver == version |
74 | | DRIVER_NOT_EQUAL, // driver != version |
75 | | DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax |
76 | | DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax |
77 | | DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax |
78 | | DRIVER_COMPARISON_IGNORED |
79 | | }; |
80 | | |
81 | | enum DeviceFamily { |
82 | | IntelGMA500, |
83 | | IntelGMA900, |
84 | | IntelGMA950, |
85 | | IntelGMA3150, |
86 | | IntelGMAX3000, |
87 | | IntelGMAX4500HD, |
88 | | IntelHDGraphicsToSandyBridge, |
89 | | IntelHDGraphicsToHaswell, |
90 | | IntelHD3000, |
91 | | IntelMobileHDGraphics, |
92 | | NvidiaBlockD3D9Layers, |
93 | | RadeonX1000, |
94 | | Geforce7300GT, |
95 | | Nvidia310M, |
96 | | Nvidia8800GTS, |
97 | | Bug1137716, |
98 | | Bug1116812, |
99 | | Bug1155608, |
100 | | Bug1207665, |
101 | | Bug1447141, |
102 | | DeviceFamilyMax |
103 | | }; |
104 | | |
105 | | enum DeviceVendor { |
106 | | VendorAll, // There is an assumption that this is the first enum |
107 | | VendorIntel, |
108 | | VendorNVIDIA, |
109 | | VendorAMD, |
110 | | VendorATI, |
111 | | VendorMicrosoft, |
112 | | VendorParallels, |
113 | | VendorQualcomm, |
114 | | DeviceVendorMax |
115 | | }; |
116 | | |
117 | | /* Array of devices to match, or an empty array for all devices */ |
118 | | typedef nsTArray<nsString> GfxDeviceFamily; |
119 | | |
120 | | struct GfxDriverInfo |
121 | | { |
122 | | // If |ownDevices| is true, you are transferring ownership of the devices |
123 | | // array, and it will be deleted when this GfxDriverInfo is destroyed. |
124 | | GfxDriverInfo(OperatingSystem os, nsAString& vendor, GfxDeviceFamily* devices, |
125 | | int32_t feature, int32_t featureStatus, VersionComparisonOp op, |
126 | | uint64_t driverVersion, const char *ruleId, |
127 | | const char *suggestedVersion = nullptr, |
128 | | bool ownDevices = false, bool gpu2 = false); |
129 | | |
130 | | GfxDriverInfo(); |
131 | | GfxDriverInfo(const GfxDriverInfo&); |
132 | | ~GfxDriverInfo(); |
133 | | |
134 | | OperatingSystem mOperatingSystem; |
135 | | uint32_t mOperatingSystemVersion; |
136 | | |
137 | | nsString mAdapterVendor; |
138 | | |
139 | | static GfxDeviceFamily* const allDevices; |
140 | | GfxDeviceFamily* mDevices; |
141 | | |
142 | | // Whether the mDevices array should be deleted when this structure is |
143 | | // deallocated. False by default. |
144 | | bool mDeleteDevices; |
145 | | |
146 | | /* A feature from nsIGfxInfo, or all features */ |
147 | | int32_t mFeature; |
148 | | static int32_t allFeatures; |
149 | | |
150 | | /* A feature status from nsIGfxInfo */ |
151 | | int32_t mFeatureStatus; |
152 | | |
153 | | VersionComparisonOp mComparisonOp; |
154 | | |
155 | | /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */ |
156 | | uint64_t mDriverVersion; |
157 | | uint64_t mDriverVersionMax; |
158 | | static uint64_t allDriverVersions; |
159 | | |
160 | | const char *mSuggestedVersion; |
161 | | nsCString mRuleId; |
162 | | |
163 | | static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id); |
164 | | static GfxDeviceFamily* sDeviceFamilies[DeviceFamilyMax]; |
165 | | |
166 | | static const nsAString& GetDeviceVendor(DeviceVendor id); |
167 | | static nsAString* sDeviceVendors[DeviceVendorMax]; |
168 | | |
169 | | nsString mModel, mHardware, mProduct, mManufacturer; |
170 | | |
171 | | bool mGpu2; |
172 | | }; |
173 | | |
174 | | #define GFX_DRIVER_VERSION(a,b,c,d) \ |
175 | | ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d)) |
176 | | |
177 | | inline uint64_t |
178 | | V(uint32_t a, uint32_t b, uint32_t c, uint32_t d) |
179 | | { |
180 | | // We make sure every driver number is padded by 0s, this will allow us the |
181 | | // easiest 'compare as if decimals' approach. See ParseDriverVersion for a |
182 | | // more extensive explanation of this approach. |
183 | | while (b > 0 && b < 1000) { |
184 | | b *= 10; |
185 | | } |
186 | | while (c > 0 && c < 1000) { |
187 | | c *= 10; |
188 | | } |
189 | | while (d > 0 && d < 1000) { |
190 | | d *= 10; |
191 | | } |
192 | | return GFX_DRIVER_VERSION(a, b, c, d); |
193 | | } |
194 | | |
195 | | // All destination string storage needs to have at least 5 bytes available. |
196 | | inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr) |
197 | 0 | { |
198 | 0 | // sscanf doesn't do what we want here to we parse this manually. |
199 | 0 | int len = strlen(aSource); |
200 | 0 |
|
201 | 0 | // This "4" is hardcoded in a few places, including once as a 3. |
202 | 0 | char *dest[4] = { aAStr, aBStr, aCStr, aDStr }; |
203 | 0 | unsigned destIdx = 0; |
204 | 0 | unsigned destPos = 0; |
205 | 0 |
|
206 | 0 | for (int i = 0; i < len; i++) { |
207 | 0 | if (destIdx >= 4) { |
208 | 0 | // Invalid format found. Ensure we don't access dest beyond bounds. |
209 | 0 | return false; |
210 | 0 | } |
211 | 0 | |
212 | 0 | if (aSource[i] == '.') { |
213 | 0 | MOZ_ASSERT (destIdx < 4 && destPos <= 4); |
214 | 0 | dest[destIdx++][destPos] = 0; |
215 | 0 | destPos = 0; |
216 | 0 | continue; |
217 | 0 | } |
218 | 0 |
|
219 | 0 | if (destPos > 3) { |
220 | 0 | // Ignore more than 4 chars. Ensure we never access dest[destIdx] |
221 | 0 | // beyond its bounds. |
222 | 0 | continue; |
223 | 0 | } |
224 | 0 | |
225 | 0 | MOZ_ASSERT (destIdx < 4 && destPos < 4); |
226 | 0 | dest[destIdx][destPos++] = aSource[i]; |
227 | 0 | } |
228 | 0 |
|
229 | 0 | // Take care of the trailing period |
230 | 0 | if (destIdx >= 4) { |
231 | 0 | return false; |
232 | 0 | } |
233 | 0 | |
234 | 0 | // Add last terminator. |
235 | 0 | MOZ_ASSERT (destIdx < 4 && destPos <= 4); |
236 | 0 | dest[destIdx][destPos] = 0; |
237 | 0 |
|
238 | 0 | if (destIdx != 3) { |
239 | 0 | return false; |
240 | 0 | } |
241 | 0 | return true; |
242 | 0 | } |
243 | | |
244 | | // This allows us to pad driver version 'substrings' with 0s, this |
245 | | // effectively allows us to treat the version numbers as 'decimals'. This is |
246 | | // a little strange but this method seems to do the right thing for all |
247 | | // different vendor's driver strings. i.e. .98 will become 9800, which is |
248 | | // larger than .978 which would become 9780. |
249 | | inline void PadDriverDecimal(char *aString) |
250 | | { |
251 | | for (int i = 0; i < 4; i++) { |
252 | | if (!aString[i]) { |
253 | | for (int c = i; c < 4; c++) { |
254 | | aString[c] = '0'; |
255 | | } |
256 | | break; |
257 | | } |
258 | | } |
259 | | aString[4] = 0; |
260 | | } |
261 | | |
262 | | inline bool |
263 | | ParseDriverVersion(const nsAString& aVersion, uint64_t *aNumericVersion) |
264 | | { |
265 | | *aNumericVersion = 0; |
266 | | |
267 | | #if defined(XP_WIN) |
268 | | int a, b, c, d; |
269 | | char aStr[8], bStr[8], cStr[8], dStr[8]; |
270 | | /* honestly, why do I even bother */ |
271 | | if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr, bStr, cStr, dStr)) |
272 | | return false; |
273 | | |
274 | | PadDriverDecimal(bStr); |
275 | | PadDriverDecimal(cStr); |
276 | | PadDriverDecimal(dStr); |
277 | | |
278 | | a = atoi(aStr); |
279 | | b = atoi(bStr); |
280 | | c = atoi(cStr); |
281 | | d = atoi(dStr); |
282 | | |
283 | | if (a < 0 || a > 0xffff) return false; |
284 | | if (b < 0 || b > 0xffff) return false; |
285 | | if (c < 0 || c > 0xffff) return false; |
286 | | if (d < 0 || d > 0xffff) return false; |
287 | | |
288 | | *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d); |
289 | | MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions); |
290 | | return true; |
291 | | #elif defined(ANDROID) |
292 | | // Can't use aVersion.ToInteger() because that's not compiled into our code |
293 | | // unless we have XPCOM_GLUE_AVOID_NSPR disabled. |
294 | | *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get()); |
295 | | MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions); |
296 | | return true; |
297 | | #else |
298 | | return false; |
299 | | #endif |
300 | | } |
301 | | |
302 | | } // namespace widget |
303 | | } // namespace mozilla |
304 | | |
305 | | #endif /*__mozilla_widget_GfxDriverInfo_h__ */ |