Implement WSL package version check (#13457)

This commit is contained in:
Blue 2025-09-05 15:06:55 -07:00 committed by Blue
parent e6e380e556
commit 0388a6dbfb
3 changed files with 42 additions and 11 deletions

View File

@ -336,7 +336,7 @@ try
// Check if the WSL package is installed, and if the version supports WSLA
auto version = wsl::windows::common::wslutil::GetInstalledPackageVersion();
constexpr auto minimalPackageVersion = wsl::shared::PackageVersion; // TODO: replace with correct version once WSLA is released.
constexpr auto minimalPackageVersion = std::tuple{2, 7, 0};
WI_SetFlagIf(*Components, WslInstallComponentWslPackage, !version.has_value() || version < minimalPackageVersion);
// TODO: Check if hardware supports virtualization.

View File

@ -163,10 +163,8 @@ template <typename T>
class RegistryKeyChange
{
public:
RegistryKeyChange(HKEY Hive, LPCWSTR Key, LPCWSTR Name, const T& Value) : m_value(Name)
RegistryKeyChange(HKEY Hive, LPCWSTR Key, LPCWSTR Name, const T& Value) : m_hive(Hive), m_key(Key), m_value(Name)
{
m_key = wsl::windows::common::registry::CreateKey(Hive, Key, KEY_ALL_ACCESS);
m_originalValue = Get();
Set(Value);
@ -174,38 +172,51 @@ public:
~RegistryKeyChange()
{
if (m_key)
if (m_key != nullptr)
{
auto key = wsl::windows::common::registry::CreateKey(m_hive, m_key, KEY_ALL_ACCESS);
if (m_originalValue.has_value())
{
Set(m_originalValue.value());
}
else
{
wsl::windows::common::registry::DeleteKeyValue(m_key.get(), m_value.c_str());
wsl::windows::common::registry::DeleteKeyValue(key.get(), m_value.c_str());
}
}
}
wil::unique_hkey OpenKey()
{
return;
}
RegistryKeyChange(const RegistryKeyChange&) = delete;
RegistryKeyChange(RegistryKeyChange&& other) = default;
const RegistryKeyChange& operator=(RegistryKeyChange&& other)
{
m_hive = std::move(other.m_hive);
m_key = std::move(other.m_key);
m_value = std::move(other.m_value);
other.m_hive = nullptr;
other.m_key = nullptr;
}
const RegistryKeyChange& operator=(RegistryKeyChange&) = delete;
void Set(const T& Value)
{
auto key = wsl::windows::common::registry::CreateKey(m_hive, m_key, KEY_ALL_ACCESS);
if constexpr (std::is_same_v<std::remove_reference_t<T>, DWORD>)
{
wsl::windows::common::registry::WriteDword(m_key.get(), nullptr, m_value.c_str(), Value);
wsl::windows::common::registry::WriteDword(key.get(), nullptr, m_value.c_str(), Value);
}
else if constexpr (std::is_same_v<std::remove_reference_t<T>, std::wstring>)
{
wsl::windows::common::registry::WriteString(m_key.get(), nullptr, m_value.c_str(), Value.c_str());
wsl::windows::common::registry::WriteString(key.get(), nullptr, m_value.c_str(), Value.c_str());
}
else
{
@ -215,11 +226,14 @@ public:
auto Get() const
{
auto key = wsl::windows::common::registry::CreateKey(m_hive, m_key, KEY_ALL_ACCESS);
if constexpr (std::is_same_v<T, DWORD>)
{
DWORD Value = 0;
DWORD Size = sizeof(Value);
const auto Result = RegGetValueW(m_key.get(), nullptr, m_value.c_str(), RRF_RT_REG_DWORD, nullptr, &Value, &Size);
const auto Result = RegGetValueW(key.get(), nullptr, m_value.c_str(), RRF_RT_REG_DWORD, nullptr, &Value, &Size);
if (Result == ERROR_SUCCESS)
{
WI_ASSERT(Size == sizeof(Value));
@ -236,7 +250,7 @@ public:
}
else if constexpr (std::is_same_v<std::remove_reference_t<T>, std::wstring>)
{
return wsl::windows::common::registry::ReadOptionalString(m_key.get(), nullptr, m_value.c_str());
return wsl::windows::common::registry::ReadOptionalString(key.get(), nullptr, m_value.c_str());
}
else
{
@ -245,7 +259,8 @@ public:
}
private:
wil::unique_hkey m_key;
HKEY m_hive = nullptr;
LPCWSTR m_key = nullptr;
std::wstring m_value;
std::optional<T> m_originalValue;
};

View File

@ -1052,6 +1052,20 @@ class InstallerTests
VERIFY_ARE_EQUAL(WslInstallComponents(WslInstallComponentWslPackage, nullptr, nullptr), E_INVALIDARG);
// TODO: remove once 2.7.0 is released.
RegistryKeyChange<std::wstring> version(HKEY_LOCAL_MACHINE, LXSS_REGISTRY_PATH "\\MSI", L"Version", L"2.7.0");
expectComponents(WslInstallComponentNone);
// Validate that a package < 2.7 is handled correctly.
{
version.Set(L"2.6.0");
expectComponents(WslInstallComponentWslPackage);
}
version.Set(L"2.7.0");
// Validate that a missing package is detected.
expectComponents(WslInstallComponentNone);
UninstallMsi();
@ -1070,6 +1084,8 @@ class InstallerTests
VERIFY_ARE_EQUAL(progressedComponents, WslInstallComponentWslPackage);
ValidateInstalledVersion(WIDEN(WSL_PACKAGE_VERSION));
version.Set(L"2.7.0");
expectComponents(WslInstallComponentNone);
progressedComponents = WslInstallComponentNone;