# HG changeset patch # User moel.mich # Date 1275941028 0 # Node ID fa2957aa06996b1879449477c3e40441791e6976 # Parent 51a15cf90d22cfb83f88072343882a51484ab2c8 Added (partial) SMBIOS support for Linux by reading from sysfs. diff -r 51a15cf90d22 -r fa2957aa0699 GUI/MainForm.cs --- a/GUI/MainForm.cs Sun Jun 06 14:44:53 2010 +0000 +++ b/GUI/MainForm.cs Mon Jun 07 20:03:48 2010 +0000 @@ -140,10 +140,9 @@ UnitManager.TemperatureUnit == TemperatureUnit.Celcius; fahrenheitToolStripMenuItem.Checked = !celciusToolStripMenuItem.Checked; - // Hide the system tray and auto startup menu items on Unix + // Hide the auto startup menu item on Unix int p = (int)System.Environment.OSVersion.Platform; if ((p == 4) || (p == 128)) { - minTrayMenuItem.Visible = false; startupMenuItem.Visible = false; } diff -r 51a15cf90d22 -r fa2957aa0699 Hardware/LPC/LMSensors.cs --- a/Hardware/LPC/LMSensors.cs Sun Jun 06 14:44:53 2010 +0000 +++ b/Hardware/LPC/LMSensors.cs Mon Jun 07 20:03:48 2010 +0000 @@ -1,191 +1,191 @@ -/* - - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the License. - - The Original Code is the Open Hardware Monitor code. - - The Initial Developer of the Original Code is - Michael Möller . - Portions created by the Initial Developer are Copyright (C) 2009-2010 - the Initial Developer. All Rights Reserved. - - Contributor(s): - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - -*/ - -using System; -using System.Collections.Generic; -using System.IO; - -namespace OpenHardwareMonitor.Hardware.LPC { - - public class LMSensors { - - private List lmChips = new List(); - - public LMSensors () { - string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/"); - foreach (string path in devicePaths) { - string name = null; - try { - StreamReader reader = new StreamReader(path + "/device/name"); - name = reader.ReadLine(); - reader.Close(); - } catch (IOException) { } - switch (name) { - case "f71858fg": - lmChips.Add(new LMChip(Chip.F71858, path + "/device")); break; - case "f71862fg": - lmChips.Add(new LMChip(Chip.F71862, path + "/device")); break; - case "f71882fg": - lmChips.Add(new LMChip(Chip.F71882, path + "/device")); break; - case "f71889fg": - lmChips.Add(new LMChip(Chip.F71889F, path + "/device")); break; - - case "it8712": - lmChips.Add(new LMChip(Chip.IT8712F, path + "/device")); break; - case "it8716": - lmChips.Add(new LMChip(Chip.IT8716F, path + "/device")); break; - case "it8718": - lmChips.Add(new LMChip(Chip.IT8718F, path + "/device")); break; - case "it8720": - lmChips.Add(new LMChip(Chip.IT8720F, path + "/device")); break; - - case "w83627ehf": - lmChips.Add(new LMChip(Chip.W83627EHF, path + "/device")); break; - case "w83627dhg": - lmChips.Add(new LMChip(Chip.W83627DHG, path + "/device")); break; - case "w83667hg": - lmChips.Add(new LMChip(Chip.W83667HG, path + "/device")); break; - case "w83627hf": - lmChips.Add(new LMChip(Chip.W83627HF, path + "/device")); break; - case "w83627thf": - lmChips.Add(new LMChip(Chip.W83627THF, path + "/device")); break; - case "w83687thf": - lmChips.Add(new LMChip(Chip.W83687THF, path + "/device")); break; - } - } - } - - public void Close() { - foreach (LMChip lmChip in lmChips) - lmChip.Close(); - } - - public ISuperIO[] SuperIO { - get { - return lmChips.ToArray(); - } - } - - private class LMChip : ISuperIO { - - private string path; - private Chip chip; - - private float?[] voltages; - private float?[] temperatures ; - private float?[] fans; - - private StreamReader[] voltageReaders; - private StreamReader[] temperatureReaders; - private StreamReader[] fanReaders; - - public Chip Chip { get { return chip; } } - public float?[] Voltages { get { return voltages; } } - public float?[] Temperatures { get { return temperatures; } } - public float?[] Fans { get { return fans; } } - - - public LMChip(Chip chip, string path) { - this.path = path; - this.chip = chip; - - string[] voltagePaths = Directory.GetFiles(path, "in*_input"); - this.voltages = new float?[voltagePaths.Length]; - this.voltageReaders = new StreamReader[voltagePaths.Length]; - for (int i = 0; i < voltagePaths.Length; i++) - voltageReaders[i] = new StreamReader(voltagePaths[i]); - - string[] temperaturePaths = Directory.GetFiles(path, "temp*_input"); - this.temperatures = new float?[temperaturePaths.Length]; - this.temperatureReaders = new StreamReader[temperaturePaths.Length]; - for (int i = 0; i < temperaturePaths.Length; i++) - temperatureReaders[i] = new StreamReader(temperaturePaths[i]); - - string[] fanPaths = Directory.GetFiles(path, "fan*_input"); - this.fans = new float?[fanPaths.Length]; - this.fanReaders = new StreamReader[fanPaths.Length]; - for (int i = 0; i < fanPaths.Length; i++) - fanReaders[i] = new StreamReader(fanPaths[i]); - } - - public string GetReport() { - return null; - } - - public void Update() { - for (int i = 0; i < voltages.Length; i++) { - voltageReaders[i].BaseStream.Seek(0, SeekOrigin.Begin); - string s = voltageReaders[i].ReadLine(); - try { - voltages[i] = 0.001f * long.Parse(s); - } catch { - voltages[i] = null; - } - } - - for (int i = 0; i < temperatures.Length; i++) { - temperatureReaders[i].BaseStream.Seek(0, SeekOrigin.Begin); - string s = temperatureReaders[i].ReadLine(); - try { - temperatures[i] = 0.001f * long.Parse(s); - } catch { - temperatures[i] = null; - } - } - - for (int i = 0; i < fans.Length; i++) { - fanReaders[i].BaseStream.Seek(0, SeekOrigin.Begin); - string s = fanReaders[i].ReadLine(); - try { - fans[i] = long.Parse(s); - } catch { - fans[i] = null; - } - } - } - - public void Close() { - foreach (StreamReader reader in voltageReaders) - reader.Close(); - foreach (StreamReader reader in temperatureReaders) - reader.Close(); - foreach (StreamReader reader in fanReaders) - reader.Close(); - } - } - } -} +/* + + Version: MPL 1.1/GPL 2.0/LGPL 2.1 + + The contents of this file are subject to the Mozilla Public License Version + 1.1 (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the License. + + The Original Code is the Open Hardware Monitor code. + + The Initial Developer of the Original Code is + Michael Möller . + Portions created by the Initial Developer are Copyright (C) 2009-2010 + the Initial Developer. All Rights Reserved. + + Contributor(s): + + Alternatively, the contents of this file may be used under the terms of + either the GNU General Public License Version 2 or later (the "GPL"), or + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + in which case the provisions of the GPL or the LGPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of either the GPL or the LGPL, and not to allow others to + use your version of this file under the terms of the MPL, indicate your + decision by deleting the provisions above and replace them with the notice + and other provisions required by the GPL or the LGPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the MPL, the GPL or the LGPL. + +*/ + +using System; +using System.Collections.Generic; +using System.IO; + +namespace OpenHardwareMonitor.Hardware.LPC { + + public class LMSensors { + + private List lmChips = new List(); + + public LMSensors() { + string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/"); + foreach (string path in devicePaths) { + string name = null; + try { + StreamReader reader = new StreamReader(path + "/device/name"); + name = reader.ReadLine(); + reader.Close(); + } catch (IOException) { } + switch (name) { + case "f71858fg": + lmChips.Add(new LMChip(Chip.F71858, path + "/device")); break; + case "f71862fg": + lmChips.Add(new LMChip(Chip.F71862, path + "/device")); break; + case "f71882fg": + lmChips.Add(new LMChip(Chip.F71882, path + "/device")); break; + case "f71889fg": + lmChips.Add(new LMChip(Chip.F71889F, path + "/device")); break; + + case "it8712": + lmChips.Add(new LMChip(Chip.IT8712F, path + "/device")); break; + case "it8716": + lmChips.Add(new LMChip(Chip.IT8716F, path + "/device")); break; + case "it8718": + lmChips.Add(new LMChip(Chip.IT8718F, path + "/device")); break; + case "it8720": + lmChips.Add(new LMChip(Chip.IT8720F, path + "/device")); break; + + case "w83627ehf": + lmChips.Add(new LMChip(Chip.W83627EHF, path + "/device")); break; + case "w83627dhg": + lmChips.Add(new LMChip(Chip.W83627DHG, path + "/device")); break; + case "w83667hg": + lmChips.Add(new LMChip(Chip.W83667HG, path + "/device")); break; + case "w83627hf": + lmChips.Add(new LMChip(Chip.W83627HF, path + "/device")); break; + case "w83627thf": + lmChips.Add(new LMChip(Chip.W83627THF, path + "/device")); break; + case "w83687thf": + lmChips.Add(new LMChip(Chip.W83687THF, path + "/device")); break; + } + } + } + + public void Close() { + foreach (LMChip lmChip in lmChips) + lmChip.Close(); + } + + public ISuperIO[] SuperIO { + get { + return lmChips.ToArray(); + } + } + + private class LMChip : ISuperIO { + + private string path; + private Chip chip; + + private float?[] voltages; + private float?[] temperatures; + private float?[] fans; + + private StreamReader[] voltageReaders; + private StreamReader[] temperatureReaders; + private StreamReader[] fanReaders; + + public Chip Chip { get { return chip; } } + public float?[] Voltages { get { return voltages; } } + public float?[] Temperatures { get { return temperatures; } } + public float?[] Fans { get { return fans; } } + + + public LMChip(Chip chip, string path) { + this.path = path; + this.chip = chip; + + string[] voltagePaths = Directory.GetFiles(path, "in*_input"); + this.voltages = new float?[voltagePaths.Length]; + this.voltageReaders = new StreamReader[voltagePaths.Length]; + for (int i = 0; i < voltagePaths.Length; i++) + voltageReaders[i] = new StreamReader(voltagePaths[i]); + + string[] temperaturePaths = Directory.GetFiles(path, "temp*_input"); + this.temperatures = new float?[temperaturePaths.Length]; + this.temperatureReaders = new StreamReader[temperaturePaths.Length]; + for (int i = 0; i < temperaturePaths.Length; i++) + temperatureReaders[i] = new StreamReader(temperaturePaths[i]); + + string[] fanPaths = Directory.GetFiles(path, "fan*_input"); + this.fans = new float?[fanPaths.Length]; + this.fanReaders = new StreamReader[fanPaths.Length]; + for (int i = 0; i < fanPaths.Length; i++) + fanReaders[i] = new StreamReader(fanPaths[i]); + } + + public string GetReport() { + return null; + } + + public void Update() { + for (int i = 0; i < voltages.Length; i++) { + voltageReaders[i].BaseStream.Seek(0, SeekOrigin.Begin); + string s = voltageReaders[i].ReadLine(); + try { + voltages[i] = 0.001f * long.Parse(s); + } catch { + voltages[i] = null; + } + } + + for (int i = 0; i < temperatures.Length; i++) { + temperatureReaders[i].BaseStream.Seek(0, SeekOrigin.Begin); + string s = temperatureReaders[i].ReadLine(); + try { + temperatures[i] = 0.001f * long.Parse(s); + } catch { + temperatures[i] = null; + } + } + + for (int i = 0; i < fans.Length; i++) { + fanReaders[i].BaseStream.Seek(0, SeekOrigin.Begin); + string s = fanReaders[i].ReadLine(); + try { + fans[i] = long.Parse(s); + } catch { + fans[i] = null; + } + } + } + + public void Close() { + foreach (StreamReader reader in voltageReaders) + reader.Close(); + foreach (StreamReader reader in temperatureReaders) + reader.Close(); + foreach (StreamReader reader in fanReaders) + reader.Close(); + } + } + } +} diff -r 51a15cf90d22 -r fa2957aa0699 Hardware/Mainboard/Mainboard.cs --- a/Hardware/Mainboard/Mainboard.cs Sun Jun 06 14:44:53 2010 +0000 +++ b/Hardware/Mainboard/Mainboard.cs Mon Jun 07 20:03:48 2010 +0000 @@ -107,7 +107,8 @@ r.AppendLine(); r.Append(smbios.GetReport()); - r.Append(lpcio.GetReport()); + if (lpcio != null) + r.Append(lpcio.GetReport()); return r.ToString(); } diff -r 51a15cf90d22 -r fa2957aa0699 Hardware/Mainboard/SMBIOS.cs --- a/Hardware/Mainboard/SMBIOS.cs Sun Jun 06 14:44:53 2010 +0000 +++ b/Hardware/Mainboard/SMBIOS.cs Mon Jun 07 20:03:48 2010 +0000 @@ -37,6 +37,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Management; using System.Text; @@ -44,76 +45,104 @@ public class SMBIOS { + private byte[] raw; private Structure[] table; private BIOSInformation biosInformation = null; private BaseBoardInformation baseBoardInformation = null; + private string ReadSysFS(string path) { + try { + if (File.Exists(path)) { + using (StreamReader reader = new StreamReader(path)) + return reader.ReadLine(); + } else { + return null; + } + } catch { + return null; + } + } + public SMBIOS() { int p = (int)System.Environment.OSVersion.Platform; - if ((p == 4) || (p == 128)) - return; - - List structureList = new List(); + if ((p == 4) || (p == 128)) { + this.raw = null; + this.table = null; + + string boardVendor = ReadSysFS("/sys/class/dmi/id/board_vendor"); + string boardName = ReadSysFS("/sys/class/dmi/id/board_name"); + string boardVersion = ReadSysFS("/sys/class/dmi/id/board_version"); + this.baseBoardInformation = new BaseBoardInformation( + boardVendor, boardName, boardVersion, null); + + string biosVendor = ReadSysFS("/sys/class/dmi/id/bios_vendor"); + string biosVersion = ReadSysFS("/sys/class/dmi/id/bios_version"); + this.biosInformation = new BIOSInformation(biosVendor, biosVersion); + + } else { + List structureList = new List(); - byte[] raw = null; - try { - ManagementObjectCollection collection = new ManagementObjectSearcher( - "root\\WMI", "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables").Get(); - - foreach (ManagementObject mo in collection) { - raw = (byte[])mo["SMBiosData"]; - break; - } - } catch { } - - if (raw != null && raw.Length > 0) { - int offset = 0; - byte type = raw[offset]; - while (offset + 4 < raw.Length && type != 127) { - - type = raw[offset]; - int length = raw[offset + 1]; - ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]); - - if (offset + length > raw.Length) + raw = null; + try { + ManagementObjectCollection collection = + new ManagementObjectSearcher("root\\WMI", + "SELECT SMBiosData FROM MSSMBios_RawSMBiosTables").Get(); + + foreach (ManagementObject mo in collection) { + raw = (byte[])mo["SMBiosData"]; break; - byte[] data = new byte[length]; - Array.Copy(raw, offset, data, 0, length); - offset += length; - - List stringsList = new List(); - if (offset < raw.Length && raw[offset] == 0) - offset++; - - while (offset < raw.Length && raw[offset] != 0) { - StringBuilder sb = new StringBuilder(); + } + } catch { } + + if (raw != null && raw.Length > 0) { + int offset = 0; + byte type = raw[offset]; + while (offset + 4 < raw.Length && type != 127) { + + type = raw[offset]; + int length = raw[offset + 1]; + ushort handle = (ushort)((raw[offset + 2] << 8) | raw[offset + 3]); + + if (offset + length > raw.Length) + break; + byte[] data = new byte[length]; + Array.Copy(raw, offset, data, 0, length); + offset += length; + + List stringsList = new List(); + if (offset < raw.Length && raw[offset] == 0) + offset++; + while (offset < raw.Length && raw[offset] != 0) { - sb.Append((char)raw[offset]); offset++; + StringBuilder sb = new StringBuilder(); + while (offset < raw.Length && raw[offset] != 0) { + sb.Append((char)raw[offset]); offset++; + } + offset++; + stringsList.Add(sb.ToString()); } offset++; - stringsList.Add(sb.ToString()); - } - offset++; - switch (type) { - case 0x00: - this.biosInformation = new BIOSInformation( - type, handle, data, stringsList.ToArray()); - structureList.Add(this.biosInformation); break; - case 0x02: this.baseBoardInformation = new BaseBoardInformation( - type, handle, data, stringsList.ToArray()); - structureList.Add(this.baseBoardInformation); break; - default: structureList.Add(new Structure( - type, handle, data, stringsList.ToArray())); break; + switch (type) { + case 0x00: + this.biosInformation = new BIOSInformation( + type, handle, data, stringsList.ToArray()); + structureList.Add(this.biosInformation); break; + case 0x02: this.baseBoardInformation = new BaseBoardInformation( + type, handle, data, stringsList.ToArray()); + structureList.Add(this.baseBoardInformation); break; + default: structureList.Add(new Structure( + type, handle, data, stringsList.ToArray())); break; + } } } + + table = structureList.ToArray(); } - - table = structureList.ToArray(); } public string GetReport() { - StringBuilder r = new StringBuilder(); + StringBuilder r = new StringBuilder(); if (biosInformation != null) { r.Append("BIOS Vendor: "); r.AppendLine(biosInformation.Vendor); @@ -122,13 +151,31 @@ } if (baseBoardInformation != null) { - r.Append("Mainboard Manufacturer: "); + r.Append("Mainboard Manufacturer: "); r.AppendLine(baseBoardInformation.ManufacturerName); - r.Append("Mainboard Name: "); + r.Append("Mainboard Name: "); r.AppendLine(baseBoardInformation.ProductName); r.AppendLine(); } - + + if (raw != null) { + string base64 = Convert.ToBase64String(raw); + r.AppendLine("SMBIOS Table"); + r.AppendLine(); + + for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) { + r.Append(" "); + for (int j = 0; j < 0x40; j++) { + int index = (i << 6) | j; + if (index < base64.Length) { + r.Append(base64[index]); + } + } + r.AppendLine(); + } + r.AppendLine(); + } + return r.ToString(); } @@ -167,16 +214,23 @@ public ushort Handle { get { return handle; } } } - + public class BIOSInformation : Structure { private string vendor; private string version; - + + public BIOSInformation(string vendor, string version) + : base (0x00, 0, null, null) + { + this.vendor = vendor; + this.version = version; + } + public BIOSInformation(byte type, ushort handle, byte[] data, string[] strings) - : base(type, handle, data, strings) { - + : base(type, handle, data, strings) + { this.vendor = GetString(0x04); this.version = GetString(0x05); } @@ -195,15 +249,9 @@ private Manufacturer manufacturer; private Model model; - public BaseBoardInformation(byte type, ushort handle, byte[] data, - string[] strings) - : base(type, handle, data, strings) { - - this.manufacturerName = GetString(0x04).Trim(); - this.productName = GetString(0x05).Trim(); - this.version = GetString(0x06).Trim(); - this.serialNumber = GetString(0x07).Trim(); - + private void SetManufacturerName(string manufacturerName) { + this.manufacturerName = manufacturerName; + switch (manufacturerName) { case "ASUSTeK Computer INC.": manufacturer = Manufacturer.ASUS; break; @@ -224,7 +272,11 @@ default: manufacturer = Manufacturer.Unknown; break; } - + } + + private void SetProductName(string productName) { + this.productName = productName; + switch (productName) { case "Crosshair III Formula": model = Model.Crosshair_III_Formula; break; @@ -258,7 +310,27 @@ model = Model.Unknown; break; } } + + public BaseBoardInformation(string manufacturerName, string productName, + string version, string serialNumber) + : base(0x02, 0, null, null) + { + SetManufacturerName(manufacturerName); + SetProductName(productName); + this.version = version; + this.serialNumber = serialNumber; + } + + public BaseBoardInformation(byte type, ushort handle, byte[] data, + string[] strings) + : base(type, handle, data, strings) { + SetManufacturerName(GetString(0x04).Trim()); + SetProductName(GetString(0x05).Trim()); + this.version = GetString(0x06).Trim(); + this.serialNumber = GetString(0x07).Trim(); + } + public string ManufacturerName { get { return manufacturerName; } } public string ProductName { get { return productName; } }