blob: ba4bb3984b6842da082ee8bdc90c2b1ebecf0d86 [file]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/win/hardware_check.h"
#include <windows.h>
#include <tbs.h>
#include <string_view>
#include "base/cpu.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "build/build_config.h"
namespace base::win {
namespace {
bool IsWin11SupportedProcessor(const CPU& cpu_info,
std::string_view vendor_name) {
#if defined(ARCH_CPU_X86_FAMILY)
if (vendor_name == "GenuineIntel") {
// Windows 11 is supported on Intel 8th Gen and higher models
// CPU model ID's can be referenced from the following file in
// the kernel source: arch/x86/include/asm/intel-family.h
if (cpu_info.family() != 0x06 || cpu_info.model() <= 0x5F ||
(cpu_info.model() == 0x8E &&
(cpu_info.stepping() < 9 || cpu_info.stepping() > 12)) ||
(cpu_info.model() == 0x9E &&
(cpu_info.stepping() < 10 || cpu_info.stepping() > 13))) {
return false;
}
return true;
}
if (vendor_name == "AuthenticAMD") {
// Windows 11 is supported on AMD Zen+ and higher models
if (cpu_info.family() < 0x17 ||
(cpu_info.family() == 0x17 &&
(cpu_info.model() == 0x1 || cpu_info.model() == 0x11))) {
return false;
}
return true;
}
#elif defined(ARCH_CPU_ARM_FAMILY)
if (vendor_name == "Qualcomm Technologies Inc") {
// Windows 11 is supported on all Qualcomm models with the exception
// of 1st Gen Compute Platforms due to lack of TPM 2.0
return true;
}
#else
#error Unsupported CPU architecture
#endif
return false;
}
bool IsUEFISecureBootEnabled() {
static constexpr wchar_t kSecureBootRegPath[] =
L"SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State";
RegKey key;
auto result =
key.Open(HKEY_LOCAL_MACHINE, kSecureBootRegPath, KEY_QUERY_VALUE);
if (result != ERROR_SUCCESS) {
return false;
}
DWORD secure_boot = 0;
result = key.ReadValueDW(L"UEFISecureBootEnabled", &secure_boot);
return result == ERROR_SUCCESS && secure_boot == 1;
}
bool IsTPM20Supported() {
TPM_DEVICE_INFO tpm_info{};
if (::Tbsi_GetDeviceInfo(sizeof(tpm_info), &tpm_info) != TBS_SUCCESS) {
return false;
}
return tpm_info.tpmVersion >= TPM_VERSION_20;
}
} // namespace
bool HardwareEvaluationResult::IsEligible() const {
return this->cpu && this->memory && this->disk && this->firmware && this->tpm;
}
HardwareEvaluationResult EvaluateWin11UpgradeEligibility() {
static constexpr int64_t kMinTotalDiskSpace = 64 * 1024 * 1024;
static constexpr uint64_t kMinTotalPhysicalMemory = 4 * 1024 * 1024;
static const HardwareEvaluationResult evaluate_win11_upgrade_eligibility =
[] {
HardwareEvaluationResult result;
result.cpu = IsWin11SupportedProcessor(
CPU(), OSInfo::GetInstance()->processor_vendor_name());
result.memory =
SysInfo::AmountOfPhysicalMemory() >= kMinTotalPhysicalMemory;
FilePath system_path;
result.disk =
PathService::Get(DIR_SYSTEM, &system_path) &&
SysInfo::AmountOfTotalDiskSpace(
FilePath(system_path.GetComponents()[0])) >= kMinTotalDiskSpace;
result.firmware = IsUEFISecureBootEnabled();
result.tpm = IsTPM20Supported();
return result;
}();
return evaluate_win11_upgrade_eligibility;
}
} // namespace base::win