1
2
3
4
5 package oshi.hardware.platform.windows;
6
7 import static oshi.util.Memoizer.defaultExpiration;
8 import static oshi.util.Memoizer.memoize;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.function.Supplier;
13
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16
17 import com.sun.jna.platform.win32.Kernel32;
18 import com.sun.jna.platform.win32.Psapi;
19 import com.sun.jna.platform.win32.VersionHelpers;
20 import com.sun.jna.platform.win32.COM.WbemcliUtil.WmiResult;
21
22 import oshi.annotation.concurrent.ThreadSafe;
23 import oshi.driver.windows.wmi.Win32PhysicalMemory;
24 import oshi.driver.windows.wmi.Win32PhysicalMemory.PhysicalMemoryProperty;
25 import oshi.driver.windows.wmi.Win32PhysicalMemory.PhysicalMemoryPropertyWin8;
26 import oshi.hardware.PhysicalMemory;
27 import oshi.hardware.VirtualMemory;
28 import oshi.hardware.common.AbstractGlobalMemory;
29 import oshi.jna.Struct.CloseablePerformanceInformation;
30 import oshi.util.platform.windows.WmiUtil;
31 import oshi.util.tuples.Triplet;
32
33
34
35
36 @ThreadSafe
37 final class WindowsGlobalMemory extends AbstractGlobalMemory {
38
39 private static final Logger LOG = LoggerFactory.getLogger(WindowsGlobalMemory.class);
40
41 private static final boolean IS_WINDOWS10_OR_GREATER = VersionHelpers.IsWindows10OrGreater();
42
43 private final Supplier<Triplet<Long, Long, Long>> availTotalSize = memoize(WindowsGlobalMemory::readPerfInfo,
44 defaultExpiration());
45
46 private final Supplier<VirtualMemory> vm = memoize(this::createVirtualMemory);
47
48 @Override
49 public long getAvailable() {
50 return availTotalSize.get().getA();
51 }
52
53 @Override
54 public long getTotal() {
55 return availTotalSize.get().getB();
56 }
57
58 @Override
59 public long getPageSize() {
60 return availTotalSize.get().getC();
61 }
62
63 @Override
64 public VirtualMemory getVirtualMemory() {
65 return vm.get();
66 }
67
68 private VirtualMemory createVirtualMemory() {
69 return new WindowsVirtualMemory(this);
70 }
71
72 @Override
73 public List<PhysicalMemory> getPhysicalMemory() {
74 List<PhysicalMemory> physicalMemoryList = new ArrayList<>();
75 if (IS_WINDOWS10_OR_GREATER) {
76 WmiResult<PhysicalMemoryProperty> bankMap = Win32PhysicalMemory.queryphysicalMemory();
77 for (int index = 0; index < bankMap.getResultCount(); index++) {
78 String bankLabel = WmiUtil.getString(bankMap, PhysicalMemoryProperty.BANKLABEL, index);
79 long capacity = WmiUtil.getUint64(bankMap, PhysicalMemoryProperty.CAPACITY, index);
80 long speed = WmiUtil.getUint32(bankMap, PhysicalMemoryProperty.SPEED, index) * 1_000_000L;
81 String manufacturer = WmiUtil.getString(bankMap, PhysicalMemoryProperty.MANUFACTURER, index);
82 String memoryType = smBiosMemoryType(
83 WmiUtil.getUint32(bankMap, PhysicalMemoryProperty.SMBIOSMEMORYTYPE, index));
84 String partNumber = WmiUtil.getString(bankMap, PhysicalMemoryProperty.PARTNUMBER, index);
85 String serialNumber = WmiUtil.getString(bankMap, PhysicalMemoryProperty.SERIALNUMBER, index);
86 physicalMemoryList.add(new PhysicalMemory(bankLabel, capacity, speed, manufacturer, memoryType,
87 partNumber, serialNumber));
88 }
89 } else {
90 WmiResult<PhysicalMemoryPropertyWin8> bankMap = Win32PhysicalMemory.queryphysicalMemoryWin8();
91 for (int index = 0; index < bankMap.getResultCount(); index++) {
92 String bankLabel = WmiUtil.getString(bankMap, PhysicalMemoryPropertyWin8.BANKLABEL, index);
93 long capacity = WmiUtil.getUint64(bankMap, PhysicalMemoryPropertyWin8.CAPACITY, index);
94 long speed = WmiUtil.getUint32(bankMap, PhysicalMemoryPropertyWin8.SPEED, index) * 1_000_000L;
95 String manufacturer = WmiUtil.getString(bankMap, PhysicalMemoryPropertyWin8.MANUFACTURER, index);
96 String memoryType = memoryType(
97 WmiUtil.getUint16(bankMap, PhysicalMemoryPropertyWin8.MEMORYTYPE, index));
98 String partNumber = WmiUtil.getString(bankMap, PhysicalMemoryPropertyWin8.PARTNUMBER, index);
99 String serialNumber = WmiUtil.getString(bankMap, PhysicalMemoryPropertyWin8.SERIALNUMBER, index);
100 physicalMemoryList.add(new PhysicalMemory(bankLabel, capacity, speed, manufacturer, memoryType,
101 partNumber, serialNumber));
102 }
103 }
104 return physicalMemoryList;
105 }
106
107
108
109
110
111
112
113 private static String memoryType(int type) {
114
115 switch (type) {
116 case 0:
117 return "Unknown";
118 case 1:
119 return "Other";
120 case 2:
121 return "DRAM";
122 case 3:
123 return "Synchronous DRAM";
124 case 4:
125 return "Cache DRAM";
126 case 5:
127 return "EDO";
128 case 6:
129 return "EDRAM";
130 case 7:
131 return "VRAM";
132 case 8:
133 return "SRAM";
134 case 9:
135 return "RAM";
136 case 10:
137 return "ROM";
138 case 11:
139 return "Flash";
140 case 12:
141 return "EEPROM";
142 case 13:
143 return "FEPROM";
144 case 14:
145 return "EPROM";
146 case 15:
147 return "CDRAM";
148 case 16:
149 return "3DRAM";
150 case 17:
151 return "SDRAM";
152 case 18:
153 return "SGRAM";
154 case 19:
155 return "RDRAM";
156 case 20:
157 return "DDR";
158 case 21:
159 return "DDR2";
160 case 22:
161 return "BRAM";
162 case 23:
163 return "DDR FB-DIMM";
164 default:
165
166 return smBiosMemoryType(type);
167 }
168 }
169
170
171
172
173
174
175
176 private static String smBiosMemoryType(int type) {
177
178
179 switch (type) {
180 case 0x01:
181 return "Other";
182 case 0x03:
183 return "DRAM";
184 case 0x04:
185 return "EDRAM";
186 case 0x05:
187 return "VRAM";
188 case 0x06:
189 return "SRAM";
190 case 0x07:
191 return "RAM";
192 case 0x08:
193 return "ROM";
194 case 0x09:
195 return "FLASH";
196 case 0x0A:
197 return "EEPROM";
198 case 0x0B:
199 return "FEPROM";
200 case 0x0C:
201 return "EPROM";
202 case 0x0D:
203 return "CDRAM";
204 case 0x0E:
205 return "3DRAM";
206 case 0x0F:
207 return "SDRAM";
208 case 0x10:
209 return "SGRAM";
210 case 0x11:
211 return "RDRAM";
212 case 0x12:
213 return "DDR";
214 case 0x13:
215 return "DDR2";
216 case 0x14:
217 return "DDR2 FB-DIMM";
218 case 0x18:
219 return "DDR3";
220 case 0x19:
221 return "FBD2";
222 case 0x1A:
223 return "DDR4";
224 case 0x1B:
225 return "LPDDR";
226 case 0x1C:
227 return "LPDDR2";
228 case 0x1D:
229 return "LPDDR3";
230 case 0x1E:
231 return "LPDDR4";
232 case 0x1F:
233 return "Logical non-volatile device";
234 case 0x20:
235 return "HBM";
236 case 0x21:
237 return "HBM2";
238 case 0x22:
239 return "DDR5";
240 case 0x23:
241 return "LPDDR5";
242 case 0x24:
243 return "HBM3";
244 case 0x02:
245 default:
246 return "Unknown";
247 }
248 }
249
250 private static Triplet<Long, Long, Long> readPerfInfo() {
251 try (CloseablePerformanceInformation performanceInfo = new CloseablePerformanceInformation()) {
252 if (!Psapi.INSTANCE.GetPerformanceInfo(performanceInfo, performanceInfo.size())) {
253 LOG.error("Failed to get Performance Info. Error code: {}", Kernel32.INSTANCE.GetLastError());
254 return new Triplet<>(0L, 0L, 4098L);
255 }
256 long pageSize = performanceInfo.PageSize.longValue();
257 long memAvailable = pageSize * performanceInfo.PhysicalAvailable.longValue();
258 long memTotal = pageSize * performanceInfo.PhysicalTotal.longValue();
259 return new Triplet<>(memAvailable, memTotal, pageSize);
260 }
261 }
262 }