Hardware/Mainboard/SMBIOS.cs
author moel.mich
Thu, 07 Jul 2011 20:41:09 +0000
changeset 308 d882720734bf
parent 296 414783d1cda9
child 311 d687db11035c
permissions -rw-r--r--
Added support for reading the TAMG ACPI table on Gigabyte mainboards. Fixed a small problem with HDD/SSD names (0 chars are trimmed now as well).
     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 "Supermicro":
   316             return Manufacturer.Supermicro;
   317           case "TOSHIBA":
   318             return Manufacturer.Toshiba;
   319           case "XFX":
   320             return  Manufacturer.XFX;
   321           case "To be filled by O.E.M.":
   322             return  Manufacturer.Unknown;
   323           default:
   324             return  Manufacturer.Unknown;
   325         }
   326       }
   327 
   328       private static Model GetModel(string name) {
   329         switch (name) {
   330           case "880GMH/USB3":
   331             return Model._880GMH_USB3;
   332           case "ASRock AOD790GX/128M":
   333             return Model.AOD790GX_128M;
   334           case "P55 Deluxe":
   335             return Model.P55_Deluxe;
   336           case "Crosshair III Formula":
   337             return Model.Crosshair_III_Formula;
   338           case "M2N-SLI DELUXE":
   339             return Model.M2N_SLI_DELUXE;
   340           case "M4A79XTD EVO":
   341             return Model.M4A79XTD_EVO;
   342           case "P5W DH Deluxe":
   343             return Model.P5W_DH_Deluxe;
   344           case "P6X58D-E":
   345             return Model.P6X58D_E;
   346           case "P8P67 PRO":
   347             return Model.P8P67_PRO;
   348           case "P8P67-M PRO":
   349             return Model.P8P67_M_PRO;
   350           case "Rampage Extreme":
   351             return Model.Rampage_Extreme;
   352           case "Rampage II GENE":
   353             return Model.Rampage_II_GENE;
   354           case "LP BI P45-T2RS Elite":
   355             return Model.LP_BI_P45_T2RS_Elite;
   356           case "LP DK P55-T3eH9":
   357             return Model.LP_DK_P55_T3eH9;
   358           case "A890GXM-A":
   359             return Model.A890GXM_A;
   360           case "X58 SLI Classified":
   361             return Model.X58_SLI_Classified;
   362           case "965P-S3":
   363             return Model._965P_S3;
   364           case "EP45-DS3R":
   365             return Model.EP45_DS3R;
   366           case "EP45-UD3R":
   367             return Model.EP45_UD3R;
   368           case "EX58-EXTREME":
   369             return Model.EX58_EXTREME;
   370           case "GA-MA770T-UD3":
   371             return Model.GA_MA770T_UD3;
   372           case "GA-MA785GMT-UD2H":
   373             return Model.GA_MA785GMT_UD2H;
   374           case "H67A-UD3H-B3":
   375             return Model.H67A_UD3H_B3;
   376           case "P35-DS3":
   377             return Model.P35_DS3;
   378           case "P35-DS3L":
   379             return Model.P35_DS3L;
   380           case "P55-UD4":
   381             return Model.P55_UD4;
   382           case "P55M-UD4":
   383             return Model.P55M_UD4;
   384           case "P67A-UD4-B3":
   385             return Model.P67A_UD4_B3;
   386           case "X38-DS5":
   387             return Model.X38_DS5;
   388           case "X58A-UD3R":
   389             return Model.X58A_UD3R;
   390           case "Z68X-UD7-B3":
   391             return Model.Z68X_UD7_B3;
   392           case "Base Board Product Name":
   393           case "To be filled by O.E.M.":
   394             return Model.Unknown;
   395           default:
   396             return Model.Unknown;
   397         }
   398       }
   399       
   400       public BaseBoardInformation(string manufacturerName, string productName, 
   401         string version, string serialNumber) 
   402         : base(0x02, 0, null, null) 
   403       {
   404         this.manufacturerName = manufacturerName;
   405         this.manufacturer = GetManufacturer(manufacturerName);
   406         this.productName = productName;
   407         this.model = GetModel(productName);
   408         this.version = version;
   409         this.serialNumber = serialNumber;
   410       }
   411       
   412       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   413         string[] strings)
   414         : base(type, handle, data, strings) {
   415 
   416         this.manufacturerName = GetString(0x04).Trim();
   417         this.manufacturer = GetManufacturer(this.manufacturerName);
   418         this.productName = GetString(0x05).Trim();
   419         this.model = GetModel(this.productName);
   420         this.version = GetString(0x06).Trim();
   421         this.serialNumber = GetString(0x07).Trim();               
   422       }
   423       
   424       public string ManufacturerName { get { return manufacturerName; } }
   425 
   426       public string ProductName { get { return productName; } }
   427 
   428       public string Version { get { return version; } }
   429 
   430       public string SerialNumber { get { return serialNumber; } }
   431 
   432       public Manufacturer Manufacturer { get { return manufacturer; } }
   433 
   434       public Model Model { get { return model; } }
   435 
   436     }
   437   }
   438 }