Hardware/Mainboard/SMBIOS.cs
author moel.mich
Sun, 15 Aug 2010 14:46:58 +0000
changeset 167 b7cc9d09aefe
parent 165 813d8bc3192f
child 168 7f90baeb96b0
permissions -rw-r--r--
Fixed some Code Analysis 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 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 "EPoX COMPUTER CO., LTD":
   271             manufacturer = Manufacturer.EPoX; break;
   272           case "EVGA":
   273             manufacturer = Manufacturer.EVGA; break;
   274           case "First International Computer, Inc.":
   275             manufacturer = Manufacturer.FIC; break;
   276           case "Gigabyte Technology Co., Ltd.":
   277             manufacturer = Manufacturer.Gigabyte; break;
   278           case "Hewlett-Packard":
   279             manufacturer = Manufacturer.HP; break;
   280           case "IBM":
   281             manufacturer = Manufacturer.IBM; break;
   282           case "MICRO-STAR INTERNATIONAL CO., LTD":
   283           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   284             manufacturer = Manufacturer.MSI; break;
   285           case "XFX":
   286             manufacturer = Manufacturer.XFX; break;
   287           case "To be filled by O.E.M.":
   288             manufacturer = Manufacturer.Unknown; break;
   289           default:
   290             manufacturer = Manufacturer.Unknown; break;
   291         }
   292       }
   293       
   294       private void SetProductName(string name) {
   295         this.productName = name;
   296         
   297         switch (name) {
   298           case "880GMH/USB3":
   299             model = Model._880GMH_USB3; break;
   300           case "Crosshair III Formula":
   301             model = Model.Crosshair_III_Formula; break;
   302           case "M2N-SLI DELUXE":
   303             model = Model.M2N_SLI_DELUXE; break;
   304           case "M4A79XTD EVO":
   305             model = Model.M4A79XTD_EVO; break;
   306           case "P5W DH Deluxe":
   307             model = Model.P5W_DH_Deluxe; break;
   308           case "P6X58D-E":
   309             model = Model.P6X58D_E; break;
   310           case "LP BI P45-T2RS Elite":
   311             model = Model.LP_BI_P45_T2RS_Elite; break;
   312           case "LP DK P55-T3eH9":
   313             model = Model.LP_DK_P55_T3eH9; break;
   314           case "X58 SLI Classified":
   315             model = Model.X58_SLI_Classified; break;
   316           case "965P-S3":
   317             model = Model._965P_S3; break;
   318           case "EP45-DS3R":
   319             model = Model.EP45_DS3R; break;
   320           case "EP45-UD3R":
   321             model = Model.EP45_UD3R; break;
   322           case "EX58-EXTREME":
   323             model = Model.EX58_EXTREME; break;
   324           case "GA-MA770T-UD3":
   325             model = Model.GA_MA770T_UD3; break;
   326           case "GA-MA785GMT-UD2H":
   327             model = Model.GA_MA785GMT_UD2H; break;
   328           case "P35-DS3":
   329             model = Model.P35_DS3; break;
   330           case "P35-DS3L":
   331             model = Model.P35_DS3L; break;
   332           case "P55-UD4":
   333             model = Model.P55_UD4; break;
   334           case "X38-DS5":
   335             model = Model.X38_DS5; break;
   336           case "X58A-UD3R":
   337             model = Model.X58A_UD3R; break;
   338           case "To be filled by O.E.M.":
   339             model = Model.Unknown; break;
   340           default:
   341             model = Model.Unknown; break;
   342         }
   343       }
   344       
   345       public BaseBoardInformation(string manufacturerName, string productName, 
   346         string version, string serialNumber) 
   347         : base(0x02, 0, null, null) 
   348       {        
   349         SetManufacturerName(manufacturerName);
   350         SetProductName(productName);
   351         this.version = version;
   352         this.serialNumber = serialNumber;
   353       }
   354       
   355       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   356         string[] strings)
   357         : base(type, handle, data, strings) {
   358 
   359         SetManufacturerName(GetString(0x04).Trim());
   360         SetProductName(GetString(0x05).Trim());
   361         this.version = GetString(0x06).Trim();
   362         this.serialNumber = GetString(0x07).Trim();               
   363       }
   364       
   365       public string ManufacturerName { get { return manufacturerName; } }
   366 
   367       public string ProductName { get { return productName; } }
   368 
   369       public string Version { get { return version; } }
   370 
   371       public string SerialNumber { get { return serialNumber; } }
   372 
   373       public Manufacturer Manufacturer { get { return manufacturer; } }
   374 
   375       public Model Model { get { return model; } }
   376 
   377     }
   378   }
   379 }