File: hardware_check.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (144 lines) | stat: -rw-r--r-- 4,462 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// 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 <winternl.h>

#include <tbs.h>

#include <string_view>

#include "base/cpu.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/scoped_native_library.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 {

// ntstatus.h conflicts with windows.h so define this locally.
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define SystemSecureBootInformation 0x91

struct SYSTEM_SECUREBOOT_INFORMATION {
  BOOLEAN SecureBootEnabled;
  BOOLEAN SecureBootCapable;
};

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 IsUEFISecureBootCapable() {
  SYSTEM_SECUREBOOT_INFORMATION secure_boot_info{};
  if (::NtQuerySystemInformation(
          static_cast<SYSTEM_INFORMATION_CLASS>(SystemSecureBootInformation),
          &secure_boot_info, sizeof(SYSTEM_SECUREBOOT_INFORMATION),
          nullptr) != STATUS_SUCCESS) {
    return false;
  }

  return !!secure_boot_info.SecureBootCapable;
}

bool IsTPM20Supported() {
  // Using dynamic loading instead of using linker support for delay
  // loading to prevent failed loads being treated as a fatal failure which
  // can happen in rare cases due to missing or corrupted DLL file.
  ScopedNativeLibrary tbs_library(LoadSystemLibrary(L"tbs.dll"));
  if (!tbs_library.is_valid()) {
    return false;
  }

  decltype(Tbsi_GetDeviceInfo)* tbsi_get_device_info_proc =
      reinterpret_cast<decltype(Tbsi_GetDeviceInfo)*>(
          tbs_library.GetFunctionPointer("Tbsi_GetDeviceInfo"));
  if (!tbsi_get_device_info_proc) {
    return false;
  }

  TPM_DEVICE_INFO tpm_info{};
  TBS_RESULT result = tbsi_get_device_info_proc(sizeof(tpm_info), &tpm_info);
  return result == TBS_SUCCESS && tpm_info.tpmVersion >= TPM_VERSION_20;
}

}  // namespace

bool HardwareEvaluationResult::IsEligible() const {
  return this->cpu && this->memory && this->disk && this->firmware && this->tpm;
}

HardwareEvaluationResult EvaluateWin11HardwareRequirements() {
  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 = IsUEFISecureBootCapable();

        result.tpm = IsTPM20Supported();

        return result;
      }();

  return evaluate_win11_upgrade_eligibility;
}

}  // namespace base::win