Hardware/Mainboard/SMBIOS.cs
author paulwerelds
Tue, 21 Sep 2010 10:33:28 +0000
changeset 194 fbf22ccd9d6f
parent 174 51d62ed28ff5
child 195 0ee888c485d5
permissions -rw-r--r--
Fixed some silly mistakes
     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 byte[] raw;
    49     private Structure[] table;
    50 
    51     private BIOSInformation biosInformation = null;
    52     private BaseBoardInformation baseBoardInformation = null;
    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)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           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 byte type;
   197       private ushort handle;
   198 
   199       private byte[] data;
   200       private 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 string vendor;
   226       private 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 string manufacturerName;
   251       private string productName;
   252       private string version;
   253       private string serialNumber;
   254       private Manufacturer manufacturer;
   255       private Model model;
   256 
   257       private void SetManufacturerName(string name) {
   258         this.manufacturerName = name;
   259         
   260         switch (name) {
   261           case "ASRock":
   262             manufacturer = Manufacturer.ASRock; break;
   263           case "ASUSTeK Computer INC.":
   264             manufacturer = Manufacturer.ASUS; break;
   265           case "Dell Inc.":
   266             manufacturer = Manufacturer.Dell; break;
   267           case "DFI":
   268           case "DFI Inc.":            
   269             manufacturer = Manufacturer.DFI; break;
   270           case "ECS":
   271             manufacturer = Manufacturer.ECS; break;
   272           case "EPoX COMPUTER CO., LTD":
   273             manufacturer = Manufacturer.EPoX; break;
   274           case "EVGA":
   275             manufacturer = Manufacturer.EVGA; break;
   276           case "First International Computer, Inc.":
   277             manufacturer = Manufacturer.FIC; break;
   278           case "Gigabyte Technology Co., Ltd.":
   279             manufacturer = Manufacturer.Gigabyte; break;
   280           case "Hewlett-Packard":
   281             manufacturer = Manufacturer.HP; break;
   282           case "IBM":
   283             manufacturer = Manufacturer.IBM; break;
   284           case "MICRO-STAR INTERNATIONAL CO., LTD":
   285           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   286             manufacturer = Manufacturer.MSI; break;
   287           case "XFX":
   288             manufacturer = Manufacturer.XFX; break;
   289           case "To be filled by O.E.M.":
   290             manufacturer = Manufacturer.Unknown; break;
   291           default:
   292             manufacturer = Manufacturer.Unknown; break;
   293         }
   294       }
   295       
   296       private void SetProductName(string name) {
   297         this.productName = name;
   298         
   299         switch (name) {
   300           case "880GMH/USB3":
   301             model = Model._880GMH_USB3; break;
   302           case "Crosshair III Formula":
   303             model = Model.Crosshair_III_Formula; break;
   304           case "M2N-SLI DELUXE":
   305             model = Model.M2N_SLI_DELUXE; break;
   306           case "M4A79XTD EVO":
   307             model = Model.M4A79XTD_EVO; break;
   308           case "P5W DH Deluxe":
   309             model = Model.P5W_DH_Deluxe; break;
   310           case "P6X58D-E":
   311             model = Model.P6X58D_E; break;
   312           case "Rampage Extreme":
   313             model = Model.Rampage_Extreme; break;
   314           case "Rampage II GENE":
   315             model = Model.Rampage_II_GENE; break;
   316           case "LP BI P45-T2RS Elite":
   317             model = Model.LP_BI_P45_T2RS_Elite; break;
   318           case "LP DK P55-T3eH9":
   319             model = Model.LP_DK_P55_T3eH9; break;
   320           case "A890GXM-A":
   321             model = Model.A890GXM_A; break;
   322           case "X58 SLI Classified":
   323             model = Model.X58_SLI_Classified; break;
   324           case "965P-S3":
   325             model = Model._965P_S3; break;
   326           case "EP45-DS3R":
   327             model = Model.EP45_DS3R; break;
   328           case "EP45-UD3R":
   329             model = Model.EP45_UD3R; break;
   330           case "EX58-EXTREME":
   331             model = Model.EX58_EXTREME; break;
   332           case "GA-MA770T-UD3":
   333             model = Model.GA_MA770T_UD3; break;
   334           case "GA-MA785GMT-UD2H":
   335             model = Model.GA_MA785GMT_UD2H; break;
   336           case "P35-DS3":
   337             model = Model.P35_DS3; break;
   338           case "P35-DS3L":
   339             model = Model.P35_DS3L; break;
   340           case "P55-UD4":
   341             model = Model.P55_UD4; break;
   342           case "P55M-UD4":
   343             model = Model.P55M_UD4; break;
   344           case "X38-DS5":
   345             model = Model.X38_DS5; break;
   346           case "X58A-UD3R":
   347             model = Model.X58A_UD3R; break;
   348           case "To be filled by O.E.M.":
   349             model = Model.Unknown; break;
   350           default:
   351             model = Model.Unknown; break;
   352         }
   353       }
   354       
   355       public BaseBoardInformation(string manufacturerName, string productName, 
   356         string version, string serialNumber) 
   357         : base(0x02, 0, null, null) 
   358       {        
   359         SetManufacturerName(manufacturerName);
   360         SetProductName(productName);
   361         this.version = version;
   362         this.serialNumber = serialNumber;
   363       }
   364       
   365       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   366         string[] strings)
   367         : base(type, handle, data, strings) {
   368 
   369         SetManufacturerName(GetString(0x04).Trim());
   370         SetProductName(GetString(0x05).Trim());
   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 }