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
5 #include "base/system/sys_info.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <windows.h>
10
11 #include <limits>
12
13 #include "base/files/file_path.h"
14 #include "base/logging.h"
15 #include "base/process/process_metrics.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/scoped_blocking_call.h"
20 #include "base/win/windows_version.h"
21 #include "base/win/wmi.h"
22
23 namespace {
24
AmountOfMemory(DWORDLONG MEMORYSTATUSEX::* memory_field)25 int64_t AmountOfMemory(DWORDLONG MEMORYSTATUSEX::*memory_field) {
26 MEMORYSTATUSEX memory_info;
27 memory_info.dwLength = sizeof(memory_info);
28 if (!GlobalMemoryStatusEx(&memory_info)) {
29 NOTREACHED();
30 return 0;
31 }
32
33 int64_t rv = static_cast<int64_t>(memory_info.*memory_field);
34 return rv < 0 ? std::numeric_limits<int64_t>::max() : rv;
35 }
36
GetDiskSpaceInfo(const base::FilePath & path,int64_t * available_bytes,int64_t * total_bytes)37 bool GetDiskSpaceInfo(const base::FilePath& path,
38 int64_t* available_bytes,
39 int64_t* total_bytes) {
40 ULARGE_INTEGER available;
41 ULARGE_INTEGER total;
42 ULARGE_INTEGER free;
43 if (!GetDiskFreeSpaceExW(path.value().c_str(), &available, &total, &free))
44 return false;
45
46 if (available_bytes) {
47 *available_bytes = static_cast<int64_t>(available.QuadPart);
48 if (*available_bytes < 0)
49 *available_bytes = std::numeric_limits<int64_t>::max();
50 }
51 if (total_bytes) {
52 *total_bytes = static_cast<int64_t>(total.QuadPart);
53 if (*total_bytes < 0)
54 *total_bytes = std::numeric_limits<int64_t>::max();
55 }
56 return true;
57 }
58
59 } // namespace
60
61 namespace base {
62
63 // static
NumberOfProcessors()64 int SysInfo::NumberOfProcessors() {
65 return win::OSInfo::GetInstance()->processors();
66 }
67
68 // static
AmountOfPhysicalMemoryImpl()69 int64_t SysInfo::AmountOfPhysicalMemoryImpl() {
70 return AmountOfMemory(&MEMORYSTATUSEX::ullTotalPhys);
71 }
72
73 // static
AmountOfAvailablePhysicalMemoryImpl()74 int64_t SysInfo::AmountOfAvailablePhysicalMemoryImpl() {
75 SystemMemoryInfoKB info;
76 if (!GetSystemMemoryInfo(&info))
77 return 0;
78 return static_cast<int64_t>(info.avail_phys) * 1024;
79 }
80
81 // static
AmountOfVirtualMemory()82 int64_t SysInfo::AmountOfVirtualMemory() {
83 return AmountOfMemory(&MEMORYSTATUSEX::ullTotalVirtual);
84 }
85
86 // static
AmountOfFreeDiskSpace(const FilePath & path)87 int64_t SysInfo::AmountOfFreeDiskSpace(const FilePath& path) {
88 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
89 base::BlockingType::MAY_BLOCK);
90
91 int64_t available;
92 if (!GetDiskSpaceInfo(path, &available, nullptr))
93 return -1;
94 return available;
95 }
96
97 // static
AmountOfTotalDiskSpace(const FilePath & path)98 int64_t SysInfo::AmountOfTotalDiskSpace(const FilePath& path) {
99 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
100 base::BlockingType::MAY_BLOCK);
101
102 int64_t total;
103 if (!GetDiskSpaceInfo(path, nullptr, &total))
104 return -1;
105 return total;
106 }
107
OperatingSystemName()108 std::string SysInfo::OperatingSystemName() {
109 return "Windows NT";
110 }
111
112 // static
OperatingSystemVersion()113 std::string SysInfo::OperatingSystemVersion() {
114 win::OSInfo* os_info = win::OSInfo::GetInstance();
115 win::OSInfo::VersionNumber version_number = os_info->version_number();
116 std::string version(StringPrintf("%d.%d.%d", version_number.major,
117 version_number.minor, version_number.build));
118 win::OSInfo::ServicePack service_pack = os_info->service_pack();
119 if (service_pack.major != 0) {
120 version += StringPrintf(" SP%d", service_pack.major);
121 if (service_pack.minor != 0)
122 version += StringPrintf(".%d", service_pack.minor);
123 }
124 return version;
125 }
126
127 // TODO: Implement OperatingSystemVersionComplete, which would include
128 // patchlevel/service pack number.
129 // See chrome/browser/feedback/feedback_util.h, FeedbackUtil::SetOSVersion.
130
131 // static
OperatingSystemArchitecture()132 std::string SysInfo::OperatingSystemArchitecture() {
133 win::OSInfo::WindowsArchitecture arch = win::OSInfo::GetArchitecture();
134 switch (arch) {
135 case win::OSInfo::X86_ARCHITECTURE:
136 return "x86";
137 case win::OSInfo::X64_ARCHITECTURE:
138 return "x86_64";
139 case win::OSInfo::IA64_ARCHITECTURE:
140 return "ia64";
141 case win::OSInfo::ARM64_ARCHITECTURE:
142 return "arm64";
143 default:
144 return "";
145 }
146 }
147
148 // static
CPUModelName()149 std::string SysInfo::CPUModelName() {
150 return win::OSInfo::GetInstance()->processor_model_name();
151 }
152
153 // static
VMAllocationGranularity()154 size_t SysInfo::VMAllocationGranularity() {
155 return win::OSInfo::GetInstance()->allocation_granularity();
156 }
157
158 // static
OperatingSystemVersionNumbers(int32_t * major_version,int32_t * minor_version,int32_t * bugfix_version)159 void SysInfo::OperatingSystemVersionNumbers(int32_t* major_version,
160 int32_t* minor_version,
161 int32_t* bugfix_version) {
162 win::OSInfo* os_info = win::OSInfo::GetInstance();
163 *major_version = os_info->version_number().major;
164 *minor_version = os_info->version_number().minor;
165 *bugfix_version = 0;
166 }
167
168 // static
GetHardwareInfoSync()169 SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
170 win::WmiComputerSystemInfo wmi_info = win::WmiComputerSystemInfo::Get();
171
172 HardwareInfo info;
173 info.manufacturer = WideToUTF8(wmi_info.manufacturer());
174 info.model = WideToUTF8(wmi_info.model());
175 info.serial_number = WideToUTF8(wmi_info.serial_number());
176 DCHECK(IsStringUTF8(info.manufacturer));
177 DCHECK(IsStringUTF8(info.model));
178 DCHECK(IsStringUTF8(info.serial_number));
179 return info;
180 }
181
182 } // namespace base
183