// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware) // Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao) // SPDX-License-Identifier: Apache-2.0 #include "qwindowkit_windows.h" namespace QWK { static RTL_OSVERSIONINFOW GetRealOSVersionImpl() { HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll"); Q_ASSERT(hMod); using RtlGetVersionPtr = NTSTATUS(WINAPI *)(PRTL_OSVERSIONINFOW); auto pRtlGetVersion = reinterpret_cast(::GetProcAddress(hMod, "RtlGetVersion")); Q_ASSERT(pRtlGetVersion); RTL_OSVERSIONINFOW rovi{}; rovi.dwOSVersionInfoSize = sizeof(rovi); pRtlGetVersion(&rovi); return rovi; } namespace Private { RTL_OSVERSIONINFOW GetRealOSVersion() { static const auto result = GetRealOSVersionImpl(); return result; } } #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) WindowsRegistryKey::WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions, REGSAM access) { if (::RegOpenKeyExW(parentHandle, reinterpret_cast(subKey.utf16()), 0, permissions | access, &m_key) != ERROR_SUCCESS) { m_key = nullptr; } } WindowsRegistryKey::~WindowsRegistryKey() { close(); } void WindowsRegistryKey::close() { if (isValid()) { ::RegCloseKey(m_key); m_key = nullptr; } } QString WindowsRegistryKey::stringValue(QStringView subKey) const { QString result; if (!isValid()) return result; DWORD type; DWORD size; auto subKeyC = reinterpret_cast(subKey.utf16()); if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, nullptr, &size) != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ) || size <= 2) { return result; } // Reserve more for rare cases where trailing '\0' are missing in registry. // Rely on 0-termination since strings of size 256 padded with 0 have been // observed (QTBUG-84455). size += 2; QVarLengthArray buffer(static_cast(size)); std::fill(buffer.data(), buffer.data() + size, 0u); if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, buffer.data(), &size) == ERROR_SUCCESS) result = QString::fromWCharArray(reinterpret_cast(buffer.constData())); return result; } QPair WindowsRegistryKey::dwordValue(QStringView subKey) const { if (!isValid()) return qMakePair(0, false); DWORD type; auto subKeyC = reinterpret_cast(subKey.utf16()); if (::RegQueryValueExW(m_key, subKeyC, nullptr, &type, nullptr, nullptr) != ERROR_SUCCESS || type != REG_DWORD) { return qMakePair(0, false); } DWORD value = 0; DWORD size = sizeof(value); const bool ok = ::RegQueryValueExW(m_key, subKeyC, nullptr, nullptr, reinterpret_cast(&value), &size) == ERROR_SUCCESS; return qMakePair(value, ok); } #endif }