# HG changeset patch # User moel.mich # Date 1310071269 0 # Node ID d882720734bff66cc389b6b07c69c0261dc7893d # Parent 31b2b9b5eae92d2dd581cf807dd23acb591b35b0 Added support for reading the TAMG ACPI table on Gigabyte mainboards. Fixed a small problem with HDD/SSD names (0 chars are trimmed now as well). diff -r 31b2b9b5eae9 -r d882720734bf Hardware/FirmwareTable.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hardware/FirmwareTable.cs Thu Jul 07 20:41:09 2011 +0000 @@ -0,0 +1,121 @@ +/* + + 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) 2011 + 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.ComponentModel; +using System.Runtime.InteropServices; +using System.Text; + +namespace OpenHardwareMonitor.Hardware { + + internal static class FirmwareTable { + + public static byte[] GetTable(Provider provider, string table) { + int id = table[3] << 24 | table[2] << 16 | table[1] << 8 | table[0]; + return GetTable(provider, id); + } + + public static byte[] GetTable(Provider provider, int table) { + + int size; + try { + size = NativeMethods.GetSystemFirmwareTable(provider, table, + IntPtr.Zero, 0); + } catch (DllNotFoundException) { return null; } + catch (EntryPointNotFoundException) { return null; } + + if (size <= 0) + return null; + + IntPtr nativeBuffer = Marshal.AllocHGlobal(size); + NativeMethods.GetSystemFirmwareTable(provider, table, nativeBuffer, size); + + if (Marshal.GetLastWin32Error() != 0) + return null; + + byte[] buffer = new byte[size]; + Marshal.Copy(nativeBuffer, buffer, 0, size); + Marshal.FreeHGlobal(nativeBuffer); + + return buffer; + } + + public static string[] EnumerateTables(Provider provider) { + int size; + try { + size = NativeMethods.EnumSystemFirmwareTables( + provider, IntPtr.Zero, 0); + } catch (DllNotFoundException) { return null; } + catch (EntryPointNotFoundException) { return null; } + + IntPtr nativeBuffer = Marshal.AllocHGlobal(size); + NativeMethods.EnumSystemFirmwareTables( + provider, nativeBuffer, size); + byte[] buffer = new byte[size]; + Marshal.Copy(nativeBuffer, buffer, 0, size); + Marshal.FreeHGlobal(nativeBuffer); + + string[] result = new string[size / 4]; + for (int i = 0; i < result.Length; i++) + result[i] = Encoding.ASCII.GetString(buffer, 4 * i, 4); + + return result; + } + + public enum Provider : int { + ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I', + FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M', + RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B' + } + + private static class NativeMethods { + private const string KERNEL = "kernel32.dll"; + + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, + SetLastError = true)] + public static extern int EnumSystemFirmwareTables( + Provider firmwareTableProviderSignature, + IntPtr firmwareTableBuffer, int bufferSize); + + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi, + SetLastError = true)] + public static extern int GetSystemFirmwareTable( + Provider firmwareTableProviderSignature, + int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize); + } + } +} diff -r 31b2b9b5eae9 -r d882720734bf Hardware/HDD/SMART.cs --- a/Hardware/HDD/SMART.cs Sun Jun 26 20:04:26 2011 +0000 +++ b/Hardware/HDD/SMART.cs Thu Jul 07 20:41:09 2011 +0000 @@ -16,7 +16,7 @@ The Initial Developer of the Original Code is Michael Möller . - Portions created by the Initial Developer are Copyright (C) 2009-2010 + Portions created by the Initial Developer are Copyright (C) 2009-2011 the Initial Developer. All Rights Reserved. Contributor(s): Paul Werelds @@ -462,7 +462,7 @@ chars[i + 1] = (char)bytes[i]; } - return new string(chars).Trim(); + return new string(chars).Trim(new char[] {' ', '\0'}); } } diff -r 31b2b9b5eae9 -r d882720734bf Hardware/Mainboard/GigabyteTAMG.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hardware/Mainboard/GigabyteTAMG.cs Thu Jul 07 20:41:09 2011 +0000 @@ -0,0 +1,174 @@ +/* + + 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) 2011 + 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; +using System.IO.Compression; +using System.Runtime.InteropServices; +using System.Text; + +namespace OpenHardwareMonitor.Hardware.Mainboard { + + internal class GigabyteTAMG { + private byte[] table; + + private Sensor[] sensors; + + private struct Sensor { + public string Name; + public SensorType Type; + public int Channel; + public float Value; + } + + private enum SensorType { + Voltage = 1, + Temperature = 2, + Fan = 4, + Case = 8, + } + + public GigabyteTAMG(byte[] table) { + if (table == null) + throw new ArgumentNullException("table"); + + this.table = table; + + int index = IndexOf(table, Encoding.ASCII.GetBytes("$HEALTH$"), 0); + + if (index >= 0) { + index += 8; + using (MemoryStream m = + new MemoryStream(table, index, table.Length - index)) + using (BinaryReader r = new BinaryReader(m)) { + try { + r.ReadInt64(); + int count = r.ReadInt32(); + r.ReadInt64(); + r.ReadInt32(); + sensors = new Sensor[count]; + for (int i = 0; i < sensors.Length; i++) { + sensors[i].Name = new string(r.ReadChars(32)).TrimEnd('\0'); + sensors[i].Type = (SensorType)r.ReadByte(); + sensors[i].Channel = r.ReadInt16(); + sensors[i].Channel |= r.ReadByte() << 24; + r.ReadInt64(); + int value = r.ReadInt32(); + switch (sensors[i].Type) { + case SensorType.Voltage: + sensors[i].Value = 1e-3f * value; break; + default: + sensors[i].Value = value; break; + } + r.ReadInt64(); + } + } catch (IOException) { sensors = new Sensor[0]; } + } + } else { + sensors = new Sensor[0]; + } + } + + public static int IndexOf(byte[] array, byte[] pattern, int startIndex) { + if (array == null || pattern == null || pattern.Length > array.Length) + return -1; + + for (int i = startIndex; i < array.Length - pattern.Length; i++) { + bool found = true; + for (int j = 0; j < pattern.Length; j++) { + if (array[i + j] != pattern[j]) { + found = false; + break; + } + } + if (found) + return i; + } + return -1; + } + + private string GetCompressedAndEncodedTable() { + string base64; + using (MemoryStream m = new MemoryStream()) { + using (GZipStream c = new GZipStream(m, CompressionMode.Compress)) { + c.Write(table, 0, table.Length); + } + base64 = Convert.ToBase64String(m.ToArray()); + } + + StringBuilder r = new StringBuilder(); + 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(); + } + + return r.ToString(); + } + + public string GetReport() { + StringBuilder r = new StringBuilder(); + + if (sensors.Length > 0) { + r.AppendLine("Gigabyte TAMG Sensors"); + r.AppendLine(); + + foreach (Sensor sensor in sensors) { + r.AppendFormat(" {0,-10}: {1,8:G6} ({2})", sensor.Name, sensor.Value, + sensor.Type); + r.AppendLine(); + } + r.AppendLine(); + } + + if (table.Length > 0) { + r.AppendLine("Gigabyte TAMG Table"); + r.AppendLine(); + r.Append(GetCompressedAndEncodedTable()); + r.AppendLine(); + } + + return r.ToString(); + } + } +} diff -r 31b2b9b5eae9 -r d882720734bf Hardware/Mainboard/Mainboard.cs --- a/Hardware/Mainboard/Mainboard.cs Sun Jun 26 20:04:26 2011 +0000 +++ b/Hardware/Mainboard/Mainboard.cs Thu Jul 07 20:41:09 2011 +0000 @@ -124,6 +124,13 @@ if (lpcio != null) r.Append(lpcio.GetReport()); + byte[] table = + FirmwareTable.GetTable(FirmwareTable.Provider.ACPI, "TAMG"); + if (table != null) { + GigabyteTAMG tamg = new GigabyteTAMG(table); + r.Append(tamg.GetReport()); + } + return r.ToString(); } diff -r 31b2b9b5eae9 -r d882720734bf OpenHardwareMonitorLib.csproj --- a/OpenHardwareMonitorLib.csproj Sun Jun 26 20:04:26 2011 +0000 +++ b/OpenHardwareMonitorLib.csproj Thu Jul 07 20:41:09 2011 +0000 @@ -61,6 +61,7 @@ + @@ -73,6 +74,7 @@ + diff -r 31b2b9b5eae9 -r d882720734bf Properties/AssemblyVersion.cs --- a/Properties/AssemblyVersion.cs Sun Jun 26 20:04:26 2011 +0000 +++ b/Properties/AssemblyVersion.cs Thu Jul 07 20:41:09 2011 +0000 @@ -37,5 +37,5 @@ using System.Reflection; -[assembly: AssemblyVersion("0.3.2.4")] -[assembly: AssemblyInformationalVersion("0.3.2.4 Alpha")] \ No newline at end of file +[assembly: AssemblyVersion("0.3.2.5")] +[assembly: AssemblyInformationalVersion("0.3.2.5 Alpha")] \ No newline at end of file