13#include <config_folders.h>
15#if !defined WIN32_LEAN_AND_MEAN
16# define WIN32_LEAN_AND_MEAN
26#include <osl/file.hxx>
27#include <rtl/bootstrap.hxx>
28#include <rtl/ustrbuf.hxx>
37bool GetKeyValue(
const WCHAR* keyLocation,
const WCHAR* keyName, OUString& destString,
int type)
46 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyLocation, 0, KEY_QUERY_VALUE, &key);
47 if (
result != ERROR_SUCCESS)
57 dwcbData =
sizeof(dValue);
58 result = RegQueryValueExW(key, keyName,
nullptr, &resultType,
59 reinterpret_cast<LPBYTE
>(&dValue), &dwcbData);
60 if (
result == ERROR_SUCCESS && resultType == REG_DWORD)
62 dValue = dValue / 1024 / 1024;
63 destString += OUString::number(int32_t(dValue));
74 WCHAR wCharValue[1024];
75 dwcbData =
sizeof(wCharValue);
77 result = RegQueryValueExW(key, keyName,
nullptr, &resultType,
78 reinterpret_cast<LPBYTE
>(wCharValue), &dwcbData);
79 if (
result == ERROR_SUCCESS && resultType == REG_MULTI_SZ)
84 DWORD strLen = dwcbData/
sizeof(wCharValue[0]);
85 for (DWORD
i = 0;
i < strLen;
i++)
87 if (wCharValue[
i] ==
'\0')
89 if (
i < strLen - 1 && wCharValue[
i + 1] ==
'\0')
102 wCharValue[strLen-1] =
'\0';
105 destString = OUString(o3tl::toU(wCharValue));
123uint32_t ParseIDFromDeviceID(
const OUString &key,
const char *
prefix,
int length)
125 OUString
id = key.toAsciiUpperCase();
126 OUString aPrefix = OUString::fromUtf8(
prefix);
127 int32_t
start =
id.indexOf(aPrefix);
132 return id.toUInt32(16);
141template<
typename T>
void appendIntegerWithPadding(OUString& rString, T
value, sal_uInt32 nChars)
144 OUString aValue = OUString::number(
value, 16);
145 sal_Int32
nLength = aValue.getLength();
146 sal_uInt32 nPadLength = nChars -
nLength;
147 assert(nPadLength >= 0);
149 for (sal_uInt32
i = 0;
i < nPadLength; ++
i)
153 rString +=
aBuffer.makeStringAndClear() + aValue;
156#define DEVICE_KEY_PREFIX L"\\Registry\\Machine\\"
168 OUString url(
"$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER);
169 rtl::Bootstrap::expandMacros(url);
171 return url +
"/opengl/opengl_denylist_windows.xml";
182OUString getCacheFolder()
184 OUString url(
"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/" SAL_CONFIGFILE(
"bootstrap")
":UserInstallation}/cache/");
185 rtl::Bootstrap::expandMacros(url);
187 osl::Directory::create(url);
192void writeToLog(
SvStream& rStrm,
const char* pKey, std::u16string_view rVal)
217 OUString aCacheFolder = getCacheFolder();
219 OUString aCacheFile(aCacheFolder +
"/opengl_device.log");
220 SvFileStream aOpenGLLogFile(aCacheFile, StreamMode::WRITE|StreamMode::TRUNC);
224 writeToLog(aOpenGLLogFile,
"DeviceID",
maDeviceID);
228 writeToLog(aOpenGLLogFile,
"DeviceKey",
maDeviceKey);
237 SAL_WARN(
"vcl.opengl",
"all OpenGL blocked for RDP sessions");
246 DISPLAY_DEVICEW displayDevice;
247 displayDevice.cb =
sizeof(displayDevice);
251 while (EnumDisplayDevicesW(
nullptr, deviceIndex, &displayDevice, 0))
253 if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
262 if (wcsnlen(displayDevice.DeviceKey,
SAL_N_ELEMENTS(displayDevice.DeviceKey))
266 SAL_WARN(
"vcl.opengl",
"string not null terminated");
275 SAL_WARN(
"vcl.opengl",
"incorrect DeviceKey");
282 maDeviceID = o3tl::toU(displayDevice.DeviceID);
291 SAL_WARN(
"vcl.opengl",
"RDP => blocked");
296 HDEVINFO devinfo = SetupDiGetClassDevsW(
nullptr, o3tl::toW(
maDeviceID.getStr()),
nullptr,
297 DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
299 if (devinfo != INVALID_HANDLE_VALUE)
305 SP_DEVINFO_DATA devinfoData;
306 DWORD memberIndex = 0;
308 devinfoData.cbSize =
sizeof(devinfoData);
310 while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData))
313 if (SetupDiGetDeviceRegistryPropertyW(devinfo,
317 reinterpret_cast<PBYTE
>(
value),
321 OUString driverKey(OUString::Concat(
"System\\CurrentControlSet\\Control\\Class\\") + o3tl::toU(
value));
322 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, o3tl::toW(driverKey.getStr()), 0, KEY_QUERY_VALUE, &key);
323 if (
result == ERROR_SUCCESS)
326 dwcbData =
sizeof(
value);
327 result = RegQueryValueExW(key, L
"DriverVersion",
nullptr,
nullptr,
328 reinterpret_cast<LPBYTE
>(
value), &dwcbData);
329 if (
result == ERROR_SUCCESS)
338 dwcbData =
sizeof(
value);
339 result = RegQueryValueExW(key, L
"DriverDate",
nullptr,
nullptr,
340 reinterpret_cast<LPBYTE
>(
value), &dwcbData);
341 if (
result == ERROR_SUCCESS)
356 SetupDiDestroyDeviceInfoList(devinfo);
360 SAL_WARN(
"vcl.opengl",
"invalid handle value");
370 CLSID GUID_DISPLAY_DEVICE_ARRIVAL;
371 HRESULT hresult = CLSIDFromString(L
"{1CA05180-A699-450A-9A0C-DE4FBE3DDD89}",
372 &GUID_DISPLAY_DEVICE_ARRIVAL);
373 if (hresult == NOERROR)
375 devinfo = SetupDiGetClassDevsW(&GUID_DISPLAY_DEVICE_ARRIVAL,
377 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
379 if (devinfo != INVALID_HANDLE_VALUE)
385 SP_DEVINFO_DATA devinfoData;
386 DWORD memberIndex = 0;
387 devinfoData.cbSize =
sizeof(devinfoData);
389 OUString aAdapterDriver2;
391 OUString aDriverVersion2;
392 OUString aDriverDate2;
393 uint32_t adapterVendorID2;
394 uint32_t adapterDeviceID2;
397 while (SetupDiEnumDeviceInfo(devinfo, memberIndex++, &devinfoData))
400 if (SetupDiGetDeviceRegistryPropertyW(devinfo,
404 reinterpret_cast<PBYTE
>(
value),
408 OUString driverKey2(OUString::Concat(
"System\\CurrentControlSet\\Control\\Class\\") + o3tl::toU(
value));
409 result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, o3tl::toW(driverKey2.getStr()), 0, KEY_QUERY_VALUE, &key);
410 if (
result == ERROR_SUCCESS)
412 dwcbData =
sizeof(
value);
413 result = RegQueryValueExW(key, L
"MatchingDeviceId",
nullptr,
414 nullptr,
reinterpret_cast<LPBYTE
>(
value), &dwcbData);
415 if (
result != ERROR_SUCCESS)
419 aDeviceID2 = o3tl::toU(
value);
420 OUString aAdapterVendorID2String;
421 OUString aAdapterDeviceID2String;
422 adapterVendorID2 = ParseIDFromDeviceID(aDeviceID2,
"VEN_", 4);
423 appendIntegerWithPadding(aAdapterVendorID2String, adapterVendorID2, 4);
424 adapterDeviceID2 = ParseIDFromDeviceID(aDeviceID2,
"&DEV_", 4);
425 appendIntegerWithPadding(aAdapterDeviceID2String, adapterDeviceID2, 4);
435 if (!GetKeyValue(o3tl::toW(driverKey2.getStr()), L
"InstalledDisplayDrivers",
436 aAdapterDriver2, REG_MULTI_SZ))
441 dwcbData =
sizeof(
value);
442 result = RegQueryValueExW(key, L
"DriverVersion",
nullptr,
nullptr,
443 reinterpret_cast<LPBYTE
>(
value), &dwcbData);
444 if (
result != ERROR_SUCCESS)
449 aDriverVersion2 = o3tl::toU(
value);
450 dwcbData =
sizeof(
value);
451 result = RegQueryValueExW(key, L
"DriverDate",
nullptr,
nullptr,
452 reinterpret_cast<LPBYTE
>(
value), &dwcbData);
453 if (
result != ERROR_SUCCESS)
458 aDriverDate2 = o3tl::toU(
value);
459 dwcbData =
sizeof(
value);
460 result = RegQueryValueExW(key, L
"Device Description",
nullptr,
461 nullptr,
reinterpret_cast<LPBYTE
>(
value), &dwcbData);
462 if (
result != ERROR_SUCCESS)
464 dwcbData =
sizeof(
value);
465 result = RegQueryValueExW(key, L
"DriverDesc",
nullptr,
nullptr,
466 reinterpret_cast<LPBYTE
>(
value), &dwcbData);
469 if (
result == ERROR_SUCCESS)
486 SetupDiDestroyDeviceInfoList(devinfo);
static OUString getDenylistFile()
#define DEVICE_KEY_PREFIX
static void addKeyValue(SAL_UNUSED_PARAMETER const OUString &, SAL_UNUSED_PARAMETER const OUString &, SAL_UNUSED_PARAMETER tAddKeyHandling)
SvStream & WriteOString(std::string_view rStr)
SvStream & WriteChar(char nChar)
OUString maAdapterDeviceID
OUString maAdapterSubsysID
bool FindBlocklistedDeviceInList()
OUString maAdapterSubsysID2
OUString maDriverVersion2
OUString maAdapterDeviceID2
OUString maAdapterVendorID
OUString maAdapterVendorID2
#define SAL_CONFIGFILE(name)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
bool IsDeviceBlocked(const OUString &blocklistURL, VersionType versionType, std::u16string_view driverVersion, std::u16string_view vendorId, const OUString &deviceId)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::unique_ptr< char[]> aBuffer