Hardware/Mainboard/SMBIOS.cs
author moel.mich
Sun, 17 Oct 2010 16:04:19 +0000
changeset 228 458a6c3de579
parent 220 e51749b206ee
child 242 881aedb94bc6
permissions -rw-r--r--
Added code to read the additional fans on the ASRock P55 Deluxe mainboard via special GPIO switching.
     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 "ASRock AOD790GX/128M":
   299             return Model.AOD790GX_128M;
   300           case "P55 Deluxe":
   301             return Model.P55_Deluxe;
   302           case "Crosshair III Formula":
   303             return Model.Crosshair_III_Formula;
   304           case "M2N-SLI DELUXE":
   305             return Model.M2N_SLI_DELUXE;
   306           case "M4A79XTD EVO":
   307             return Model.M4A79XTD_EVO;
   308           case "P5W DH Deluxe":
   309             return Model.P5W_DH_Deluxe;
   310           case "P6X58D-E":
   311             return Model.P6X58D_E;
   312           case "Rampage Extreme":
   313             return Model.Rampage_Extreme;
   314           case "Rampage II GENE":
   315             return Model.Rampage_II_GENE;
   316           case "LP BI P45-T2RS Elite":
   317             return Model.LP_BI_P45_T2RS_Elite;
   318           case "LP DK P55-T3eH9":
   319             return Model.LP_DK_P55_T3eH9;
   320           case "A890GXM-A":
   321             return Model.A890GXM_A;
   322           case "X58 SLI Classified":
   323             return Model.X58_SLI_Classified;
   324           case "965P-S3":
   325             return Model._965P_S3;
   326           case "EP45-DS3R":
   327             return Model.EP45_DS3R;
   328           case "EP45-UD3R":
   329             return Model.EP45_UD3R;
   330           case "EX58-EXTREME":
   331             return Model.EX58_EXTREME;
   332           case "GA-MA770T-UD3":
   333             return Model.GA_MA770T_UD3;
   334           case "GA-MA785GMT-UD2H":
   335             return Model.GA_MA785GMT_UD2H;
   336           case "P35-DS3":
   337             return Model.P35_DS3;
   338           case "P35-DS3L":
   339             return Model.P35_DS3L;
   340           case "P55-UD4":
   341             return Model.P55_UD4;
   342           case "P55M-UD4":
   343             return Model.P55M_UD4;
   344           case "X38-DS5":
   345             return Model.X38_DS5;
   346           case "X58A-UD3R":
   347             return Model.X58A_UD3R;
   348           case "To be filled by O.E.M.":
   349             return Model.Unknown;
   350           default:
   351             return Model.Unknown;
   352         }
   353       }
   354       
   355       public BaseBoardInformation(string manufacturerName, string productName, 
   356         string version, string serialNumber) 
   357         : base(0x02, 0, null, null) 
   358       {
   359         this.manufacturerName = manufacturerName;
   360         this.manufacturer = GetManufacturer(manufacturerName);
   361         this.productName = productName;
   362         this.model = GetModel(productName);
   363         this.version = version;
   364         this.serialNumber = serialNumber;
   365       }
   366       
   367       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   368         string[] strings)
   369         : base(type, handle, data, strings) {
   370 
   371         this.manufacturerName = GetString(0x04).Trim();
   372         this.manufacturer = GetManufacturer(this.manufacturerName);
   373         this.productName = GetString(0x05).Trim();
   374         this.model = GetModel(this.productName);
   375         this.version = GetString(0x06).Trim();
   376         this.serialNumber = GetString(0x07).Trim();               
   377       }
   378       
   379       public string ManufacturerName { get { return manufacturerName; } }
   380 
   381       public string ProductName { get { return productName; } }
   382 
   383       public string Version { get { return version; } }
   384 
   385       public string SerialNumber { get { return serialNumber; } }
   386 
   387       public Manufacturer Manufacturer { get { return manufacturer; } }
   388 
   389       public Model Model { get { return model; } }
   390 
   391     }
   392   }
   393 }