Hardware/Mainboard/SMBIOS.cs
author moel.mich
Tue, 02 Aug 2011 21:05:17 +0000
changeset 319 35cda448fc5f
parent 312 35fb76b88d94
child 320 df3493f75225
permissions -rw-r--r--
Added initial support for the ITE IT8772E super I/O chip.
     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-2011
    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 "Alienware":
   273             return Manufacturer.Alienware;
   274           case "Apple Inc.":
   275             return Manufacturer.Apple;
   276           case "ASRock":
   277             return Manufacturer.ASRock;
   278           case "ASUSTeK Computer INC.":
   279             return Manufacturer.ASUS;
   280           case "Dell Inc.":
   281             return Manufacturer.Dell;
   282           case "DFI":
   283           case "DFI Inc.":            
   284             return Manufacturer.DFI;
   285           case "ECS":
   286             return Manufacturer.ECS;
   287           case "EPoX COMPUTER CO., LTD":
   288             return Manufacturer.EPoX;
   289           case "EVGA":
   290             return  Manufacturer.EVGA;
   291           case "First International Computer, Inc.":
   292             return Manufacturer.FIC;
   293           case "FUJITSU":
   294           case "FUJITSU SIEMENS":
   295             return Manufacturer.Fujitsu;
   296           case "Gigabyte Technology Co., Ltd.":
   297             return  Manufacturer.Gigabyte;
   298           case "Hewlett-Packard":
   299             return  Manufacturer.HP;
   300           case "IBM":
   301             return  Manufacturer.IBM;
   302           case "Intel":
   303           case "Intel Corp.":
   304           case "Intel Corporation":
   305           case "INTEL Corporation":
   306             return Manufacturer.Intel;   
   307           case "Lenovo":
   308           case "LENOVO":
   309             return Manufacturer.Lenovo;
   310           case "Micro-Star International":
   311           case "MICRO-STAR INTERNATIONAL CO., LTD":
   312           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   313           case "MSI":
   314             return Manufacturer.MSI;
   315           case "Shuttle":
   316             return Manufacturer.Shuttle;
   317           case "Supermicro":
   318             return Manufacturer.Supermicro;
   319           case "TOSHIBA":
   320             return Manufacturer.Toshiba;
   321           case "XFX":
   322             return  Manufacturer.XFX;
   323           case "To be filled by O.E.M.":
   324             return  Manufacturer.Unknown;
   325           default:
   326             return  Manufacturer.Unknown;
   327         }
   328       }
   329 
   330       private static Model GetModel(string name) {
   331         switch (name) {
   332           case "880GMH/USB3":
   333             return Model._880GMH_USB3;
   334           case "ASRock AOD790GX/128M":
   335             return Model.AOD790GX_128M;
   336           case "P55 Deluxe":
   337             return Model.P55_Deluxe;
   338           case "Crosshair III Formula":
   339             return Model.Crosshair_III_Formula;
   340           case "M2N-SLI DELUXE":
   341             return Model.M2N_SLI_DELUXE;
   342           case "M4A79XTD EVO":
   343             return Model.M4A79XTD_EVO;
   344           case "P5W DH Deluxe":
   345             return Model.P5W_DH_Deluxe;
   346           case "P6X58D-E":
   347             return Model.P6X58D_E;
   348           case "P8P67":
   349             return Model.P8P67;
   350           case "P8P67 EVO":
   351             return Model.P8P67_EVO;
   352           case "P8P67 PRO":
   353             return Model.P8P67_PRO;
   354           case "P8P67-M PRO":
   355             return Model.P8P67_M_PRO;
   356           case "Rampage Extreme":
   357             return Model.Rampage_Extreme;
   358           case "Rampage II GENE":
   359             return Model.Rampage_II_GENE;
   360           case "LP BI P45-T2RS Elite":
   361             return Model.LP_BI_P45_T2RS_Elite;
   362           case "LP DK P55-T3eH9":
   363             return Model.LP_DK_P55_T3eH9;
   364           case "A890GXM-A":
   365             return Model.A890GXM_A;
   366           case "X58 SLI Classified":
   367             return Model.X58_SLI_Classified;
   368           case "965P-S3":
   369             return Model._965P_S3;
   370           case "EP45-DS3R":
   371             return Model.EP45_DS3R;
   372           case "EP45-UD3R":
   373             return Model.EP45_UD3R;
   374           case "EX58-EXTREME":
   375             return Model.EX58_EXTREME;
   376           case "GA-MA770T-UD3":
   377             return Model.GA_MA770T_UD3;
   378           case "GA-MA785GMT-UD2H":
   379             return Model.GA_MA785GMT_UD2H;
   380           case "H67A-UD3H-B3":
   381             return Model.H67A_UD3H_B3;
   382           case "P35-DS3":
   383             return Model.P35_DS3;
   384           case "P35-DS3L":
   385             return Model.P35_DS3L;
   386           case "P55-UD4":
   387             return Model.P55_UD4;
   388           case "P55M-UD4":
   389             return Model.P55M_UD4;
   390           case "P67A-UD4-B3":
   391             return Model.P67A_UD4_B3;
   392           case "X38-DS5":
   393             return Model.X38_DS5;
   394           case "X58A-UD3R":
   395             return Model.X58A_UD3R;
   396           case "Z68X-UD7-B3":
   397             return Model.Z68X_UD7_B3;
   398           case "Base Board Product Name":
   399           case "To be filled by O.E.M.":
   400             return Model.Unknown;
   401           default:
   402             return Model.Unknown;
   403         }
   404       }
   405       
   406       public BaseBoardInformation(string manufacturerName, string productName, 
   407         string version, string serialNumber) 
   408         : base(0x02, 0, null, null) 
   409       {
   410         this.manufacturerName = manufacturerName;
   411         this.manufacturer = GetManufacturer(manufacturerName);
   412         this.productName = productName;
   413         this.model = GetModel(productName);
   414         this.version = version;
   415         this.serialNumber = serialNumber;
   416       }
   417       
   418       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   419         string[] strings)
   420         : base(type, handle, data, strings) {
   421 
   422         this.manufacturerName = GetString(0x04).Trim();
   423         this.manufacturer = GetManufacturer(this.manufacturerName);
   424         this.productName = GetString(0x05).Trim();
   425         this.model = GetModel(this.productName);
   426         this.version = GetString(0x06).Trim();
   427         this.serialNumber = GetString(0x07).Trim();               
   428       }
   429       
   430       public string ManufacturerName { get { return manufacturerName; } }
   431 
   432       public string ProductName { get { return productName; } }
   433 
   434       public string Version { get { return version; } }
   435 
   436       public string SerialNumber { get { return serialNumber; } }
   437 
   438       public Manufacturer Manufacturer { get { return manufacturer; } }
   439 
   440       public Model Model { get { return model; } }
   441 
   442     }
   443   }
   444 }