Hardware/Mainboard/SMBIOS.cs
author moel.mich
Tue, 15 Mar 2011 17:55:11 +0000
changeset 259 d83e927ee9d2
parent 221 a950ba30d4dd
child 265 961c07a3bd78
permissions -rw-r--r--
Fixed Issue 165.
     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   internal class SMBIOS {
    47 
    48     private readonly byte[] raw;
    49     private readonly Structure[] table;
    50 
    51     private readonly Version version;
    52     private readonly BIOSInformation biosInformation;
    53     private readonly BaseBoardInformation baseBoardInformation;
    54 
    55     private static string ReadSysFS(string path) {
    56       try {
    57         if (File.Exists(path)) {
    58           using (StreamReader reader = new StreamReader(path)) 
    59             return reader.ReadLine();
    60         } else {
    61           return null;
    62         }
    63       } catch {
    64         return null;
    65       }
    66     }
    67     
    68     public SMBIOS() {
    69       int p = (int)Environment.OSVersion.Platform;
    70       if ((p == 4) || (p == 128)) {
    71         this.raw = null;
    72         this.table = null;
    73         
    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);
    79         
    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);
    83         
    84       } else {              
    85         List<Structure> structureList = new List<Structure>();
    86 
    87         raw = null;
    88         byte majorVersion = 0;
    89         byte minorVersion = 0;
    90         try {
    91           ManagementObjectCollection collection;
    92           using (ManagementObjectSearcher searcher = 
    93             new ManagementObjectSearcher("root\\WMI", 
    94               "SELECT * FROM MSSMBios_RawSMBiosTables")) {
    95             collection = searcher.Get();
    96           }
    97          
    98           foreach (ManagementObject mo in collection) {
    99             raw = (byte[])mo["SMBiosData"];
   100             majorVersion = (byte)mo["SmbiosMajorVersion"];
   101             minorVersion = (byte)mo["SmbiosMinorVersion"];            
   102             break;
   103           }
   104         } catch { }
   105 
   106         if (majorVersion > 0 || minorVersion > 0)
   107           version = new Version(majorVersion, minorVersion);
   108   
   109         if (raw != null && raw.Length > 0) {
   110           int offset = 0;
   111           byte type = raw[offset];
   112           while (offset + 4 < raw.Length && type != 127) {
   113   
   114             type = raw[offset];
   115             int length = raw[offset + 1];
   116             ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
   117   
   118             if (offset + length > raw.Length)
   119               break;
   120             byte[] data = new byte[length];
   121             Array.Copy(raw, offset, data, 0, length);
   122             offset += length;
   123   
   124             List<string> stringsList = new List<string>();
   125             if (offset < raw.Length && raw[offset] == 0)
   126               offset++;
   127   
   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++;
   132               }
   133               offset++;
   134               stringsList.Add(sb.ToString());
   135             }
   136             offset++;
   137             switch (type) {
   138               case 0x00:
   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;
   147             }
   148           }
   149         }
   150               
   151         table = structureList.ToArray();
   152       }
   153     }
   154 
   155     public string GetReport() {
   156       StringBuilder r = new StringBuilder();
   157 
   158       if (version != null) {
   159         r.Append("SMBIOS Version: "); r.AppendLine(version.ToString(2));
   160         r.AppendLine();
   161       }
   162 
   163       if (BIOS != null) {
   164         r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
   165         r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
   166         r.AppendLine();
   167       }
   168 
   169       if (Board != null) {
   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);
   176         r.AppendLine();
   177       }
   178 
   179       if (raw != null) {
   180         string base64 = Convert.ToBase64String(raw);
   181         r.AppendLine("SMBIOS Table");
   182         r.AppendLine();
   183 
   184         for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   185           r.Append(" ");
   186           for (int j = 0; j < 0x40; j++) {
   187             int index = (i << 6) | j;
   188             if (index < base64.Length) {              
   189               r.Append(base64[index]);
   190             }
   191           }
   192           r.AppendLine();
   193         }
   194         r.AppendLine();
   195       }
   196 
   197       return r.ToString();
   198     }
   199 
   200     public BIOSInformation BIOS {
   201       get { return biosInformation; }
   202     }
   203 
   204     public BaseBoardInformation Board {
   205       get { return baseBoardInformation; }
   206     }
   207 
   208     public class Structure {
   209       private readonly byte type;
   210       private readonly ushort handle;
   211 
   212       private readonly byte[] data;
   213       private readonly string[] strings;
   214 
   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];
   219         else
   220           return "";
   221       }
   222 
   223       public Structure(byte type, ushort handle, byte[] data, string[] strings) 
   224       {
   225         this.type = type;
   226         this.handle = handle;
   227         this.data = data;
   228         this.strings = strings;
   229       }
   230 
   231       public byte Type { get { return type; } }
   232 
   233       public ushort Handle { get { return handle; } }
   234     }
   235       
   236     public class BIOSInformation : Structure {
   237 
   238       private readonly string vendor;
   239       private readonly string version;
   240       
   241       public BIOSInformation(string vendor, string version) 
   242         : base (0x00, 0, null, null) 
   243       {
   244         this.vendor = vendor;
   245         this.version = version;
   246       }
   247       
   248       public BIOSInformation(byte type, ushort handle, byte[] data,
   249         string[] strings)
   250         : base(type, handle, data, strings) 
   251       {
   252         this.vendor = GetString(0x04);
   253         this.version = GetString(0x05);
   254       }
   255 
   256       public string Vendor { get { return vendor; } }
   257 
   258       public string Version { get { return version; } }
   259     }
   260 
   261     public class BaseBoardInformation : Structure {
   262 
   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;
   269 
   270       private static Manufacturer GetManufacturer(string name) {               
   271         switch (name) {
   272           case "ASRock":
   273             return Manufacturer.ASRock;
   274           case "ASUSTeK Computer INC.":
   275             return Manufacturer.ASUS;
   276           case "Dell Inc.":
   277             return Manufacturer.Dell;
   278           case "DFI":
   279           case "DFI Inc.":            
   280             return Manufacturer.DFI;
   281           case "ECS":
   282             return Manufacturer.ECS;
   283           case "EPoX COMPUTER CO., LTD":
   284             return Manufacturer.EPoX;
   285           case "EVGA":
   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;
   293           case "IBM":
   294             return  Manufacturer.IBM;
   295           case "MICRO-STAR INTERNATIONAL CO., LTD":
   296           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   297             return  Manufacturer.MSI;
   298           case "XFX":
   299             return  Manufacturer.XFX;
   300           case "To be filled by O.E.M.":
   301             return  Manufacturer.Unknown;
   302           default:
   303             return  Manufacturer.Unknown;
   304         }
   305       }
   306 
   307       private static Model GetModel(string name) {
   308         switch (name) {
   309           case "880GMH/USB3":
   310             return Model._880GMH_USB3;
   311           case "ASRock AOD790GX/128M":
   312             return Model.AOD790GX_128M;
   313           case "P55 Deluxe":
   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;
   319           case "M4A79XTD EVO":
   320             return Model.M4A79XTD_EVO;
   321           case "P5W DH Deluxe":
   322             return Model.P5W_DH_Deluxe;
   323           case "P6X58D-E":
   324             return Model.P6X58D_E;
   325           case "Rampage Extreme":
   326             return Model.Rampage_Extreme;
   327           case "Rampage II GENE":
   328             return Model.Rampage_II_GENE;
   329           case "LP BI P45-T2RS Elite":
   330             return Model.LP_BI_P45_T2RS_Elite;
   331           case "LP DK P55-T3eH9":
   332             return Model.LP_DK_P55_T3eH9;
   333           case "A890GXM-A":
   334             return Model.A890GXM_A;
   335           case "X58 SLI Classified":
   336             return Model.X58_SLI_Classified;
   337           case "965P-S3":
   338             return Model._965P_S3;
   339           case "EP45-DS3R":
   340             return Model.EP45_DS3R;
   341           case "EP45-UD3R":
   342             return Model.EP45_UD3R;
   343           case "EX58-EXTREME":
   344             return Model.EX58_EXTREME;
   345           case "GA-MA770T-UD3":
   346             return Model.GA_MA770T_UD3;
   347           case "GA-MA785GMT-UD2H":
   348             return Model.GA_MA785GMT_UD2H;
   349           case "P35-DS3":
   350             return Model.P35_DS3;
   351           case "P35-DS3L":
   352             return Model.P35_DS3L;
   353           case "P55-UD4":
   354             return Model.P55_UD4;
   355           case "P55M-UD4":
   356             return Model.P55M_UD4;
   357           case "X38-DS5":
   358             return Model.X38_DS5;
   359           case "X58A-UD3R":
   360             return Model.X58A_UD3R;
   361           case "To be filled by O.E.M.":
   362             return Model.Unknown;
   363           default:
   364             return Model.Unknown;
   365         }
   366       }
   367       
   368       public BaseBoardInformation(string manufacturerName, string productName, 
   369         string version, string serialNumber) 
   370         : base(0x02, 0, null, null) 
   371       {
   372         this.manufacturerName = manufacturerName;
   373         this.manufacturer = GetManufacturer(manufacturerName);
   374         this.productName = productName;
   375         this.model = GetModel(productName);
   376         this.version = version;
   377         this.serialNumber = serialNumber;
   378       }
   379       
   380       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   381         string[] strings)
   382         : base(type, handle, data, strings) {
   383 
   384         this.manufacturerName = GetString(0x04).Trim();
   385         this.manufacturer = GetManufacturer(this.manufacturerName);
   386         this.productName = GetString(0x05).Trim();
   387         this.model = GetModel(this.productName);
   388         this.version = GetString(0x06).Trim();
   389         this.serialNumber = GetString(0x07).Trim();               
   390       }
   391       
   392       public string ManufacturerName { get { return manufacturerName; } }
   393 
   394       public string ProductName { get { return productName; } }
   395 
   396       public string Version { get { return version; } }
   397 
   398       public string SerialNumber { get { return serialNumber; } }
   399 
   400       public Manufacturer Manufacturer { get { return manufacturer; } }
   401 
   402       public Model Model { get { return model; } }
   403 
   404     }
   405   }
   406 }