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-2010
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 BIOSInformation biosInformation;
52 private readonly BaseBoardInformation baseBoardInformation;
54 private static string ReadSysFS(string path) {
56 if (File.Exists(path)) {
57 using (StreamReader reader = new StreamReader(path))
58 return reader.ReadLine();
68 int p = (int)Environment.OSVersion.Platform;
69 if ((p == 4) || (p == 128)) {
73 string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
74 string boardName = ReadSysFS("/sys/class/dmi/id/board_name");
75 string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");
76 this.baseBoardInformation = new BaseBoardInformation(
77 boardVendor, boardName, boardVersion, null);
79 string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
80 string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
81 this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
84 List<Structure> structureList = new List<Structure>();
88 ManagementObjectCollection collection;
89 using (ManagementObjectSearcher searcher =
90 new ManagementObjectSearcher("root\\WMI",
91 "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables")) {
92 collection = searcher.Get();
95 foreach (ManagementObject mo in collection) {
96 raw = (byte[])mo["SMBiosData"];
101 if (raw != null && raw.Length > 0) {
103 byte type = raw[offset];
104 while (offset + 4 < raw.Length && type != 127) {
107 int length = raw[offset + 1];
108 ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
110 if (offset + length > raw.Length)
112 byte[] data = new byte[length];
113 Array.Copy(raw, offset, data, 0, length);
116 List<string> stringsList = new List<string>();
117 if (offset < raw.Length && raw[offset] == 0)
120 while (offset < raw.Length && raw[offset] != 0) {
121 StringBuilder sb = new StringBuilder();
122 while (offset < raw.Length && raw[offset] != 0) {
123 sb.Append((char)raw[offset]); offset++;
126 stringsList.Add(sb.ToString());
131 this.biosInformation = new BIOSInformation(
132 type, handle, data, stringsList.ToArray());
133 structureList.Add(this.biosInformation); break;
134 case 0x02: this.baseBoardInformation = new BaseBoardInformation(
135 type, handle, data, stringsList.ToArray());
136 structureList.Add(this.baseBoardInformation); break;
137 default: structureList.Add(new Structure(
138 type, handle, data, stringsList.ToArray())); break;
143 table = structureList.ToArray();
147 public string GetReport() {
148 StringBuilder r = new StringBuilder();
151 r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
152 r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
157 r.Append("Mainboard Manufacturer: ");
158 r.AppendLine(Board.ManufacturerName);
159 r.Append("Mainboard Name: ");
160 r.AppendLine(Board.ProductName);
161 r.Append("Mainboard Version: ");
162 r.AppendLine(Board.Version);
167 string base64 = Convert.ToBase64String(raw);
168 r.AppendLine("SMBIOS Table");
171 for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
173 for (int j = 0; j < 0x40; j++) {
174 int index = (i << 6) | j;
175 if (index < base64.Length) {
176 r.Append(base64[index]);
187 public BIOSInformation BIOS {
188 get { return biosInformation; }
191 public BaseBoardInformation Board {
192 get { return baseBoardInformation; }
195 public class Structure {
196 private readonly byte type;
197 private readonly ushort handle;
199 private readonly byte[] data;
200 private readonly string[] strings;
202 protected string GetString(int offset) {
203 if (offset < data.Length && data[offset] > 0 &&
204 data[offset] <= strings.Length)
205 return strings[data[offset] - 1];
210 public Structure(byte type, ushort handle, byte[] data, string[] strings)
213 this.handle = handle;
215 this.strings = strings;
218 public byte Type { get { return type; } }
220 public ushort Handle { get { return handle; } }
223 public class BIOSInformation : Structure {
225 private readonly string vendor;
226 private readonly string version;
228 public BIOSInformation(string vendor, string version)
229 : base (0x00, 0, null, null)
231 this.vendor = vendor;
232 this.version = version;
235 public BIOSInformation(byte type, ushort handle, byte[] data,
237 : base(type, handle, data, strings)
239 this.vendor = GetString(0x04);
240 this.version = GetString(0x05);
243 public string Vendor { get { return vendor; } }
245 public string Version { get { return version; } }
248 public class BaseBoardInformation : Structure {
250 private readonly string manufacturerName;
251 private readonly string productName;
252 private readonly string version;
253 private readonly string serialNumber;
254 private readonly Manufacturer manufacturer;
255 private readonly Model model;
257 private static Manufacturer GetManufacturer(string name) {
260 return Manufacturer.ASRock;
261 case "ASUSTeK Computer INC.":
262 return Manufacturer.ASUS;
264 return Manufacturer.Dell;
267 return Manufacturer.DFI;
269 return Manufacturer.ECS;
270 case "EPoX COMPUTER CO., LTD":
271 return Manufacturer.EPoX;
273 return Manufacturer.EVGA;
274 case "First International Computer, Inc.":
275 return Manufacturer.FIC;
276 case "Gigabyte Technology Co., Ltd.":
277 return Manufacturer.Gigabyte;
278 case "Hewlett-Packard":
279 return Manufacturer.HP;
281 return Manufacturer.IBM;
282 case "MICRO-STAR INTERNATIONAL CO., LTD":
283 case "MICRO-STAR INTERNATIONAL CO.,LTD":
284 return Manufacturer.MSI;
286 return Manufacturer.XFX;
287 case "To be filled by O.E.M.":
288 return Manufacturer.Unknown;
290 return Manufacturer.Unknown;
294 private static Model GetModel(string name) {
297 return Model._880GMH_USB3;
298 case "ASRock AOD790GX/128M":
299 return Model.AOD790GX_128M;
301 return Model.P55_Deluxe;
302 case "Crosshair III Formula":
303 return Model.Crosshair_III_Formula;
304 case "M2N-SLI DELUXE":
305 return Model.M2N_SLI_DELUXE;
307 return Model.M4A79XTD_EVO;
308 case "P5W DH Deluxe":
309 return Model.P5W_DH_Deluxe;
311 return Model.P6X58D_E;
312 case "Rampage Extreme":
313 return Model.Rampage_Extreme;
314 case "Rampage II GENE":
315 return Model.Rampage_II_GENE;
316 case "LP BI P45-T2RS Elite":
317 return Model.LP_BI_P45_T2RS_Elite;
318 case "LP DK P55-T3eH9":
319 return Model.LP_DK_P55_T3eH9;
321 return Model.A890GXM_A;
322 case "X58 SLI Classified":
323 return Model.X58_SLI_Classified;
325 return Model._965P_S3;
327 return Model.EP45_DS3R;
329 return Model.EP45_UD3R;
331 return Model.EX58_EXTREME;
332 case "GA-MA770T-UD3":
333 return Model.GA_MA770T_UD3;
334 case "GA-MA785GMT-UD2H":
335 return Model.GA_MA785GMT_UD2H;
337 return Model.P35_DS3;
339 return Model.P35_DS3L;
341 return Model.P55_UD4;
343 return Model.P55M_UD4;
345 return Model.X38_DS5;
347 return Model.X58A_UD3R;
348 case "To be filled by O.E.M.":
349 return Model.Unknown;
351 return Model.Unknown;
355 public BaseBoardInformation(string manufacturerName, string productName,
356 string version, string serialNumber)
357 : base(0x02, 0, null, null)
359 this.manufacturerName = manufacturerName;
360 this.manufacturer = GetManufacturer(manufacturerName);
361 this.productName = productName;
362 this.model = GetModel(productName);
363 this.version = version;
364 this.serialNumber = serialNumber;
367 public BaseBoardInformation(byte type, ushort handle, byte[] data,
369 : base(type, handle, data, strings) {
371 this.manufacturerName = GetString(0x04).Trim();
372 this.manufacturer = GetManufacturer(this.manufacturerName);
373 this.productName = GetString(0x05).Trim();
374 this.model = GetModel(this.productName);
375 this.version = GetString(0x06).Trim();
376 this.serialNumber = GetString(0x07).Trim();
379 public string ManufacturerName { get { return manufacturerName; } }
381 public string ProductName { get { return productName; } }
383 public string Version { get { return version; } }
385 public string SerialNumber { get { return serialNumber; } }
387 public Manufacturer Manufacturer { get { return manufacturer; } }
389 public Model Model { get { return model; } }