Hardware/Mainboard/SMBIOS.cs
author moel.mich
Tue, 21 Sep 2010 20:32:36 +0000
changeset 195 0ee888c485d5
parent 177 510f27ad65ac
child 220 e51749b206ee
permissions -rw-r--r--
Refactored some of the hardware monitoring code and fixed a few code inspection warnings.
     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 BIOSInformation biosInformation;
    52     private readonly BaseBoardInformation baseBoardInformation;
    53 
    54     private static 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)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           using (ManagementObjectSearcher searcher = 
    90             new ManagementObjectSearcher("root\\WMI", 
    91               "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables")) {
    92             collection = searcher.Get();
    93           }
    94          
    95           foreach (ManagementObject mo in collection) {
    96             raw = (byte[])mo["SMBiosData"];
    97             break;
    98           }
    99         } catch { }
   100   
   101         if (raw != null && raw.Length > 0) {
   102           int offset = 0;
   103           byte type = raw[offset];
   104           while (offset + 4 < raw.Length && type != 127) {
   105   
   106             type = raw[offset];
   107             int length = raw[offset + 1];
   108             ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
   109   
   110             if (offset + length > raw.Length)
   111               break;
   112             byte[] data = new byte[length];
   113             Array.Copy(raw, offset, data, 0, length);
   114             offset += length;
   115   
   116             List<string> stringsList = new List<string>();
   117             if (offset < raw.Length && raw[offset] == 0)
   118               offset++;
   119   
   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++;
   124               }
   125               offset++;
   126               stringsList.Add(sb.ToString());
   127             }
   128             offset++;
   129             switch (type) {
   130               case 0x00:
   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;
   139             }
   140           }
   141         }
   142               
   143         table = structureList.ToArray();
   144       }
   145     }
   146 
   147     public string GetReport() {
   148       StringBuilder r = new StringBuilder();
   149 
   150       if (BIOS != null) {
   151         r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
   152         r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
   153         r.AppendLine();
   154       }
   155 
   156       if (Board != null) {
   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);
   163         r.AppendLine();
   164       }
   165 
   166       if (raw != null) {
   167         string base64 = Convert.ToBase64String(raw);
   168         r.AppendLine("SMBIOS Table");
   169         r.AppendLine();
   170 
   171         for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   172           r.Append(" ");
   173           for (int j = 0; j < 0x40; j++) {
   174             int index = (i << 6) | j;
   175             if (index < base64.Length) {              
   176               r.Append(base64[index]);
   177             }
   178           }
   179           r.AppendLine();
   180         }
   181         r.AppendLine();
   182       }
   183 
   184       return r.ToString();
   185     }
   186 
   187     public BIOSInformation BIOS {
   188       get { return biosInformation; }
   189     }
   190 
   191     public BaseBoardInformation Board {
   192       get { return baseBoardInformation; }
   193     }
   194 
   195     public class Structure {
   196       private readonly byte type;
   197       private readonly ushort handle;
   198 
   199       private readonly byte[] data;
   200       private readonly string[] strings;
   201 
   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];
   206         else
   207           return "";
   208       }
   209 
   210       public Structure(byte type, ushort handle, byte[] data, string[] strings) 
   211       {
   212         this.type = type;
   213         this.handle = handle;
   214         this.data = data;
   215         this.strings = strings;
   216       }
   217 
   218       public byte Type { get { return type; } }
   219 
   220       public ushort Handle { get { return handle; } }
   221     }
   222       
   223     public class BIOSInformation : Structure {
   224 
   225       private readonly string vendor;
   226       private readonly string version;
   227       
   228       public BIOSInformation(string vendor, string version) 
   229         : base (0x00, 0, null, null) 
   230       {
   231         this.vendor = vendor;
   232         this.version = version;
   233       }
   234       
   235       public BIOSInformation(byte type, ushort handle, byte[] data,
   236         string[] strings)
   237         : base(type, handle, data, strings) 
   238       {
   239         this.vendor = GetString(0x04);
   240         this.version = GetString(0x05);
   241       }
   242 
   243       public string Vendor { get { return vendor; } }
   244 
   245       public string Version { get { return version; } }
   246     }
   247 
   248     public class BaseBoardInformation : Structure {
   249 
   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;
   256 
   257       private static Manufacturer GetManufacturer(string name) {               
   258         switch (name) {
   259           case "ASRock":
   260             return Manufacturer.ASRock;
   261           case "ASUSTeK Computer INC.":
   262             return Manufacturer.ASUS;
   263           case "Dell Inc.":
   264             return Manufacturer.Dell;
   265           case "DFI":
   266           case "DFI Inc.":            
   267             return Manufacturer.DFI;
   268           case "ECS":
   269             return Manufacturer.ECS;
   270           case "EPoX COMPUTER CO., LTD":
   271             return Manufacturer.EPoX;
   272           case "EVGA":
   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;
   280           case "IBM":
   281             return  Manufacturer.IBM;
   282           case "MICRO-STAR INTERNATIONAL CO., LTD":
   283           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   284             return  Manufacturer.MSI;
   285           case "XFX":
   286             return  Manufacturer.XFX;
   287           case "To be filled by O.E.M.":
   288             return  Manufacturer.Unknown;
   289           default:
   290             return  Manufacturer.Unknown;
   291         }
   292       }
   293 
   294       private static Model GetModel(string name) {
   295         switch (name) {
   296           case "880GMH/USB3":
   297             return Model._880GMH_USB3;
   298           case "Crosshair III Formula":
   299             return Model.Crosshair_III_Formula;
   300           case "M2N-SLI DELUXE":
   301             return Model.M2N_SLI_DELUXE;
   302           case "M4A79XTD EVO":
   303             return Model.M4A79XTD_EVO;
   304           case "P5W DH Deluxe":
   305             return Model.P5W_DH_Deluxe;
   306           case "P6X58D-E":
   307             return Model.P6X58D_E;
   308           case "Rampage Extreme":
   309             return Model.Rampage_Extreme;
   310           case "Rampage II GENE":
   311             return Model.Rampage_II_GENE;
   312           case "LP BI P45-T2RS Elite":
   313             return Model.LP_BI_P45_T2RS_Elite;
   314           case "LP DK P55-T3eH9":
   315             return Model.LP_DK_P55_T3eH9;
   316           case "A890GXM-A":
   317             return Model.A890GXM_A;
   318           case "X58 SLI Classified":
   319             return Model.X58_SLI_Classified;
   320           case "965P-S3":
   321             return Model._965P_S3;
   322           case "EP45-DS3R":
   323             return Model.EP45_DS3R;
   324           case "EP45-UD3R":
   325             return Model.EP45_UD3R;
   326           case "EX58-EXTREME":
   327             return Model.EX58_EXTREME;
   328           case "GA-MA770T-UD3":
   329             return Model.GA_MA770T_UD3;
   330           case "GA-MA785GMT-UD2H":
   331             return Model.GA_MA785GMT_UD2H;
   332           case "P35-DS3":
   333             return Model.P35_DS3;
   334           case "P35-DS3L":
   335             return Model.P35_DS3L;
   336           case "P55-UD4":
   337             return Model.P55_UD4;
   338           case "P55M-UD4":
   339             return Model.P55M_UD4;
   340           case "X38-DS5":
   341             return Model.X38_DS5;
   342           case "X58A-UD3R":
   343             return Model.X58A_UD3R;
   344           case "To be filled by O.E.M.":
   345             return Model.Unknown;
   346           default:
   347             return Model.Unknown;
   348         }
   349       }
   350       
   351       public BaseBoardInformation(string manufacturerName, string productName, 
   352         string version, string serialNumber) 
   353         : base(0x02, 0, null, null) 
   354       {
   355         this.manufacturerName = manufacturerName;
   356         this.manufacturer = GetManufacturer(manufacturerName);
   357         this.productName = productName;
   358         this.model = GetModel(productName);
   359         this.version = version;
   360         this.serialNumber = serialNumber;
   361       }
   362       
   363       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   364         string[] strings)
   365         : base(type, handle, data, strings) {
   366 
   367         this.manufacturerName = GetString(0x04).Trim();
   368         this.manufacturer = GetManufacturer(this.manufacturerName);
   369         this.productName = GetString(0x05).Trim();
   370         this.model = GetModel(this.productName);
   371         this.version = GetString(0x06).Trim();
   372         this.serialNumber = GetString(0x07).Trim();               
   373       }
   374       
   375       public string ManufacturerName { get { return manufacturerName; } }
   376 
   377       public string ProductName { get { return productName; } }
   378 
   379       public string Version { get { return version; } }
   380 
   381       public string SerialNumber { get { return serialNumber; } }
   382 
   383       public Manufacturer Manufacturer { get { return manufacturer; } }
   384 
   385       public Model Model { get { return model; } }
   386 
   387     }
   388   }
   389 }