Added (partial) SMBIOS support for Linux by reading from sysfs.
authormoel.mich
Mon, 07 Jun 2010 20:03:48 +0000
changeset 136fa2957aa0699
parent 135 51a15cf90d22
child 137 9ed52fa44ecf
Added (partial) SMBIOS support for Linux by reading from sysfs.
GUI/MainForm.cs
Hardware/LPC/LMSensors.cs
Hardware/Mainboard/Mainboard.cs
Hardware/Mainboard/SMBIOS.cs
     1.1 --- a/GUI/MainForm.cs	Sun Jun 06 14:44:53 2010 +0000
     1.2 +++ b/GUI/MainForm.cs	Mon Jun 07 20:03:48 2010 +0000
     1.3 @@ -140,10 +140,9 @@
     1.4          UnitManager.TemperatureUnit == TemperatureUnit.Celcius;
     1.5        fahrenheitToolStripMenuItem.Checked = !celciusToolStripMenuItem.Checked;
     1.6  
     1.7 -      // Hide the system tray and auto startup menu items on Unix
     1.8 +      // Hide the auto startup menu item on Unix
     1.9        int p = (int)System.Environment.OSVersion.Platform;
    1.10        if ((p == 4) || (p == 128)) {
    1.11 -        minTrayMenuItem.Visible = false;
    1.12          startupMenuItem.Visible = false;
    1.13        }
    1.14        
     2.1 --- a/Hardware/LPC/LMSensors.cs	Sun Jun 06 14:44:53 2010 +0000
     2.2 +++ b/Hardware/LPC/LMSensors.cs	Mon Jun 07 20:03:48 2010 +0000
     2.3 @@ -1,191 +1,191 @@
     2.4 -/*
     2.5 -  
     2.6 -  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     2.7 -
     2.8 -  The contents of this file are subject to the Mozilla Public License Version
     2.9 -  1.1 (the "License"); you may not use this file except in compliance with
    2.10 -  the License. You may obtain a copy of the License at
    2.11 - 
    2.12 -  http://www.mozilla.org/MPL/
    2.13 -
    2.14 -  Software distributed under the License is distributed on an "AS IS" basis,
    2.15 -  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    2.16 -  for the specific language governing rights and limitations under the License.
    2.17 -
    2.18 -  The Original Code is the Open Hardware Monitor code.
    2.19 -
    2.20 -  The Initial Developer of the Original Code is 
    2.21 -  Michael Möller <m.moeller@gmx.ch>.
    2.22 -  Portions created by the Initial Developer are Copyright (C) 2009-2010
    2.23 -  the Initial Developer. All Rights Reserved.
    2.24 -
    2.25 -  Contributor(s):
    2.26 -
    2.27 -  Alternatively, the contents of this file may be used under the terms of
    2.28 -  either the GNU General Public License Version 2 or later (the "GPL"), or
    2.29 -  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    2.30 -  in which case the provisions of the GPL or the LGPL are applicable instead
    2.31 -  of those above. If you wish to allow use of your version of this file only
    2.32 -  under the terms of either the GPL or the LGPL, and not to allow others to
    2.33 -  use your version of this file under the terms of the MPL, indicate your
    2.34 -  decision by deleting the provisions above and replace them with the notice
    2.35 -  and other provisions required by the GPL or the LGPL. If you do not delete
    2.36 -  the provisions above, a recipient may use your version of this file under
    2.37 -  the terms of any one of the MPL, the GPL or the LGPL.
    2.38 - 
    2.39 -*/
    2.40 -
    2.41 -using System;
    2.42 -using System.Collections.Generic;
    2.43 -using System.IO;
    2.44 -
    2.45 -namespace OpenHardwareMonitor.Hardware.LPC {
    2.46 -
    2.47 -  public class LMSensors {
    2.48 -
    2.49 -    private List<LMChip> lmChips = new List<LMChip>();
    2.50 -    
    2.51 -    public LMSensors () {
    2.52 -      string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/");
    2.53 -      foreach (string path in devicePaths) {
    2.54 -        string name = null;
    2.55 -        try {
    2.56 -          StreamReader reader = new StreamReader(path + "/device/name");
    2.57 -          name = reader.ReadLine();
    2.58 -          reader.Close();
    2.59 -        } catch (IOException) { }
    2.60 -        switch (name) {
    2.61 -          case "f71858fg": 
    2.62 -            lmChips.Add(new LMChip(Chip.F71858, path + "/device")); break; 
    2.63 -          case "f71862fg": 
    2.64 -            lmChips.Add(new LMChip(Chip.F71862, path + "/device")); break; 
    2.65 -          case "f71882fg": 
    2.66 -            lmChips.Add(new LMChip(Chip.F71882, path + "/device")); break; 
    2.67 -          case "f71889fg": 
    2.68 -            lmChips.Add(new LMChip(Chip.F71889F, path + "/device")); break; 
    2.69 -        
    2.70 -          case "it8712": 
    2.71 -            lmChips.Add(new LMChip(Chip.IT8712F, path + "/device")); break; 
    2.72 -          case "it8716": 
    2.73 -            lmChips.Add(new LMChip(Chip.IT8716F, path + "/device")); break; 
    2.74 -          case "it8718": 
    2.75 -            lmChips.Add(new LMChip(Chip.IT8718F, path + "/device")); break; 
    2.76 -          case "it8720": 
    2.77 -            lmChips.Add(new LMChip(Chip.IT8720F, path + "/device")); break; 
    2.78 -          
    2.79 -          case "w83627ehf": 
    2.80 -            lmChips.Add(new LMChip(Chip.W83627EHF, path + "/device")); break;                               
    2.81 -          case "w83627dhg": 
    2.82 -            lmChips.Add(new LMChip(Chip.W83627DHG, path + "/device")); break;     
    2.83 -          case "w83667hg": 
    2.84 -            lmChips.Add(new LMChip(Chip.W83667HG, path + "/device")); break;               
    2.85 -          case "w83627hf": 
    2.86 -            lmChips.Add(new LMChip(Chip.W83627HF, path + "/device")); break;
    2.87 -          case "w83627thf": 
    2.88 -            lmChips.Add(new LMChip(Chip.W83627THF, path + "/device")); break;   
    2.89 -          case "w83687thf": 
    2.90 -            lmChips.Add(new LMChip(Chip.W83687THF, path + "/device")); break;             
    2.91 -        }
    2.92 -      }
    2.93 -    }
    2.94 -    
    2.95 -    public void Close() {
    2.96 -      foreach (LMChip lmChip in lmChips)
    2.97 -        lmChip.Close();
    2.98 -    }
    2.99 -    
   2.100 -    public ISuperIO[] SuperIO {
   2.101 -      get {
   2.102 -        return lmChips.ToArray();
   2.103 -      }
   2.104 -    }
   2.105 -    
   2.106 -    private class LMChip : ISuperIO {
   2.107 -      
   2.108 -      private string path;
   2.109 -      private Chip chip;
   2.110 -      
   2.111 -      private float?[] voltages;
   2.112 -      private float?[] temperatures ;
   2.113 -      private float?[] fans;
   2.114 -      
   2.115 -      private StreamReader[] voltageReaders;
   2.116 -      private StreamReader[] temperatureReaders;
   2.117 -      private StreamReader[] fanReaders;
   2.118 -      
   2.119 -      public Chip Chip { get { return chip; } }
   2.120 -      public float?[] Voltages { get { return voltages; } }
   2.121 -      public float?[] Temperatures { get { return temperatures; } }
   2.122 -      public float?[] Fans { get { return fans; } }
   2.123 -      
   2.124 -      
   2.125 -      public LMChip(Chip chip, string path) {
   2.126 -        this.path = path;
   2.127 -        this.chip = chip;
   2.128 -        
   2.129 -        string[] voltagePaths = Directory.GetFiles(path, "in*_input");        
   2.130 -        this.voltages = new float?[voltagePaths.Length];
   2.131 -        this.voltageReaders = new StreamReader[voltagePaths.Length];
   2.132 -        for (int i = 0; i < voltagePaths.Length; i++) 
   2.133 -         voltageReaders[i] = new StreamReader(voltagePaths[i]); 
   2.134 -        
   2.135 -        string[] temperaturePaths = Directory.GetFiles(path, "temp*_input");        
   2.136 -        this.temperatures = new float?[temperaturePaths.Length];
   2.137 -        this.temperatureReaders = new StreamReader[temperaturePaths.Length];
   2.138 -        for (int i = 0; i < temperaturePaths.Length; i++) 
   2.139 -         temperatureReaders[i] = new StreamReader(temperaturePaths[i]);    
   2.140 -        
   2.141 -        string[] fanPaths = Directory.GetFiles(path, "fan*_input");        
   2.142 -        this.fans = new float?[fanPaths.Length];
   2.143 -        this.fanReaders = new StreamReader[fanPaths.Length];
   2.144 -        for (int i = 0; i < fanPaths.Length; i++) 
   2.145 -         fanReaders[i] = new StreamReader(fanPaths[i]);    
   2.146 -      }
   2.147 -      
   2.148 -      public string GetReport() {
   2.149 -        return null;
   2.150 -      }
   2.151 -      
   2.152 -      public void Update() {
   2.153 -        for (int i = 0; i < voltages.Length; i++) {
   2.154 -          voltageReaders[i].BaseStream.Seek(0, SeekOrigin.Begin);
   2.155 -          string s = voltageReaders[i].ReadLine();  
   2.156 -          try {
   2.157 -            voltages[i] = 0.001f * long.Parse(s);
   2.158 -          } catch {
   2.159 -            voltages[i] = null;
   2.160 -          }
   2.161 -        }
   2.162 -        
   2.163 -        for (int i = 0; i < temperatures.Length; i++) {
   2.164 -          temperatureReaders[i].BaseStream.Seek(0, SeekOrigin.Begin);
   2.165 -          string s = temperatureReaders[i].ReadLine();  
   2.166 -          try {
   2.167 -            temperatures[i] = 0.001f * long.Parse(s);           
   2.168 -          } catch {
   2.169 -            temperatures[i] = null; 
   2.170 -          }
   2.171 -        }
   2.172 -        
   2.173 -        for (int i = 0; i < fans.Length; i++) {
   2.174 -          fanReaders[i].BaseStream.Seek(0, SeekOrigin.Begin);
   2.175 -          string s = fanReaders[i].ReadLine();  
   2.176 -          try {
   2.177 -            fans[i] = long.Parse(s);           
   2.178 -          } catch {
   2.179 -            fans[i] = null; 
   2.180 -          }
   2.181 -        }
   2.182 -      }
   2.183 -      
   2.184 -      public void Close() {
   2.185 -        foreach (StreamReader reader in voltageReaders)
   2.186 -          reader.Close();
   2.187 -        foreach (StreamReader reader in temperatureReaders)
   2.188 -          reader.Close();        
   2.189 -        foreach (StreamReader reader in fanReaders)
   2.190 -          reader.Close();
   2.191 -      }      
   2.192 -    }
   2.193 -  }
   2.194 -}
   2.195 +/*
   2.196 +  
   2.197 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
   2.198 +
   2.199 +  The contents of this file are subject to the Mozilla Public License Version
   2.200 +  1.1 (the "License"); you may not use this file except in compliance with
   2.201 +  the License. You may obtain a copy of the License at
   2.202 + 
   2.203 +  http://www.mozilla.org/MPL/
   2.204 +
   2.205 +  Software distributed under the License is distributed on an "AS IS" basis,
   2.206 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   2.207 +  for the specific language governing rights and limitations under the License.
   2.208 +
   2.209 +  The Original Code is the Open Hardware Monitor code.
   2.210 +
   2.211 +  The Initial Developer of the Original Code is 
   2.212 +  Michael Möller <m.moeller@gmx.ch>.
   2.213 +  Portions created by the Initial Developer are Copyright (C) 2009-2010
   2.214 +  the Initial Developer. All Rights Reserved.
   2.215 +
   2.216 +  Contributor(s):
   2.217 +
   2.218 +  Alternatively, the contents of this file may be used under the terms of
   2.219 +  either the GNU General Public License Version 2 or later (the "GPL"), or
   2.220 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   2.221 +  in which case the provisions of the GPL or the LGPL are applicable instead
   2.222 +  of those above. If you wish to allow use of your version of this file only
   2.223 +  under the terms of either the GPL or the LGPL, and not to allow others to
   2.224 +  use your version of this file under the terms of the MPL, indicate your
   2.225 +  decision by deleting the provisions above and replace them with the notice
   2.226 +  and other provisions required by the GPL or the LGPL. If you do not delete
   2.227 +  the provisions above, a recipient may use your version of this file under
   2.228 +  the terms of any one of the MPL, the GPL or the LGPL.
   2.229 + 
   2.230 +*/
   2.231 +
   2.232 +using System;
   2.233 +using System.Collections.Generic;
   2.234 +using System.IO;
   2.235 +
   2.236 +namespace OpenHardwareMonitor.Hardware.LPC {
   2.237 +
   2.238 +  public class LMSensors {
   2.239 +
   2.240 +    private List<LMChip> lmChips = new List<LMChip>();
   2.241 +
   2.242 +    public LMSensors() {
   2.243 +      string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/");
   2.244 +      foreach (string path in devicePaths) {
   2.245 +        string name = null;
   2.246 +        try {
   2.247 +          StreamReader reader = new StreamReader(path + "/device/name");
   2.248 +          name = reader.ReadLine();
   2.249 +          reader.Close();
   2.250 +        } catch (IOException) { }
   2.251 +        switch (name) {
   2.252 +          case "f71858fg":
   2.253 +            lmChips.Add(new LMChip(Chip.F71858, path + "/device")); break;
   2.254 +          case "f71862fg":
   2.255 +            lmChips.Add(new LMChip(Chip.F71862, path + "/device")); break;
   2.256 +          case "f71882fg":
   2.257 +            lmChips.Add(new LMChip(Chip.F71882, path + "/device")); break;
   2.258 +          case "f71889fg":
   2.259 +            lmChips.Add(new LMChip(Chip.F71889F, path + "/device")); break;
   2.260 +
   2.261 +          case "it8712":
   2.262 +            lmChips.Add(new LMChip(Chip.IT8712F, path + "/device")); break;
   2.263 +          case "it8716":
   2.264 +            lmChips.Add(new LMChip(Chip.IT8716F, path + "/device")); break;
   2.265 +          case "it8718":
   2.266 +            lmChips.Add(new LMChip(Chip.IT8718F, path + "/device")); break;
   2.267 +          case "it8720":
   2.268 +            lmChips.Add(new LMChip(Chip.IT8720F, path + "/device")); break;
   2.269 +
   2.270 +          case "w83627ehf":
   2.271 +            lmChips.Add(new LMChip(Chip.W83627EHF, path + "/device")); break;
   2.272 +          case "w83627dhg":
   2.273 +            lmChips.Add(new LMChip(Chip.W83627DHG, path + "/device")); break;
   2.274 +          case "w83667hg":
   2.275 +            lmChips.Add(new LMChip(Chip.W83667HG, path + "/device")); break;
   2.276 +          case "w83627hf":
   2.277 +            lmChips.Add(new LMChip(Chip.W83627HF, path + "/device")); break;
   2.278 +          case "w83627thf":
   2.279 +            lmChips.Add(new LMChip(Chip.W83627THF, path + "/device")); break;
   2.280 +          case "w83687thf":
   2.281 +            lmChips.Add(new LMChip(Chip.W83687THF, path + "/device")); break;
   2.282 +        }
   2.283 +      }
   2.284 +    }
   2.285 +
   2.286 +    public void Close() {
   2.287 +      foreach (LMChip lmChip in lmChips)
   2.288 +        lmChip.Close();
   2.289 +    }
   2.290 +
   2.291 +    public ISuperIO[] SuperIO {
   2.292 +      get {
   2.293 +        return lmChips.ToArray();
   2.294 +      }
   2.295 +    }
   2.296 +
   2.297 +    private class LMChip : ISuperIO {
   2.298 +
   2.299 +      private string path;
   2.300 +      private Chip chip;
   2.301 +
   2.302 +      private float?[] voltages;
   2.303 +      private float?[] temperatures;
   2.304 +      private float?[] fans;
   2.305 +
   2.306 +      private StreamReader[] voltageReaders;
   2.307 +      private StreamReader[] temperatureReaders;
   2.308 +      private StreamReader[] fanReaders;
   2.309 +
   2.310 +      public Chip Chip { get { return chip; } }
   2.311 +      public float?[] Voltages { get { return voltages; } }
   2.312 +      public float?[] Temperatures { get { return temperatures; } }
   2.313 +      public float?[] Fans { get { return fans; } }
   2.314 +
   2.315 +
   2.316 +      public LMChip(Chip chip, string path) {
   2.317 +        this.path = path;
   2.318 +        this.chip = chip;
   2.319 +
   2.320 +        string[] voltagePaths = Directory.GetFiles(path, "in*_input");
   2.321 +        this.voltages = new float?[voltagePaths.Length];
   2.322 +        this.voltageReaders = new StreamReader[voltagePaths.Length];
   2.323 +        for (int i = 0; i < voltagePaths.Length; i++)
   2.324 +          voltageReaders[i] = new StreamReader(voltagePaths[i]);
   2.325 +
   2.326 +        string[] temperaturePaths = Directory.GetFiles(path, "temp*_input");
   2.327 +        this.temperatures = new float?[temperaturePaths.Length];
   2.328 +        this.temperatureReaders = new StreamReader[temperaturePaths.Length];
   2.329 +        for (int i = 0; i < temperaturePaths.Length; i++)
   2.330 +          temperatureReaders[i] = new StreamReader(temperaturePaths[i]);
   2.331 +
   2.332 +        string[] fanPaths = Directory.GetFiles(path, "fan*_input");
   2.333 +        this.fans = new float?[fanPaths.Length];
   2.334 +        this.fanReaders = new StreamReader[fanPaths.Length];
   2.335 +        for (int i = 0; i < fanPaths.Length; i++)
   2.336 +          fanReaders[i] = new StreamReader(fanPaths[i]);
   2.337 +      }
   2.338 +
   2.339 +      public string GetReport() {
   2.340 +        return null;
   2.341 +      }
   2.342 +
   2.343 +      public void Update() {
   2.344 +        for (int i = 0; i < voltages.Length; i++) {
   2.345 +          voltageReaders[i].BaseStream.Seek(0, SeekOrigin.Begin);
   2.346 +          string s = voltageReaders[i].ReadLine();
   2.347 +          try {
   2.348 +            voltages[i] = 0.001f * long.Parse(s);
   2.349 +          } catch {
   2.350 +            voltages[i] = null;
   2.351 +          }
   2.352 +        }
   2.353 +
   2.354 +        for (int i = 0; i < temperatures.Length; i++) {
   2.355 +          temperatureReaders[i].BaseStream.Seek(0, SeekOrigin.Begin);
   2.356 +          string s = temperatureReaders[i].ReadLine();
   2.357 +          try {
   2.358 +            temperatures[i] = 0.001f * long.Parse(s);
   2.359 +          } catch {
   2.360 +            temperatures[i] = null;
   2.361 +          }
   2.362 +        }
   2.363 +
   2.364 +        for (int i = 0; i < fans.Length; i++) {
   2.365 +          fanReaders[i].BaseStream.Seek(0, SeekOrigin.Begin);
   2.366 +          string s = fanReaders[i].ReadLine();
   2.367 +          try {
   2.368 +            fans[i] = long.Parse(s);
   2.369 +          } catch {
   2.370 +            fans[i] = null;
   2.371 +          }
   2.372 +        }
   2.373 +      }
   2.374 +
   2.375 +      public void Close() {
   2.376 +        foreach (StreamReader reader in voltageReaders)
   2.377 +          reader.Close();
   2.378 +        foreach (StreamReader reader in temperatureReaders)
   2.379 +          reader.Close();
   2.380 +        foreach (StreamReader reader in fanReaders)
   2.381 +          reader.Close();
   2.382 +      }
   2.383 +    }
   2.384 +  }
   2.385 +}
     3.1 --- a/Hardware/Mainboard/Mainboard.cs	Sun Jun 06 14:44:53 2010 +0000
     3.2 +++ b/Hardware/Mainboard/Mainboard.cs	Mon Jun 07 20:03:48 2010 +0000
     3.3 @@ -107,7 +107,8 @@
     3.4        r.AppendLine();           
     3.5        r.Append(smbios.GetReport());
     3.6  
     3.7 -      r.Append(lpcio.GetReport());
     3.8 +      if (lpcio != null)
     3.9 +        r.Append(lpcio.GetReport());
    3.10  
    3.11        return r.ToString();
    3.12      }
     4.1 --- a/Hardware/Mainboard/SMBIOS.cs	Sun Jun 06 14:44:53 2010 +0000
     4.2 +++ b/Hardware/Mainboard/SMBIOS.cs	Mon Jun 07 20:03:48 2010 +0000
     4.3 @@ -37,6 +37,7 @@
     4.4  
     4.5  using System;
     4.6  using System.Collections.Generic;
     4.7 +using System.IO;
     4.8  using System.Management;
     4.9  using System.Text;
    4.10  
    4.11 @@ -44,76 +45,104 @@
    4.12  
    4.13    public class SMBIOS {
    4.14  
    4.15 +    private byte[] raw;
    4.16      private Structure[] table;
    4.17  
    4.18      private BIOSInformation biosInformation = null;
    4.19      private BaseBoardInformation baseBoardInformation = null;
    4.20  
    4.21 +    private string ReadSysFS(string path) {
    4.22 +      try {
    4.23 +        if (File.Exists(path)) {
    4.24 +          using (StreamReader reader = new StreamReader(path)) 
    4.25 +            return reader.ReadLine();
    4.26 +        } else {
    4.27 +          return null;
    4.28 +        }
    4.29 +      } catch {
    4.30 +        return null;
    4.31 +      }
    4.32 +    }
    4.33 +    
    4.34      public SMBIOS() {
    4.35        int p = (int)System.Environment.OSVersion.Platform;
    4.36 -      if ((p == 4) || (p == 128))
    4.37 -        return;
    4.38 -      
    4.39 -      List<Structure> structureList = new List<Structure>();
    4.40 +      if ((p == 4) || (p == 128)) {
    4.41 +        this.raw = null;
    4.42 +        this.table = null;
    4.43 +        
    4.44 +        string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor");
    4.45 +        string boardName = ReadSysFS("/sys/class/dmi/id/board_name");        
    4.46 +        string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version");        
    4.47 +        this.baseBoardInformation = new BaseBoardInformation(
    4.48 +          boardVendor, boardName, boardVersion, null);
    4.49 +        
    4.50 +        string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor");
    4.51 +        string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version");
    4.52 +        this.biosInformation = new BIOSInformation(biosVendor, biosVersion);
    4.53 +        
    4.54 +      } else {              
    4.55 +        List<Structure> structureList = new List<Structure>();
    4.56  
    4.57 -      byte[] raw = null;
    4.58 -      try {
    4.59 -        ManagementObjectCollection collection = new ManagementObjectSearcher(
    4.60 -          "root\\WMI", "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables").Get();
    4.61 -       
    4.62 -        foreach (ManagementObject mo in collection) {
    4.63 -          raw = (byte[])mo["SMBiosData"];
    4.64 -          break;
    4.65 -        }
    4.66 -      } catch { }      
    4.67 -
    4.68 -      if (raw != null && raw.Length > 0) {
    4.69 -        int offset = 0;
    4.70 -        byte type = raw[offset];
    4.71 -        while (offset + 4 < raw.Length && type != 127) {
    4.72 -
    4.73 -          type = raw[offset];
    4.74 -          int length = raw[offset + 1];
    4.75 -          ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
    4.76 -
    4.77 -          if (offset + length > raw.Length)
    4.78 +        raw = null;
    4.79 +        try {
    4.80 +          ManagementObjectCollection collection = 
    4.81 +            new ManagementObjectSearcher("root\\WMI", 
    4.82 +              "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables").Get();
    4.83 +         
    4.84 +          foreach (ManagementObject mo in collection) {
    4.85 +            raw = (byte[])mo["SMBiosData"];
    4.86              break;
    4.87 -          byte[] data = new byte[length];
    4.88 -          Array.Copy(raw, offset, data, 0, length);
    4.89 -          offset += length;
    4.90 -
    4.91 -          List<string> stringsList = new List<string>();
    4.92 -          if (offset < raw.Length && raw[offset] == 0)
    4.93 -            offset++;
    4.94 -
    4.95 -          while (offset < raw.Length && raw[offset] != 0) {
    4.96 -            StringBuilder sb = new StringBuilder();
    4.97 +          }
    4.98 +        } catch { }
    4.99 +  
   4.100 +        if (raw != null && raw.Length > 0) {
   4.101 +          int offset = 0;
   4.102 +          byte type = raw[offset];
   4.103 +          while (offset + 4 < raw.Length && type != 127) {
   4.104 +  
   4.105 +            type = raw[offset];
   4.106 +            int length = raw[offset + 1];
   4.107 +            ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]);
   4.108 +  
   4.109 +            if (offset + length > raw.Length)
   4.110 +              break;
   4.111 +            byte[] data = new byte[length];
   4.112 +            Array.Copy(raw, offset, data, 0, length);
   4.113 +            offset += length;
   4.114 +  
   4.115 +            List<string> stringsList = new List<string>();
   4.116 +            if (offset < raw.Length && raw[offset] == 0)
   4.117 +              offset++;
   4.118 +  
   4.119              while (offset < raw.Length && raw[offset] != 0) {
   4.120 -              sb.Append((char)raw[offset]); offset++;
   4.121 +              StringBuilder sb = new StringBuilder();
   4.122 +              while (offset < raw.Length && raw[offset] != 0) {
   4.123 +                sb.Append((char)raw[offset]); offset++;
   4.124 +              }
   4.125 +              offset++;
   4.126 +              stringsList.Add(sb.ToString());
   4.127              }
   4.128              offset++;
   4.129 -            stringsList.Add(sb.ToString());
   4.130 -          }
   4.131 -          offset++;
   4.132 -          switch (type) {
   4.133 -            case 0x00:
   4.134 -              this.biosInformation = new BIOSInformation(
   4.135 -                type, handle, data, stringsList.ToArray());
   4.136 -              structureList.Add(this.biosInformation); break;
   4.137 -            case 0x02: this.baseBoardInformation = new BaseBoardInformation(
   4.138 -                type, handle, data, stringsList.ToArray());
   4.139 -              structureList.Add(this.baseBoardInformation); break;
   4.140 -            default: structureList.Add(new Structure(
   4.141 -              type, handle, data, stringsList.ToArray())); break;
   4.142 +            switch (type) {
   4.143 +              case 0x00:
   4.144 +                this.biosInformation = new BIOSInformation(
   4.145 +                  type, handle, data, stringsList.ToArray());
   4.146 +                structureList.Add(this.biosInformation); break;
   4.147 +              case 0x02: this.baseBoardInformation = new BaseBoardInformation(
   4.148 +                  type, handle, data, stringsList.ToArray());
   4.149 +                structureList.Add(this.baseBoardInformation); break;
   4.150 +              default: structureList.Add(new Structure(
   4.151 +                type, handle, data, stringsList.ToArray())); break;
   4.152 +            }
   4.153            }
   4.154          }
   4.155 +              
   4.156 +        table = structureList.ToArray();
   4.157        }
   4.158 -            
   4.159 -      table = structureList.ToArray();
   4.160      }
   4.161  
   4.162      public string GetReport() {
   4.163 -      StringBuilder r = new StringBuilder();      
   4.164 +      StringBuilder r = new StringBuilder();
   4.165  
   4.166        if (biosInformation != null) {
   4.167          r.Append("BIOS Vendor: "); r.AppendLine(biosInformation.Vendor);
   4.168 @@ -122,13 +151,31 @@
   4.169        }
   4.170  
   4.171        if (baseBoardInformation != null) {
   4.172 -        r.Append("Mainboard Manufacturer: "); 
   4.173 +        r.Append("Mainboard Manufacturer: ");
   4.174          r.AppendLine(baseBoardInformation.ManufacturerName);
   4.175 -        r.Append("Mainboard Name: "); 
   4.176 +        r.Append("Mainboard Name: ");
   4.177          r.AppendLine(baseBoardInformation.ProductName);
   4.178          r.AppendLine();
   4.179        }
   4.180 -     
   4.181 +
   4.182 +      if (raw != null) {
   4.183 +        string base64 = Convert.ToBase64String(raw);
   4.184 +        r.AppendLine("SMBIOS Table");
   4.185 +        r.AppendLine();
   4.186 +
   4.187 +        for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
   4.188 +          r.Append(" ");
   4.189 +          for (int j = 0; j < 0x40; j++) {
   4.190 +            int index = (i << 6) | j;
   4.191 +            if (index < base64.Length) {              
   4.192 +              r.Append(base64[index]);
   4.193 +            }
   4.194 +          }
   4.195 +          r.AppendLine();
   4.196 +        }
   4.197 +        r.AppendLine();
   4.198 +      }
   4.199 +
   4.200        return r.ToString();
   4.201      }
   4.202  
   4.203 @@ -167,16 +214,23 @@
   4.204  
   4.205        public ushort Handle { get { return handle; } }
   4.206      }
   4.207 -
   4.208 +      
   4.209      public class BIOSInformation : Structure {
   4.210  
   4.211        private string vendor;
   4.212        private string version;
   4.213 -
   4.214 +      
   4.215 +      public BIOSInformation(string vendor, string version) 
   4.216 +        : base (0x00, 0, null, null) 
   4.217 +      {
   4.218 +        this.vendor = vendor;
   4.219 +        this.version = version;
   4.220 +      }
   4.221 +      
   4.222        public BIOSInformation(byte type, ushort handle, byte[] data,
   4.223          string[] strings)
   4.224 -        : base(type, handle, data, strings) {
   4.225 -
   4.226 +        : base(type, handle, data, strings) 
   4.227 +      {
   4.228          this.vendor = GetString(0x04);
   4.229          this.version = GetString(0x05);
   4.230        }
   4.231 @@ -195,15 +249,9 @@
   4.232        private Manufacturer manufacturer;
   4.233        private Model model;
   4.234  
   4.235 -      public BaseBoardInformation(byte type, ushort handle, byte[] data,
   4.236 -        string[] strings)
   4.237 -        : base(type, handle, data, strings) {
   4.238 -
   4.239 -        this.manufacturerName = GetString(0x04).Trim();
   4.240 -        this.productName = GetString(0x05).Trim();
   4.241 -        this.version = GetString(0x06).Trim();
   4.242 -        this.serialNumber = GetString(0x07).Trim();
   4.243 -
   4.244 +      private void SetManufacturerName(string manufacturerName) {
   4.245 +        this.manufacturerName = manufacturerName;
   4.246 +        
   4.247          switch (manufacturerName) {
   4.248            case "ASUSTeK Computer INC.":
   4.249              manufacturer = Manufacturer.ASUS; break;
   4.250 @@ -224,7 +272,11 @@
   4.251            default:
   4.252              manufacturer = Manufacturer.Unknown; break;
   4.253          }
   4.254 -
   4.255 +      }
   4.256 +      
   4.257 +      private void SetProductName(string productName) {
   4.258 +        this.productName = productName;
   4.259 +        
   4.260          switch (productName) {
   4.261            case "Crosshair III Formula":
   4.262              model = Model.Crosshair_III_Formula; break;
   4.263 @@ -258,7 +310,27 @@
   4.264              model = Model.Unknown; break;
   4.265          }
   4.266        }
   4.267 +      
   4.268 +      public BaseBoardInformation(string manufacturerName, string productName, 
   4.269 +        string version, string serialNumber) 
   4.270 +        : base(0x02, 0, null, null) 
   4.271 +      {        
   4.272 +        SetManufacturerName(manufacturerName);
   4.273 +        SetProductName(productName);
   4.274 +        this.version = version;
   4.275 +        this.serialNumber = serialNumber;
   4.276 +      }
   4.277 +      
   4.278 +      public BaseBoardInformation(byte type, ushort handle, byte[] data,
   4.279 +        string[] strings)
   4.280 +        : base(type, handle, data, strings) {
   4.281  
   4.282 +        SetManufacturerName(GetString(0x04).Trim());
   4.283 +        SetProductName(GetString(0x05).Trim());
   4.284 +        this.version = GetString(0x06).Trim();
   4.285 +        this.serialNumber = GetString(0x07).Trim();               
   4.286 +      }
   4.287 +      
   4.288        public string ManufacturerName { get { return manufacturerName; } }
   4.289  
   4.290        public string ProductName { get { return productName; } }