/* -*- 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/.
*/
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyLocation, 0, KEY_QUERY_VALUE, &key); if (result != ERROR_SUCCESS)
{ returnfalse;
}
switch (type)
{ case REG_DWORD:
{ // We only use this for vram size
dwcbData = sizeof(dValue);
result = RegQueryValueExW(key, keyName, nullptr, &resultType, reinterpret_cast<LPBYTE>(&dValue), &dwcbData); if (result == ERROR_SUCCESS && resultType == REG_DWORD)
{
dValue = dValue / 1024 / 1024;
destString += OUString::number(int32_t(dValue));
} else
{
retval = false;
} break;
} case REG_MULTI_SZ:
{ // A chain of null-separated strings; we convert the nulls to spaces
WCHAR wCharValue[1024];
dwcbData = sizeof(wCharValue);
result = RegQueryValueExW(key, keyName, nullptr, &resultType, reinterpret_cast<LPBYTE>(wCharValue), &dwcbData); if (result == ERROR_SUCCESS && resultType == REG_MULTI_SZ)
{ // This bit here could probably be cleaner. bool isValid = false;
DWORD strLen = dwcbData/sizeof(wCharValue[0]); for (DWORD i = 0; i < strLen; i++)
{ if (wCharValue[i] == '\0')
{ if (i < strLen - 1 && wCharValue[i + 1] == '\0')
{
isValid = true; break;
} else
{
wCharValue[i] = ' ';
}
}
}
// ensure wCharValue is null terminated
wCharValue[strLen-1] = '\0';
if (isValid)
destString = OUString(o3tl::toU(wCharValue));
} else
{
retval = false;
}
break;
}
}
RegCloseKey(key);
return retval;
}
// The device ID is a string like PCI\VEN_15AD&DEV_0405&SUBSYS_040515AD // this function is used to extract the id's out of it
uint32_t ParseIDFromDeviceID(const OUString &key, constchar *prefix, int length)
{
OUString id = key.toAsciiUpperCase();
OUString aPrefix = OUString::fromUtf8(prefix);
int32_t start = id.indexOf(aPrefix); if (start != -1)
{
id = id.copy(start + aPrefix.getLength(), length);
} return id.toUInt32(16);
}
/* Other interesting places for info: * IDXGIAdapter::GetDesc() * IDirectDraw7::GetAvailableVidMem() * e->GetAvailableTextureMem()
* */
// Check if the device is blocked from the downloaded blocklist. If not, check // the static list after that. This order is used so that we can later escape // out of static blocks (i.e. if we were wrong or something was patched, we // can back out our static block without doing a release). if (mbRDP)
{
SAL_WARN("vcl.opengl", "all OpenGL blocked for RDP sessions"); returntrue;
}
while (EnumDisplayDevicesW(nullptr, deviceIndex, &displayDevice, 0))
{ if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{ break;
}
deviceIndex++;
}
// make sure the string is null terminated // (using the term "null" here to mean a zero UTF-16 unit) if (wcsnlen(displayDevice.DeviceKey, SAL_N_ELEMENTS(displayDevice.DeviceKey))
== SAL_N_ELEMENTS(displayDevice.DeviceKey))
{ // we did not find a null
SAL_WARN("vcl.opengl", "string not null terminated"); return;
}
/* DeviceKey is "reserved" according to MSDN so we'll be careful with it */ /* check that DeviceKey begins with DEVICE_KEY_PREFIX */ /* some systems have a DeviceKey starting with \REGISTRY\Machine\ so we need to compare case insensitively */ if (_wcsnicmp(displayDevice.DeviceKey, DEVICE_KEY_PREFIX, SAL_N_ELEMENTS(DEVICE_KEY_PREFIX)-1) != 0)
{
SAL_WARN("vcl.opengl", "incorrect DeviceKey"); return;
}
// chop off DEVICE_KEY_PREFIX
maDeviceKey = o3tl::toU(displayDevice.DeviceKey) + SAL_N_ELEMENTS(DEVICE_KEY_PREFIX)-1;
if (maDeviceID.isEmpty() &&
(maDeviceString == "RDPDD Chained DD" ||
(maDeviceString == "RDPUDD Chained DD")))
{ // we need to block RDP as it does not provide OpenGL 2.1+
mbRDP = true;
SAL_WARN("vcl.opengl", "RDP => blocked"); return;
}
/* create a device information set composed of the current display device */
HDEVINFO devinfo = SetupDiGetClassDevsW(nullptr, o3tl::toW(maDeviceID.getStr()), nullptr,
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
if (devinfo != INVALID_HANDLE_VALUE)
{
HKEY key; LONG result;
WCHAR value[255];
DWORD dwcbData;
SP_DEVINFO_DATA devinfoData;
DWORD memberIndex = 0;
devinfoData.cbSize = sizeof(devinfoData); /* enumerate device information elements in the device information set */ while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData))
{ /* get a string that identifies the device's driver key */ if (SetupDiGetDeviceRegistryPropertyW(devinfo,
&devinfoData,
SPDRP_DRIVER,
nullptr, reinterpret_cast<PBYTE>(value), sizeof(value),
nullptr))
{
OUString driverKey(OUString::Concat("System\\CurrentControlSet\\Control\\Class\\") + o3tl::toU(value));
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, o3tl::toW(driverKey.getStr()), 0, KEY_QUERY_VALUE, &key); if (result == ERROR_SUCCESS)
{ /* we've found the driver we're looking for */
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverVersion", nullptr, nullptr, reinterpret_cast<LPBYTE>(value), &dwcbData); if (result == ERROR_SUCCESS)
{
maDriverVersion = OUString(o3tl::toU(value));
} else
{ // If the entry wasn't found, assume the worst (0.0.0.0).
maDriverVersion = OUString("0.0.0.0");
}
dwcbData = sizeof(value);
result = RegQueryValueExW(key, L"DriverDate", nullptr, nullptr, reinterpret_cast<LPBYTE>(value), &dwcbData); if (result == ERROR_SUCCESS)
{
maDriverDate = o3tl::toU(value);
} else
{ // Again, assume the worst
maDriverDate = OUString("01-01-1970");
}
RegCloseKey(key); break;
}
}
}
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.