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).
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Hardware/FirmwareTable.cs Thu Jul 07 20:41:09 2011 +0000
1.3 @@ -0,0 +1,121 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2011
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.ComponentModel;
1.43 +using System.Runtime.InteropServices;
1.44 +using System.Text;
1.45 +
1.46 +namespace OpenHardwareMonitor.Hardware {
1.47 +
1.48 + internal static class FirmwareTable {
1.49 +
1.50 + public static byte[] GetTable(Provider provider, string table) {
1.51 + int id = table[3] << 24 | table[2] << 16 | table[1] << 8 | table[0];
1.52 + return GetTable(provider, id);
1.53 + }
1.54 +
1.55 + public static byte[] GetTable(Provider provider, int table) {
1.56 +
1.57 + int size;
1.58 + try {
1.59 + size = NativeMethods.GetSystemFirmwareTable(provider, table,
1.60 + IntPtr.Zero, 0);
1.61 + } catch (DllNotFoundException) { return null; }
1.62 + catch (EntryPointNotFoundException) { return null; }
1.63 +
1.64 + if (size <= 0)
1.65 + return null;
1.66 +
1.67 + IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
1.68 + NativeMethods.GetSystemFirmwareTable(provider, table, nativeBuffer, size);
1.69 +
1.70 + if (Marshal.GetLastWin32Error() != 0)
1.71 + return null;
1.72 +
1.73 + byte[] buffer = new byte[size];
1.74 + Marshal.Copy(nativeBuffer, buffer, 0, size);
1.75 + Marshal.FreeHGlobal(nativeBuffer);
1.76 +
1.77 + return buffer;
1.78 + }
1.79 +
1.80 + public static string[] EnumerateTables(Provider provider) {
1.81 + int size;
1.82 + try {
1.83 + size = NativeMethods.EnumSystemFirmwareTables(
1.84 + provider, IntPtr.Zero, 0);
1.85 + } catch (DllNotFoundException) { return null; }
1.86 + catch (EntryPointNotFoundException) { return null; }
1.87 +
1.88 + IntPtr nativeBuffer = Marshal.AllocHGlobal(size);
1.89 + NativeMethods.EnumSystemFirmwareTables(
1.90 + provider, nativeBuffer, size);
1.91 + byte[] buffer = new byte[size];
1.92 + Marshal.Copy(nativeBuffer, buffer, 0, size);
1.93 + Marshal.FreeHGlobal(nativeBuffer);
1.94 +
1.95 + string[] result = new string[size / 4];
1.96 + for (int i = 0; i < result.Length; i++)
1.97 + result[i] = Encoding.ASCII.GetString(buffer, 4 * i, 4);
1.98 +
1.99 + return result;
1.100 + }
1.101 +
1.102 + public enum Provider : int {
1.103 + ACPI = (byte)'A' << 24 | (byte)'C' << 16 | (byte)'P' << 8 | (byte)'I',
1.104 + FIRM = (byte)'F' << 24 | (byte)'I' << 16 | (byte)'R' << 8 | (byte)'M',
1.105 + RSMB = (byte)'R' << 24 | (byte)'S' << 16 | (byte)'M' << 8 | (byte)'B'
1.106 + }
1.107 +
1.108 + private static class NativeMethods {
1.109 + private const string KERNEL = "kernel32.dll";
1.110 +
1.111 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
1.112 + SetLastError = true)]
1.113 + public static extern int EnumSystemFirmwareTables(
1.114 + Provider firmwareTableProviderSignature,
1.115 + IntPtr firmwareTableBuffer, int bufferSize);
1.116 +
1.117 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
1.118 + SetLastError = true)]
1.119 + public static extern int GetSystemFirmwareTable(
1.120 + Provider firmwareTableProviderSignature,
1.121 + int firmwareTableID, IntPtr firmwareTableBuffer, int bufferSize);
1.122 + }
1.123 + }
1.124 +}
2.1 --- a/Hardware/HDD/SMART.cs Sun Jun 26 20:04:26 2011 +0000
2.2 +++ b/Hardware/HDD/SMART.cs Thu Jul 07 20:41:09 2011 +0000
2.3 @@ -16,7 +16,7 @@
2.4
2.5 The Initial Developer of the Original Code is
2.6 Michael Möller <m.moeller@gmx.ch>.
2.7 - Portions created by the Initial Developer are Copyright (C) 2009-2010
2.8 + Portions created by the Initial Developer are Copyright (C) 2009-2011
2.9 the Initial Developer. All Rights Reserved.
2.10
2.11 Contributor(s): Paul Werelds
2.12 @@ -462,7 +462,7 @@
2.13 chars[i + 1] = (char)bytes[i];
2.14 }
2.15
2.16 - return new string(chars).Trim();
2.17 + return new string(chars).Trim(new char[] {' ', '\0'});
2.18 }
2.19 }
2.20
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/Hardware/Mainboard/GigabyteTAMG.cs Thu Jul 07 20:41:09 2011 +0000
3.3 @@ -0,0 +1,174 @@
3.4 +/*
3.5 +
3.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
3.7 +
3.8 + The contents of this file are subject to the Mozilla Public License Version
3.9 + 1.1 (the "License"); you may not use this file except in compliance with
3.10 + the License. You may obtain a copy of the License at
3.11 +
3.12 + http://www.mozilla.org/MPL/
3.13 +
3.14 + Software distributed under the License is distributed on an "AS IS" basis,
3.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
3.16 + for the specific language governing rights and limitations under the License.
3.17 +
3.18 + The Original Code is the Open Hardware Monitor code.
3.19 +
3.20 + The Initial Developer of the Original Code is
3.21 + Michael Möller <m.moeller@gmx.ch>.
3.22 + Portions created by the Initial Developer are Copyright (C) 2011
3.23 + the Initial Developer. All Rights Reserved.
3.24 +
3.25 + Contributor(s):
3.26 +
3.27 + Alternatively, the contents of this file may be used under the terms of
3.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
3.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
3.30 + in which case the provisions of the GPL or the LGPL are applicable instead
3.31 + of those above. If you wish to allow use of your version of this file only
3.32 + under the terms of either the GPL or the LGPL, and not to allow others to
3.33 + use your version of this file under the terms of the MPL, indicate your
3.34 + decision by deleting the provisions above and replace them with the notice
3.35 + and other provisions required by the GPL or the LGPL. If you do not delete
3.36 + the provisions above, a recipient may use your version of this file under
3.37 + the terms of any one of the MPL, the GPL or the LGPL.
3.38 +
3.39 +*/
3.40 +
3.41 +using System;
3.42 +using System.Collections.Generic;
3.43 +using System.IO;
3.44 +using System.IO.Compression;
3.45 +using System.Runtime.InteropServices;
3.46 +using System.Text;
3.47 +
3.48 +namespace OpenHardwareMonitor.Hardware.Mainboard {
3.49 +
3.50 + internal class GigabyteTAMG {
3.51 + private byte[] table;
3.52 +
3.53 + private Sensor[] sensors;
3.54 +
3.55 + private struct Sensor {
3.56 + public string Name;
3.57 + public SensorType Type;
3.58 + public int Channel;
3.59 + public float Value;
3.60 + }
3.61 +
3.62 + private enum SensorType {
3.63 + Voltage = 1,
3.64 + Temperature = 2,
3.65 + Fan = 4,
3.66 + Case = 8,
3.67 + }
3.68 +
3.69 + public GigabyteTAMG(byte[] table) {
3.70 + if (table == null)
3.71 + throw new ArgumentNullException("table");
3.72 +
3.73 + this.table = table;
3.74 +
3.75 + int index = IndexOf(table, Encoding.ASCII.GetBytes("$HEALTH$"), 0);
3.76 +
3.77 + if (index >= 0) {
3.78 + index += 8;
3.79 + using (MemoryStream m =
3.80 + new MemoryStream(table, index, table.Length - index))
3.81 + using (BinaryReader r = new BinaryReader(m)) {
3.82 + try {
3.83 + r.ReadInt64();
3.84 + int count = r.ReadInt32();
3.85 + r.ReadInt64();
3.86 + r.ReadInt32();
3.87 + sensors = new Sensor[count];
3.88 + for (int i = 0; i < sensors.Length; i++) {
3.89 + sensors[i].Name = new string(r.ReadChars(32)).TrimEnd('\0');
3.90 + sensors[i].Type = (SensorType)r.ReadByte();
3.91 + sensors[i].Channel = r.ReadInt16();
3.92 + sensors[i].Channel |= r.ReadByte() << 24;
3.93 + r.ReadInt64();
3.94 + int value = r.ReadInt32();
3.95 + switch (sensors[i].Type) {
3.96 + case SensorType.Voltage:
3.97 + sensors[i].Value = 1e-3f * value; break;
3.98 + default:
3.99 + sensors[i].Value = value; break;
3.100 + }
3.101 + r.ReadInt64();
3.102 + }
3.103 + } catch (IOException) { sensors = new Sensor[0]; }
3.104 + }
3.105 + } else {
3.106 + sensors = new Sensor[0];
3.107 + }
3.108 + }
3.109 +
3.110 + public static int IndexOf(byte[] array, byte[] pattern, int startIndex) {
3.111 + if (array == null || pattern == null || pattern.Length > array.Length)
3.112 + return -1;
3.113 +
3.114 + for (int i = startIndex; i < array.Length - pattern.Length; i++) {
3.115 + bool found = true;
3.116 + for (int j = 0; j < pattern.Length; j++) {
3.117 + if (array[i + j] != pattern[j]) {
3.118 + found = false;
3.119 + break;
3.120 + }
3.121 + }
3.122 + if (found)
3.123 + return i;
3.124 + }
3.125 + return -1;
3.126 + }
3.127 +
3.128 + private string GetCompressedAndEncodedTable() {
3.129 + string base64;
3.130 + using (MemoryStream m = new MemoryStream()) {
3.131 + using (GZipStream c = new GZipStream(m, CompressionMode.Compress)) {
3.132 + c.Write(table, 0, table.Length);
3.133 + }
3.134 + base64 = Convert.ToBase64String(m.ToArray());
3.135 + }
3.136 +
3.137 + StringBuilder r = new StringBuilder();
3.138 + for (int i = 0; i < Math.Ceiling(base64.Length / 64.0); i++) {
3.139 + r.Append(" ");
3.140 + for (int j = 0; j < 0x40; j++) {
3.141 + int index = (i << 6) | j;
3.142 + if (index < base64.Length) {
3.143 + r.Append(base64[index]);
3.144 + }
3.145 + }
3.146 + r.AppendLine();
3.147 + }
3.148 +
3.149 + return r.ToString();
3.150 + }
3.151 +
3.152 + public string GetReport() {
3.153 + StringBuilder r = new StringBuilder();
3.154 +
3.155 + if (sensors.Length > 0) {
3.156 + r.AppendLine("Gigabyte TAMG Sensors");
3.157 + r.AppendLine();
3.158 +
3.159 + foreach (Sensor sensor in sensors) {
3.160 + r.AppendFormat(" {0,-10}: {1,8:G6} ({2})", sensor.Name, sensor.Value,
3.161 + sensor.Type);
3.162 + r.AppendLine();
3.163 + }
3.164 + r.AppendLine();
3.165 + }
3.166 +
3.167 + if (table.Length > 0) {
3.168 + r.AppendLine("Gigabyte TAMG Table");
3.169 + r.AppendLine();
3.170 + r.Append(GetCompressedAndEncodedTable());
3.171 + r.AppendLine();
3.172 + }
3.173 +
3.174 + return r.ToString();
3.175 + }
3.176 + }
3.177 +}
4.1 --- a/Hardware/Mainboard/Mainboard.cs Sun Jun 26 20:04:26 2011 +0000
4.2 +++ b/Hardware/Mainboard/Mainboard.cs Thu Jul 07 20:41:09 2011 +0000
4.3 @@ -124,6 +124,13 @@
4.4 if (lpcio != null)
4.5 r.Append(lpcio.GetReport());
4.6
4.7 + byte[] table =
4.8 + FirmwareTable.GetTable(FirmwareTable.Provider.ACPI, "TAMG");
4.9 + if (table != null) {
4.10 + GigabyteTAMG tamg = new GigabyteTAMG(table);
4.11 + r.Append(tamg.GetReport());
4.12 + }
4.13 +
4.14 return r.ToString();
4.15 }
4.16
5.1 --- a/OpenHardwareMonitorLib.csproj Sun Jun 26 20:04:26 2011 +0000
5.2 +++ b/OpenHardwareMonitorLib.csproj Thu Jul 07 20:41:09 2011 +0000
5.3 @@ -61,6 +61,7 @@
5.4 <Compile Include="Hardware\ATI\ATIGPU.cs" />
5.5 <Compile Include="Hardware\ATI\ATIGroup.cs" />
5.6 <Compile Include="Hardware\Control.cs" />
5.7 + <Compile Include="Hardware\FirmwareTable.cs" />
5.8 <Compile Include="Hardware\IControl.cs" />
5.9 <Compile Include="Hardware\IOControlCode.cs" />
5.10 <Compile Include="Hardware\Computer.cs" />
5.11 @@ -73,6 +74,7 @@
5.12 <Compile Include="Hardware\CPU\CPULoad.cs" />
5.13 <Compile Include="Hardware\CPU\IntelCPU.cs" />
5.14 <Compile Include="Hardware\LPC\NCT677X.cs" />
5.15 + <Compile Include="Hardware\Mainboard\GigabyteTAMG.cs" />
5.16 <Compile Include="Hardware\Opcode.cs" />
5.17 <Compile Include="Hardware\Ring0.cs" />
5.18 <Compile Include="Hardware\KernelDriver.cs" />
6.1 --- a/Properties/AssemblyVersion.cs Sun Jun 26 20:04:26 2011 +0000
6.2 +++ b/Properties/AssemblyVersion.cs Thu Jul 07 20:41:09 2011 +0000
6.3 @@ -37,5 +37,5 @@
6.4
6.5 using System.Reflection;
6.6
6.7 -[assembly: AssemblyVersion("0.3.2.4")]
6.8 -[assembly: AssemblyInformationalVersion("0.3.2.4 Alpha")]
6.9 \ No newline at end of file
6.10 +[assembly: AssemblyVersion("0.3.2.5")]
6.11 +[assembly: AssemblyInformationalVersion("0.3.2.5 Alpha")]
6.12 \ No newline at end of file