Hardware/Mainboard/SMBIOS.cs
author moel.mich
Mon, 02 Jan 2012 20:45:18 +0000
changeset 329 756af5ee409e
parent 319 35cda448fc5f
child 332 19b1e150e7af
permissions -rw-r--r--
Small corrections for AMD family 15h CPUs (based on documentation).
     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 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             return Manufacturer.ASUS;
   347           case "Dell Inc.":
   348             return Manufacturer.Dell;
   349           case "DFI":
   350           case "DFI Inc.":            
   351             return Manufacturer.DFI;
   352           case "ECS":
   353             return Manufacturer.ECS;
   354           case "EPoX COMPUTER CO., LTD":
   355             return Manufacturer.EPoX;
   356           case "EVGA":
   357             return  Manufacturer.EVGA;
   358           case "First International Computer, Inc.":
   359             return Manufacturer.FIC;
   360           case "FUJITSU":
   361           case "FUJITSU SIEMENS":
   362             return Manufacturer.Fujitsu;
   363           case "Gigabyte Technology Co., Ltd.":
   364             return  Manufacturer.Gigabyte;
   365           case "Hewlett-Packard":
   366             return  Manufacturer.HP;
   367           case "IBM":
   368             return  Manufacturer.IBM;
   369           case "Intel":
   370           case "Intel Corp.":
   371           case "Intel Corporation":
   372           case "INTEL Corporation":
   373             return Manufacturer.Intel;   
   374           case "Lenovo":
   375           case "LENOVO":
   376             return Manufacturer.Lenovo;
   377           case "Micro-Star International":
   378           case "MICRO-STAR INTERNATIONAL CO., LTD":
   379           case "MICRO-STAR INTERNATIONAL CO.,LTD":
   380           case "MSI":
   381             return Manufacturer.MSI;
   382           case "Shuttle":
   383             return Manufacturer.Shuttle;
   384           case "Supermicro":
   385             return Manufacturer.Supermicro;
   386           case "TOSHIBA":
   387             return Manufacturer.Toshiba;
   388           case "XFX":
   389             return  Manufacturer.XFX;
   390           case "To be filled by O.E.M.":
   391             return  Manufacturer.Unknown;
   392           default:
   393             return  Manufacturer.Unknown;
   394         }
   395       }
   396 
   397       private static Model GetModel(string name) {
   398         switch (name) {
   399           case "880GMH/USB3":
   400             return Model._880GMH_USB3;
   401           case "ASRock AOD790GX/128M":
   402             return Model.AOD790GX_128M;
   403           case "P55 Deluxe":
   404             return Model.P55_Deluxe;
   405           case "Crosshair III Formula":
   406             return Model.Crosshair_III_Formula;
   407           case "M2N-SLI DELUXE":
   408             return Model.M2N_SLI_DELUXE;
   409           case "M4A79XTD EVO":
   410             return Model.M4A79XTD_EVO;
   411           case "P5W DH Deluxe":
   412             return Model.P5W_DH_Deluxe;
   413           case "P6X58D-E":
   414             return Model.P6X58D_E;
   415           case "P8P67":
   416             return Model.P8P67;
   417           case "P8P67 EVO":
   418             return Model.P8P67_EVO;
   419           case "P8P67 PRO":
   420             return Model.P8P67_PRO;
   421           case "P8P67-M PRO":
   422             return Model.P8P67_M_PRO;
   423           case "Rampage Extreme":
   424             return Model.Rampage_Extreme;
   425           case "Rampage II GENE":
   426             return Model.Rampage_II_GENE;
   427           case "LP BI P45-T2RS Elite":
   428             return Model.LP_BI_P45_T2RS_Elite;
   429           case "LP DK P55-T3eH9":
   430             return Model.LP_DK_P55_T3eH9;
   431           case "A890GXM-A":
   432             return Model.A890GXM_A;
   433           case "X58 SLI Classified":
   434             return Model.X58_SLI_Classified;
   435           case "965P-S3":
   436             return Model._965P_S3;
   437           case "EP45-DS3R":
   438             return Model.EP45_DS3R;
   439           case "EP45-UD3R":
   440             return Model.EP45_UD3R;
   441           case "EX58-EXTREME":
   442             return Model.EX58_EXTREME;
   443           case "GA-MA770T-UD3":
   444             return Model.GA_MA770T_UD3;
   445           case "GA-MA785GMT-UD2H":
   446             return Model.GA_MA785GMT_UD2H;
   447           case "H67A-UD3H-B3":
   448             return Model.H67A_UD3H_B3;
   449           case "P35-DS3":
   450             return Model.P35_DS3;
   451           case "P35-DS3L":
   452             return Model.P35_DS3L;
   453           case "P55-UD4":
   454             return Model.P55_UD4;
   455           case "P55M-UD4":
   456             return Model.P55M_UD4;
   457           case "P67A-UD4-B3":
   458             return Model.P67A_UD4_B3;
   459           case "X38-DS5":
   460             return Model.X38_DS5;
   461           case "X58A-UD3R":
   462             return Model.X58A_UD3R;
   463           case "Z68X-UD7-B3":
   464             return Model.Z68X_UD7_B3;
   465           case "FH67":
   466             return Model.FH67;
   467           case "Base Board Product Name":
   468           case "To be filled by O.E.M.":
   469             return Model.Unknown;
   470           default:
   471             return Model.Unknown;
   472         }
   473       }
   474       
   475       public BaseBoardInformation(string manufacturerName, string productName, 
   476         string version, string serialNumber) 
   477         : base(0x02, 0, null, null) 
   478       {
   479         this.manufacturerName = manufacturerName;
   480         this.manufacturer = GetManufacturer(manufacturerName);
   481         this.productName = productName;
   482         this.model = GetModel(productName);
   483         this.version = version;
   484         this.serialNumber = serialNumber;
   485       }
   486       
   487       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   488         string[] strings)
   489         : base(type, handle, data, strings) {
   490 
   491         this.manufacturerName = GetString(0x04).Trim();
   492         this.manufacturer = GetManufacturer(this.manufacturerName);
   493         this.productName = GetString(0x05).Trim();
   494         this.model = GetModel(this.productName);
   495         this.version = GetString(0x06).Trim();
   496         this.serialNumber = GetString(0x07).Trim();               
   497       }
   498       
   499       public string ManufacturerName { get { return manufacturerName; } }
   500 
   501       public string ProductName { get { return productName; } }
   502 
   503       public string Version { get { return version; } }
   504 
   505       public string SerialNumber { get { return serialNumber; } }
   506 
   507       public Manufacturer Manufacturer { get { return manufacturer; } }
   508 
   509       public Model Model { get { return model; } }
   510 
   511     }
   512   }
   513 }