/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef INCLUDED_VCL_DRIVERBLOCKLIST_HXX #define INCLUDED_VCL_DRIVERBLOCKLIST_HXX #include #include #include #include namespace DriverBlocklist { // Details of how to treat a version number. enum class VersionType { OpenGL, // a.b.c.d, 1.98 > 1.978 Vulkan // a.b.c , 1.98 < 1.978 }; VCL_DLLPUBLIC bool IsDeviceBlocked(const OUString& blocklistURL, VersionType versionType, std::u16string_view driverVersion, std::u16string_view vendorId, const OUString& deviceId); #ifdef _WIN32 VCL_DLLPUBLIC int32_t GetWindowsVersion(); #endif enum DeviceVendor { VendorAll, VendorIntel, VendorNVIDIA, VendorAMD, VendorMicrosoft, }; const int DeviceVendorMax = VendorMicrosoft + 1; /// Returns vendor for the given vendor ID, or VendorAll if not known. VCL_DLLPUBLIC DeviceVendor GetVendorFromId(uint32_t id); VCL_DLLPUBLIC std::string_view GetVendorNameFromId(uint32_t id); // The rest should be private (only for the unittest). struct InvalidFileException { }; enum OperatingSystem { DRIVER_OS_UNKNOWN = 0, DRIVER_OS_WINDOWS_FIRST, DRIVER_OS_WINDOWS_7 = DRIVER_OS_WINDOWS_FIRST, DRIVER_OS_WINDOWS_8, DRIVER_OS_WINDOWS_8_1, DRIVER_OS_WINDOWS_10, DRIVER_OS_WINDOWS_LAST = DRIVER_OS_WINDOWS_10, DRIVER_OS_WINDOWS_ALL, DRIVER_OS_LINUX, DRIVER_OS_OSX_FIRST, DRIVER_OS_OSX_10_5 = DRIVER_OS_OSX_FIRST, DRIVER_OS_OSX_10_6, DRIVER_OS_OSX_10_7, DRIVER_OS_OSX_10_8, DRIVER_OS_OSX_LAST = DRIVER_OS_OSX_10_8, DRIVER_OS_OSX_ALL, DRIVER_OS_ANDROID, DRIVER_OS_ALL }; enum VersionComparisonOp { DRIVER_LESS_THAN, // driver < version DRIVER_LESS_THAN_OR_EQUAL, // driver <= version DRIVER_GREATER_THAN, // driver > version DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version DRIVER_EQUAL, // driver == version DRIVER_NOT_EQUAL, // driver != version DRIVER_BETWEEN_EXCLUSIVE, // driver > version && driver < versionMax DRIVER_BETWEEN_INCLUSIVE, // driver >= version && driver <= versionMax DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax DRIVER_COMPARISON_IGNORED }; struct DriverInfo { DriverInfo(OperatingSystem os, const OUString& vendor, VersionComparisonOp op, uint64_t driverVersion, bool bAllowListed = false, const char* suggestedVersion = nullptr); DriverInfo(); OperatingSystem meOperatingSystem; OUString maAdapterVendor; std::vector maDevices; bool mbAllowlisted; VersionComparisonOp meComparisonOp; /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */ uint64_t mnDriverVersion; uint64_t mnDriverVersionMax; OUString maSuggestedVersion; OUString maMsg; }; class VCL_DLLPUBLIC Parser { public: Parser(const OUString& rURL, std::vector& rDriverList, VersionType versionType); bool parse(); private: void handleEntry(DriverInfo& rDriver, xmlreader::XmlReader& rReader); void handleList(xmlreader::XmlReader& rReader); void handleContent(xmlreader::XmlReader& rReader); static void handleDevices(DriverInfo& rDriver, xmlreader::XmlReader& rReader); uint64_t getVersion(std::string_view rString); enum class BlockType { ALLOWLIST, DENYLIST, UNKNOWN }; BlockType meBlockType; std::vector& mrDriverList; OUString maURL; const VersionType mVersionType; }; OUString VCL_DLLPUBLIC GetVendorId(DeviceVendor id); bool VCL_DLLPUBLIC FindBlocklistedDeviceInList(std::vector& aDeviceInfos, VersionType versionType, std::u16string_view sDriverVersion, std::u16string_view sAdapterVendorID, OUString const& sAdapterDeviceID, OperatingSystem system, const OUString& blocklistURL = OUString()); #define GFX_DRIVER_VERSION(a, b, c, d) \ ((uint64_t(a) << 48) | (uint64_t(b) << 32) | (uint64_t(c) << 16) | uint64_t(d)) inline uint64_t OpenGLVersion(uint32_t a, uint32_t b, uint32_t c, uint32_t d) { // We make sure every driver number is padded by 0s, this will allow us the // easiest 'compare as if decimals' approach. See ParseDriverVersion for a // more extensive explanation of this approach. while (b > 0 && b < 1000) { b *= 10; } while (c > 0 && c < 1000) { c *= 10; } while (d > 0 && d < 1000) { d *= 10; } return GFX_DRIVER_VERSION(a, b, c, d); } } // namespace #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */