Hardware/SMBIOS.cs
author sl
Sun, 03 Feb 2013 18:01:50 +0100
changeset 391 ca4c0e7ae75d
parent 373 3b8443edb0e6
permissions -rw-r--r--
Converted project to VisualStudio 2012.
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.IO;
    14 using System.Management;
    15 using System.Text;
    16 
    17 namespace OpenHardwareMonitor.Hardware {
    18 
    19   internal class SMBIOS {
    20 
    21     private readonly byte[] raw;
    22     private readonly Structure[] table;
    23 
    24     private readonly Version version;
    25     private readonly BIOSInformation biosInformation;
    26     private readonly SystemInformation systemInformation;
    27     private readonly BaseBoardInformation baseBoardInformation;
    28     private readonly ProcessorInformation processorInformation;
    29     private readonly MemoryDevice[] memoryDevices;
    30 
    31     private static string ReadSysFS(string path) {
    32       try {
    33         if (File.Exists(path)) {
    34           using (StreamReader reader = new StreamReader(path)) 
    35             return reader.ReadLine();
    36         } else {
    37           return null;
    38         }
    39       } catch {
    40         return null;
    41       }
    42     }
    43     
    44     public SMBIOS() {
    45       int p = (int)Environment.OSVersion.Platform;
    46       if ((p == 4) || (p == 128)) {
    47         this.raw = null;
    48         this.table = null;
    49         
    50         string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
    51         string boardName = ReadSysFS("/sys/class/dmi/id/board_name");        
    52         string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");        
    53         this.baseBoardInformation = new BaseBoardInformation(
    54           boardVendor, boardName, boardVersion, null);
    55 
    56         string systemVendor = ReadSysFS("/sys/class/dmi/id/sys_vendor");
    57         string productName = ReadSysFS("/sys/class/dmi/id/product_name");
    58         string productVersion = ReadSysFS("/sys/class/dmi/id/product_version");    
    59         this.systemInformation = new SystemInformation(systemVendor, 
    60           productName, productVersion, null, null);
    61 
    62         string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
    63         string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
    64         this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
    65 
    66         this.memoryDevices = new MemoryDevice[0];
    67       } else {              
    68         List<Structure> structureList = new List<Structure>();
    69         List<MemoryDevice> memoryDeviceList = new List<MemoryDevice>();
    70 
    71         raw = null;
    72         byte majorVersion = 0;
    73         byte minorVersion = 0;
    74         try {
    75           ManagementObjectCollection collection;
    76           using (ManagementObjectSearcher searcher = 
    77             new ManagementObjectSearcher("root\\WMI", 
    78               "SELECT * FROM MSSMBios_RawSMBiosTables")) {
    79             collection = searcher.Get();
    80           }
    81          
    82           foreach (ManagementObject mo in collection) {
    83             raw = (byte[])mo["SMBiosData"];
    84             majorVersion = (byte)mo["SmbiosMajorVersion"];
    85             minorVersion = (byte)mo["SmbiosMinorVersion"];            
    86             break;
    87           }
    88         } catch { }      
    89 
    90         if (majorVersion > 0 || minorVersion > 0)
    91           version = new Version(majorVersion, minorVersion);
    92   
    93         if (raw != null && raw.Length > 0) {
    94           int offset = 0;
    95           byte type = raw[offset];
    96           while (offset + 4 < raw.Length && type != 127) {
    97   
    98             type = raw[offset];
    99             int length = raw[offset + 1];
   100             ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
   101   
   102             if (offset + length > raw.Length)
   103               break;
   104             byte[] data = new byte[length];
   105             Array.Copy(raw, offset, data, 0, length);
   106             offset += length;
   107   
   108             List<string> stringsList = new List<string>();
   109             if (offset < raw.Length && raw[offset] == 0)
   110               offset++;
   111   
   112             while (offset < raw.Length && raw[offset] != 0) {
   113               StringBuilder sb = new StringBuilder();
   114               while (offset < raw.Length && raw[offset] != 0) {
   115                 sb.Append((char)raw[offset]); offset++;
   116               }
   117               offset++;
   118               stringsList.Add(sb.ToString());
   119             }
   120             offset++;
   121             switch (type) {
   122               case 0x00:
   123                 this.biosInformation = new BIOSInformation(
   124                   type, handle, data, stringsList.ToArray());
   125                 structureList.Add(this.biosInformation); break;
   126               case 0x01:
   127                 this.systemInformation = new SystemInformation(
   128                   type, handle, data, stringsList.ToArray());
   129                 structureList.Add(this.systemInformation); break;
   130               case 0x02: this.baseBoardInformation = new BaseBoardInformation(
   131                   type, handle, data, stringsList.ToArray());
   132                 structureList.Add(this.baseBoardInformation); break;
   133               case 0x04: this.processorInformation = new ProcessorInformation(
   134                   type, handle, data, stringsList.ToArray());
   135                 structureList.Add(this.processorInformation); break;
   136               case 0x11: MemoryDevice m = new MemoryDevice(
   137                   type, handle, data, stringsList.ToArray());
   138                 memoryDeviceList.Add(m);
   139                 structureList.Add(m); break;
   140               default: structureList.Add(new Structure(
   141                 type, handle, data, stringsList.ToArray())); break;
   142             }
   143           }
   144         }
   145 
   146         memoryDevices = memoryDeviceList.ToArray();
   147         table = structureList.ToArray();
   148       }
   149     }
   150 
   151     public string GetReport() {
   152       StringBuilder r = new StringBuilder();
   153 
   154       if (version != null) {
   155         r.Append("SMBIOS Version: "); r.AppendLine(version.ToString(2));
   156         r.AppendLine();
   157       }
   158 
   159       if (BIOS != null) {
   160         r.Append("BIOS Vendor: "); r.AppendLine(BIOS.Vendor);
   161         r.Append("BIOS Version: "); r.AppendLine(BIOS.Version);
   162         r.AppendLine();
   163       }
   164 
   165       if (System != null) {
   166         r.Append("System Manufacturer: ");
   167         r.AppendLine(System.ManufacturerName);
   168         r.Append("System Name: ");
   169         r.AppendLine(System.ProductName);
   170         r.Append("System Version: ");
   171         r.AppendLine(System.Version);
   172         r.AppendLine();
   173       }
   174 
   175       if (Board != null) {
   176         r.Append("Mainboard Manufacturer: ");
   177         r.AppendLine(Board.ManufacturerName);
   178         r.Append("Mainboard Name: ");
   179         r.AppendLine(Board.ProductName);
   180         r.Append("Mainboard Version: ");
   181         r.AppendLine(Board.Version);
   182         r.AppendLine();
   183       }
   184 
   185       if (Processor != null) {
   186         r.Append("Processor Manufacturer: ");
   187         r.AppendLine(Processor.ManufacturerName);
   188         r.Append("Processor Version: ");
   189         r.AppendLine(Processor.Version);
   190         r.Append("Processor Core Count: ");
   191         r.AppendLine(Processor.CoreCount.ToString());
   192         r.Append("Processor Core Enabled: ");
   193         r.AppendLine(Processor.CoreEnabled.ToString());
   194         r.Append("Processor Thread Count: ");
   195         r.AppendLine(Processor.ThreadCount.ToString());
   196         r.Append("Processor External Clock: ");
   197         r.Append(Processor.ExternalClock);
   198         r.AppendLine(" Mhz");
   199         r.AppendLine();
   200       }
   201 
   202       for (int i = 0; i < MemoryDevices.Length; i++) {        
   203         r.Append("Memory Device [" + i + "] Manufacturer: ");
   204         r.AppendLine(MemoryDevices[i].ManufacturerName);
   205         r.Append("Memory Device [" + i + "] Part Number: ");
   206         r.AppendLine(MemoryDevices[i].PartNumber);
   207         r.Append("Memory Device [" + i + "] Device Locator: ");
   208         r.AppendLine(MemoryDevices[i].DeviceLocator);
   209         r.Append("Memory Device [" + i + "] Bank Locator: ");
   210         r.AppendLine(MemoryDevices[i].BankLocator);
   211         r.Append("Memory Device [" + i + "] Speed: ");
   212         r.Append(MemoryDevices[i].Speed);
   213         r.AppendLine(" MHz");
   214         r.AppendLine();
   215       }
   216 
   217       if (raw != null) {
   218         string base64 = Convert.ToBase64String(raw);
   219         r.AppendLine("SMBIOS Table");
   220         r.AppendLine();
   221 
   222         for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   223           r.Append(" ");
   224           for (int j = 0; j < 0x40; j++) {
   225             int index = (i << 6) | j;
   226             if (index < base64.Length) {              
   227               r.Append(base64[index]);
   228             }
   229           }
   230           r.AppendLine();
   231         }
   232         r.AppendLine();
   233       }
   234 
   235       return r.ToString();
   236     }
   237 
   238     public BIOSInformation BIOS {
   239       get { return biosInformation; }
   240     }
   241 
   242     public SystemInformation System {
   243       get { return systemInformation; }
   244     }
   245 
   246     public BaseBoardInformation Board {
   247       get { return baseBoardInformation; }
   248     }
   249 
   250 
   251     public ProcessorInformation Processor {
   252       get { return processorInformation; }
   253     }
   254 
   255     public MemoryDevice[] MemoryDevices {
   256       get { return memoryDevices; }
   257     }
   258 
   259     public class Structure {
   260       private readonly byte type;
   261       private readonly ushort handle;
   262 
   263       private readonly byte[] data;
   264       private readonly string[] strings;
   265 
   266       protected int GetByte(int offset) {
   267         if (offset < data.Length && offset >= 0)
   268           return data[offset];
   269         else
   270           return 0;
   271       }
   272 
   273       protected int GetWord(int offset) {
   274         if (offset + 1 < data.Length && offset >= 0)
   275           return (data[offset + 1] << 8) | data[offset];
   276         else
   277           return 0;
   278       }
   279 
   280       protected string GetString(int offset) {
   281         if (offset < data.Length && data[offset] > 0 &&
   282          data[offset] <= strings.Length)
   283           return strings[data[offset] - 1];
   284         else
   285           return "";
   286       }
   287 
   288       public Structure(byte type, ushort handle, byte[] data, string[] strings) 
   289       {
   290         this.type = type;
   291         this.handle = handle;
   292         this.data = data;
   293         this.strings = strings;
   294       }
   295 
   296       public byte Type { get { return type; } }
   297 
   298       public ushort Handle { get { return handle; } }
   299     }
   300       
   301     public class BIOSInformation : Structure {
   302 
   303       private readonly string vendor;
   304       private readonly string version;
   305       
   306       public BIOSInformation(string vendor, string version) 
   307         : base (0x00, 0, null, null) 
   308       {
   309         this.vendor = vendor;
   310         this.version = version;
   311       }
   312       
   313       public BIOSInformation(byte type, ushort handle, byte[] data,
   314         string[] strings)
   315         : base(type, handle, data, strings) 
   316       {
   317         this.vendor = GetString(0x04);
   318         this.version = GetString(0x05);
   319       }
   320 
   321       public string Vendor { get { return vendor; } }
   322 
   323       public string Version { get { return version; } }
   324     }
   325 
   326     public class SystemInformation : Structure {
   327 
   328       private readonly string manufacturerName;
   329       private readonly string productName;
   330       private readonly string version;
   331       private readonly string serialNumber;
   332       private readonly string family;
   333 
   334       public SystemInformation(string manufacturerName, string productName, 
   335         string version, string serialNumber, string family) 
   336         : base (0x01, 0, null, null) 
   337       {
   338         this.manufacturerName = manufacturerName;
   339         this.productName = productName;
   340         this.version = version;
   341         this.serialNumber = serialNumber;
   342         this.family = family;
   343       }
   344 
   345       public SystemInformation(byte type, ushort handle, byte[] data,
   346         string[] strings)
   347         : base(type, handle, data, strings) 
   348       {
   349         this.manufacturerName = GetString(0x04);
   350         this.productName = GetString(0x05);
   351         this.version = GetString(0x06);
   352         this.serialNumber = GetString(0x07);
   353         this.family = GetString(0x1A);
   354       }
   355 
   356       public string ManufacturerName { get { return manufacturerName; } }
   357 
   358       public string ProductName { get { return productName; } }
   359 
   360       public string Version { get { return version; } }
   361 
   362       public string SerialNumber { get { return serialNumber; } }
   363 
   364       public string Family { get { return family; } }
   365 
   366     }
   367 
   368     public class BaseBoardInformation : Structure {
   369 
   370       private readonly string manufacturerName;
   371       private readonly string productName;
   372       private readonly string version;
   373       private readonly string serialNumber;
   374       
   375       public BaseBoardInformation(string manufacturerName, string productName, 
   376         string version, string serialNumber) 
   377         : base(0x02, 0, null, null) 
   378       {
   379         this.manufacturerName = manufacturerName;
   380         this.productName = productName;
   381         this.version = version;
   382         this.serialNumber = serialNumber;
   383       }
   384       
   385       public BaseBoardInformation(byte type, ushort handle, byte[] data,
   386         string[] strings)
   387         : base(type, handle, data, strings) {
   388 
   389         this.manufacturerName = GetString(0x04).Trim();
   390         this.productName = GetString(0x05).Trim();
   391         this.version = GetString(0x06).Trim();
   392         this.serialNumber = GetString(0x07).Trim();               
   393       }
   394       
   395       public string ManufacturerName { get { return manufacturerName; } }
   396 
   397       public string ProductName { get { return productName; } }
   398 
   399       public string Version { get { return version; } }
   400 
   401       public string SerialNumber { get { return serialNumber; } }
   402 
   403     }
   404 
   405     public class ProcessorInformation : Structure {
   406 
   407       public ProcessorInformation(byte type, ushort handle, byte[] data,
   408         string[] strings)
   409         : base(type, handle, data, strings) 
   410       {
   411         this.ManufacturerName = GetString(0x07).Trim();
   412         this.Version = GetString(0x10).Trim();
   413         this.CoreCount = GetByte(0x23);
   414         this.CoreEnabled = GetByte(0x24);
   415         this.ThreadCount = GetByte(0x25);
   416         this.ExternalClock = GetWord(0x12);
   417       }
   418 
   419       public string ManufacturerName { get; private set; }
   420 
   421       public string Version { get; private set; }
   422 
   423       public int CoreCount { get; private set; }
   424 
   425       public int CoreEnabled { get; private set; }
   426 
   427       public int ThreadCount { get; private set; }
   428      
   429       public int ExternalClock { get; private set; }
   430     }
   431 
   432     public class MemoryDevice : Structure {
   433 
   434       private readonly string deviceLocator;
   435       private readonly string bankLocator;
   436       private readonly string manufacturerName;
   437       private readonly string serialNumber;
   438       private readonly string partNumber;
   439       private readonly int speed;
   440 
   441       public MemoryDevice(byte type, ushort handle, byte[] data,
   442         string[] strings)
   443         : base(type, handle, data, strings) 
   444       {
   445         this.deviceLocator = GetString(0x10).Trim();
   446         this.bankLocator = GetString(0x11).Trim();
   447         this.manufacturerName = GetString(0x17).Trim();
   448         this.serialNumber = GetString(0x18).Trim();
   449         this.partNumber = GetString(0x1A).Trim();
   450         this.speed = GetWord(0x15);
   451       }
   452 
   453       public string DeviceLocator { get { return deviceLocator; } }
   454 
   455       public string BankLocator { get { return bankLocator; } }
   456 
   457       public string ManufacturerName { get { return manufacturerName; } }
   458 
   459       public string SerialNumber { get { return serialNumber; } }
   460 
   461       public string PartNumber { get { return partNumber; } }
   462 
   463       public int Speed { get { return speed; } }
   464 
   465     }
   466   }
   467 }