1 | #include "blocklist_driver.h" |
2 | |
3 | #include <base/system.h> |
4 | |
5 | #include <cstddef> |
6 | |
7 | #define VERSION_PARTS 4 |
8 | |
9 | struct SVersion |
10 | { |
11 | int m_aParts[VERSION_PARTS]; |
12 | |
13 | bool operator<=(const SVersion &Other) const |
14 | { |
15 | for(int i = 0; i < VERSION_PARTS; i++) |
16 | { |
17 | if(m_aParts[i] < Other.m_aParts[i]) |
18 | return true; |
19 | if(m_aParts[i] > Other.m_aParts[i]) |
20 | return false; |
21 | } |
22 | return true; |
23 | } |
24 | }; |
25 | |
26 | enum EBackendDriverBlockListType |
27 | { |
28 | BACKEND_DRIVER_BLOCKLIST_TYPE_VERSION = 0, |
29 | BACKEND_DRIVER_BLOCKLIST_TYPE_VENDOR, |
30 | }; |
31 | |
32 | /* TODO: generalize it more for other drivers / vendors */ |
33 | struct SBackEndDriverBlockList |
34 | { |
35 | EBackendDriverBlockListType m_BlockListType; |
36 | |
37 | SVersion m_VersionMin; |
38 | SVersion m_VersionMax; |
39 | |
40 | const char *m_pVendorName; |
41 | |
42 | // the OpenGL version, that is supported |
43 | int m_AllowedMajor; |
44 | int m_AllowedMinor; |
45 | int m_AllowedPatch; |
46 | |
47 | const char *m_pReason; |
48 | |
49 | bool m_DisplayReason; |
50 | const char *m_pOSName; |
51 | }; |
52 | |
53 | static SBackEndDriverBlockList gs_aBlockList[] = { |
54 | {.m_BlockListType: BACKEND_DRIVER_BLOCKLIST_TYPE_VENDOR, .m_VersionMin: {26, 20, 100, 7800}, .m_VersionMax: {27, 20, 100, 8853}, .m_pVendorName: "Intel" , .m_AllowedMajor: 2, .m_AllowedMinor: 0, .m_AllowedPatch: 0, .m_pReason: "This Intel driver version can cause crashes, please update it to a newer version." , .m_DisplayReason: false, .m_pOSName: "windows" }}; |
55 | |
56 | const char *ParseBlocklistDriverVersions(const char *pVendorStr, const char *pVersionStr, int &BlocklistMajor, int &BlocklistMinor, int &BlocklistPatch, bool &RequiresWarning) |
57 | { |
58 | if(str_find_nocase(haystack: pVendorStr, needle: "Intel" ) == NULL) |
59 | return NULL; |
60 | |
61 | const char *pVersionStrStart = str_find_nocase(haystack: pVersionStr, needle: "Build " ); |
62 | if(pVersionStrStart == NULL) |
63 | return NULL; |
64 | |
65 | // ignore "Build ", after that, it should directly start with the driver version |
66 | pVersionStrStart += (ptrdiff_t)str_length(str: "Build " ); |
67 | |
68 | char aVersionStrHelper[512]; // the size is random, but shouldn't be too small probably |
69 | |
70 | SVersion Version; |
71 | for(int &VersionPart : Version.m_aParts) |
72 | { |
73 | pVersionStrStart = str_next_token(str: pVersionStrStart, delim: "." , buffer: aVersionStrHelper, buffer_size: sizeof(aVersionStrHelper)); |
74 | if(pVersionStrStart == NULL) |
75 | return NULL; |
76 | |
77 | VersionPart = str_toint(str: aVersionStrHelper); |
78 | } |
79 | |
80 | for(const auto &BlockListItem : gs_aBlockList) |
81 | { |
82 | if(str_comp(a: BlockListItem.m_pOSName, CONF_FAMILY_STRING) == 0) |
83 | { |
84 | bool DriverBlocked = false; |
85 | if(BlockListItem.m_BlockListType == BACKEND_DRIVER_BLOCKLIST_TYPE_VENDOR) |
86 | { |
87 | if(str_find_nocase(haystack: pVendorStr, needle: BlockListItem.m_pVendorName) != NULL) |
88 | { |
89 | DriverBlocked = true; |
90 | } |
91 | } |
92 | else if(BlockListItem.m_BlockListType == BACKEND_DRIVER_BLOCKLIST_TYPE_VERSION) |
93 | { |
94 | if(BlockListItem.m_VersionMin <= Version && Version <= BlockListItem.m_VersionMax) |
95 | { |
96 | DriverBlocked = true; |
97 | } |
98 | } |
99 | |
100 | if(DriverBlocked) |
101 | { |
102 | RequiresWarning = BlockListItem.m_DisplayReason; |
103 | BlocklistMajor = BlockListItem.m_AllowedMajor; |
104 | BlocklistMinor = BlockListItem.m_AllowedMinor; |
105 | BlocklistPatch = BlockListItem.m_AllowedPatch; |
106 | return BlockListItem.m_pReason; |
107 | } |
108 | } |
109 | } |
110 | |
111 | return NULL; |
112 | } |
113 | |