Fixed Issue 156.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 The contents of this file are subject to the Mozilla Public License Version
6 1.1 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
9 http://www.mozilla.org/MPL/
11 Software distributed under the License is distributed on an "AS IS" basis,
12 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 for the specific language governing rights and limitations under the License.
15 The Original Code is the Open Hardware Monitor code.
17 The Initial Developer of the Original Code is
18 Michael Möller <m.moeller@gmx.ch>.
19 Portions created by the Initial Developer are Copyright (C) 2009-2011
20 the Initial Developer. All Rights Reserved.
24 Alternatively, the contents of this file may be used under the terms of
25 either the GNU General Public License Version 2 or later (the "GPL"), or
26 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 in which case the provisions of the GPL or the LGPL are applicable instead
28 of those above. If you wish to allow use of your version of this file only
29 under the terms of either the GPL or the LGPL, and not to allow others to
30 use your version of this file under the terms of the MPL, indicate your
31 decision by deleting the provisions above and replace them with the notice
32 and other provisions required by the GPL or the LGPL. If you do not delete
33 the provisions above, a recipient may use your version of this file under
34 the terms of any one of the MPL, the GPL or the LGPL.
39 using System.Collections.Generic;
41 using System.Management;
44 namespace OpenHardwareMonitor.Hardware.Mainboard {
46 internal class SMBIOS {
48 private readonly byte[] raw;
49 private readonly Structure[] table;
51 private readonly Version version;
52 private readonly BIOSInformation biosInformation;
53 private readonly BaseBoardInformation baseBoardInformation;
55 private static string ReadSysFS(string path) {
57 if (File.Exists(path)) {
58 using (StreamReader reader = new StreamReader(path))
59 return reader.ReadLine();
69 int p = (int)Environment.OSVersion.Platform;
70 if ((p == 4) || (p == 128)) {
74 string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
75 string boardName = ReadSysFS("/sys/class/dmi/id/board_name");
76 string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");
77 this.baseBoardInformation = new BaseBoardInformation(
78 boardVendor, boardName, boardVersion, null);
80 string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
81 string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
82 this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
85 List<Structure> structureList = new List<Structure>();
88 byte majorVersion = 0;
89 byte minorVersion = 0;
91 ManagementObjectCollection collection;
92 using (ManagementObjectSearcher searcher =
93 new ManagementObjectSearcher("root\\WMI",
94 "SELECT * FROM MSSMBios_RawSMBiosTables")) {
95 collection = searcher.Get();
98 foreach (ManagementObject mo in collection) {
99 raw = (byte[])mo["SMBiosData"];
100 majorVersion = (byte)mo["SmbiosMajorVersion"];
101 minorVersion = (byte)mo["SmbiosMinorVersion"];
106 if (majorVersion > 0 || minorVersion > 0)
107 version = new Version(majorVersion, minorVersion);
109 if (raw != null && raw.Length > 0) {
111 byte type = raw[offset];
112 while (offset + 4 < raw.Length && type != 127) {
115 int length = raw[offset + 1];
116 ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
118 if (offset + length > raw.Length)
120 byte[] data = new byte[length];
121 Array.Copy(raw, offset, data, 0, length);
124 List<string> stringsList = new List<string>();
125 if (offset < raw.Length && raw[offset] == 0)
128 while (offset < raw.Length && raw[offset] != 0) {
129 StringBuilder sb = new StringBuilder();
130 while (offset < raw.Length && raw[offset] != 0) {
131 sb.Append((char)raw[offset]); offset++;
134 stringsList.Add(sb.ToString());
139 this.biosInformation = new BIOSInformation(
140 type, handle, data, stringsList.ToArray());
141 structureList.Add(this.biosInformation); break;
142 case 0x02: this.baseBoardInformation = new BaseBoardInformation(
143 type, handle, data, stringsList.ToArray());
144 structureList.Add(this.baseBoardInformation); break;
145 default: structureList.Add(new Structure(
146 type, handle, data, stringsList.ToArray())); break;
151 table = structureList.ToArray();
155 public string GetReport() {
156 StringBuilder r = new StringBuilder();
158 if (version != null) {
159 r.Append("SMBIOS Version: "); r.AppendLine(version.ToString(2));
164 r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
165 r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
170 r.Append("Mainboard Manufacturer: ");
171 r.AppendLine(Board.ManufacturerName);
172 r.Append("Mainboard Name: ");
173 r.AppendLine(Board.ProductName);
174 r.Append("Mainboard Version: ");
175 r.AppendLine(Board.Version);
180 string base64 = Convert.ToBase64String(raw);
181 r.AppendLine("SMBIOS Table");
184 for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
186 for (int j = 0; j < 0x40; j++) {
187 int index = (i << 6) | j;
188 if (index < base64.Length) {
189 r.Append(base64[index]);
200 public BIOSInformation BIOS {
201 get { return biosInformation; }
204 public BaseBoardInformation Board {
205 get { return baseBoardInformation; }
208 public class Structure {
209 private readonly byte type;
210 private readonly ushort handle;
212 private readonly byte[] data;
213 private readonly string[] strings;
215 protected string GetString(int offset) {
216 if (offset < data.Length && data[offset] > 0 &&
217 data[offset] <= strings.Length)
218 return strings[data[offset] - 1];
223 public Structure(byte type, ushort handle, byte[] data, string[] strings)
226 this.handle = handle;
228 this.strings = strings;
231 public byte Type { get { return type; } }
233 public ushort Handle { get { return handle; } }
236 public class BIOSInformation : Structure {
238 private readonly string vendor;
239 private readonly string version;
241 public BIOSInformation(string vendor, string version)
242 : base (0x00, 0, null, null)
244 this.vendor = vendor;
245 this.version = version;
248 public BIOSInformation(byte type, ushort handle, byte[] data,
250 : base(type, handle, data, strings)
252 this.vendor = GetString(0x04);
253 this.version = GetString(0x05);
256 public string Vendor { get { return vendor; } }
258 public string Version { get { return version; } }
261 public class BaseBoardInformation : Structure {
263 private readonly string manufacturerName;
264 private readonly string productName;
265 private readonly string version;
266 private readonly string serialNumber;
267 private readonly Manufacturer manufacturer;
268 private readonly Model model;
270 private static Manufacturer GetManufacturer(string name) {
273 return Manufacturer.ASRock;
274 case "ASUSTeK Computer INC.":
275 return Manufacturer.ASUS;
277 return Manufacturer.Dell;
280 return Manufacturer.DFI;
282 return Manufacturer.ECS;
283 case "EPoX COMPUTER CO., LTD":
284 return Manufacturer.EPoX;
286 return Manufacturer.EVGA;
287 case "First International Computer, Inc.":
288 return Manufacturer.FIC;
289 case "Gigabyte Technology Co., Ltd.":
290 return Manufacturer.Gigabyte;
291 case "Hewlett-Packard":
292 return Manufacturer.HP;
294 return Manufacturer.IBM;
295 case "MICRO-STAR INTERNATIONAL CO., LTD":
296 case "MICRO-STAR INTERNATIONAL CO.,LTD":
297 return Manufacturer.MSI;
299 return Manufacturer.XFX;
300 case "To be filled by O.E.M.":
301 return Manufacturer.Unknown;
303 return Manufacturer.Unknown;
307 private static Model GetModel(string name) {
310 return Model._880GMH_USB3;
311 case "ASRock AOD790GX/128M":
312 return Model.AOD790GX_128M;
314 return Model.P55_Deluxe;
315 case "Crosshair III Formula":
316 return Model.Crosshair_III_Formula;
317 case "M2N-SLI DELUXE":
318 return Model.M2N_SLI_DELUXE;
320 return Model.M4A79XTD_EVO;
321 case "P5W DH Deluxe":
322 return Model.P5W_DH_Deluxe;
324 return Model.P6X58D_E;
326 return Model.P8P67_PRO;
327 case "Rampage Extreme":
328 return Model.Rampage_Extreme;
329 case "Rampage II GENE":
330 return Model.Rampage_II_GENE;
331 case "LP BI P45-T2RS Elite":
332 return Model.LP_BI_P45_T2RS_Elite;
333 case "LP DK P55-T3eH9":
334 return Model.LP_DK_P55_T3eH9;
336 return Model.A890GXM_A;
337 case "X58 SLI Classified":
338 return Model.X58_SLI_Classified;
340 return Model._965P_S3;
342 return Model.EP45_DS3R;
344 return Model.EP45_UD3R;
346 return Model.EX58_EXTREME;
347 case "GA-MA770T-UD3":
348 return Model.GA_MA770T_UD3;
349 case "GA-MA785GMT-UD2H":
350 return Model.GA_MA785GMT_UD2H;
352 return Model.P35_DS3;
354 return Model.P35_DS3L;
356 return Model.P55_UD4;
358 return Model.P55M_UD4;
360 return Model.X38_DS5;
362 return Model.X58A_UD3R;
363 case "To be filled by O.E.M.":
364 return Model.Unknown;
366 return Model.Unknown;
370 public BaseBoardInformation(string manufacturerName, string productName,
371 string version, string serialNumber)
372 : base(0x02, 0, null, null)
374 this.manufacturerName = manufacturerName;
375 this.manufacturer = GetManufacturer(manufacturerName);
376 this.productName = productName;
377 this.model = GetModel(productName);
378 this.version = version;
379 this.serialNumber = serialNumber;
382 public BaseBoardInformation(byte type, ushort handle, byte[] data,
384 : base(type, handle, data, strings) {
386 this.manufacturerName = GetString(0x04).Trim();
387 this.manufacturer = GetManufacturer(this.manufacturerName);
388 this.productName = GetString(0x05).Trim();
389 this.model = GetModel(this.productName);
390 this.version = GetString(0x06).Trim();
391 this.serialNumber = GetString(0x07).Trim();
394 public string ManufacturerName { get { return manufacturerName; } }
396 public string ProductName { get { return productName; } }
398 public string Version { get { return version; } }
400 public string SerialNumber { get { return serialNumber; } }
402 public Manufacturer Manufacturer { get { return manufacturer; } }
404 public Model Model { get { return model; } }