Added a RAM hardware and sensor, fixed Issue 115.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
14 using System.Management;
17 namespace OpenHardwareMonitor.Hardware {
19 internal class SMBIOS {
21 private readonly byte[] raw;
22 private readonly Structure[] table;
24 private readonly Version version;
25 private readonly BIOSInformation biosInformation;
26 private readonly SystemInformation systemInformation;
27 private readonly BaseBoardInformation baseBoardInformation;
28 private readonly MemoryDevice[] memoryDevices;
30 private static string ReadSysFS(string path) {
32 if (File.Exists(path)) {
33 using (StreamReader reader = new StreamReader(path))
34 return reader.ReadLine();
44 int p = (int)Environment.OSVersion.Platform;
45 if ((p == 4) || (p == 128)) {
49 string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
50 string boardName = ReadSysFS("/sys/class/dmi/id/board_name");
51 string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");
52 this.baseBoardInformation = new BaseBoardInformation(
53 boardVendor, boardName, boardVersion, null);
55 string systemVendor = ReadSysFS("/sys/class/dmi/id/sys_vendor");
56 string productName = ReadSysFS("/sys/class/dmi/id/product_name");
57 string productVersion = ReadSysFS("/sys/class/dmi/id/product_version");
58 this.systemInformation = new SystemInformation(systemVendor,
59 productName, productVersion, null, null);
61 string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
62 string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
63 this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
65 this.memoryDevices = new MemoryDevice[0];
67 List<Structure> structureList = new List<Structure>();
68 List<MemoryDevice> memoryDeviceList = new List<MemoryDevice>();
71 byte majorVersion = 0;
72 byte minorVersion = 0;
74 ManagementObjectCollection collection;
75 using (ManagementObjectSearcher searcher =
76 new ManagementObjectSearcher("root\\WMI",
77 "SELECT * FROM MSSMBios_RawSMBiosTables")) {
78 collection = searcher.Get();
81 foreach (ManagementObject mo in collection) {
82 raw = (byte[])mo["SMBiosData"];
83 majorVersion = (byte)mo["SmbiosMajorVersion"];
84 minorVersion = (byte)mo["SmbiosMinorVersion"];
89 if (majorVersion > 0 || minorVersion > 0)
90 version = new Version(majorVersion, minorVersion);
92 if (raw != null && raw.Length > 0) {
94 byte type = raw[offset];
95 while (offset + 4 < raw.Length && type != 127) {
98 int length = raw[offset + 1];
99 ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
101 if (offset + length > raw.Length)
103 byte[] data = new byte[length];
104 Array.Copy(raw, offset, data, 0, length);
107 List<string> stringsList = new List<string>();
108 if (offset < raw.Length && raw[offset] == 0)
111 while (offset < raw.Length && raw[offset] != 0) {
112 StringBuilder sb = new StringBuilder();
113 while (offset < raw.Length && raw[offset] != 0) {
114 sb.Append((char)raw[offset]); offset++;
117 stringsList.Add(sb.ToString());
122 this.biosInformation = new BIOSInformation(
123 type, handle, data, stringsList.ToArray());
124 structureList.Add(this.biosInformation); break;
126 this.systemInformation = new SystemInformation(
127 type, handle, data, stringsList.ToArray());
128 structureList.Add(this.systemInformation); break;
129 case 0x02: this.baseBoardInformation = new BaseBoardInformation(
130 type, handle, data, stringsList.ToArray());
131 structureList.Add(this.baseBoardInformation); break;
132 case 0x11: MemoryDevice m = new MemoryDevice(
133 type, handle, data, stringsList.ToArray());
134 memoryDeviceList.Add(m);
135 structureList.Add(m); break;
136 default: structureList.Add(new Structure(
137 type, handle, data, stringsList.ToArray())); break;
142 memoryDevices = memoryDeviceList.ToArray();
143 table = structureList.ToArray();
147 public string GetReport() {
148 StringBuilder r = new StringBuilder();
150 if (version != null) {
151 r.Append("SMBIOS Version: "); r.AppendLine(version.ToString(2));
156 r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
157 r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
161 if (System != null) {
162 r.Append("System Manufacturer: ");
163 r.AppendLine(System.ManufacturerName);
164 r.Append("System Name: ");
165 r.AppendLine(System.ProductName);
166 r.Append("System Version: ");
167 r.AppendLine(System.Version);
172 r.Append("Mainboard Manufacturer: ");
173 r.AppendLine(Board.ManufacturerName);
174 r.Append("Mainboard Name: ");
175 r.AppendLine(Board.ProductName);
176 r.Append("Mainboard Version: ");
177 r.AppendLine(Board.Version);
181 for (int i = 0; i < MemoryDevices.Length; i++) {
182 r.Append("Memory Device [" + i + "] Manufacturer: ");
183 r.AppendLine(MemoryDevices[i].ManufacturerName);
184 r.Append("Memory Device [" + i + "] Part Number: ");
185 r.AppendLine(MemoryDevices[i].PartNumber);
190 string base64 = Convert.ToBase64String(raw);
191 r.AppendLine("SMBIOS Table");
194 for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
196 for (int j = 0; j < 0x40; j++) {
197 int index = (i << 6) | j;
198 if (index < base64.Length) {
199 r.Append(base64[index]);
210 public BIOSInformation BIOS {
211 get { return biosInformation; }
214 public SystemInformation System {
215 get { return systemInformation; }
218 public BaseBoardInformation Board {
219 get { return baseBoardInformation; }
222 public MemoryDevice[] MemoryDevices {
223 get { return memoryDevices; }
226 public class Structure {
227 private readonly byte type;
228 private readonly ushort handle;
230 private readonly byte[] data;
231 private readonly string[] strings;
233 protected string GetString(int offset) {
234 if (offset < data.Length && data[offset] > 0 &&
235 data[offset] <= strings.Length)
236 return strings[data[offset] - 1];
241 public Structure(byte type, ushort handle, byte[] data, string[] strings)
244 this.handle = handle;
246 this.strings = strings;
249 public byte Type { get { return type; } }
251 public ushort Handle { get { return handle; } }
254 public class BIOSInformation : Structure {
256 private readonly string vendor;
257 private readonly string version;
259 public BIOSInformation(string vendor, string version)
260 : base (0x00, 0, null, null)
262 this.vendor = vendor;
263 this.version = version;
266 public BIOSInformation(byte type, ushort handle, byte[] data,
268 : base(type, handle, data, strings)
270 this.vendor = GetString(0x04);
271 this.version = GetString(0x05);
274 public string Vendor { get { return vendor; } }
276 public string Version { get { return version; } }
279 public class SystemInformation : Structure {
281 private readonly string manufacturerName;
282 private readonly string productName;
283 private readonly string version;
284 private readonly string serialNumber;
285 private readonly string family;
287 public SystemInformation(string manufacturerName, string productName,
288 string version, string serialNumber, string family)
289 : base (0x01, 0, null, null)
291 this.manufacturerName = manufacturerName;
292 this.productName = productName;
293 this.version = version;
294 this.serialNumber = serialNumber;
295 this.family = family;
298 public SystemInformation(byte type, ushort handle, byte[] data,
300 : base(type, handle, data, strings)
302 this.manufacturerName = GetString(0x04);
303 this.productName = GetString(0x05);
304 this.version = GetString(0x06);
305 this.serialNumber = GetString(0x07);
306 this.family = GetString(0x1A);
309 public string ManufacturerName { get { return manufacturerName; } }
311 public string ProductName { get { return productName; } }
313 public string Version { get { return version; } }
315 public string SerialNumber { get { return serialNumber; } }
317 public string Family { get { return family; } }
321 public class BaseBoardInformation : Structure {
323 private readonly string manufacturerName;
324 private readonly string productName;
325 private readonly string version;
326 private readonly string serialNumber;
328 public BaseBoardInformation(string manufacturerName, string productName,
329 string version, string serialNumber)
330 : base(0x02, 0, null, null)
332 this.manufacturerName = manufacturerName;
333 this.productName = productName;
334 this.version = version;
335 this.serialNumber = serialNumber;
338 public BaseBoardInformation(byte type, ushort handle, byte[] data,
340 : base(type, handle, data, strings) {
342 this.manufacturerName = GetString(0x04).Trim();
343 this.productName = GetString(0x05).Trim();
344 this.version = GetString(0x06).Trim();
345 this.serialNumber = GetString(0x07).Trim();
348 public string ManufacturerName { get { return manufacturerName; } }
350 public string ProductName { get { return productName; } }
352 public string Version { get { return version; } }
354 public string SerialNumber { get { return serialNumber; } }
358 public class MemoryDevice : Structure {
360 private readonly string manufacturerName;
361 private readonly string serialNumber;
362 private readonly string partNumber;
364 public MemoryDevice(string manufacturerName, string serialNumber,
366 : base(0x11, 0, null, null) {
367 this.manufacturerName = manufacturerName;
368 this.serialNumber = serialNumber;
369 this.partNumber = partNumber;
372 public MemoryDevice(byte type, ushort handle, byte[] data,
374 : base(type, handle, data, strings) {
375 this.manufacturerName = GetString(0x17).Trim();
376 this.serialNumber = GetString(0x18).Trim();
377 this.partNumber = GetString(0x1A).Trim();
380 public string ManufacturerName { get { return manufacturerName; } }
382 public string SerialNumber { get { return serialNumber; } }
384 public string PartNumber { get { return partNumber; } }