Hardware/Mainboard/SMBIOS.cs
author moel.mich
Sun, 04 Jul 2010 12:12:37 +0000
changeset 150 522da3b8cb1a
parent 144 44a688398012
child 152 98187e7a08b2
permissions -rw-r--r--
Fixed Issue 66.
     1 /*
     2   
     3   Version: MPL 1.1/GPL 2.0/LGPL 2.1
     4 
     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
     8  
     9   http://www.mozilla.org/MPL/
    10 
    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.
    14 
    15   The Original Code is the Open Hardware Monitor code.
    16 
    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.
    21 
    22   Contributor(s):
    23 
    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.
    35  
    36 */
    37 
    38 using System;
    39 using System.Collections.Generic;
    40 using System.IO;
    41 using System.Management;
    42 using System.Text;
    43 
    44 namespace OpenHardwareMonitor.Hardware.Mainboard {
    45 
    46   public class SMBIOS {
    47 
    48     private byte[] raw;
    49     private Structure[] table;
    50 
    51     private BIOSInformation biosInformation = null;
    52     private BaseBoardInformation baseBoardInformation = null;
    53 
    54     private string ReadSysFS(string path) {
    55       try {
    56         if (File.Exists(path)) {
    57           using (StreamReader reader = new StreamReader(path)) 
    58             return reader.ReadLine();
    59         } else {
    60           return null;
    61         }
    62       } catch {
    63         return null;
    64       }
    65     }
    66     
    67     public SMBIOS() {
    68       int p = (int)System.Environment.OSVersion.Platform;
    69       if ((p == 4) || (p == 128)) {
    70         this.raw = null;
    71         this.table = null;
    72         
    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);
    78         
    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);
    82         
    83       } else {              
    84         List<Structure> structureList = new List<Structure>();
    85 
    86         raw = null;
    87         try {
    88           ManagementObjectCollection collection = 
    89             new ManagementObjectSearcher("root\\WMI", 
    90               "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables").Get();
    91          
    92           foreach (ManagementObject mo in collection) {
    93             raw = (byte[])mo["SMBiosData"];
    94             break;
    95           }
    96         } catch { }
    97   
    98         if (raw != null && raw.Length > 0) {
    99           int offset = 0;
   100           byte type = raw[offset];
   101           while (offset + 4 < raw.Length && type != 127) {
   102   
   103             type = raw[offset];
   104             int length = raw[offset + 1];
   105             ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
   106   
   107             if (offset + length > raw.Length)
   108               break;
   109             byte[] data = new byte[length];
   110             Array.Copy(raw, offset, data, 0, length);
   111             offset += length;
   112   
   113             List<string> stringsList = new List<string>();
   114             if (offset < raw.Length && raw[offset] == 0)
   115               offset++;
   116   
   117             while (offset < raw.Length && raw[offset] != 0) {
   118               StringBuilder sb = new StringBuilder();
   119               while (offset < raw.Length && raw[offset] != 0) {
   120                 sb.Append((char)raw[offset]); offset++;
   121               }
   122               offset++;
   123               stringsList.Add(sb.ToString());
   124             }
   125             offset++;
   126             switch (type) {
   127               case 0x00:
   128                 this.biosInformation = new BIOSInformation(
   129                   type, handle, data, stringsList.ToArray());
   130                 structureList.Add(this.biosInformation); break;
   131               case 0x02: this.baseBoardInformation = new BaseBoardInformation(
   132                   type, handle, data, stringsList.ToArray());
   133                 structureList.Add(this.baseBoardInformation); break;
   134               default: structureList.Add(new Structure(
   135                 type, handle, data, stringsList.ToArray())); break;
   136             }
   137           }
   138         }
   139               
   140         table = structureList.ToArray();
   141       }
   142     }
   143 
   144     public string GetReport() {
   145       StringBuilder r = new StringBuilder();
   146 
   147       if (biosInformation != null) {
   148         r.Append("BIOS Vendor: "); r.AppendLine(biosInformation.Vendor);
   149         r.Append("BIOS Version: "); r.AppendLine(biosInformation.Version);
   150         r.AppendLine();
   151       }
   152 
   153       if (baseBoardInformation != null) {
   154         r.Append("Mainboard Manufacturer: ");
   155         r.AppendLine(baseBoardInformation.ManufacturerName);
   156         r.Append("Mainboard Name: ");
   157         r.AppendLine(baseBoardInformation.ProductName);
   158         r.AppendLine();
   159       }
   160 
   161       if (raw != null) {
   162         string base64 = Convert.ToBase64String(raw);
   163         r.AppendLine("SMBIOS Table");
   164         r.AppendLine();
   165 
   166         for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   167           r.Append(" ");
   168           for (int j = 0; j < 0x40; j++) {
   169             int index = (i << 6) | j;
   170             if (index < base64.Length) {              
   171               r.Append(base64[index]);
   172             }
   173           }
   174           r.AppendLine();
   175         }
   176         r.AppendLine();
   177       }
   178 
   179       return r.ToString();
   180     }
   181 
   182     public BIOSInformation BIOS {
   183       get { return biosInformation; }
   184     }
   185 
   186     public BaseBoardInformation Board {
   187       get { return baseBoardInformation; }
   188     }
   189 
   190     public class Structure {
   191       private byte type;
   192       private ushort handle;
   193 
   194       private byte[] data;
   195       private string[] strings;
   196 
   197       protected string GetString(int offset) {
   198         if (offset < data.Length && data[offset] > 0 &&
   199          data[offset] <= strings.Length)
   200           return strings[data[offset] - 1];
   201         else
   202           return "";
   203       }
   204 
   205       public Structure(byte type, ushort handle, byte[] data, string[] strings) 
   206       {
   207         this.type = type;
   208         this.handle = handle;
   209         this.data = data;
   210         this.strings = strings;
   211       }
   212 
   213       public byte Type { get { return type; } }
   214 
   215       public ushort Handle { get { return handle; } }
   216     }
   217       
   218     public class BIOSInformation : Structure {
   219 
   220       private string vendor;
   221       private string version;
   222       
   223       public BIOSInformation(string vendor, string version) 
   224         : base (0x00, 0, null, null) 
   225       {
   226         this.vendor = vendor;
   227         this.version = version;
   228       }
   229       
   230       public BIOSInformation(byte type, ushort handle, byte[] data,
   231         string[] strings)
   232         : base(type, handle, data, strings) 
   233       {
   234         this.vendor = GetString(0x04);
   235         this.version = GetString(0x05);
   236       }
   237 
   238       public string Vendor { get { return vendor; } }
   239 
   240       public string Version { get { return version; } }
   241     }
   242 
   243     public class BaseBoardInformation : Structure {
   244 
   245       private string manufacturerName;
   246       private string productName;
   247       private string version;
   248       private string serialNumber;
   249       private Manufacturer manufacturer;
   250       private Model model;
   251 
   252       private void SetManufacturerName(string manufacturerName) {
   253         this.manufacturerName = manufacturerName;
   254         
   255         switch (manufacturerName) {
   256           case "ASUSTeK Computer INC.":
   257             manufacturer = Manufacturer.ASUS; break;
   258           case "DFI":
   259           case "DFI Inc.":            
   260             manufacturer = Manufacturer.DFI; break;
   261           case "EPoX COMPUTER CO., LTD":
   262             manufacturer = Manufacturer.EPoX; break;
   263           case "EVGA":
   264             manufacturer = Manufacturer.EVGA; break;
   265           case "Gigabyte Technology Co., Ltd.":
   266             manufacturer = Manufacturer.Gigabyte; break;
   267           case "IBM":
   268             manufacturer = Manufacturer.IBM; break;
   269           case "MICRO-STAR INTERNATIONAL CO., LTD":
   270           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   271             manufacturer = Manufacturer.MSI; break;
   272           default:
   273             manufacturer = Manufacturer.Unknown; break;
   274         }
   275       }
   276       
   277       private void SetProductName(string productName) {
   278         this.productName = productName;
   279         
   280         switch (productName) {
   281           case "Crosshair III Formula":
   282             model = Model.Crosshair_III_Formula; break;
   283           case "M2N-SLI DELUXE":
   284             model = Model.M2N_SLI_DELUXE; break;
   285           case "M4A79XTD EVO":
   286             model = Model.M4A79XTD_EVO; break;
   287           case "P5W DH Deluxe":
   288             model = Model.P5W_DH_Deluxe; break;
   289           case "LP BI P45-T2RS Elite":
   290             model = Model.LP_BI_P45_T2RS_Elite; break;
   291           case "LP DK P55-T3eH9":
   292             model = Model.LP_DK_P55_T3eH9; break;
   293           case "X58 SLI Classified":
   294             model = Model.X58_SLI_Classified; break;
   295           case "965P-S3":
   296             model = Model._965P_S3; break;
   297           case "EP45-DS3R":
   298             model = Model.EP45_DS3R; break;
   299           case "EP45-UD3R":
   300             model = Model.EP45_UD3R; break;
   301           case "EX58-EXTREME":
   302             model = Model.EX58_EXTREME; break;
   303           case "GA-MA785GMT-UD2H":
   304             model = Model.GA_MA785GMT_UD2H; break;
   305           case "P35-DS3":
   306             model = Model.P35_DS3; break;
   307           case "P35-DS3L":
   308             model = Model.P35_DS3L; break;
   309           case "P55-UD4":
   310             model = Model.P55_UD4; break;
   311           case "X38-DS5":
   312             model = Model.X38_DS5; break;
   313           case "X58A-UD3R":
   314             model = Model.X58A_UD3R; break;
   315           default:
   316             model = Model.Unknown; break;
   317         }
   318       }
   319       
   320       public BaseBoardInformation(string manufacturerName, string productName, 
   321         string version, string serialNumber) 
   322         : base(0x02, 0, null, null) 
   323       {        
   324         SetManufacturerName(manufacturerName);
   325         SetProductName(productName);
   326         this.version = version;
   327         this.serialNumber = serialNumber;
   328       }
   329       
   330       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   331         string[] strings)
   332         : base(type, handle, data, strings) {
   333 
   334         SetManufacturerName(GetString(0x04).Trim());
   335         SetProductName(GetString(0x05).Trim());
   336         this.version = GetString(0x06).Trim();
   337         this.serialNumber = GetString(0x07).Trim();               
   338       }
   339       
   340       public string ManufacturerName { get { return manufacturerName; } }
   341 
   342       public string ProductName { get { return productName; } }
   343 
   344       public string Version { get { return version; } }
   345 
   346       public string SerialNumber { get { return serialNumber; } }
   347 
   348       public Manufacturer Manufacturer { get { return manufacturer; } }
   349 
   350       public Model Model { get { return model; } }
   351 
   352     }
   353   }
   354 }