sys_info_win.cc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/system/sys_info.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <windows.h>
  8. #include <limits>
  9. #include "base/check.h"
  10. #include "base/files/file_path.h"
  11. #include "base/notreached.h"
  12. #include "base/numerics/safe_conversions.h"
  13. #include "base/process/process_metrics.h"
  14. #include "base/strings/string_util.h"
  15. #include "base/strings/stringprintf.h"
  16. #include "base/strings/sys_string_conversions.h"
  17. #include "base/strings/utf_string_conversions.h"
  18. #include "base/threading/scoped_blocking_call.h"
  19. #include "base/win/registry.h"
  20. #include "base/win/windows_version.h"
  21. namespace {
  22. uint64_t AmountOfMemory(DWORDLONG MEMORYSTATUSEX::*memory_field) {
  23. MEMORYSTATUSEX memory_info;
  24. memory_info.dwLength = sizeof(memory_info);
  25. if (!GlobalMemoryStatusEx(&memory_info)) {
  26. NOTREACHED();
  27. return 0;
  28. }
  29. return memory_info.*memory_field;
  30. }
  31. bool GetDiskSpaceInfo(const base::FilePath& path,
  32. int64_t* available_bytes,
  33. int64_t* total_bytes) {
  34. ULARGE_INTEGER available;
  35. ULARGE_INTEGER total;
  36. ULARGE_INTEGER free;
  37. if (!GetDiskFreeSpaceExW(path.value().c_str(), &available, &total, &free))
  38. return false;
  39. if (available_bytes) {
  40. *available_bytes = static_cast<int64_t>(available.QuadPart);
  41. if (*available_bytes < 0)
  42. *available_bytes = std::numeric_limits<int64_t>::max();
  43. }
  44. if (total_bytes) {
  45. *total_bytes = static_cast<int64_t>(total.QuadPart);
  46. if (*total_bytes < 0)
  47. *total_bytes = std::numeric_limits<int64_t>::max();
  48. }
  49. return true;
  50. }
  51. } // namespace
  52. namespace base {
  53. // static
  54. int SysInfo::NumberOfProcessors() {
  55. return win::OSInfo::GetInstance()->processors();
  56. }
  57. // static
  58. uint64_t SysInfo::AmountOfPhysicalMemoryImpl() {
  59. return AmountOfMemory(&MEMORYSTATUSEX::ullTotalPhys);
  60. }
  61. // static
  62. uint64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
  63. SystemMemoryInfoKB info;
  64. if (!GetSystemMemoryInfo(&info))
  65. return 0;
  66. return checked_cast<uint64_t>(info.avail_phys) * 1024;
  67. }
  68. // static
  69. uint64_t SysInfo::AmountOfVirtualMemory() {
  70. return AmountOfMemory(&MEMORYSTATUSEX::ullTotalVirtual);
  71. }
  72. // static
  73. int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
  74. base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
  75. base::BlockingType::MAY_BLOCK);
  76. int64_t available;
  77. if (!GetDiskSpaceInfo(path, &available, nullptr))
  78. return -1;
  79. return available;
  80. }
  81. // static
  82. int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
  83. base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
  84. base::BlockingType::MAY_BLOCK);
  85. int64_t total;
  86. if (!GetDiskSpaceInfo(path, nullptr, &total))
  87. return -1;
  88. return total;
  89. }
  90. std::string SysInfo::OperatingSystemName() {
  91. return "Windows NT";
  92. }
  93. // static
  94. std::string SysInfo::OperatingSystemVersion() {
  95. win::OSInfo* os_info = win::OSInfo::GetInstance();
  96. win::OSInfo::VersionNumber version_number = os_info->version_number();
  97. std::string version(StringPrintf("%d.%d.%d", version_number.major,
  98. version_number.minor, version_number.build));
  99. win::OSInfo::ServicePack service_pack = os_info->service_pack();
  100. if (service_pack.major != 0) {
  101. version += StringPrintf(" SP%d", service_pack.major);
  102. if (service_pack.minor != 0)
  103. version += StringPrintf(".%d", service_pack.minor);
  104. }
  105. return version;
  106. }
  107. // TODO: Implement OperatingSystemVersionComplete, which would include
  108. // patchlevel/service pack number.
  109. // See chrome/browser/feedback/feedback_util.h, FeedbackUtil::SetOSVersion.
  110. // static
  111. std::string SysInfo::OperatingSystemArchitecture() {
  112. win::OSInfo::WindowsArchitecture arch = win::OSInfo::GetArchitecture();
  113. switch (arch) {
  114. case win::OSInfo::X86_ARCHITECTURE:
  115. return "x86";
  116. case win::OSInfo::X64_ARCHITECTURE:
  117. return "x86_64";
  118. case win::OSInfo::IA64_ARCHITECTURE:
  119. return "ia64";
  120. case win::OSInfo::ARM64_ARCHITECTURE:
  121. return "arm64";
  122. default:
  123. return "";
  124. }
  125. }
  126. // static
  127. std::string SysInfo::CPUModelName() {
  128. return win::OSInfo::GetInstance()->processor_model_name();
  129. }
  130. // static
  131. size_t SysInfo::VMAllocationGranularity() {
  132. return win::OSInfo::GetInstance()->allocation_granularity();
  133. }
  134. // static
  135. void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
  136. int32_t* minor_version,
  137. int32_t* bugfix_version) {
  138. win::OSInfo* os_info = win::OSInfo::GetInstance();
  139. *major_version = static_cast<int32_t>(os_info->version_number().major);
  140. *minor_version = static_cast<int32_t>(os_info->version_number().minor);
  141. *bugfix_version = 0;
  142. }
  143. // static
  144. std::string ReadHardwareInfoFromRegistry(const wchar_t* reg_value_name) {
  145. // On some systems or VMs, the system information and some of the below
  146. // locations may be missing info. Attempt to find the info from the below
  147. // registry keys in the order provided.
  148. static const wchar_t* const kSystemInfoRegKeyPaths[] = {
  149. L"HARDWARE\\DESCRIPTION\\System\\BIOS",
  150. L"SYSTEM\\CurrentControlSet\\Control\\SystemInformation",
  151. L"SYSTEM\\HardwareConfig\\Current",
  152. };
  153. std::wstring value;
  154. for (const wchar_t* system_info_reg_key_path : kSystemInfoRegKeyPaths) {
  155. base::win::RegKey system_information_key;
  156. if (system_information_key.Open(HKEY_LOCAL_MACHINE,
  157. system_info_reg_key_path,
  158. KEY_READ) == ERROR_SUCCESS) {
  159. if ((system_information_key.ReadValue(reg_value_name, &value) ==
  160. ERROR_SUCCESS) &&
  161. !value.empty()) {
  162. break;
  163. }
  164. }
  165. }
  166. return base::SysWideToUTF8(value);
  167. }
  168. // static
  169. SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
  170. HardwareInfo info = {ReadHardwareInfoFromRegistry(L"SystemManufacturer"),
  171. SysInfo::HardwareModelName()};
  172. return info;
  173. }
  174. // static
  175. std::string SysInfo::HardwareModelName() {
  176. return ReadHardwareInfoFromRegistry(L"SystemProductName");
  177. }
  178. } // namespace base