/* -*- 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/.
*/
// This allows us to pad driver version 'substrings' with 0s, this // effectively allows us to treat the version numbers as 'decimals'. This is // a little strange but this method seems to do the right thing for all // different vendor's driver strings. i.e. .98 will become 9800, which is // larger than .978 which would become 9780. staticvoid PadDriverDecimal(char* aString)
{ for (int i = 0; i < 4; i++)
{ if (!aString[i])
{ for (int c = i; c < 4; c++)
{
aString[c] = '0';
} break;
}
}
aString[4] = 0;
}
// All destination string storage needs to have at least 5 bytes available. staticbool SplitDriverVersion(constchar* aSource, char* aAStr, char* aBStr, char* aCStr, char* aDStr, VersionType versionType)
{ // sscanf doesn't do what we want here to we parse this manually. int len = strlen(aSource); char* dest[4] = { aAStr, aBStr, aCStr, aDStr }; unsigned destIdx = 0; unsigned destPos = 0;
for (int i = 0; i < len; i++)
{ if (destIdx >= SAL_N_ELEMENTS(dest))
{ // Invalid format found. Ensure we don't access dest beyond bounds. returnfalse;
}
int a, b, c, d; char aStr[8], bStr[8], cStr[8], dStr[8]; /* honestly, why do I even bother */
OString aOVersion = OUStringToOString(aVersion, RTL_TEXTENCODING_UTF8); if (!SplitDriverVersion(aOVersion.getStr(), aStr, bStr, cStr, dStr, versionType)) returnfalse;
if (versionType == VersionType::OpenGL)
{
PadDriverDecimal(bStr);
PadDriverDecimal(cStr);
PadDriverDecimal(dStr);
}
a = atoi(aStr);
b = atoi(bStr);
c = atoi(cStr);
d = atoi(dStr);
if (versionType == VersionType::Vulkan)
assert(d == 0);
if (a < 0 || a > 0xffff) returnfalse; if (b < 0 || b > 0xffff) returnfalse; if (c < 0 || c > 0xffff) returnfalse; if (d < 0 || d > 0xffff) returnfalse;
static OperatingSystem getOperatingSystem()
{ #ifdef _WIN32 // OS version in 16.16 major/minor form // based on http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx switch (DriverBlocklist::GetWindowsVersion())
{ case 0x000A0000: // Major 10 Minor 0 return DRIVER_OS_WINDOWS_10; default: return DRIVER_OS_UNKNOWN;
} #elifdefined LINUX return DRIVER_OS_LINUX; #else return DRIVER_OS_UNKNOWN; #endif
}
switch (rDeviceInfo.meComparisonOp)
{ case DRIVER_LESS_THAN:
match = driverVersion < rDeviceInfo.mnDriverVersion; break; case DRIVER_LESS_THAN_OR_EQUAL:
match = driverVersion <= rDeviceInfo.mnDriverVersion; break; case DRIVER_GREATER_THAN:
match = driverVersion > rDeviceInfo.mnDriverVersion; break; case DRIVER_GREATER_THAN_OR_EQUAL:
match = driverVersion >= rDeviceInfo.mnDriverVersion; break; case DRIVER_EQUAL:
match = driverVersion == rDeviceInfo.mnDriverVersion; break; case DRIVER_NOT_EQUAL:
match = driverVersion != rDeviceInfo.mnDriverVersion; break; case DRIVER_BETWEEN_EXCLUSIVE:
match = driverVersion > rDeviceInfo.mnDriverVersion
&& driverVersion < rDeviceInfo.mnDriverVersionMax; break; case DRIVER_BETWEEN_INCLUSIVE:
match = driverVersion >= rDeviceInfo.mnDriverVersion
&& driverVersion <= rDeviceInfo.mnDriverVersionMax; break; case DRIVER_BETWEEN_INCLUSIVE_START:
match = driverVersion >= rDeviceInfo.mnDriverVersion
&& driverVersion < rDeviceInfo.mnDriverVersionMax; break; case DRIVER_COMPARISON_IGNORED: // We don't have a comparison op, so we match everything.
match = true; break; default:
SAL_WARN("vcl.driver", "Bogus op in " << blocklistURL); break;
}
if (match || rDeviceInfo.mnDriverVersion == allDriverVersions)
{ // white listed drivers if (rDeviceInfo.mbAllowlisted)
{
SAL_INFO("vcl.driver", "allowlisted driver"); returnfalse;
}
match = true; if (!rDeviceInfo.maSuggestedVersion.isEmpty())
{
SAL_WARN("vcl.driver", "use : " << rDeviceInfo.maSuggestedVersion);
} break;
}
}
#ifdef _WIN32
int32_t GetWindowsVersion()
{ static int32_t winVersion = []() { // GetVersion(Ex) and VersionHelpers (based on VerifyVersionInfo) API are // subject to manifest-based behavior since Windows 8.1, so give wrong results. // Another approach would be to use NetWkstaGetInfo, but that has some small // reported delays (some milliseconds), and might get slower in domains with // poor network connections. // So go with a solution described at https://msdn.microsoft.com/en-us/library/ms724429
HINSTANCE hLibrary = LoadLibraryW(L"kernel32.dll"); if (hLibrary != nullptr)
{ wchar_t szPath[MAX_PATH];
DWORD dwCount = GetModuleFileNameW(hLibrary, szPath, SAL_N_ELEMENTS(szPath));
FreeLibrary(hLibrary); if (dwCount != 0 && dwCount < SAL_N_ELEMENTS(szPath))
{
dwCount = GetFileVersionInfoSizeW(szPath, nullptr); if (dwCount != 0)
{
std::unique_ptr<char[]> ver(newchar[dwCount]); if (GetFileVersionInfoW(szPath, 0, dwCount, ver.get()) != FALSE)
{ void* pBlock = nullptr;
UINT dwBlockSz = 0; if (VerQueryValueW(ver.get(), L"\\", &pBlock, &dwBlockSz) != FALSE
&& dwBlockSz >= sizeof(VS_FIXEDFILEINFO))
{
VS_FIXEDFILEINFO* vinfo = static_cast<VS_FIXEDFILEINFO*>(pBlock); return int32_t(vinfo->dwProductVersionMS);
}
}
}
}
} return 0;
}();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.