Hardware/Mainboard/SMBIOS.cs
author moel.mich
Sun, 15 Jan 2012 14:05:52 +0000
changeset 332 19b1e150e7af
parent 320 df3493f75225
child 336 1966500884bc
permissions -rw-r--r--
Added a mainboard specific configuration for the ASUS P9X79 (detailed fan and control configuration still missing).
     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-2012
    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 SystemInformation systemInformation;
    54     private readonly BaseBoardInformation baseBoardInformation;
    55 
    56     private static string ReadSysFS(string path) {
    57       try {
    58         if (File.Exists(path)) {
    59           using (StreamReader reader = new StreamReader(path)) 
    60             return reader.ReadLine();
    61         } else {
    62           return null;
    63         }
    64       } catch {
    65         return null;
    66       }
    67     }
    68     
    69     public SMBIOS() {
    70       int p = (int)Environment.OSVersion.Platform;
    71       if ((p == 4) || (p == 128)) {
    72         this.raw = null;
    73         this.table = null;
    74         
    75         string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
    76         string boardName = ReadSysFS("/sys/class/dmi/id/board_name");        
    77         string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");        
    78         this.baseBoardInformation = new BaseBoardInformation(
    79           boardVendor, boardName, boardVersion, null);
    80 
    81         string systemVendor = ReadSysFS("/sys/class/dmi/id/sys_vendor");
    82         string productName = ReadSysFS("/sys/class/dmi/id/product_name");
    83         string productVersion = ReadSysFS("/sys/class/dmi/id/product_version");    
    84         this.systemInformation = new SystemInformation(systemVendor, 
    85           productName, productVersion, null, null);
    86 
    87         string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
    88         string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
    89         this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
    90         
    91       } else {              
    92         List<Structure> structureList = new List<Structure>();
    93 
    94         raw = null;
    95         byte majorVersion = 0;
    96         byte minorVersion = 0;
    97         try {
    98           ManagementObjectCollection collection;
    99           using (ManagementObjectSearcher searcher = 
   100             new ManagementObjectSearcher("root\\WMI", 
   101               "SELECT * FROM MSSMBios_RawSMBiosTables")) {
   102             collection = searcher.Get();
   103           }
   104          
   105           foreach (ManagementObject mo in collection) {
   106             raw = (byte[])mo["SMBiosData"];
   107             majorVersion = (byte)mo["SmbiosMajorVersion"];
   108             minorVersion = (byte)mo["SmbiosMinorVersion"];            
   109             break;
   110           }
   111         } catch { }
   112 
   113         if (majorVersion > 0 || minorVersion > 0)
   114           version = new Version(majorVersion, minorVersion);
   115   
   116         if (raw != null && raw.Length > 0) {
   117           int offset = 0;
   118           byte type = raw[offset];
   119           while (offset + 4 < raw.Length && type != 127) {
   120   
   121             type = raw[offset];
   122             int length = raw[offset + 1];
   123             ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
   124   
   125             if (offset + length > raw.Length)
   126               break;
   127             byte[] data = new byte[length];
   128             Array.Copy(raw, offset, data, 0, length);
   129             offset += length;
   130   
   131             List<string> stringsList = new List<string>();
   132             if (offset < raw.Length && raw[offset] == 0)
   133               offset++;
   134   
   135             while (offset < raw.Length && raw[offset] != 0) {
   136               StringBuilder sb = new StringBuilder();
   137               while (offset < raw.Length && raw[offset] != 0) {
   138                 sb.Append((char)raw[offset]); offset++;
   139               }
   140               offset++;
   141               stringsList.Add(sb.ToString());
   142             }
   143             offset++;
   144             switch (type) {
   145               case 0x00:
   146                 this.biosInformation = new BIOSInformation(
   147                   type, handle, data, stringsList.ToArray());
   148                 structureList.Add(this.biosInformation); break;
   149               case 0x01:
   150                 this.systemInformation = new SystemInformation(
   151                   type, handle, data, stringsList.ToArray());
   152                 structureList.Add(this.systemInformation); break;
   153               case 0x02: this.baseBoardInformation = new BaseBoardInformation(
   154                   type, handle, data, stringsList.ToArray());
   155                 structureList.Add(this.baseBoardInformation); break;
   156               default: structureList.Add(new Structure(
   157                 type, handle, data, stringsList.ToArray())); break;
   158             }
   159           }
   160         }
   161               
   162         table = structureList.ToArray();
   163       }
   164     }
   165 
   166     public string GetReport() {
   167       StringBuilder r = new StringBuilder();
   168 
   169       if (version != null) {
   170         r.Append("SMBIOS Version: "); r.AppendLine(version.ToString(2));
   171         r.AppendLine();
   172       }
   173 
   174       if (BIOS != null) {
   175         r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
   176         r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
   177         r.AppendLine();
   178       }
   179 
   180       if (System != null) {
   181         r.Append("System Manufacturer: ");
   182         r.AppendLine(System.ManufacturerName);
   183         r.Append("System Name: ");
   184         r.AppendLine(System.ProductName);
   185         r.Append("System Version: ");
   186         r.AppendLine(System.Version);
   187         r.AppendLine();
   188       }
   189 
   190       if (Board != null) {
   191         r.Append("Mainboard Manufacturer: ");
   192         r.AppendLine(Board.ManufacturerName);
   193         r.Append("Mainboard Name: ");
   194         r.AppendLine(Board.ProductName);
   195         r.Append("Mainboard Version: ");
   196         r.AppendLine(Board.Version);
   197         r.AppendLine();
   198       }
   199 
   200       if (raw != null) {
   201         string base64 = Convert.ToBase64String(raw);
   202         r.AppendLine("SMBIOS Table");
   203         r.AppendLine();
   204 
   205         for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   206           r.Append(" ");
   207           for (int j = 0; j < 0x40; j++) {
   208             int index = (i << 6) | j;
   209             if (index < base64.Length) {              
   210               r.Append(base64[index]);
   211             }
   212           }
   213           r.AppendLine();
   214         }
   215         r.AppendLine();
   216       }
   217 
   218       return r.ToString();
   219     }
   220 
   221     public BIOSInformation BIOS {
   222       get { return biosInformation; }
   223     }
   224 
   225     public SystemInformation System {
   226       get { return systemInformation; }
   227     }
   228 
   229     public BaseBoardInformation Board {
   230       get { return baseBoardInformation; }
   231     }
   232 
   233     public class Structure {
   234       private readonly byte type;
   235       private readonly ushort handle;
   236 
   237       private readonly byte[] data;
   238       private readonly string[] strings;
   239 
   240       protected string GetString(int offset) {
   241         if (offset < data.Length && data[offset] > 0 &&
   242          data[offset] <= strings.Length)
   243           return strings[data[offset] - 1];
   244         else
   245           return "";
   246       }
   247 
   248       public Structure(byte type, ushort handle, byte[] data, string[] strings) 
   249       {
   250         this.type = type;
   251         this.handle = handle;
   252         this.data = data;
   253         this.strings = strings;
   254       }
   255 
   256       public byte Type { get { return type; } }
   257 
   258       public ushort Handle { get { return handle; } }
   259     }
   260       
   261     public class BIOSInformation : Structure {
   262 
   263       private readonly string vendor;
   264       private readonly string version;
   265       
   266       public BIOSInformation(string vendor, string version) 
   267         : base (0x00, 0, null, null) 
   268       {
   269         this.vendor = vendor;
   270         this.version = version;
   271       }
   272       
   273       public BIOSInformation(byte type, ushort handle, byte[] data,
   274         string[] strings)
   275         : base(type, handle, data, strings) 
   276       {
   277         this.vendor = GetString(0x04);
   278         this.version = GetString(0x05);
   279       }
   280 
   281       public string Vendor { get { return vendor; } }
   282 
   283       public string Version { get { return version; } }
   284     }
   285 
   286     public class SystemInformation : Structure {
   287 
   288       private readonly string manufacturerName;
   289       private readonly string productName;
   290       private readonly string version;
   291       private readonly string serialNumber;
   292       private readonly string family;
   293 
   294       public SystemInformation(string manufacturerName, string productName, 
   295         string version, string serialNumber, string family) 
   296         : base (0x01, 0, null, null) 
   297       {
   298         this.manufacturerName = manufacturerName;
   299         this.productName = productName;
   300         this.version = version;
   301         this.serialNumber = serialNumber;
   302         this.family = family;
   303       }
   304 
   305       public SystemInformation(byte type, ushort handle, byte[] data,
   306         string[] strings)
   307         : base(type, handle, data, strings) 
   308       {
   309         this.manufacturerName = GetString(0x04);
   310         this.productName = GetString(0x05);
   311         this.version = GetString(0x06);
   312         this.serialNumber = GetString(0x07);
   313         this.family = GetString(0x1A);
   314       }
   315 
   316       public string ManufacturerName { get { return manufacturerName; } }
   317 
   318       public string ProductName { get { return productName; } }
   319 
   320       public string Version { get { return version; } }
   321 
   322       public string SerialNumber { get { return serialNumber; } }
   323 
   324       public string Family { get { return family; } }
   325 
   326     }
   327 
   328     public class BaseBoardInformation : Structure {
   329 
   330       private readonly string manufacturerName;
   331       private readonly string productName;
   332       private readonly string version;
   333       private readonly string serialNumber;
   334       private readonly Manufacturer manufacturer;
   335       private readonly Model model;
   336 
   337       private static Manufacturer GetManufacturer(string name) {               
   338         switch (name) {
   339           case "Alienware":
   340             return Manufacturer.Alienware;
   341           case "Apple Inc.":
   342             return Manufacturer.Apple;
   343           case "ASRock":
   344             return Manufacturer.ASRock;
   345           case "ASUSTeK Computer INC.":
   346           case "ASUSTeK COMPUTER INC.":
   347             return Manufacturer.ASUS;
   348           case "Dell Inc.":
   349             return Manufacturer.Dell;
   350           case "DFI":
   351           case "DFI Inc.":            
   352             return Manufacturer.DFI;
   353           case "ECS":
   354             return Manufacturer.ECS;
   355           case "EPoX COMPUTER CO., LTD":
   356             return Manufacturer.EPoX;
   357           case "EVGA":
   358             return  Manufacturer.EVGA;
   359           case "First International Computer, Inc.":
   360             return Manufacturer.FIC;
   361           case "FUJITSU":
   362           case "FUJITSU SIEMENS":
   363             return Manufacturer.Fujitsu;
   364           case "Gigabyte Technology Co., Ltd.":
   365             return  Manufacturer.Gigabyte;
   366           case "Hewlett-Packard":
   367             return  Manufacturer.HP;
   368           case "IBM":
   369             return  Manufacturer.IBM;
   370           case "Intel":
   371           case "Intel Corp.":
   372           case "Intel Corporation":
   373           case "INTEL Corporation":
   374             return Manufacturer.Intel;   
   375           case "Lenovo":
   376           case "LENOVO":
   377             return Manufacturer.Lenovo;
   378           case "Micro-Star International":
   379           case "MICRO-STAR INTERNATIONAL CO., LTD":
   380           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   381           case "MSI":
   382             return Manufacturer.MSI;
   383           case "Shuttle":
   384             return Manufacturer.Shuttle;
   385           case "Supermicro":
   386             return Manufacturer.Supermicro;
   387           case "TOSHIBA":
   388             return Manufacturer.Toshiba;
   389           case "XFX":
   390             return  Manufacturer.XFX;
   391           case "To be filled by O.E.M.":
   392             return  Manufacturer.Unknown;
   393           default:
   394             return  Manufacturer.Unknown;
   395         }
   396       }
   397 
   398       private static Model GetModel(string name) {
   399         switch (name) {
   400           case "880GMH/USB3":
   401             return Model._880GMH_USB3;
   402           case "ASRock AOD790GX/128M":
   403             return Model.AOD790GX_128M;
   404           case "P55 Deluxe":
   405             return Model.P55_Deluxe;
   406           case "Crosshair III Formula":
   407             return Model.Crosshair_III_Formula;
   408           case "M2N-SLI DELUXE":
   409             return Model.M2N_SLI_DELUXE;
   410           case "M4A79XTD EVO":
   411             return Model.M4A79XTD_EVO;
   412           case "P5W DH Deluxe":
   413             return Model.P5W_DH_Deluxe;
   414           case "P6X58D-E":
   415             return Model.P6X58D_E;
   416           case "P8P67":
   417             return Model.P8P67;
   418           case "P8P67 EVO":
   419             return Model.P8P67_EVO;
   420           case "P8P67 PRO":
   421             return Model.P8P67_PRO;
   422           case "P8P67-M PRO":
   423             return Model.P8P67_M_PRO;
   424           case "P9X79":
   425             return Model.P9X79;
   426           case "Rampage Extreme":
   427             return Model.Rampage_Extreme;
   428           case "Rampage II GENE":
   429             return Model.Rampage_II_GENE;
   430           case "LP BI P45-T2RS Elite":
   431             return Model.LP_BI_P45_T2RS_Elite;
   432           case "LP DK P55-T3eH9":
   433             return Model.LP_DK_P55_T3eH9;
   434           case "A890GXM-A":
   435             return Model.A890GXM_A;
   436           case "X58 SLI Classified":
   437             return Model.X58_SLI_Classified;
   438           case "965P-S3":
   439             return Model._965P_S3;
   440           case "EP45-DS3R":
   441             return Model.EP45_DS3R;
   442           case "EP45-UD3R":
   443             return Model.EP45_UD3R;
   444           case "EX58-EXTREME":
   445             return Model.EX58_EXTREME;
   446           case "GA-MA770T-UD3":
   447             return Model.GA_MA770T_UD3;
   448           case "GA-MA785GMT-UD2H":
   449             return Model.GA_MA785GMT_UD2H;
   450           case "H67A-UD3H-B3":
   451             return Model.H67A_UD3H_B3;
   452           case "P35-DS3":
   453             return Model.P35_DS3;
   454           case "P35-DS3L":
   455             return Model.P35_DS3L;
   456           case "P55-UD4":
   457             return Model.P55_UD4;
   458           case "P55M-UD4":
   459             return Model.P55M_UD4;
   460           case "P67A-UD4-B3":
   461             return Model.P67A_UD4_B3;
   462           case "X38-DS5":
   463             return Model.X38_DS5;
   464           case "X58A-UD3R":
   465             return Model.X58A_UD3R;
   466           case "Z68X-UD7-B3":
   467             return Model.Z68X_UD7_B3;
   468           case "FH67":
   469             return Model.FH67;
   470           case "Base Board Product Name":
   471           case "To be filled by O.E.M.":
   472             return Model.Unknown;
   473           default:
   474             return Model.Unknown;
   475         }
   476       }
   477       
   478       public BaseBoardInformation(string manufacturerName, string productName, 
   479         string version, string serialNumber) 
   480         : base(0x02, 0, null, null) 
   481       {
   482         this.manufacturerName = manufacturerName;
   483         this.manufacturer = GetManufacturer(manufacturerName);
   484         this.productName = productName;
   485         this.model = GetModel(productName);
   486         this.version = version;
   487         this.serialNumber = serialNumber;
   488       }
   489       
   490       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   491         string[] strings)
   492         : base(type, handle, data, strings) {
   493 
   494         this.manufacturerName = GetString(0x04).Trim();
   495         this.manufacturer = GetManufacturer(this.manufacturerName);
   496         this.productName = GetString(0x05).Trim();
   497         this.model = GetModel(this.productName);
   498         this.version = GetString(0x06).Trim();
   499         this.serialNumber = GetString(0x07).Trim();               
   500       }
   501       
   502       public string ManufacturerName { get { return manufacturerName; } }
   503 
   504       public string ProductName { get { return productName; } }
   505 
   506       public string Version { get { return version; } }
   507 
   508       public string SerialNumber { get { return serialNumber; } }
   509 
   510       public Manufacturer Manufacturer { get { return manufacturer; } }
   511 
   512       public Model Model { get { return model; } }
   513 
   514     }
   515   }
   516 }