Modified and extended version of the patch v4 by Roland Reinl (see Issue 256). Main differences to the original patch: DeviceIoControl refactorings removed, SmartAttribute is now descriptive only and does not hold any state, report is written as one 80 columns table, sensors are created only for meaningful values and without duplicates (remaining life, temperatures, host writes and reads). Also the current implementation should really preserve all the functionality of the old system. Additionally there is now a simple SMART devices emulation class (DebugSmart) that can be used in place of WindowsSmart for testing with reported data.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Collections/Pair.cs Sat Dec 31 17:31:04 2011 +0000
1.3 @@ -0,0 +1,67 @@
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.Collections.Generic;
1.43 +
1.44 +namespace OpenHardwareMonitor.Collections {
1.45 +
1.46 + public struct Pair<F, S> {
1.47 + private F first;
1.48 + private S second;
1.49 +
1.50 + public Pair(F first, S second) {
1.51 + this.first = first;
1.52 + this.second = second;
1.53 + }
1.54 +
1.55 + public F First {
1.56 + get { return first; }
1.57 + set { first = value; }
1.58 + }
1.59 +
1.60 + public S Second {
1.61 + get { return second; }
1.62 + set { second = value; }
1.63 + }
1.64 +
1.65 + public override int GetHashCode() {
1.66 + return (first != null ? first.GetHashCode() : 0) ^
1.67 + (second != null ? second.GetHashCode() : 0);
1.68 + }
1.69 + }
1.70 +}
2.1 --- a/GUI/HardwareNode.cs Wed Aug 31 22:48:49 2011 +0000
2.2 +++ b/GUI/HardwareNode.cs Sat Dec 31 17:31:04 2011 +0000
2.3 @@ -66,6 +66,7 @@
2.4 typeNodes.Add(new TypeNode(SensorType.Control));
2.5 typeNodes.Add(new TypeNode(SensorType.Level));
2.6 typeNodes.Add(new TypeNode(SensorType.Power));
2.7 + typeNodes.Add(new TypeNode(SensorType.Data));
2.8
2.9 foreach (ISensor sensor in hardware.Sensors)
2.10 SensorAdded(sensor);
3.1 --- a/GUI/SensorGadget.cs Wed Aug 31 22:48:49 2011 +0000
3.2 +++ b/GUI/SensorGadget.cs Sat Dec 31 17:31:04 2011 +0000
3.3 @@ -518,6 +518,9 @@
3.4 case SensorType.Power:
3.5 format = "{0:F1} W";
3.6 break;
3.7 + case SensorType.Data:
3.8 + format = "{0:F1} GB";
3.9 + break;
3.10 }
3.11
3.12 if (sensor.SensorType == SensorType.Temperature &&
4.1 --- a/GUI/SensorNode.cs Wed Aug 31 22:48:49 2011 +0000
4.2 +++ b/GUI/SensorNode.cs Sat Dec 31 17:31:04 2011 +0000
4.3 @@ -76,6 +76,7 @@
4.4 case SensorType.Control: format = "{0:F1} %"; break;
4.5 case SensorType.Level: format = "{0:F1} %"; break;
4.6 case SensorType.Power: format = "{0:F1} W"; break;
4.7 + case SensorType.Data: format = "{0:F1} GB"; break;
4.8 }
4.9
4.10 bool hidden = settings.GetValue(new Identifier(sensor.Identifier,
5.1 --- a/GUI/SensorNotifyIcon.cs Wed Aug 31 22:48:49 2011 +0000
5.2 +++ b/GUI/SensorNotifyIcon.cs Sat Dec 31 17:31:04 2011 +0000
5.3 @@ -198,6 +198,8 @@
5.4 return string.Format("{0:F0}", sensor.Value);
5.5 case SensorType.Power:
5.6 return string.Format("{0:F0}", sensor.Value);
5.7 + case SensorType.Data:
5.8 + return string.Format("{0:F0}", sensor.Value);
5.9 }
5.10 return "-";
5.11 }
5.12 @@ -286,6 +288,7 @@
5.13 case SensorType.Control: format = "\n{0}: {1:F1} %"; break;
5.14 case SensorType.Level: format = "\n{0}: {1:F1} %"; break;
5.15 case SensorType.Power: format = "\n{0}: {1:F0} W"; break;
5.16 + case SensorType.Data: format = "\n{0}: {1:F0} GB"; break;
5.17 }
5.18 string formattedValue = string.Format(format, sensor.Name, sensor.Value);
5.19 string hardwareName = sensor.Hardware.Name;
6.1 --- a/GUI/TypeNode.cs Wed Aug 31 22:48:49 2011 +0000
6.2 +++ b/GUI/TypeNode.cs Sat Dec 31 17:31:04 2011 +0000
6.3 @@ -84,6 +84,10 @@
6.4 this.Image = Utilities.EmbeddedResources.GetImage("power.png");
6.5 this.Text = "Powers";
6.6 break;
6.7 + case SensorType.Data:
6.8 + this.Image = Utilities.EmbeddedResources.GetImage("data.png");
6.9 + this.Text = "Data";
6.10 + break;
6.11 }
6.12
6.13 NodeAdded += new NodeEventHandler(TypeNode_NodeAdded);
7.1 --- a/Hardware/Computer.cs Wed Aug 31 22:48:49 2011 +0000
7.2 +++ b/Hardware/Computer.cs Sat Dec 31 17:31:04 2011 +0000
7.3 @@ -16,7 +16,7 @@
7.4
7.5 The Initial Developer of the Original Code is
7.6 Michael Möller <m.moeller@gmx.ch>.
7.7 - Portions created by the Initial Developer are Copyright (C) 2009-2010
7.8 + Portions created by the Initial Developer are Copyright (C) 2009-2011
7.9 the Initial Developer. All Rights Reserved.
7.10
7.11 Contributor(s):
7.12 @@ -98,7 +98,7 @@
7.13 Add(new Heatmaster.HeatmasterGroup(settings));
7.14
7.15 if (hddEnabled)
7.16 - Add(new HDD.HDDGroup(settings));
7.17 + Add(new HDD.HarddriveGroup(settings));
7.18
7.19 open = true;
7.20 }
7.21 @@ -109,11 +109,11 @@
7.22 [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
7.23 set {
7.24 if (open && value && !hddEnabled) {
7.25 - Add(new HDD.HDDGroup(settings));
7.26 + Add(new HDD.HarddriveGroup(settings));
7.27 } else if (open && !value && hddEnabled) {
7.28 List<IGroup> list = new List<IGroup>();
7.29 foreach (IGroup group in groups)
7.30 - if (group is HDD.HDDGroup)
7.31 + if (group is HDD.HarddriveGroup)
7.32 list.Add(group);
7.33 foreach (IGroup group in list)
7.34 Remove(group);
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/Hardware/HDD/AbstractHarddrive.cs Sat Dec 31 17:31:04 2011 +0000
8.3 @@ -0,0 +1,294 @@
8.4 +/*
8.5 +
8.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
8.7 +
8.8 + The contents of this file are subject to the Mozilla Public License Version
8.9 + 1.1 (the "License"); you may not use this file except in compliance with
8.10 + the License. You may obtain a copy of the License at
8.11 +
8.12 + http://www.mozilla.org/MPL/
8.13 +
8.14 + Software distributed under the License is distributed on an "AS IS" basis,
8.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8.16 + for the specific language governing rights and limitations under the License.
8.17 +
8.18 + The Original Code is the Open Hardware Monitor code.
8.19 +
8.20 + The Initial Developer of the Original Code is
8.21 + Michael Möller <m.moeller@gmx.ch>.
8.22 + Portions created by the Initial Developer are Copyright (C) 2009-2011
8.23 + the Initial Developer. All Rights Reserved.
8.24 +
8.25 + Contributor(s):
8.26 + Paul Werelds
8.27 + Roland Reinl <roland-reinl@gmx.de>
8.28 +
8.29 + Alternatively, the contents of this file may be used under the terms of
8.30 + either the GNU General Public License Version 2 or later (the "GPL"), or
8.31 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
8.32 + in which case the provisions of the GPL or the LGPL are applicable instead
8.33 + of those above. If you wish to allow use of your version of this file only
8.34 + under the terms of either the GPL or the LGPL, and not to allow others to
8.35 + use your version of this file under the terms of the MPL, indicate your
8.36 + decision by deleting the provisions above and replace them with the notice
8.37 + and other provisions required by the GPL or the LGPL. If you do not delete
8.38 + the provisions above, a recipient may use your version of this file under
8.39 + the terms of any one of the MPL, the GPL or the LGPL.
8.40 +
8.41 +*/
8.42 +
8.43 +using System;
8.44 +using System.Collections.Generic;
8.45 +using System.Globalization;
8.46 +using System.Text;
8.47 +using OpenHardwareMonitor.Collections;
8.48 +
8.49 +namespace OpenHardwareMonitor.Hardware.HDD {
8.50 + internal abstract class AbstractHarddrive : Hardware {
8.51 +
8.52 + private const int UPDATE_DIVIDER = 30; // update only every 30s
8.53 +
8.54 + // array of all harddrive types, matching type is searched in this order
8.55 + private static Type[] hddTypes = {
8.56 + typeof(SSDPlextor),
8.57 + typeof(SSDIntel),
8.58 + typeof(SSDSandforce),
8.59 + typeof(SSDIndilinx),
8.60 + typeof(GenericHarddisk)
8.61 + };
8.62 +
8.63 + private readonly ISmart smart;
8.64 +
8.65 + private readonly IntPtr handle;
8.66 + private readonly int index;
8.67 + private int count;
8.68 +
8.69 + private IList<SmartAttribute> smartAttributes;
8.70 + private IDictionary<SmartAttribute, Sensor> sensors;
8.71 +
8.72 + protected AbstractHarddrive(ISmart smart, string name, int index,
8.73 + IEnumerable<SmartAttribute> smartAttributes, ISettings settings)
8.74 + : base(name, new Identifier("hdd",
8.75 + index.ToString(CultureInfo.InvariantCulture)), settings)
8.76 + {
8.77 + this.smart = smart;
8.78 + handle = smart.OpenDrive(index);
8.79 +
8.80 + smart.EnableSmart(handle, index);
8.81 +
8.82 + this.index = index;
8.83 + this.count = 0;
8.84 +
8.85 + this.smartAttributes = new List<SmartAttribute>(smartAttributes);
8.86 +
8.87 + CreateSensors();
8.88 + }
8.89 +
8.90 + public static AbstractHarddrive CreateInstance(ISmart smart,
8.91 + int driveIndex, ISettings settings)
8.92 + {
8.93 + IntPtr deviceHandle = smart.OpenDrive(driveIndex);
8.94 +
8.95 + if (deviceHandle == smart.InvalidHandle)
8.96 + return null;
8.97 +
8.98 + string name = smart.ReadName(deviceHandle, driveIndex);
8.99 + bool smartEnabled = smart.EnableSmart(deviceHandle, driveIndex);
8.100 +
8.101 + DriveAttributeValue[] values = {};
8.102 + if (smartEnabled)
8.103 + values = smart.ReadSmartData(deviceHandle, driveIndex);
8.104 +
8.105 + smart.CloseHandle(deviceHandle);
8.106 +
8.107 + if (string.IsNullOrEmpty(name))
8.108 + return null;
8.109 +
8.110 + foreach (Type type in hddTypes) {
8.111 + // get the array of name prefixes for the current type
8.112 + NamePrefixAttribute[] namePrefixes = type.GetCustomAttributes(
8.113 + typeof(NamePrefixAttribute), true) as NamePrefixAttribute[];
8.114 +
8.115 + // get the array of the required SMART attributes for the current type
8.116 + RequireSmartAttribute[] requiredAttributes = type.GetCustomAttributes(
8.117 + typeof(RequireSmartAttribute), true) as RequireSmartAttribute[];
8.118 +
8.119 + // check if all required attributes are present
8.120 + bool allRequiredAttributesFound = true;
8.121 + foreach (var requireAttribute in requiredAttributes) {
8.122 + bool adttributeFound = false;
8.123 + foreach (DriveAttributeValue value in values) {
8.124 + if (value.Identifier == requireAttribute.AttributeId) {
8.125 + adttributeFound = true;
8.126 + break;
8.127 + }
8.128 + }
8.129 + if (!adttributeFound) {
8.130 + allRequiredAttributesFound = false;
8.131 + break;
8.132 + }
8.133 + }
8.134 +
8.135 + // if an attribute is missing, then try the next type
8.136 + if (!allRequiredAttributesFound)
8.137 + continue;
8.138 +
8.139 + // check if there is a matching name prefix for this type
8.140 + foreach (NamePrefixAttribute prefix in namePrefixes) {
8.141 + if (name.StartsWith(prefix.Prefix, StringComparison.InvariantCulture))
8.142 + return Activator.CreateInstance(type, smart, name, driveIndex,
8.143 + settings) as AbstractHarddrive;
8.144 + }
8.145 + }
8.146 +
8.147 + // no matching type has been found
8.148 + return null;
8.149 + }
8.150 +
8.151 + private void CreateSensors() {
8.152 + sensors = new Dictionary<SmartAttribute, Sensor>();
8.153 +
8.154 + IList<Pair<SensorType, int>> sensorTypeAndChannels =
8.155 + new List<Pair<SensorType, int>>();
8.156 +
8.157 + DriveAttributeValue[] values = smart.ReadSmartData(handle, index);
8.158 +
8.159 + foreach (SmartAttribute attribute in smartAttributes) {
8.160 + if (!attribute.SensorType.HasValue)
8.161 + continue;
8.162 +
8.163 + bool found = false;
8.164 + foreach (DriveAttributeValue value in values) {
8.165 + if (value.Identifier == attribute.Identifier) {
8.166 + found = true;
8.167 + break;
8.168 + }
8.169 + }
8.170 + if (!found)
8.171 + continue;
8.172 +
8.173 + Pair<SensorType, int> pair = new Pair<SensorType, int>(
8.174 + attribute.SensorType.Value, attribute.SensorChannel);
8.175 +
8.176 + if (!sensorTypeAndChannels.Contains(pair)) {
8.177 + Sensor sensor = new Sensor(attribute.Name,
8.178 + attribute.SensorChannel, attribute.SensorType.Value, this,
8.179 + settings);
8.180 +
8.181 + sensors.Add(attribute, sensor);
8.182 + sensorTypeAndChannels.Add(pair);
8.183 + }
8.184 + }
8.185 + }
8.186 +
8.187 + public override HardwareType HardwareType {
8.188 + get { return HardwareType.HDD; }
8.189 + }
8.190 +
8.191 + public override ISensor[] Sensors {
8.192 + get {
8.193 + Sensor[] array = new Sensor[sensors.Count];
8.194 + sensors.Values.CopyTo(array, 0);
8.195 + return array;
8.196 + }
8.197 + }
8.198 +
8.199 + public override void Update() {
8.200 + if (count == 0) {
8.201 + DriveAttributeValue[] values = smart.ReadSmartData(handle, index);
8.202 +
8.203 + foreach (KeyValuePair<SmartAttribute, Sensor> keyValuePair in sensors) {
8.204 + SmartAttribute attribute = keyValuePair.Key;
8.205 + foreach (DriveAttributeValue value in values) {
8.206 + if (value.Identifier == attribute.Identifier) {
8.207 + Sensor sensor = keyValuePair.Value;
8.208 + sensor.Value = attribute.ConvertValue(value);
8.209 + }
8.210 + }
8.211 + }
8.212 + }
8.213 +
8.214 + count++;
8.215 + count %= UPDATE_DIVIDER;
8.216 + }
8.217 +
8.218 + public override string GetReport() {
8.219 + StringBuilder r = new StringBuilder();
8.220 + DriveAttributeValue[] values = smart.ReadSmartData(handle, index);
8.221 + DriveThresholdValue[] thresholds =
8.222 + smart.ReadSmartThresholds(handle, index);
8.223 +
8.224 + if (values.Length > 0) {
8.225 + r.AppendLine(this.GetType().Name);
8.226 + r.AppendLine();
8.227 + r.AppendLine("Drive name: " + name);
8.228 + r.AppendLine();
8.229 + r.AppendFormat(CultureInfo.InvariantCulture,
8.230 + " {0}{1}{2}{3}{4}{5}{6}{7}",
8.231 + ("ID").PadRight(3),
8.232 + ("Description").PadRight(32),
8.233 + ("Raw Value").PadRight(13),
8.234 + ("Worst").PadRight(6),
8.235 + ("Value").PadRight(6),
8.236 + ("Thres").PadRight(6),
8.237 + ("Physical").PadRight(8),
8.238 + Environment.NewLine);
8.239 +
8.240 + foreach (DriveAttributeValue value in values) {
8.241 + if (value.Identifier == 0x00)
8.242 + break;
8.243 +
8.244 + byte? threshold = null;
8.245 + foreach (DriveThresholdValue t in thresholds) {
8.246 + if (t.Identifier == value.Identifier) {
8.247 + threshold = t.Threshold;
8.248 + }
8.249 + }
8.250 +
8.251 + string description = "Unknown";
8.252 + float? physical = null;
8.253 + foreach (SmartAttribute a in smartAttributes) {
8.254 + if (a.Identifier == value.Identifier) {
8.255 + description = a.Name;
8.256 + if (a.HasRawValueConversion | a.SensorType.HasValue)
8.257 + physical = a.ConvertValue(value);
8.258 + else
8.259 + physical = null;
8.260 + }
8.261 + }
8.262 +
8.263 + string raw = BitConverter.ToString(value.RawValue);
8.264 + r.AppendFormat(CultureInfo.InvariantCulture,
8.265 + " {0}{1}{2}{3}{4}{5}{6}{7}",
8.266 + value.Identifier.ToString("X2").PadRight(3),
8.267 + description.PadRight(32),
8.268 + raw.Replace("-", "").PadRight(13),
8.269 + value.WorstValue.ToString(CultureInfo.InvariantCulture).PadRight(6),
8.270 + value.AttrValue.ToString(CultureInfo.InvariantCulture).PadRight(6),
8.271 + (threshold.HasValue ? threshold.Value.ToString(
8.272 + CultureInfo.InvariantCulture) : "-").PadRight(6),
8.273 + (physical.HasValue ? physical.Value.ToString(
8.274 + CultureInfo.InvariantCulture) : "-").PadRight(8),
8.275 + Environment.NewLine);
8.276 + }
8.277 + r.AppendLine();
8.278 + }
8.279 +
8.280 + return r.ToString();
8.281 + }
8.282 +
8.283 + protected static float RawToInt(byte[] raw, byte value) {
8.284 + return (raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0];
8.285 + }
8.286 +
8.287 + public override void Close() {
8.288 + smart.CloseHandle(handle);
8.289 + base.Close();
8.290 + }
8.291 +
8.292 + public override void Traverse(IVisitor visitor) {
8.293 + foreach (ISensor sensor in Sensors)
8.294 + sensor.Accept(visitor);
8.295 + }
8.296 + }
8.297 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/Hardware/HDD/DebugSmart.cs Sat Dec 31 17:31:04 2011 +0000
9.3 @@ -0,0 +1,287 @@
9.4 +/*
9.5 +
9.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
9.7 +
9.8 + The contents of this file are subject to the Mozilla Public License Version
9.9 + 1.1 (the "License"); you may not use this file except in compliance with
9.10 + the License. You may obtain a copy of the License at
9.11 +
9.12 + http://www.mozilla.org/MPL/
9.13 +
9.14 + Software distributed under the License is distributed on an "AS IS" basis,
9.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
9.16 + for the specific language governing rights and limitations under the License.
9.17 +
9.18 + The Original Code is the Open Hardware Monitor code.
9.19 +
9.20 + The Initial Developer of the Original Code is
9.21 + Michael Möller <m.moeller@gmx.ch>.
9.22 + Portions created by the Initial Developer are Copyright (C) 2011
9.23 + the Initial Developer. All Rights Reserved.
9.24 +
9.25 + Contributor(s):
9.26 +
9.27 + Alternatively, the contents of this file may be used under the terms of
9.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
9.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
9.30 + in which case the provisions of the GPL or the LGPL are applicable instead
9.31 + of those above. If you wish to allow use of your version of this file only
9.32 + under the terms of either the GPL or the LGPL, and not to allow others to
9.33 + use your version of this file under the terms of the MPL, indicate your
9.34 + decision by deleting the provisions above and replace them with the notice
9.35 + and other provisions required by the GPL or the LGPL. If you do not delete
9.36 + the provisions above, a recipient may use your version of this file under
9.37 + the terms of any one of the MPL, the GPL or the LGPL.
9.38 +
9.39 +*/
9.40 +
9.41 +using System;
9.42 +using System.Collections.Generic;
9.43 +using System.Text;
9.44 +
9.45 +namespace OpenHardwareMonitor.Hardware.HDD {
9.46 +
9.47 +#if DEBUG
9.48 +
9.49 + internal class DebugSmart : ISmart {
9.50 +
9.51 + private Drive[] drives = {
9.52 + new Drive("KINGSTON SNV425S264GB", 16,
9.53 + @" 01 000000000000 100 100
9.54 + 02 000000000000 100 100
9.55 + 03 000000000000 100 100
9.56 + 05 000000000000 100 100
9.57 + 07 000000000000 100 100
9.58 + 08 000000000000 100 100
9.59 + 09 821E00000000 100 100
9.60 + 0A 000000000000 100 100
9.61 + 0C 950200000000 100 100
9.62 + A8 000000000000 100 100
9.63 + AF 000000000000 100 100
9.64 + C0 000000000000 100 100
9.65 + C2 290014002B00 100 41
9.66 + C5 000000000000 100 100
9.67 + F0 000000000000 100 100
9.68 + AA 07007B000000 100 100
9.69 + AD 0E1E71304919 100 100"),
9.70 +
9.71 + new Drive("PLEXTOR PX-128M2S", 16,
9.72 + @" 01 000000000000 100 100 0
9.73 + 03 000000000000 100 100 0
9.74 + 04 000000000000 100 100 0
9.75 + 05 000000000000 100 100 0
9.76 + 09 250100000000 100 100 0
9.77 + 0A 000000000000 100 100 0
9.78 + 0C D10000000000 100 100 0
9.79 + B2 000000000000 100 100 0
9.80 + BB 000000000000 100 100 0
9.81 + BE 000000000000 100 100 0
9.82 + C0 000000000000 100 100 0
9.83 + C1 000000000000 100 100 0
9.84 + C2 000000000000 100 100 0
9.85 + C3 000000000000 100 100 0
9.86 + C5 000000000000 100 100 0
9.87 + C6 000000000000 100 100 0
9.88 + C7 000000000000 100 100 0"),
9.89 +
9.90 + new Drive("OCZ-VERTEX2", 16,
9.91 + @" 01 DADAD5000000 100 106 50
9.92 + 05 000000000000 100 100 3
9.93 + 09 DF0900004A2F 100 100 0
9.94 + 0C FC0100000000 100 100 0
9.95 + AB 000000000000 0 0 0
9.96 + AC 000000000000 0 0 0
9.97 + AE 1F0000000000 0 0 0
9.98 + B1 000000000000 0 0 0
9.99 + B5 000000000000 0 0 0
9.100 + B6 000000000000 0 0 0
9.101 + BB 000000000000 100 100 0
9.102 + C2 010081007F00 129 1 0
9.103 + C3 DADAD5000000 100 106 0
9.104 + C4 000000000000 100 100 0
9.105 + E7 000000000000 100 100 10
9.106 + E9 800400000000 0 0 0
9.107 + EA 000600000000 0 0 0
9.108 + F1 000600000000 0 0 0
9.109 + F2 801200000000 0 0 0"),
9.110 +
9.111 + new Drive("WDC WD5000AADS-00S9B0", 10,
9.112 + @" 1 000000000000 200 200
9.113 + 3 820D00000000 149 150
9.114 + 4 610800000000 98 98
9.115 + 5 000000000000 200 200
9.116 + 7 000000000000 253 100
9.117 + 9 0F1F00000000 90 90
9.118 + 10 000000000000 100 100
9.119 + 11 000000000000 100 100
9.120 + 12 880200000000 100 100
9.121 + 192 6B0000000000 200 200
9.122 + 193 E9CB03000000 118 118
9.123 + 194 280000000000 94 103
9.124 + 196 000000000000 200 200
9.125 + 197 000000000000 200 200
9.126 + 198 000000000000 200 200
9.127 + 199 000000000000 200 200
9.128 + 200 000000000000 200 200
9.129 + 130 7B0300010002 1 41
9.130 + 5 000000000000 0 0
9.131 + 1 000000000000 0 0"),
9.132 +
9.133 + new Drive("INTEL SSDSA2M080G2GC", 10,
9.134 + @" 3 000000000000 100 100
9.135 + 4 000000000000 100 100
9.136 + 5 010000000000 100 100
9.137 + 9 B10B00000000 100 100
9.138 + 12 DD0300000000 100 100
9.139 + 192 480000000000 100 100
9.140 + 225 89DB00000000 200 200
9.141 + 226 3D1B00000000 100 100
9.142 + 227 030000000000 100 100
9.143 + 228 7F85703C0000 100 100
9.144 + 232 000000000000 99 99
9.145 + 233 000000000000 98 98
9.146 + 184 000000000000 100 100
9.147 + 1 000000000000 0 0"),
9.148 +
9.149 + new Drive("OCZ-VERTEX", 10,
9.150 + @" 1 000000000000 0 8
9.151 + 9 000000000000 30 99
9.152 + 12 000000000000 0 15
9.153 + 184 000000000000 0 7
9.154 + 195 000000000000 0 0
9.155 + 196 000000000000 0 2
9.156 + 197 000000000000 0 0
9.157 + 198 B9ED00000000 214 176
9.158 + 199 352701000000 143 185
9.159 + 200 B10500000000 105 55
9.160 + 201 F40A00000000 238 194
9.161 + 202 020000000000 137 35
9.162 + 203 020000000000 125 63
9.163 + 204 000000000000 0 0
9.164 + 205 000000000000 19 136
9.165 + 206 000000000000 22 54
9.166 + 207 010000000000 113 226
9.167 + 208 000000000000 49 232
9.168 + 209 000000000000 0 98
9.169 + 211 000000000000 0 0
9.170 + 212 000000000000 0 0
9.171 + 213 000000000000 0 0"),
9.172 +
9.173 + new Drive("INTEL SSDSA2CW120G3", 16,
9.174 + @"03 000000000000 100 100 0
9.175 + 04 000000000000 100 100 0
9.176 + 05 000000000000 100 100 0
9.177 + 09 830200000000 100 100 0
9.178 + 0C 900100000000 100 100 0
9.179 + AA 000000000000 100 100 0
9.180 + AB 000000000000 100 100 0
9.181 + AC 000000000000 100 100 0
9.182 + B8 000000000000 100 100 0
9.183 + BB 000000000000 100 100 0
9.184 + C0 040000000000 100 100 0
9.185 + E1 FF4300000000 100 100 0
9.186 + E2 E57D14000000 100 100 0
9.187 + E3 000000000000 100 100 0
9.188 + E4 E39600000000 100 100 0
9.189 + E8 000000000000 100 100 0
9.190 + E9 000000000000 100 100 0
9.191 + F1 FF4300000000 100 100 0
9.192 + F2 264F00000000 100 100 0")
9.193 + };
9.194 +
9.195 + public IntPtr OpenDrive(int driveNumber) {
9.196 + if (driveNumber < drives.Length)
9.197 + return (IntPtr)driveNumber;
9.198 + else
9.199 + return InvalidHandle;
9.200 + }
9.201 +
9.202 + public bool EnableSmart(IntPtr handle, int driveNumber) {
9.203 + if (handle != (IntPtr)driveNumber)
9.204 + throw new ArgumentOutOfRangeException();
9.205 +
9.206 + return true;
9.207 + }
9.208 +
9.209 + public DriveAttributeValue[] ReadSmartData(IntPtr handle, int driveNumber) {
9.210 + if (handle != (IntPtr)driveNumber)
9.211 + throw new ArgumentOutOfRangeException();
9.212 +
9.213 + return drives[driveNumber].DriveAttributeValues;
9.214 + }
9.215 +
9.216 + public DriveThresholdValue[] ReadSmartThresholds(IntPtr handle,
9.217 + int driveNumber)
9.218 + {
9.219 + if (handle != (IntPtr)driveNumber)
9.220 + throw new ArgumentOutOfRangeException();
9.221 +
9.222 + return drives[driveNumber].DriveThresholdValues;
9.223 + }
9.224 +
9.225 + public string ReadName(IntPtr handle, int driveNumber) {
9.226 + if (handle != (IntPtr)driveNumber)
9.227 + throw new ArgumentOutOfRangeException();
9.228 +
9.229 + return drives[driveNumber].Name;
9.230 + }
9.231 +
9.232 + public void CloseHandle(IntPtr handle) { }
9.233 +
9.234 +
9.235 + private class Drive {
9.236 +
9.237 + public Drive(string name, int idBase, string value) {
9.238 + this.Name = name;
9.239 +
9.240 + string[] lines = value.Split(new[] { '\r', '\n' },
9.241 + StringSplitOptions.RemoveEmptyEntries);
9.242 +
9.243 + DriveAttributeValues = new DriveAttributeValue[lines.Length];
9.244 + List<DriveThresholdValue> thresholds = new List<DriveThresholdValue>();
9.245 +
9.246 + for (int i = 0; i < lines.Length; i++) {
9.247 +
9.248 + string[] array = lines[i].Split(new[] { ' ' },
9.249 + StringSplitOptions.RemoveEmptyEntries);
9.250 +
9.251 + if (array.Length != 4 && array.Length != 5)
9.252 + throw new Exception();
9.253 +
9.254 + DriveAttributeValue v = new DriveAttributeValue();
9.255 + v.Identifier = Convert.ToByte(array[0], idBase);
9.256 +
9.257 + v.RawValue = new byte[6];
9.258 + for (int j = 0; j < 6; j++) {
9.259 + v.RawValue[j] = Convert.ToByte(array[1].Substring(2 * j, 2), 16);
9.260 + }
9.261 +
9.262 + v.WorstValue = Convert.ToByte(array[2], 10);
9.263 + v.AttrValue = Convert.ToByte(array[3], 10);
9.264 +
9.265 + DriveAttributeValues[i] = v;
9.266 +
9.267 + if (array.Length == 5) {
9.268 + DriveThresholdValue t = new DriveThresholdValue();
9.269 + t.Identifier = v.Identifier;
9.270 + t.Threshold = Convert.ToByte(array[4], 10);
9.271 + thresholds.Add(t);
9.272 + }
9.273 + }
9.274 +
9.275 + DriveThresholdValues = thresholds.ToArray();
9.276 + }
9.277 +
9.278 + public DriveAttributeValue[] DriveAttributeValues { get; private set; }
9.279 +
9.280 + public DriveThresholdValue[] DriveThresholdValues { get; private set; }
9.281 +
9.282 + public string Name { get; private set; }
9.283 + }
9.284 +
9.285 + public IntPtr InvalidHandle { get { return (IntPtr)(-1); } }
9.286 + }
9.287 +
9.288 +#endif
9.289 +
9.290 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/Hardware/HDD/DriveAttributeValue.cs Sat Dec 31 17:31:04 2011 +0000
10.3 @@ -0,0 +1,55 @@
10.4 +/*
10.5 +
10.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
10.7 +
10.8 + The contents of this file are subject to the Mozilla Public License Version
10.9 + 1.1 (the "License"); you may not use this file except in compliance with
10.10 + the License. You may obtain a copy of the License at
10.11 +
10.12 + http://www.mozilla.org/MPL/
10.13 +
10.14 + Software distributed under the License is distributed on an "AS IS" basis,
10.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10.16 + for the specific language governing rights and limitations under the License.
10.17 +
10.18 + The Original Code is the Open Hardware Monitor code.
10.19 +
10.20 + The Initial Developer of the Original Code is
10.21 + Michael Möller <m.moeller@gmx.ch>.
10.22 + Portions created by the Initial Developer are Copyright (C) 2011
10.23 + the Initial Developer. All Rights Reserved.
10.24 +
10.25 + Contributor(s):
10.26 +
10.27 + Alternatively, the contents of this file may be used under the terms of
10.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
10.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
10.30 + in which case the provisions of the GPL or the LGPL are applicable instead
10.31 + of those above. If you wish to allow use of your version of this file only
10.32 + under the terms of either the GPL or the LGPL, and not to allow others to
10.33 + use your version of this file under the terms of the MPL, indicate your
10.34 + decision by deleting the provisions above and replace them with the notice
10.35 + and other provisions required by the GPL or the LGPL. If you do not delete
10.36 + the provisions above, a recipient may use your version of this file under
10.37 + the terms of any one of the MPL, the GPL or the LGPL.
10.38 +
10.39 +*/
10.40 +
10.41 +using System;
10.42 +using System.Collections.Generic;
10.43 +using System.Runtime.InteropServices;
10.44 +
10.45 +namespace OpenHardwareMonitor.Hardware.HDD {
10.46 +
10.47 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
10.48 + public struct DriveAttributeValue {
10.49 + public byte Identifier;
10.50 + public short StatusFlags;
10.51 + public byte AttrValue;
10.52 + public byte WorstValue;
10.53 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
10.54 + public byte[] RawValue;
10.55 + public byte Reserved;
10.56 + }
10.57 +
10.58 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/Hardware/HDD/DriveThresholdValue.cs Sat Dec 31 17:31:04 2011 +0000
11.3 @@ -0,0 +1,51 @@
11.4 +/*
11.5 +
11.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
11.7 +
11.8 + The contents of this file are subject to the Mozilla Public License Version
11.9 + 1.1 (the "License"); you may not use this file except in compliance with
11.10 + the License. You may obtain a copy of the License at
11.11 +
11.12 + http://www.mozilla.org/MPL/
11.13 +
11.14 + Software distributed under the License is distributed on an "AS IS" basis,
11.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11.16 + for the specific language governing rights and limitations under the License.
11.17 +
11.18 + The Original Code is the Open Hardware Monitor code.
11.19 +
11.20 + The Initial Developer of the Original Code is
11.21 + Michael Möller <m.moeller@gmx.ch>.
11.22 + Portions created by the Initial Developer are Copyright (C) 2011
11.23 + the Initial Developer. All Rights Reserved.
11.24 +
11.25 + Contributor(s):
11.26 +
11.27 + Alternatively, the contents of this file may be used under the terms of
11.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
11.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
11.30 + in which case the provisions of the GPL or the LGPL are applicable instead
11.31 + of those above. If you wish to allow use of your version of this file only
11.32 + under the terms of either the GPL or the LGPL, and not to allow others to
11.33 + use your version of this file under the terms of the MPL, indicate your
11.34 + decision by deleting the provisions above and replace them with the notice
11.35 + and other provisions required by the GPL or the LGPL. If you do not delete
11.36 + the provisions above, a recipient may use your version of this file under
11.37 + the terms of any one of the MPL, the GPL or the LGPL.
11.38 +
11.39 +*/
11.40 +
11.41 +using System;
11.42 +using System.Collections.Generic;
11.43 +using System.Runtime.InteropServices;
11.44 +namespace OpenHardwareMonitor.Hardware.HDD {
11.45 +
11.46 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
11.47 + public struct DriveThresholdValue {
11.48 + public byte Identifier;
11.49 + public byte Threshold;
11.50 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
11.51 + public byte[] Unknown;
11.52 + }
11.53 +
11.54 +}
12.1 --- a/Hardware/HDD/HDD.cs Wed Aug 31 22:48:49 2011 +0000
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,136 +0,0 @@
12.4 -/*
12.5 -
12.6 - Version: MPL 1.1/GPL 2.0/LGPL 2.1
12.7 -
12.8 - The contents of this file are subject to the Mozilla Public License Version
12.9 - 1.1 (the "License"); you may not use this file except in compliance with
12.10 - the License. You may obtain a copy of the License at
12.11 -
12.12 - http://www.mozilla.org/MPL/
12.13 -
12.14 - Software distributed under the License is distributed on an "AS IS" basis,
12.15 - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12.16 - for the specific language governing rights and limitations under the License.
12.17 -
12.18 - The Original Code is the Open Hardware Monitor code.
12.19 -
12.20 - The Initial Developer of the Original Code is
12.21 - Michael Möller <m.moeller@gmx.ch>.
12.22 - Portions created by the Initial Developer are Copyright (C) 2009-2011
12.23 - the Initial Developer. All Rights Reserved.
12.24 -
12.25 - Contributor(s): Paul Werelds
12.26 -
12.27 - Alternatively, the contents of this file may be used under the terms of
12.28 - either the GNU General Public License Version 2 or later (the "GPL"), or
12.29 - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
12.30 - in which case the provisions of the GPL or the LGPL are applicable instead
12.31 - of those above. If you wish to allow use of your version of this file only
12.32 - under the terms of either the GPL or the LGPL, and not to allow others to
12.33 - use your version of this file under the terms of the MPL, indicate your
12.34 - decision by deleting the provisions above and replace them with the notice
12.35 - and other provisions required by the GPL or the LGPL. If you do not delete
12.36 - the provisions above, a recipient may use your version of this file under
12.37 - the terms of any one of the MPL, the GPL or the LGPL.
12.38 -
12.39 -*/
12.40 -
12.41 -using System;
12.42 -using System.Collections.Generic;
12.43 -using System.Globalization;
12.44 -
12.45 -namespace OpenHardwareMonitor.Hardware.HDD {
12.46 - internal class HDD : Hardware {
12.47 -
12.48 - private const int UPDATE_DIVIDER = 30; // update only every 30s
12.49 -
12.50 - private readonly IntPtr handle;
12.51 - private readonly int drive;
12.52 - private int count;
12.53 -
12.54 - private readonly SMART.AttributeID temperatureID = SMART.AttributeID.None;
12.55 - private readonly SMART.AttributeID lifeID = SMART.AttributeID.None;
12.56 -
12.57 - private readonly Sensor temperatureSensor;
12.58 - private readonly Sensor lifeSensor;
12.59 -
12.60 - public HDD(string name, IntPtr handle, int drive,
12.61 - SMART.AttributeID temperatureID, SMART.AttributeID lifeID,
12.62 - ISettings settings) : base(name, new Identifier("hdd",
12.63 - drive.ToString(CultureInfo.InvariantCulture)), settings)
12.64 - {
12.65 - this.handle = handle;
12.66 - this.drive = drive;
12.67 - this.count = 0;
12.68 - if (temperatureID != SMART.AttributeID.None) {
12.69 - this.temperatureID = temperatureID;
12.70 - this.temperatureSensor = new Sensor("HDD", 0, SensorType.Temperature,
12.71 - this, settings);
12.72 - }
12.73 -
12.74 - if (lifeID != SMART.AttributeID.None) {
12.75 - this.lifeID = lifeID;
12.76 - this.lifeSensor = new Sensor("Remaining life", 0, SensorType.Level,
12.77 - this, settings);
12.78 - }
12.79 -
12.80 - Update();
12.81 - }
12.82 -
12.83 - public override HardwareType HardwareType {
12.84 - get { return HardwareType.HDD; }
12.85 - }
12.86 -
12.87 - public override ISensor[] Sensors {
12.88 - get {
12.89 - if (lifeID != SMART.AttributeID.None)
12.90 - return new ISensor[] { lifeSensor };
12.91 -
12.92 - if (temperatureID != SMART.AttributeID.None)
12.93 - return new ISensor[] { temperatureSensor };
12.94 -
12.95 - return new ISensor[] {};
12.96 - }
12.97 - }
12.98 -
12.99 - public override void Update() {
12.100 - if (count == 0) {
12.101 - SMART.DriveAttribute[] attributes = SMART.ReadSmart(handle, drive);
12.102 -
12.103 - if (temperatureID != SMART.AttributeID.None &&
12.104 - Array.Exists(attributes, attr => attr.ID == temperatureID))
12.105 - {
12.106 - temperatureSensor.Value = Array
12.107 - .Find(attributes, attr => attr.ID == temperatureID)
12.108 - .RawValue[0];
12.109 - }
12.110 -
12.111 - if (lifeID != SMART.AttributeID.None &&
12.112 - Array.Exists(attributes, attr => attr.ID == lifeID))
12.113 - {
12.114 - lifeSensor.Value = Array
12.115 - .Find(attributes, attr => attr.ID == lifeID)
12.116 - .AttrValue;
12.117 - }
12.118 - } else {
12.119 - if (temperatureID != SMART.AttributeID.None)
12.120 - temperatureSensor.Value = temperatureSensor.Value;
12.121 -
12.122 - if (lifeID != SMART.AttributeID.None)
12.123 - lifeSensor.Value = lifeSensor.Value;
12.124 - }
12.125 -
12.126 - count++; count %= UPDATE_DIVIDER;
12.127 - }
12.128 -
12.129 - public override void Close() {
12.130 - SMART.CloseHandle(handle);
12.131 - base.Close();
12.132 - }
12.133 -
12.134 - public override void Traverse(IVisitor visitor) {
12.135 - foreach (ISensor sensor in Sensors)
12.136 - sensor.Accept(visitor);
12.137 - }
12.138 - }
12.139 -}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/Hardware/HDD/HDDGeneric.cs Sat Dec 31 17:31:04 2011 +0000
13.3 @@ -0,0 +1,123 @@
13.4 +/*
13.5 +
13.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
13.7 +
13.8 + The contents of this file are subject to the Mozilla Public License Version
13.9 + 1.1 (the "License"); you may not use this file except in compliance with
13.10 + the License. You may obtain a copy of the License at
13.11 +
13.12 + http://www.mozilla.org/MPL/
13.13 +
13.14 + Software distributed under the License is distributed on an "AS IS" basis,
13.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13.16 + for the specific language governing rights and limitations under the License.
13.17 +
13.18 + The Original Code is the Open Hardware Monitor code.
13.19 +
13.20 + The Initial Developer of the Original Code is
13.21 + Roland Reinl <roland-reinl@gmx.de>.
13.22 + Portions created by the Initial Developer are Copyright (C) 2011
13.23 + the Initial Developer. All Rights Reserved.
13.24 +
13.25 + Contributor(s):
13.26 + Paul Werelds
13.27 + Michael Möller <m.moeller@gmx.ch>
13.28 +
13.29 + Alternatively, the contents of this file may be used under the terms of
13.30 + either the GNU General Public License Version 2 or later (the "GPL"), or
13.31 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
13.32 + in which case the provisions of the GPL or the LGPL are applicable instead
13.33 + of those above. If you wish to allow use of your version of this file only
13.34 + under the terms of either the GPL or the LGPL, and not to allow others to
13.35 + use your version of this file under the terms of the MPL, indicate your
13.36 + decision by deleting the provisions above and replace them with the notice
13.37 + and other provisions required by the GPL or the LGPL. If you do not delete
13.38 + the provisions above, a recipient may use your version of this file under
13.39 + the terms of any one of the MPL, the GPL or the LGPL.
13.40 +
13.41 +*/
13.42 +
13.43 +using System;
13.44 +using System.Collections.Generic;
13.45 +using System.Text;
13.46 +
13.47 +namespace OpenHardwareMonitor.Hardware.HDD {
13.48 +
13.49 + [NamePrefix("")]
13.50 + internal class GenericHarddisk : AbstractHarddrive {
13.51 +
13.52 + private static readonly List<SmartAttribute> smartAttributes =
13.53 + new List<SmartAttribute> {
13.54 + new SmartAttribute(0x01, SmartAttributeNames.ReadErrorRate),
13.55 + new SmartAttribute(0x02, SmartAttributeNames.ThroughputPerformance),
13.56 + new SmartAttribute(0x03, SmartAttributeNames.SpinUpTime),
13.57 + new SmartAttribute(0x04, SmartAttributeNames.StartStopCount, RawToInt),
13.58 + new SmartAttribute(0x05, SmartAttributeNames.ReallocatedSectorsCount),
13.59 + new SmartAttribute(0x06, SmartAttributeNames.ReadChannelMargin),
13.60 + new SmartAttribute(0x07, SmartAttributeNames.SeekErrorRate),
13.61 + new SmartAttribute(0x08, SmartAttributeNames.SeekTimePerformance),
13.62 + new SmartAttribute(0x09, SmartAttributeNames.PowerOnHours, RawToInt),
13.63 + new SmartAttribute(0x0A, SmartAttributeNames.SpinRetryCount),
13.64 + new SmartAttribute(0x0B, SmartAttributeNames.RecalibrationRetries),
13.65 + new SmartAttribute(0x0C, SmartAttributeNames.PowerCycleCount, RawToInt),
13.66 + new SmartAttribute(0x0D, SmartAttributeNames.SoftReadErrorRate),
13.67 + new SmartAttribute(0xAA, SmartAttributeNames.Unknown),
13.68 + new SmartAttribute(0xAB, SmartAttributeNames.Unknown),
13.69 + new SmartAttribute(0xAC, SmartAttributeNames.Unknown),
13.70 + new SmartAttribute(0xB7, SmartAttributeNames.SataDownshiftErrorCount),
13.71 + new SmartAttribute(0xB8, SmartAttributeNames.EndToEndError),
13.72 + new SmartAttribute(0xB9, SmartAttributeNames.HeadStability),
13.73 + new SmartAttribute(0xBA, SmartAttributeNames.InducedOpVibrationDetection),
13.74 + new SmartAttribute(0xBB, SmartAttributeNames.ReportedUncorrectableErrors),
13.75 + new SmartAttribute(0xBC, SmartAttributeNames.CommandTimeout),
13.76 + new SmartAttribute(0xBD, SmartAttributeNames.HighFlyWrites),
13.77 + new SmartAttribute(0xBF, SmartAttributeNames.GSenseErrorRate),
13.78 + new SmartAttribute(0xC0, SmartAttributeNames.EmergencyRetractCycleCount),
13.79 + new SmartAttribute(0xC1, SmartAttributeNames.LoadCycleCount),
13.80 + new SmartAttribute(0xC3, SmartAttributeNames.HardwareEccRecovered),
13.81 + new SmartAttribute(0xC4, SmartAttributeNames.ReallocationEventCount),
13.82 + new SmartAttribute(0xC5, SmartAttributeNames.CurrentPendingSectorCount),
13.83 + new SmartAttribute(0xC6, SmartAttributeNames.UncorrectableSectorCount),
13.84 + new SmartAttribute(0xC7, SmartAttributeNames.UltraDmaCrcErrorCount),
13.85 + new SmartAttribute(0xC8, SmartAttributeNames.WriteErrorRate),
13.86 + new SmartAttribute(0xCA, SmartAttributeNames.DataAddressMarkErrors),
13.87 + new SmartAttribute(0xCB, SmartAttributeNames.RunOutCancel),
13.88 + new SmartAttribute(0xCC, SmartAttributeNames.SoftEccCorrection),
13.89 + new SmartAttribute(0xCD, SmartAttributeNames.ThermalAsperityRate),
13.90 + new SmartAttribute(0xCE, SmartAttributeNames.FlyingHeight),
13.91 + new SmartAttribute(0xCF, SmartAttributeNames.SpinHighCurrent),
13.92 + new SmartAttribute(0xD0, SmartAttributeNames.SpinBuzz),
13.93 + new SmartAttribute(0xD1, SmartAttributeNames.OfflineSeekPerformance),
13.94 + new SmartAttribute(0xD3, SmartAttributeNames.VibrationDuringWrite),
13.95 + new SmartAttribute(0xD4, SmartAttributeNames.ShockDuringWrite),
13.96 + new SmartAttribute(0xDC, SmartAttributeNames.DiskShift),
13.97 + new SmartAttribute(0xDD, SmartAttributeNames.AlternativeGSenseErrorRate),
13.98 + new SmartAttribute(0xDE, SmartAttributeNames.LoadedHours),
13.99 + new SmartAttribute(0xDF, SmartAttributeNames.LoadUnloadRetryCount),
13.100 + new SmartAttribute(0xE0, SmartAttributeNames.LoadFriction),
13.101 + new SmartAttribute(0xE1, SmartAttributeNames.LoadUnloadCycleCount),
13.102 + new SmartAttribute(0xE2, SmartAttributeNames.LoadInTime),
13.103 + new SmartAttribute(0xE3, SmartAttributeNames.TorqueAmplificationCount),
13.104 + new SmartAttribute(0xE4, SmartAttributeNames.PowerOffRetractCycle),
13.105 + new SmartAttribute(0xE6, SmartAttributeNames.GmrHeadAmplitude),
13.106 + new SmartAttribute(0xE8, SmartAttributeNames.EnduranceRemaining),
13.107 + new SmartAttribute(0xE9, SmartAttributeNames.PowerOnHours),
13.108 + new SmartAttribute(0xF0, SmartAttributeNames.HeadFlyingHours),
13.109 + new SmartAttribute(0xF1, SmartAttributeNames.TotalLbasWritten),
13.110 + new SmartAttribute(0xF2, SmartAttributeNames.TotalLbasRead),
13.111 + new SmartAttribute(0xFA, SmartAttributeNames.ReadErrorRetryRate),
13.112 + new SmartAttribute(0xFE, SmartAttributeNames.FreeFallProtection),
13.113 +
13.114 + new SmartAttribute(0xC2, SmartAttributeNames.Temperature,
13.115 + (byte[] r, byte v) => { return r[0]; }, SensorType.Temperature, 0),
13.116 + new SmartAttribute(0xE7, SmartAttributeNames.Temperature,
13.117 + (byte[] r, byte v) => { return r[0]; }, SensorType.Temperature, 0),
13.118 + new SmartAttribute(0xBE, SmartAttributeNames.TemperatureDifferenceFrom100,
13.119 + null, SensorType.Temperature, 0)
13.120 + };
13.121 +
13.122 + public GenericHarddisk(ISmart smart, string name, int index,
13.123 + ISettings settings)
13.124 + : base(smart, name, index, smartAttributes, settings) { }
13.125 + }
13.126 +}
14.1 --- a/Hardware/HDD/HDDGroup.cs Wed Aug 31 22:48:49 2011 +0000
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,227 +0,0 @@
14.4 -/*
14.5 -
14.6 - Version: MPL 1.1/GPL 2.0/LGPL 2.1
14.7 -
14.8 - The contents of this file are subject to the Mozilla Public License Version
14.9 - 1.1 (the "License"); you may not use this file except in compliance with
14.10 - the License. You may obtain a copy of the License at
14.11 -
14.12 - http://www.mozilla.org/MPL/
14.13 -
14.14 - Software distributed under the License is distributed on an "AS IS" basis,
14.15 - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14.16 - for the specific language governing rights and limitations under the License.
14.17 -
14.18 - The Original Code is the Open Hardware Monitor code.
14.19 -
14.20 - The Initial Developer of the Original Code is
14.21 - Michael Möller <m.moeller@gmx.ch>.
14.22 - Portions created by the Initial Developer are Copyright (C) 2009-2010
14.23 - the Initial Developer. All Rights Reserved.
14.24 -
14.25 - Contributor(s): Paul Werelds
14.26 -
14.27 - Alternatively, the contents of this file may be used under the terms of
14.28 - either the GNU General Public License Version 2 or later (the "GPL"), or
14.29 - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
14.30 - in which case the provisions of the GPL or the LGPL are applicable instead
14.31 - of those above. If you wish to allow use of your version of this file only
14.32 - under the terms of either the GPL or the LGPL, and not to allow others to
14.33 - use your version of this file under the terms of the MPL, indicate your
14.34 - decision by deleting the provisions above and replace them with the notice
14.35 - and other provisions required by the GPL or the LGPL. If you do not delete
14.36 - the provisions above, a recipient may use your version of this file under
14.37 - the terms of any one of the MPL, the GPL or the LGPL.
14.38 -
14.39 -*/
14.40 -
14.41 -using System;
14.42 -using System.Collections.Generic;
14.43 -using System.Globalization;
14.44 -using System.Text;
14.45 -
14.46 -namespace OpenHardwareMonitor.Hardware.HDD {
14.47 - internal class HDDGroup : IGroup {
14.48 -
14.49 - private const int MAX_DRIVES = 32;
14.50 -
14.51 - private readonly List<HDD> hardware = new List<HDD>();
14.52 -
14.53 - public HDDGroup(ISettings settings) {
14.54 - int p = (int)Environment.OSVersion.Platform;
14.55 - if (p == 4 || p == 128) return;
14.56 -
14.57 - for (int drive = 0; drive < MAX_DRIVES; drive++) {
14.58 - IntPtr handle = SMART.OpenPhysicalDrive(drive);
14.59 -
14.60 - if (handle == SMART.INVALID_HANDLE_VALUE)
14.61 - continue;
14.62 -
14.63 - if (!SMART.EnableSmart(handle, drive)) {
14.64 - SMART.CloseHandle(handle);
14.65 - continue;
14.66 - }
14.67 -
14.68 - string name = SMART.ReadName(handle, drive);
14.69 - if (name == null) {
14.70 - SMART.CloseHandle(handle);
14.71 - continue;
14.72 - }
14.73 -
14.74 - SMART.DriveAttribute[] attributes = SMART.ReadSmart(handle, drive);
14.75 -
14.76 - if (attributes.Length < 1) {
14.77 - SMART.CloseHandle(handle);
14.78 - continue;
14.79 - }
14.80 -
14.81 - SMART.AttributeID ssdLifeID = GetSSDLifeID(attributes);
14.82 - if (ssdLifeID == SMART.AttributeID.None) {
14.83 - SMART.AttributeID temperatureID = GetTemperatureIndex(attributes);
14.84 -
14.85 - if (temperatureID != SMART.AttributeID.None) {
14.86 - hardware.Add(new HDD(name, handle, drive, temperatureID,
14.87 - SMART.AttributeID.None, settings));
14.88 - continue;
14.89 - }
14.90 - } else {
14.91 - hardware.Add(new HDD(name, handle, drive, SMART.AttributeID.None,
14.92 - ssdLifeID, settings));
14.93 - continue;
14.94 - }
14.95 -
14.96 - SMART.CloseHandle(handle);
14.97 - }
14.98 - }
14.99 -
14.100 - private SMART.AttributeID GetSSDLifeID(SMART.DriveAttribute[] attributes) {
14.101 - // ID E9 is present on Intel, JM, SF and Samsung (different meanings)
14.102 - // ID D2 is present on Indilinx
14.103 - // Neither ID has been found on a mechanical hard drive (yet),
14.104 - // so this seems like a good way to check if it's an SSD.
14.105 - bool isKnownSSD = (
14.106 - Array.Exists(attributes, attr => attr.ID == new SMART.AttributeID(0xE9)) ||
14.107 - Array.Exists(attributes, attr => attr.ID == new SMART.AttributeID(0xD2))
14.108 - );
14.109 -
14.110 - if (!isKnownSSD) return SMART.AttributeID.None;
14.111 -
14.112 - // We start with a traditional loop, because there are 4 unique ID's
14.113 - // that potentially identify one of the vendors
14.114 - for (int i = 0; i < attributes.Length; i++) {
14.115 - if (attributes[i].ID == SMART.SamsungAttributes.RemainingLife)
14.116 - return SMART.SamsungAttributes.RemainingLife;
14.117 -
14.118 - if (attributes[i].ID == SMART.SandForceAttributes.ProgramFailCount)
14.119 - return SMART.SandForceAttributes.RemainingLife;
14.120 -
14.121 - if (attributes[i].ID == SMART.IndilinxAttributes.UnknownUnique)
14.122 - return SMART.IndilinxAttributes.RemainingLife;
14.123 - }
14.124 -
14.125 - // TODO: Find out JMicron's Life attribute ID; their unique ID = 0xE4
14.126 -
14.127 - // For Intel, we make sure we have their 3 most important ID's
14.128 - // We do a traditional loop again, because we all we need to know
14.129 - // is whether we can find all 3; pointless to use Exists()
14.130 - int intelRegisterCount = 0;
14.131 - foreach (SMART.DriveAttribute attribute in attributes) {
14.132 - if (attribute.ID == SMART.IntelAttributes.HostWrites ||
14.133 - attribute.ID == SMART.IntelAttributes.RemainingLife ||
14.134 - attribute.ID == SMART.IntelAttributes.MediaWearOutIndicator
14.135 - )
14.136 - intelRegisterCount++;
14.137 - }
14.138 -
14.139 - return (intelRegisterCount == 3)
14.140 - ? SMART.IntelAttributes.RemainingLife
14.141 - : SMART.AttributeID.None;
14.142 - }
14.143 -
14.144 - private SMART.AttributeID GetTemperatureIndex(
14.145 - SMART.DriveAttribute[] attributes)
14.146 - {
14.147 - SMART.AttributeID[] validIds = new[] {
14.148 - SMART.CommonAttributes.Temperature,
14.149 - SMART.CommonAttributes.DriveTemperature,
14.150 - SMART.CommonAttributes.AirflowTemperature
14.151 - };
14.152 -
14.153 - foreach (SMART.AttributeID validId in validIds) {
14.154 - SMART.AttributeID id = validId;
14.155 - if (Array.Exists(attributes, attr => attr.ID == id))
14.156 - return validId;
14.157 - }
14.158 -
14.159 - return SMART.AttributeID.None;
14.160 - }
14.161 -
14.162 - public IHardware[] Hardware {
14.163 - get {
14.164 - return hardware.ToArray();
14.165 - }
14.166 - }
14.167 -
14.168 - public string GetReport() {
14.169 - int p = (int)Environment.OSVersion.Platform;
14.170 - if (p == 4 || p == 128) return null;
14.171 -
14.172 - StringBuilder r = new StringBuilder();
14.173 -
14.174 - r.AppendLine("S.M.A.R.T Data");
14.175 - r.AppendLine();
14.176 -
14.177 - for (int drive = 0; drive < MAX_DRIVES; drive++) {
14.178 - IntPtr handle = SMART.OpenPhysicalDrive(drive);
14.179 -
14.180 - if (handle == SMART.INVALID_HANDLE_VALUE)
14.181 - continue;
14.182 -
14.183 - if (!SMART.EnableSmart(handle, drive)) {
14.184 - SMART.CloseHandle(handle);
14.185 - continue;
14.186 - }
14.187 -
14.188 - string name = SMART.ReadName(handle, drive);
14.189 - if (name == null) {
14.190 - SMART.CloseHandle(handle);
14.191 - continue;
14.192 - }
14.193 -
14.194 - SMART.DriveAttribute[] attributes = SMART.ReadSmart(handle, drive);
14.195 -
14.196 - if (attributes.Length > 0) {
14.197 - r.AppendLine("Drive name: " + name);
14.198 - r.AppendLine();
14.199 - r.AppendFormat(CultureInfo.InvariantCulture, " {0}{1}{2}{3}{4}",
14.200 - ("ID").PadRight(6),
14.201 - ("RawValue").PadRight(20),
14.202 - ("WorstValue").PadRight(12),
14.203 - ("AttrValue").PadRight(12),
14.204 - Environment.NewLine);
14.205 -
14.206 - foreach (SMART.DriveAttribute a in attributes) {
14.207 - if (a.ID == SMART.AttributeID.None) continue;
14.208 - string raw = BitConverter.ToString(a.RawValue);
14.209 - r.AppendFormat(CultureInfo.InvariantCulture, " {0}{1}{2}{3}{4}",
14.210 - a.ID.ToString("d").PadRight(6),
14.211 - raw.Replace("-", " ").PadRight(20),
14.212 - a.WorstValue.ToString(CultureInfo.InvariantCulture).PadRight(12),
14.213 - a.AttrValue.ToString(CultureInfo.InvariantCulture).PadRight(12),
14.214 - Environment.NewLine);
14.215 - }
14.216 - r.AppendLine();
14.217 - }
14.218 -
14.219 - SMART.CloseHandle(handle);
14.220 - }
14.221 -
14.222 - return r.ToString();
14.223 - }
14.224 -
14.225 - public void Close() {
14.226 - foreach (HDD hdd in hardware)
14.227 - hdd.Close();
14.228 - }
14.229 - }
14.230 -}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/Hardware/HDD/HarddriveGroup.cs Sat Dec 31 17:31:04 2011 +0000
15.3 @@ -0,0 +1,83 @@
15.4 +/*
15.5 +
15.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
15.7 +
15.8 + The contents of this file are subject to the Mozilla Public License Version
15.9 + 1.1 (the "License"); you may not use this file except in compliance with
15.10 + the License. You may obtain a copy of the License at
15.11 +
15.12 + http://www.mozilla.org/MPL/
15.13 +
15.14 + Software distributed under the License is distributed on an "AS IS" basis,
15.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15.16 + for the specific language governing rights and limitations under the License.
15.17 +
15.18 + The Original Code is the Open Hardware Monitor code.
15.19 +
15.20 + The Initial Developer of the Original Code is
15.21 + Michael Möller <m.moeller@gmx.ch>.
15.22 + Portions created by the Initial Developer are Copyright (C) 2009-2011
15.23 + the Initial Developer. All Rights Reserved.
15.24 +
15.25 + Contributor(s):
15.26 + Paul Werelds
15.27 + Roland Reinl <roland-reinl@gmx.de>
15.28 +
15.29 + Alternatively, the contents of this file may be used under the terms of
15.30 + either the GNU General Public License Version 2 or later (the "GPL"), or
15.31 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
15.32 + in which case the provisions of the GPL or the LGPL are applicable instead
15.33 + of those above. If you wish to allow use of your version of this file only
15.34 + under the terms of either the GPL or the LGPL, and not to allow others to
15.35 + use your version of this file under the terms of the MPL, indicate your
15.36 + decision by deleting the provisions above and replace them with the notice
15.37 + and other provisions required by the GPL or the LGPL. If you do not delete
15.38 + the provisions above, a recipient may use your version of this file under
15.39 + the terms of any one of the MPL, the GPL or the LGPL.
15.40 +
15.41 +*/
15.42 +
15.43 +using System;
15.44 +using System.Collections.Generic;
15.45 +using System.Globalization;
15.46 +using System.Text;
15.47 +
15.48 +namespace OpenHardwareMonitor.Hardware.HDD {
15.49 + internal class HarddriveGroup : IGroup {
15.50 +
15.51 + private const int MAX_DRIVES = 32;
15.52 +
15.53 + private readonly List<AbstractHarddrive> hardware =
15.54 + new List<AbstractHarddrive>();
15.55 +
15.56 + public HarddriveGroup(ISettings settings) {
15.57 + int p = (int)Environment.OSVersion.Platform;
15.58 + if (p == 4 || p == 128) return;
15.59 +
15.60 + ISmart smart = new WindowsSmart();
15.61 +
15.62 + for (int drive = 0; drive < MAX_DRIVES; drive++) {
15.63 + AbstractHarddrive instance =
15.64 + AbstractHarddrive.CreateInstance(smart, drive, settings);
15.65 + if (instance != null) {
15.66 + this.hardware.Add(instance);
15.67 + }
15.68 + }
15.69 + }
15.70 +
15.71 + public IHardware[] Hardware {
15.72 + get {
15.73 + return hardware.ToArray();
15.74 + }
15.75 + }
15.76 +
15.77 + public string GetReport() {
15.78 + return null;
15.79 + }
15.80 +
15.81 + public void Close() {
15.82 + foreach (AbstractHarddrive hdd in hardware)
15.83 + hdd.Close();
15.84 + }
15.85 + }
15.86 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/Hardware/HDD/ISmart.cs Sat Dec 31 17:31:04 2011 +0000
16.3 @@ -0,0 +1,60 @@
16.4 +/*
16.5 +
16.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
16.7 +
16.8 + The contents of this file are subject to the Mozilla Public License Version
16.9 + 1.1 (the "License"); you may not use this file except in compliance with
16.10 + the License. You may obtain a copy of the License at
16.11 +
16.12 + http://www.mozilla.org/MPL/
16.13 +
16.14 + Software distributed under the License is distributed on an "AS IS" basis,
16.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16.16 + for the specific language governing rights and limitations under the License.
16.17 +
16.18 + The Original Code is the Open Hardware Monitor code.
16.19 +
16.20 + The Initial Developer of the Original Code is
16.21 + Michael Möller <m.moeller@gmx.ch>.
16.22 + Portions created by the Initial Developer are Copyright (C) 2011
16.23 + the Initial Developer. All Rights Reserved.
16.24 +
16.25 + Contributor(s):
16.26 +
16.27 + Alternatively, the contents of this file may be used under the terms of
16.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
16.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
16.30 + in which case the provisions of the GPL or the LGPL are applicable instead
16.31 + of those above. If you wish to allow use of your version of this file only
16.32 + under the terms of either the GPL or the LGPL, and not to allow others to
16.33 + use your version of this file under the terms of the MPL, indicate your
16.34 + decision by deleting the provisions above and replace them with the notice
16.35 + and other provisions required by the GPL or the LGPL. If you do not delete
16.36 + the provisions above, a recipient may use your version of this file under
16.37 + the terms of any one of the MPL, the GPL or the LGPL.
16.38 +
16.39 +*/
16.40 +
16.41 +using System;
16.42 +using System.Collections.Generic;
16.43 +
16.44 +
16.45 +namespace OpenHardwareMonitor.Hardware.HDD {
16.46 +
16.47 + public interface ISmart {
16.48 +
16.49 + IntPtr OpenDrive(int driveNumber);
16.50 +
16.51 + bool EnableSmart(IntPtr handle, int driveNumber);
16.52 +
16.53 + DriveAttributeValue[] ReadSmartData(IntPtr handle, int driveNumber);
16.54 +
16.55 + DriveThresholdValue[] ReadSmartThresholds(IntPtr handle, int driveNumber);
16.56 +
16.57 + string ReadName(IntPtr handle, int driveNumber);
16.58 +
16.59 + void CloseHandle(IntPtr handle);
16.60 +
16.61 + IntPtr InvalidHandle { get; }
16.62 + }
16.63 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/Hardware/HDD/NamePrefixAttribute.cs Sat Dec 31 17:31:04 2011 +0000
17.3 @@ -0,0 +1,53 @@
17.4 +/*
17.5 +
17.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
17.7 +
17.8 + The contents of this file are subject to the Mozilla Public License Version
17.9 + 1.1 (the "License"); you may not use this file except in compliance with
17.10 + the License. You may obtain a copy of the License at
17.11 +
17.12 + http://www.mozilla.org/MPL/
17.13 +
17.14 + Software distributed under the License is distributed on an "AS IS" basis,
17.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17.16 + for the specific language governing rights and limitations under the License.
17.17 +
17.18 + The Original Code is the Open Hardware Monitor code.
17.19 +
17.20 + The Initial Developer of the Original Code is
17.21 + Michael Möller <m.moeller@gmx.ch>.
17.22 + Portions created by the Initial Developer are Copyright (C) 2011
17.23 + the Initial Developer. All Rights Reserved.
17.24 +
17.25 + Contributor(s):
17.26 +
17.27 + Alternatively, the contents of this file may be used under the terms of
17.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
17.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
17.30 + in which case the provisions of the GPL or the LGPL are applicable instead
17.31 + of those above. If you wish to allow use of your version of this file only
17.32 + under the terms of either the GPL or the LGPL, and not to allow others to
17.33 + use your version of this file under the terms of the MPL, indicate your
17.34 + decision by deleting the provisions above and replace them with the notice
17.35 + and other provisions required by the GPL or the LGPL. If you do not delete
17.36 + the provisions above, a recipient may use your version of this file under
17.37 + the terms of any one of the MPL, the GPL or the LGPL.
17.38 +
17.39 +*/
17.40 +
17.41 +using System;
17.42 +using System.Collections.Generic;
17.43 +
17.44 +namespace OpenHardwareMonitor.Hardware.HDD {
17.45 +
17.46 + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
17.47 + internal class NamePrefixAttribute : Attribute {
17.48 +
17.49 + public NamePrefixAttribute(string namePrefix) {
17.50 + Prefix = namePrefix;
17.51 + }
17.52 +
17.53 + public string Prefix { get; private set; }
17.54 +
17.55 + }
17.56 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/Hardware/HDD/RequireSmartAttribute.cs Sat Dec 31 17:31:04 2011 +0000
18.3 @@ -0,0 +1,53 @@
18.4 +/*
18.5 +
18.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
18.7 +
18.8 + The contents of this file are subject to the Mozilla Public License Version
18.9 + 1.1 (the "License"); you may not use this file except in compliance with
18.10 + the License. You may obtain a copy of the License at
18.11 +
18.12 + http://www.mozilla.org/MPL/
18.13 +
18.14 + Software distributed under the License is distributed on an "AS IS" basis,
18.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
18.16 + for the specific language governing rights and limitations under the License.
18.17 +
18.18 + The Original Code is the Open Hardware Monitor code.
18.19 +
18.20 + The Initial Developer of the Original Code is
18.21 + Michael Möller <m.moeller@gmx.ch>.
18.22 + Portions created by the Initial Developer are Copyright (C) 2011
18.23 + the Initial Developer. All Rights Reserved.
18.24 +
18.25 + Contributor(s):
18.26 +
18.27 + Alternatively, the contents of this file may be used under the terms of
18.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
18.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
18.30 + in which case the provisions of the GPL or the LGPL are applicable instead
18.31 + of those above. If you wish to allow use of your version of this file only
18.32 + under the terms of either the GPL or the LGPL, and not to allow others to
18.33 + use your version of this file under the terms of the MPL, indicate your
18.34 + decision by deleting the provisions above and replace them with the notice
18.35 + and other provisions required by the GPL or the LGPL. If you do not delete
18.36 + the provisions above, a recipient may use your version of this file under
18.37 + the terms of any one of the MPL, the GPL or the LGPL.
18.38 +
18.39 +*/
18.40 +
18.41 +using System;
18.42 +using System.Collections.Generic;
18.43 +
18.44 +namespace OpenHardwareMonitor.Hardware.HDD {
18.45 +
18.46 + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
18.47 + internal class RequireSmartAttribute : Attribute {
18.48 +
18.49 + public RequireSmartAttribute(byte attributeId) {
18.50 + AttributeId = attributeId;
18.51 + }
18.52 +
18.53 + public byte AttributeId { get; private set; }
18.54 +
18.55 + }
18.56 +}
19.1 --- a/Hardware/HDD/SMART.cs Wed Aug 31 22:48:49 2011 +0000
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,508 +0,0 @@
19.4 -/*
19.5 -
19.6 - Version: MPL 1.1/GPL 2.0/LGPL 2.1
19.7 -
19.8 - The contents of this file are subject to the Mozilla Public License Version
19.9 - 1.1 (the "License"); you may not use this file except in compliance with
19.10 - the License. You may obtain a copy of the License at
19.11 -
19.12 - http://www.mozilla.org/MPL/
19.13 -
19.14 - Software distributed under the License is distributed on an "AS IS" basis,
19.15 - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19.16 - for the specific language governing rights and limitations under the License.
19.17 -
19.18 - The Original Code is the Open Hardware Monitor code.
19.19 -
19.20 - The Initial Developer of the Original Code is
19.21 - Michael Möller <m.moeller@gmx.ch>.
19.22 - Portions created by the Initial Developer are Copyright (C) 2009-2011
19.23 - the Initial Developer. All Rights Reserved.
19.24 -
19.25 - Contributor(s): Paul Werelds
19.26 -
19.27 - Alternatively, the contents of this file may be used under the terms of
19.28 - either the GNU General Public License Version 2 or later (the "GPL"), or
19.29 - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19.30 - in which case the provisions of the GPL or the LGPL are applicable instead
19.31 - of those above. If you wish to allow use of your version of this file only
19.32 - under the terms of either the GPL or the LGPL, and not to allow others to
19.33 - use your version of this file under the terms of the MPL, indicate your
19.34 - decision by deleting the provisions above and replace them with the notice
19.35 - and other provisions required by the GPL or the LGPL. If you do not delete
19.36 - the provisions above, a recipient may use your version of this file under
19.37 - the terms of any one of the MPL, the GPL or the LGPL.
19.38 -
19.39 -*/
19.40 -
19.41 -using System;
19.42 -using System.Collections.Generic;
19.43 -using System.Runtime.InteropServices;
19.44 -
19.45 -namespace OpenHardwareMonitor.Hardware.HDD {
19.46 -
19.47 - internal class SMART {
19.48 -
19.49 - [Flags]
19.50 - public enum Status : ushort {
19.51 - PreFailureWarranty = 0x01,
19.52 - OnLineCollection = 0x02,
19.53 - Performance = 0x04,
19.54 - ErrorRate = 0x08,
19.55 - EventCount = 0x10,
19.56 - SelfPreserving = 0x20
19.57 - }
19.58 -
19.59 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.60 - public struct AttributeID {
19.61 - private byte value;
19.62 -
19.63 - public AttributeID(byte value) {
19.64 - this.value = value;
19.65 - }
19.66 -
19.67 - public override bool Equals(Object obj) {
19.68 - return obj is AttributeID && this == (AttributeID)obj;
19.69 - }
19.70 - public override int GetHashCode() {
19.71 - return value.GetHashCode() ^ value.GetHashCode();
19.72 - }
19.73 - public static bool operator ==(AttributeID a, AttributeID b) {
19.74 - return a.value == b.value;
19.75 - }
19.76 - public static bool operator !=(AttributeID a, AttributeID b) {
19.77 - return !(a == b);
19.78 - }
19.79 -
19.80 - public string ToString(string format) {
19.81 - return value.ToString(format);
19.82 - }
19.83 -
19.84 - public static readonly AttributeID None = new AttributeID(0x00);
19.85 - }
19.86 -
19.87 - // These are the more-or-less standard S.M.A.R.T attributes
19.88 - // TODO: Filter out unused/obscure ones; some are interpreted differently
19.89 - // between manufacturers
19.90 - public static class CommonAttributes {
19.91 - public static readonly AttributeID
19.92 - ReadErrorRate = new AttributeID(0x01),
19.93 - ThroughputPerformance = new AttributeID(0x02),
19.94 - SpinUpTime = new AttributeID(0x03),
19.95 - StartStopCount = new AttributeID(0x04),
19.96 - ReallocatedSectorsCount = new AttributeID(0x05),
19.97 - ReadChannelMargin = new AttributeID(0x06),
19.98 - SeekErrorRate = new AttributeID(0x07),
19.99 - SeekTimePerformance = new AttributeID(0x08),
19.100 - PowerOnHours = new AttributeID(0x09),
19.101 - SpinRetryCount = new AttributeID(0x0A),
19.102 - RecalibrationRetries = new AttributeID(0x0B),
19.103 - PowerCycleCount = new AttributeID(0x0C),
19.104 - SoftReadErrorRate = new AttributeID(0x0D),
19.105 - SataDownshiftErrorCount = new AttributeID(0xB7),
19.106 - EndToEndError = new AttributeID(0xB8),
19.107 - HeadStability = new AttributeID(0xB9),
19.108 - InducedOpVibrationDetection = new AttributeID(0xBA),
19.109 - ReportedUncorrectableErrors = new AttributeID(0xBB),
19.110 - CommandTimeout = new AttributeID(0xBC),
19.111 - HighFlyWrites = new AttributeID(0xBD),
19.112 - AirflowTemperature = new AttributeID(0xBE),
19.113 - GSenseErrorRate = new AttributeID(0xBF),
19.114 - PowerOffRetractCount = new AttributeID(0xC0),
19.115 - LoadCycleCount = new AttributeID(0xC1),
19.116 - Temperature = new AttributeID(0xC2),
19.117 - HardwareEccRecovered = new AttributeID(0xC3),
19.118 - ReallocationEventCount = new AttributeID(0xC4),
19.119 - CurrentPendingSectorCount = new AttributeID(0xC5),
19.120 - UncorrectableSectorCount = new AttributeID(0xC6),
19.121 - UltraDmaCrcErrorCount = new AttributeID(0xC7),
19.122 - WriteErrorRate = new AttributeID(0xC8),
19.123 - DataAddressMarkerrors = new AttributeID(0xCA),
19.124 - RunOutCancel = new AttributeID(0xCB),
19.125 - SoftEccCorrection = new AttributeID(0xCC),
19.126 - ThermalAsperityRate = new AttributeID(0xCD),
19.127 - FlyingHeight = new AttributeID(0xCE),
19.128 - SpinHighCurrent = new AttributeID(0xCF),
19.129 - SpinBuzz = new AttributeID(0xD0),
19.130 - OfflineSeekPerformance = new AttributeID(0xD1),
19.131 - VibrationDuringWrite = new AttributeID(0xD3),
19.132 - ShockDuringWrite = new AttributeID(0xD4),
19.133 - DiskShift = new AttributeID(0xDC),
19.134 - GSenseErrorRateAlt = new AttributeID(0xDD), // Alternative to 0xBF
19.135 - LoadedHours = new AttributeID(0xDE),
19.136 - LoadUnloadRetryCount = new AttributeID(0xDF),
19.137 - LoadFriction = new AttributeID(0xE0),
19.138 - LoadUnloadCycleCount = new AttributeID(0xE1),
19.139 - LoadInTime = new AttributeID(0xE2),
19.140 - TorqueAmplificationCount = new AttributeID(0xE3),
19.141 - PowerOffRetractCycle = new AttributeID(0xE4),
19.142 - GMRHeadAmplitude = new AttributeID(0xE6),
19.143 - DriveTemperature = new AttributeID(0xE7),
19.144 - HeadFlyingHours = new AttributeID(0xF0),
19.145 - LBAsWrittenTotal = new AttributeID(0xF1),
19.146 - LBAsReadTotal = new AttributeID(0xF2),
19.147 - ReadErrorRetryRate = new AttributeID(0xFA),
19.148 - FreeFallProtection = new AttributeID(0xFE)
19.149 - ;
19.150 - }
19.151 -
19.152 - // Indilinx SSD SMART attributes
19.153 - // TODO: Find out the purpose of attribute 0xD2
19.154 - // Seems to be unique to Indilinx drives, hence its name of UnknownUnique.
19.155 - public static class IndilinxAttributes {
19.156 - public static readonly AttributeID
19.157 - ReadErrorRate = CommonAttributes.ReadErrorRate,
19.158 - PowerOnHours = CommonAttributes.PowerOnHours,
19.159 - PowerCycleCount = CommonAttributes.PowerCycleCount,
19.160 - InitialBadBlockCount = new AttributeID(0xB8),
19.161 - RemainingLife = new AttributeID(0xD1),
19.162 - ProgramFailure = new AttributeID(0xC3),
19.163 - EraseFailure = new AttributeID(0xC4),
19.164 - ReadFailure = new AttributeID(0xC5),
19.165 - SectorsRead = new AttributeID(0xC6),
19.166 - SectorsWritten = new AttributeID(0xC7),
19.167 - ReadCommands = new AttributeID(0xC8),
19.168 - WriteCommands = new AttributeID(0xC9),
19.169 - BitErrors = new AttributeID(0xCA),
19.170 - CorrectedErrors = new AttributeID(0xCB),
19.171 - BadBlockFullFlag = new AttributeID(0xCC),
19.172 - MaxCellcycles = new AttributeID(0xCD),
19.173 - MinErase = new AttributeID(0xCE),
19.174 - MaxErase = new AttributeID(0xCF),
19.175 - AverageEraseCount = new AttributeID(0xD0),
19.176 - UnknownUnique = new AttributeID(0xD2),
19.177 - SataErrorCountCRC = new AttributeID(0xD3),
19.178 - SataErrorCountHandshake = new AttributeID(0xD4)
19.179 - ;
19.180 - }
19.181 -
19.182 - // Intel SSD SMART attributes
19.183 - // TODO: Find out the meaning behind 0xE2, 0xE3 and 0xE4
19.184 - public static class IntelAttributes {
19.185 - public static readonly AttributeID
19.186 - ReadErrorRate = CommonAttributes.ReadErrorRate,
19.187 - SpinUpTime = CommonAttributes.SpinUpTime,
19.188 - StartStopCount = CommonAttributes.StartStopCount,
19.189 - ReallocatedSectorsCount = CommonAttributes.ReallocatedSectorsCount,
19.190 - PowerOnHours = CommonAttributes.PowerOnHours,
19.191 - PowerCycleCount = CommonAttributes.PowerCycleCount,
19.192 - EndToEndError = CommonAttributes.EndToEndError, // Only on G2 drives!
19.193 -
19.194 - // Different from the common attribute PowerOffRetractCount, same ID
19.195 - UnsafeShutdownCount = new AttributeID(0xC0),
19.196 - HostWrites = new AttributeID(0xE1),
19.197 - RemainingLife = new AttributeID(0xE8),
19.198 - MediaWearOutIndicator = new AttributeID(0xE9)
19.199 - ;
19.200 - }
19.201 -
19.202 - // Samsung SSD SMART attributes
19.203 - // TODO: AF, B0, B1, B5, B6, BB, C3, C6, C7, E8, E9
19.204 - public static class SamsungAttributes {
19.205 - public static readonly AttributeID
19.206 - PowerOnHours = CommonAttributes.PowerOnHours,
19.207 - PowerCycleCount = CommonAttributes.PowerCycleCount,
19.208 - UsedReservedBlockCountChip = new AttributeID(0xB2), // Unique
19.209 - UsedReservedBlockCountTotal = new AttributeID(0xB3), // Unique
19.210 - RemainingLife = new AttributeID(0xB4), // Unique
19.211 - RuntimeBadBlockTotal = new AttributeID(0xB7)
19.212 - ;
19.213 - }
19.214 -
19.215 - // SandForce SSD SMART attributes
19.216 - // Note: 0xE9 and 0xEA are reserved attributes and unique
19.217 - public static class SandForceAttributes {
19.218 - public static readonly AttributeID
19.219 - ReadErrorRate = CommonAttributes.ReadErrorRate,
19.220 - RetiredBlockCount = new AttributeID(0x05),
19.221 - PowerOnHours = CommonAttributes.PowerOnHours,
19.222 - PowerCycleCount = CommonAttributes.PowerCycleCount,
19.223 - ProgramFailCount = new AttributeID(0xAB), // Unique
19.224 - EraseFailCount = new AttributeID(0xAC), // Unique
19.225 - UnexpectedPowerLossCount = new AttributeID(0xAE), // Unique
19.226 - WearRangeDelta = new AttributeID(0xB1), // Unique
19.227 - ProgramFailCountAlt = new AttributeID(0xB5), // Same as 0xAB
19.228 - EraseFailCountAlt = new AttributeID(0xB6), // Same as 0xAC
19.229 - ReportedUncorrectableErrors =
19.230 - CommonAttributes.ReportedUncorrectableErrors,
19.231 -
19.232 - Temperature = CommonAttributes.Temperature, // SF-1500 only!
19.233 -
19.234 - // Opposite of the common attribute HardwareECCRecovered
19.235 - UnrecoverableECC = new AttributeID(0xC3),
19.236 - ReallocationEventCount = new AttributeID(0xC4),
19.237 - RemainingLife = new AttributeID(0xE7),
19.238 - LifetimeWrites = new AttributeID(0xF1),
19.239 - LifetimeReads = new AttributeID(0xF2)
19.240 - ;
19.241 - }
19.242 -
19.243 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.244 - public struct DriveAttribute {
19.245 - public AttributeID ID;
19.246 - public Status StatusFlags;
19.247 - public byte AttrValue;
19.248 - public byte WorstValue;
19.249 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
19.250 - public byte[] RawValue;
19.251 - public byte Reserved;
19.252 - };
19.253 -
19.254 - [Flags]
19.255 - protected enum AccessMode : uint {
19.256 - Read = 0x80000000,
19.257 - Write = 0x40000000,
19.258 - Execute = 0x20000000,
19.259 - All = 0x10000000
19.260 - }
19.261 -
19.262 - [Flags]
19.263 - protected enum ShareMode : uint {
19.264 - None = 0,
19.265 - Read = 1,
19.266 - Write = 2,
19.267 - Delete = 4
19.268 - }
19.269 -
19.270 - protected enum CreationMode : uint {
19.271 - New = 1,
19.272 - CreateAlways = 2,
19.273 - OpenExisting = 3,
19.274 - OpenAlways = 4,
19.275 - TruncateExisting = 5
19.276 - }
19.277 -
19.278 - [Flags]
19.279 - protected enum FileAttribute : uint {
19.280 - Readonly = 0x00000001,
19.281 - Hidden = 0x00000002,
19.282 - System = 0x00000004,
19.283 - Directory = 0x00000010,
19.284 - Archive = 0x00000020,
19.285 - Device = 0x00000040,
19.286 - Normal = 0x00000080,
19.287 - Temporary = 0x00000100,
19.288 - SparseFile = 0x00000200,
19.289 - ReparsePoint = 0x00000400,
19.290 - Compressed = 0x00000800,
19.291 - Offline = 0x00001000,
19.292 - NotContentIndexed = 0x00002000,
19.293 - Encrypted = 0x00004000,
19.294 - }
19.295 -
19.296 - protected enum DriveCommand : uint {
19.297 - GetVersion = 0x00074080,
19.298 - SendDriveCommand = 0x0007c084,
19.299 - ReceiveDriveData = 0x0007c088
19.300 - }
19.301 -
19.302 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.303 - protected struct CommandBlockRegisters {
19.304 - public byte Features;
19.305 - public byte SectorCount;
19.306 - public byte LBALow;
19.307 - public byte LBAMid;
19.308 - public byte LBAHigh;
19.309 - public byte Device;
19.310 - public byte Command;
19.311 - public byte Reserved;
19.312 - }
19.313 -
19.314 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.315 - protected struct DriveCommandParameter {
19.316 - public uint BufferSize;
19.317 - public CommandBlockRegisters Registers;
19.318 - public byte DriveNumber;
19.319 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
19.320 - public byte[] Reserved;
19.321 - }
19.322 -
19.323 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.324 - protected struct DriverStatus {
19.325 - public byte DriverError;
19.326 - public byte IDEError;
19.327 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
19.328 - public byte[] Reserved;
19.329 - }
19.330 -
19.331 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.332 - protected struct DriveCommandResult {
19.333 - public uint BufferSize;
19.334 - public DriverStatus DriverStatus;
19.335 - }
19.336 -
19.337 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.338 - protected struct DriveSmartReadResult {
19.339 - public uint BufferSize;
19.340 - public DriverStatus DriverStatus;
19.341 - public byte Version;
19.342 - public byte Reserved;
19.343 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
19.344 - public DriveAttribute[] Attributes;
19.345 - }
19.346 -
19.347 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.348 - protected struct Identify {
19.349 - public ushort GeneralConfiguration;
19.350 - public ushort NumberOfCylinders;
19.351 - public ushort Reserved;
19.352 - public ushort NumberOfHeads;
19.353 - public ushort UnformattedBytesPerTrack;
19.354 - public ushort UnformattedBytesPerSector;
19.355 - public ushort SectorsPerTrack;
19.356 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
19.357 - public ushort[] VendorUnique;
19.358 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
19.359 - public byte[] SerialNumber;
19.360 - public ushort BufferType;
19.361 - public ushort BufferSectorSize;
19.362 - public ushort NumberOfEccBytes;
19.363 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
19.364 - public byte[] FirmwareRevision;
19.365 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
19.366 - public byte[] ModelNumber;
19.367 - public ushort MoreVendorUnique;
19.368 - public ushort DoubleWordIo;
19.369 - public ushort Capabilities;
19.370 - public ushort MoreReserved;
19.371 - public ushort PioCycleTimingMode;
19.372 - public ushort DmaCycleTimingMode;
19.373 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 406)]
19.374 - public byte[] More;
19.375 - }
19.376 -
19.377 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
19.378 - protected struct DriveIdentifyResult {
19.379 - public uint BufferSize;
19.380 - public DriverStatus DriverStatus;
19.381 - public Identify Identify;
19.382 - }
19.383 -
19.384 - public static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
19.385 -
19.386 - private const byte SMART_CMD = 0xB0;
19.387 - private const byte ID_CMD = 0xEC;
19.388 -
19.389 - private const byte SMART_READ_DATA = 0xD0;
19.390 - private const byte SMART_ENABLE_OPERATIONS = 0xD8;
19.391 -
19.392 - private const byte SMART_LBA_MID = 0x4F;
19.393 - private const byte SMART_LBA_HI = 0xC2;
19.394 -
19.395 - private const int MAX_DRIVE_ATTRIBUTES = 512;
19.396 -
19.397 - private SMART() { }
19.398 -
19.399 - public static IntPtr OpenPhysicalDrive(int driveNumber) {
19.400 - return NativeMethods.CreateFile(@"\\.\PhysicalDrive" + driveNumber,
19.401 - AccessMode.Read | AccessMode.Write, ShareMode.Read | ShareMode.Write,
19.402 - IntPtr.Zero, CreationMode.OpenExisting, FileAttribute.Device,
19.403 - IntPtr.Zero);
19.404 - }
19.405 -
19.406 - public static bool EnableSmart(IntPtr handle, int driveNumber) {
19.407 - DriveCommandParameter parameter = new DriveCommandParameter();
19.408 - DriveCommandResult result;
19.409 - uint bytesReturned;
19.410 -
19.411 - parameter.DriveNumber = (byte)driveNumber;
19.412 - parameter.Registers.Features = SMART_ENABLE_OPERATIONS;
19.413 - parameter.Registers.LBAMid = SMART_LBA_MID;
19.414 - parameter.Registers.LBAHigh = SMART_LBA_HI;
19.415 - parameter.Registers.Command = SMART_CMD;
19.416 -
19.417 - return NativeMethods.DeviceIoControl(handle, DriveCommand.SendDriveCommand,
19.418 - ref parameter, Marshal.SizeOf(typeof(DriveCommandParameter)), out result,
19.419 - Marshal.SizeOf(typeof(DriveCommandResult)), out bytesReturned,
19.420 - IntPtr.Zero);
19.421 - }
19.422 -
19.423 - public static DriveAttribute[] ReadSmart(IntPtr handle,
19.424 - int driveNumber)
19.425 - {
19.426 - DriveCommandParameter parameter = new DriveCommandParameter();
19.427 - DriveSmartReadResult result;
19.428 - uint bytesReturned;
19.429 -
19.430 - parameter.DriveNumber = (byte)driveNumber;
19.431 - parameter.Registers.Features = SMART_READ_DATA;
19.432 - parameter.Registers.LBAMid = SMART_LBA_MID;
19.433 - parameter.Registers.LBAHigh = SMART_LBA_HI;
19.434 - parameter.Registers.Command = SMART_CMD;
19.435 -
19.436 - bool isValid = NativeMethods.DeviceIoControl(handle,
19.437 - DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
19.438 - out result, Marshal.SizeOf(typeof(DriveSmartReadResult)),
19.439 - out bytesReturned, IntPtr.Zero);
19.440 -
19.441 - return (isValid) ? result.Attributes : new DriveAttribute[0];
19.442 - }
19.443 -
19.444 - public static string ReadName(IntPtr handle, int driveNumber) {
19.445 - DriveCommandParameter parameter = new DriveCommandParameter();
19.446 - DriveIdentifyResult result;
19.447 - uint bytesReturned;
19.448 -
19.449 - parameter.DriveNumber = (byte)driveNumber;
19.450 - parameter.Registers.Command = ID_CMD;
19.451 -
19.452 - bool valid = NativeMethods.DeviceIoControl(handle,
19.453 - DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
19.454 - out result, Marshal.SizeOf(typeof(DriveIdentifyResult)),
19.455 - out bytesReturned, IntPtr.Zero);
19.456 -
19.457 - if (!valid)
19.458 - return null;
19.459 - else {
19.460 -
19.461 - byte[] bytes = result.Identify.ModelNumber;
19.462 - char[] chars = new char[bytes.Length];
19.463 - for (int i = 0; i < bytes.Length; i += 2) {
19.464 - chars[i] = (char)bytes[i + 1];
19.465 - chars[i + 1] = (char)bytes[i];
19.466 - }
19.467 -
19.468 - return new string(chars).Trim(new char[] {' ', '\0'});
19.469 - }
19.470 - }
19.471 -
19.472 - public static int CloseHandle(IntPtr handle) {
19.473 - return NativeMethods.CloseHandle(handle);
19.474 - }
19.475 -
19.476 - protected static class NativeMethods {
19.477 - private const string KERNEL = "kernel32.dll";
19.478 -
19.479 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
19.480 - CharSet = CharSet.Unicode)]
19.481 - public static extern IntPtr CreateFile(string fileName,
19.482 - AccessMode desiredAccess, ShareMode shareMode, IntPtr securityAttributes,
19.483 - CreationMode creationDisposition, FileAttribute flagsAndAttributes,
19.484 - IntPtr templateFilehandle);
19.485 -
19.486 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
19.487 - public static extern int CloseHandle(IntPtr handle);
19.488 -
19.489 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
19.490 - [return: MarshalAsAttribute(UnmanagedType.Bool)]
19.491 - public static extern bool DeviceIoControl(IntPtr handle,
19.492 - DriveCommand command, ref DriveCommandParameter parameter,
19.493 - int parameterSize, out DriveSmartReadResult result, int resultSize,
19.494 - out uint bytesReturned, IntPtr overlapped);
19.495 -
19.496 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
19.497 - [return: MarshalAsAttribute(UnmanagedType.Bool)]
19.498 - public static extern bool DeviceIoControl(IntPtr handle,
19.499 - DriveCommand command, ref DriveCommandParameter parameter,
19.500 - int parameterSize, out DriveCommandResult result, int resultSize,
19.501 - out uint bytesReturned, IntPtr overlapped);
19.502 -
19.503 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
19.504 - [return: MarshalAsAttribute(UnmanagedType.Bool)]
19.505 - public static extern bool DeviceIoControl(IntPtr handle,
19.506 - DriveCommand command, ref DriveCommandParameter parameter,
19.507 - int parameterSize, out DriveIdentifyResult result, int resultSize,
19.508 - out uint bytesReturned, IntPtr overlapped);
19.509 - }
19.510 - }
19.511 -}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/Hardware/HDD/SSDIndilinx.cs Sat Dec 31 17:31:04 2011 +0000
20.3 @@ -0,0 +1,77 @@
20.4 +/*
20.5 +
20.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
20.7 +
20.8 + The contents of this file are subject to the Mozilla Public License Version
20.9 + 1.1 (the "License"); you may not use this file except in compliance with
20.10 + the License. You may obtain a copy of the License at
20.11 +
20.12 + http://www.mozilla.org/MPL/
20.13 +
20.14 + Software distributed under the License is distributed on an "AS IS" basis,
20.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20.16 + for the specific language governing rights and limitations under the License.
20.17 +
20.18 + The Original Code is the Open Hardware Monitor code.
20.19 +
20.20 + The Initial Developer of the Original Code is
20.21 + Roland Reinl <roland-reinl@gmx.de>.
20.22 + Portions created by the Initial Developer are Copyright (C) 2009-2011
20.23 + the Initial Developer. All Rights Reserved.
20.24 +
20.25 + Contributor(s):
20.26 + Paul Werelds
20.27 + Michael Möller <m.moeller@gmx.ch>
20.28 +
20.29 + Alternatively, the contents of this file may be used under the terms of
20.30 + either the GNU General Public License Version 2 or later (the "GPL"), or
20.31 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20.32 + in which case the provisions of the GPL or the LGPL are applicable instead
20.33 + of those above. If you wish to allow use of your version of this file only
20.34 + under the terms of either the GPL or the LGPL, and not to allow others to
20.35 + use your version of this file under the terms of the MPL, indicate your
20.36 + decision by deleting the provisions above and replace them with the notice
20.37 + and other provisions required by the GPL or the LGPL. If you do not delete
20.38 + the provisions above, a recipient may use your version of this file under
20.39 + the terms of any one of the MPL, the GPL or the LGPL.
20.40 +
20.41 +*/
20.42 +
20.43 +namespace OpenHardwareMonitor.Hardware.HDD {
20.44 + using System.Collections.Generic;
20.45 +
20.46 + [NamePrefix(""), RequireSmart(0xD1)]
20.47 + internal class SSDIndilinx : AbstractHarddrive {
20.48 +
20.49 + private static readonly IEnumerable<SmartAttribute> smartAttributes =
20.50 + new List<SmartAttribute> {
20.51 +
20.52 + new SmartAttribute(0xB8, SmartAttributeNames.InitialBadBlockCount),
20.53 + new SmartAttribute(0xC3, SmartAttributeNames.ProgramFailure),
20.54 + new SmartAttribute(0xC4, SmartAttributeNames.EraseFailure),
20.55 + new SmartAttribute(0xC5, SmartAttributeNames.ReadFailure),
20.56 + new SmartAttribute(0xC6, SmartAttributeNames.SectorsRead),
20.57 + new SmartAttribute(0xC7, SmartAttributeNames.SectorsWritten),
20.58 + new SmartAttribute(0xC8, SmartAttributeNames.ReadCommands),
20.59 + new SmartAttribute(0xC9, SmartAttributeNames.WriteCommands),
20.60 + new SmartAttribute(0xCA, SmartAttributeNames.BitErrors),
20.61 + new SmartAttribute(0xCB, SmartAttributeNames.CorrectedErrors),
20.62 + new SmartAttribute(0xCC, SmartAttributeNames.BadBlockFullFlag),
20.63 + new SmartAttribute(0xCD, SmartAttributeNames.MaxCellCycles),
20.64 + new SmartAttribute(0xCE, SmartAttributeNames.MinErase),
20.65 + new SmartAttribute(0xCF, SmartAttributeNames.MaxErase),
20.66 + new SmartAttribute(0xD0, SmartAttributeNames.AverageEraseCount),
20.67 + new SmartAttribute(0xD1, SmartAttributeNames.RemainingLife,
20.68 + null, SensorType.Level, 0),
20.69 + new SmartAttribute(0xD2, SmartAttributeNames.UnknownUnique),
20.70 + new SmartAttribute(0xD3, SmartAttributeNames.SataErrorCountCrc),
20.71 + new SmartAttribute(0xD4, SmartAttributeNames.SataErrorCountHandshake),
20.72 + };
20.73 +
20.74 + public SSDIndilinx(ISmart smart, string name, int index, ISettings settings)
20.75 + : base(smart, name, index, smartAttributes, settings) { }
20.76 + }
20.77 +}
20.78 +
20.79 +
20.80 +
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/Hardware/HDD/SSDIntel.cs Sat Dec 31 17:31:04 2011 +0000
21.3 @@ -0,0 +1,78 @@
21.4 +/*
21.5 +
21.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
21.7 +
21.8 + The contents of this file are subject to the Mozilla Public License Version
21.9 + 1.1 (the "License"); you may not use this file except in compliance with
21.10 + the License. You may obtain a copy of the License at
21.11 +
21.12 + http://www.mozilla.org/MPL/
21.13 +
21.14 + Software distributed under the License is distributed on an "AS IS" basis,
21.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
21.16 + for the specific language governing rights and limitations under the License.
21.17 +
21.18 + The Original Code is the Open Hardware Monitor code.
21.19 +
21.20 + The Initial Developer of the Original Code is
21.21 + Michael Möller <m.moeller@gmx.ch>.
21.22 + Portions created by the Initial Developer are Copyright (C) 2009-2011
21.23 + the Initial Developer. All Rights Reserved.
21.24 +
21.25 + Contributor(s):
21.26 + Paul Werelds
21.27 + Roland Reinl <roland-reinl@gmx.de>
21.28 +
21.29 + Alternatively, the contents of this file may be used under the terms of
21.30 + either the GNU General Public License Version 2 or later (the "GPL"), or
21.31 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
21.32 + in which case the provisions of the GPL or the LGPL are applicable instead
21.33 + of those above. If you wish to allow use of your version of this file only
21.34 + under the terms of either the GPL or the LGPL, and not to allow others to
21.35 + use your version of this file under the terms of the MPL, indicate your
21.36 + decision by deleting the provisions above and replace them with the notice
21.37 + and other provisions required by the GPL or the LGPL. If you do not delete
21.38 + the provisions above, a recipient may use your version of this file under
21.39 + the terms of any one of the MPL, the GPL or the LGPL.
21.40 +
21.41 +*/
21.42 +
21.43 +namespace OpenHardwareMonitor.Hardware.HDD {
21.44 + using System.Collections.Generic;
21.45 +
21.46 + [NamePrefix("INTEL SSD"),
21.47 + RequireSmart(0xE1), RequireSmart(0xE8), RequireSmart(0xE9)]
21.48 + internal class SSDIntel : AbstractHarddrive {
21.49 +
21.50 + private static readonly IEnumerable<SmartAttribute> smartAttributes =
21.51 + new List<SmartAttribute> {
21.52 +
21.53 + new SmartAttribute(0x01, SmartAttributeNames.ReadErrorRate),
21.54 + new SmartAttribute(0x03, SmartAttributeNames.SpinUpTime),
21.55 + new SmartAttribute(0x04, SmartAttributeNames.StartStopCount, RawToInt),
21.56 + new SmartAttribute(0x05, SmartAttributeNames.ReallocatedSectorsCount),
21.57 + new SmartAttribute(0x09, SmartAttributeNames.PowerOnHours, RawToInt),
21.58 + new SmartAttribute(0x0C, SmartAttributeNames.PowerCycleCount, RawToInt),
21.59 + new SmartAttribute(0xAA, SmartAttributeNames.AvailableReservedSpace),
21.60 + new SmartAttribute(0xAB, SmartAttributeNames.ProgramFailCount),
21.61 + new SmartAttribute(0xAC, SmartAttributeNames.EraseFailCount),
21.62 + new SmartAttribute(0xB8, SmartAttributeNames.EndToEndError),
21.63 + new SmartAttribute(0xC0, SmartAttributeNames.UnsafeShutdownCount),
21.64 + new SmartAttribute(0xE1, SmartAttributeNames.HostWrites,
21.65 + (byte[] r, byte v) => { return RawToInt(r, v) / 0x20; },
21.66 + SensorType.Data, 0),
21.67 + new SmartAttribute(0xE8, SmartAttributeNames.RemainingLife,
21.68 + null, SensorType.Level, 0),
21.69 + new SmartAttribute(0xE9, SmartAttributeNames.MediaWearOutIndicator),
21.70 + new SmartAttribute(0xF1, SmartAttributeNames.HostWrites,
21.71 + (byte[] r, byte v) => { return RawToInt(r, v) / 0x20; },
21.72 + SensorType.Data, 0),
21.73 + new SmartAttribute(0xF2, SmartAttributeNames.HostReads,
21.74 + (byte[] r, byte v) => { return RawToInt(r, v) / 0x20; },
21.75 + SensorType.Data, 1),
21.76 + };
21.77 +
21.78 + public SSDIntel(ISmart smart, string name, int index, ISettings settings)
21.79 + : base(smart, name, index, smartAttributes, settings) { }
21.80 + }
21.81 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/Hardware/HDD/SSDPlextor.cs Sat Dec 31 17:31:04 2011 +0000
22.3 @@ -0,0 +1,53 @@
22.4 +/*
22.5 +
22.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
22.7 +
22.8 + The contents of this file are subject to the Mozilla Public License Version
22.9 + 1.1 (the "License"); you may not use this file except in compliance with
22.10 + the License. You may obtain a copy of the License at
22.11 +
22.12 + http://www.mozilla.org/MPL/
22.13 +
22.14 + Software distributed under the License is distributed on an "AS IS" basis,
22.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
22.16 + for the specific language governing rights and limitations under the License.
22.17 +
22.18 + The Original Code is the Open Hardware Monitor code.
22.19 +
22.20 + The Initial Developer of the Original Code is
22.21 + Michael Möller <m.moeller@gmx.ch>.
22.22 + Portions created by the Initial Developer are Copyright (C) 2011
22.23 + the Initial Developer. All Rights Reserved.
22.24 +
22.25 + Contributor(s):
22.26 +
22.27 + Alternatively, the contents of this file may be used under the terms of
22.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
22.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
22.30 + in which case the provisions of the GPL or the LGPL are applicable instead
22.31 + of those above. If you wish to allow use of your version of this file only
22.32 + under the terms of either the GPL or the LGPL, and not to allow others to
22.33 + use your version of this file under the terms of the MPL, indicate your
22.34 + decision by deleting the provisions above and replace them with the notice
22.35 + and other provisions required by the GPL or the LGPL. If you do not delete
22.36 + the provisions above, a recipient may use your version of this file under
22.37 + the terms of any one of the MPL, the GPL or the LGPL.
22.38 +
22.39 +*/
22.40 +
22.41 +namespace OpenHardwareMonitor.Hardware.HDD {
22.42 + using System.Collections.Generic;
22.43 +
22.44 + [NamePrefix("PLEXTOR")]
22.45 + internal class SSDPlextor : AbstractHarddrive {
22.46 +
22.47 + private static readonly IEnumerable<SmartAttribute> smartAttributes =
22.48 + new List<SmartAttribute> {
22.49 + new SmartAttribute(0x09, SmartAttributeNames.PowerOnHours, RawToInt),
22.50 + new SmartAttribute(0x0C, SmartAttributeNames.PowerCycleCount, RawToInt),
22.51 + };
22.52 +
22.53 + public SSDPlextor(ISmart smart, string name, int index, ISettings settings)
22.54 + : base(smart, name, index, smartAttributes, settings) { }
22.55 + }
22.56 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/Hardware/HDD/SSDSandforce.cs Sat Dec 31 17:31:04 2011 +0000
23.3 @@ -0,0 +1,72 @@
23.4 +/*
23.5 +
23.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
23.7 +
23.8 + The contents of this file are subject to the Mozilla Public License Version
23.9 + 1.1 (the "License"); you may not use this file except in compliance with
23.10 + the License. You may obtain a copy of the License at
23.11 +
23.12 + http://www.mozilla.org/MPL/
23.13 +
23.14 + Software distributed under the License is distributed on an "AS IS" basis,
23.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
23.16 + for the specific language governing rights and limitations under the License.
23.17 +
23.18 + The Original Code is the Open Hardware Monitor code.
23.19 +
23.20 + The Initial Developer of the Original Code is
23.21 + Michael Möller <m.moeller@gmx.ch>.
23.22 + Portions created by the Initial Developer are Copyright (C) 2009-2011
23.23 + the Initial Developer. All Rights Reserved.
23.24 +
23.25 + Contributor(s):
23.26 + Paul Werelds
23.27 +
23.28 + Alternatively, the contents of this file may be used under the terms of
23.29 + either the GNU General Public License Version 2 or later (the "GPL"), or
23.30 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23.31 + in which case the provisions of the GPL or the LGPL are applicable instead
23.32 + of those above. If you wish to allow use of your version of this file only
23.33 + under the terms of either the GPL or the LGPL, and not to allow others to
23.34 + use your version of this file under the terms of the MPL, indicate your
23.35 + decision by deleting the provisions above and replace them with the notice
23.36 + and other provisions required by the GPL or the LGPL. If you do not delete
23.37 + the provisions above, a recipient may use your version of this file under
23.38 + the terms of any one of the MPL, the GPL or the LGPL.
23.39 +
23.40 +*/
23.41 +
23.42 +namespace OpenHardwareMonitor.Hardware.HDD {
23.43 + using System.Collections.Generic;
23.44 +
23.45 + [NamePrefix(""), RequireSmart(0xAB)]
23.46 + internal class SSDSandforce : AbstractHarddrive {
23.47 +
23.48 + private static readonly IEnumerable<SmartAttribute> smartAttributes =
23.49 + new List<SmartAttribute> {
23.50 + new SmartAttribute(0x05, SmartAttributeNames.RetiredBlockCount),
23.51 + new SmartAttribute(0x09, SmartAttributeNames.PowerOnHours, RawToInt),
23.52 + new SmartAttribute(0x0C, SmartAttributeNames.PowerCycleCount, RawToInt),
23.53 + new SmartAttribute(0xAB, SmartAttributeNames.ProgramFailCount),
23.54 + new SmartAttribute(0xAC, SmartAttributeNames.EraseFailCount),
23.55 + new SmartAttribute(0xAE, SmartAttributeNames.UnexpectedPowerLossCount),
23.56 + new SmartAttribute(0xB1, SmartAttributeNames.WearRangeDelta),
23.57 + new SmartAttribute(0xB5, SmartAttributeNames.AlternativeProgramFailCount),
23.58 + new SmartAttribute(0xB6, SmartAttributeNames.AlternativeEraseFailCount),
23.59 + new SmartAttribute(0xC3, SmartAttributeNames.UnrecoverableEcc),
23.60 + new SmartAttribute(0xC4, SmartAttributeNames.ReallocationEventCount),
23.61 + new SmartAttribute(0xE7, SmartAttributeNames.RemainingLife,
23.62 + null, SensorType.Level, 0),
23.63 + new SmartAttribute(0xF1, SmartAttributeNames.HostWrites,
23.64 + (byte[] r, byte v) => { return RawToInt(r, v); },
23.65 + SensorType.Data, 0),
23.66 + new SmartAttribute(0xF2, SmartAttributeNames.HostReads,
23.67 + (byte[] r, byte v) => { return RawToInt(r, v); },
23.68 + SensorType.Data, 1)
23.69 + };
23.70 +
23.71 + public SSDSandforce(ISmart smart, string name, int index,
23.72 + ISettings settings)
23.73 + : base(smart, name, index, smartAttributes, settings) { }
23.74 + }
23.75 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/Hardware/HDD/SmartAttribute.cs Sat Dec 31 17:31:04 2011 +0000
24.3 @@ -0,0 +1,116 @@
24.4 +/*
24.5 +
24.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
24.7 +
24.8 + The contents of this file are subject to the Mozilla Public License Version
24.9 + 1.1 (the "License"); you may not use this file except in compliance with
24.10 + the License. You may obtain a copy of the License at
24.11 +
24.12 + http://www.mozilla.org/MPL/
24.13 +
24.14 + Software distributed under the License is distributed on an "AS IS" basis,
24.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24.16 + for the specific language governing rights and limitations under the License.
24.17 +
24.18 + The Original Code is the Open Hardware Monitor code.
24.19 +
24.20 + The Initial Developer of the Original Code is
24.21 + Michael Möller <m.moeller@gmx.ch>.
24.22 + Portions created by the Initial Developer are Copyright (C) 2011
24.23 + the Initial Developer. All Rights Reserved.
24.24 +
24.25 + Contributor(s):
24.26 + Roland Reinl <roland-reinl@gmx.de>
24.27 +
24.28 + Alternatively, the contents of this file may be used under the terms of
24.29 + either the GNU General Public License Version 2 or later (the "GPL"), or
24.30 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
24.31 + in which case the provisions of the GPL or the LGPL are applicable instead
24.32 + of those above. If you wish to allow use of your version of this file only
24.33 + under the terms of either the GPL or the LGPL, and not to allow others to
24.34 + use your version of this file under the terms of the MPL, indicate your
24.35 + decision by deleting the provisions above and replace them with the notice
24.36 + and other provisions required by the GPL or the LGPL. If you do not delete
24.37 + the provisions above, a recipient may use your version of this file under
24.38 + the terms of any one of the MPL, the GPL or the LGPL.
24.39 +
24.40 +*/
24.41 +
24.42 +using System;
24.43 +using System.Collections.Generic;
24.44 +
24.45 +namespace OpenHardwareMonitor.Hardware.HDD {
24.46 + internal class SmartAttribute {
24.47 +
24.48 + private RawValueConversion rawValueConversion;
24.49 +
24.50 + /// <summary>
24.51 + /// Initializes a new instance of the <see cref="SmartAttribute"/> class.
24.52 + /// </summary>
24.53 + /// <param name="identifier">The SMART identifier of the attribute.</param>
24.54 + /// <param name="name">The name of the attribute.</param>
24.55 + public SmartAttribute(byte identifier, string name) :
24.56 + this(identifier, name, null, null, 0) { }
24.57 +
24.58 + /// <summary>
24.59 + /// Initializes a new instance of the <see cref="SmartAttribute"/> class.
24.60 + /// </summary>
24.61 + /// <param name="identifier">The SMART identifier of the attribute.</param>
24.62 + /// <param name="name">The name of the attribute.</param>
24.63 + /// <param name="rawValueConversion">A delegate for converting the raw byte
24.64 + /// array into a value (or null to use the attribute value).</param>
24.65 + public SmartAttribute(byte identifier, string name,
24.66 + RawValueConversion rawValueConversion) :
24.67 + this(identifier, name, rawValueConversion, null, 0) { }
24.68 +
24.69 + /// <summary>
24.70 + /// Initializes a new instance of the <see cref="SmartAttribute"/> class.
24.71 + /// </summary>
24.72 + /// <param name="identifier">The SMART identifier of the attribute.</param>
24.73 + /// <param name="name">The name of the attribute.</param>
24.74 + /// <param name="rawValueConversion">A delegate for converting the raw byte
24.75 + /// array into a value (or null to use the attribute value).</param>
24.76 + /// <param name="sensorType">Type of the sensor or null if no sensor is to
24.77 + /// be created.</param>
24.78 + /// <param name="sensorChannel">If there exists more than one attribute with
24.79 + /// the same sensor channel and type, then a sensor is created only for the
24.80 + /// first attribute.</param>
24.81 + public SmartAttribute(byte identifier, string name,
24.82 + RawValueConversion rawValueConversion, SensorType? sensorType,
24.83 + int sensorChannel)
24.84 + {
24.85 + this.Identifier = identifier;
24.86 + this.Name = name;
24.87 + this.rawValueConversion = rawValueConversion;
24.88 + this.SensorType = sensorType;
24.89 + this.SensorChannel = sensorChannel;
24.90 + }
24.91 +
24.92 + /// <summary>
24.93 + /// Gets the SMART identifier.
24.94 + /// </summary>
24.95 + public byte Identifier { get; private set; }
24.96 +
24.97 + public string Name { get; private set; }
24.98 +
24.99 + public SensorType? SensorType { get; private set; }
24.100 +
24.101 + public int SensorChannel { get; private set; }
24.102 +
24.103 + public bool HasRawValueConversion {
24.104 + get {
24.105 + return rawValueConversion != null;
24.106 + }
24.107 + }
24.108 +
24.109 + public float ConvertValue(DriveAttributeValue value) {
24.110 + if (rawValueConversion == null) {
24.111 + return value.AttrValue;
24.112 + } else {
24.113 + return rawValueConversion(value.RawValue, value.AttrValue);
24.114 + }
24.115 + }
24.116 +
24.117 + public delegate float RawValueConversion(byte[] rawValue, byte value);
24.118 + }
24.119 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/Hardware/HDD/SmartAttributeNames.cs Sat Dec 31 17:31:04 2011 +0000
25.3 @@ -0,0 +1,449 @@
25.4 +/*
25.5 +
25.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
25.7 +
25.8 + The contents of this file are subject to the Mozilla Public License Version
25.9 + 1.1 (the "License"); you may not use this file except in compliance with
25.10 + the License. You may obtain a copy of the License at
25.11 +
25.12 + http://www.mozilla.org/MPL/
25.13 +
25.14 + Software distributed under the License is distributed on an "AS IS" basis,
25.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
25.16 + for the specific language governing rights and limitations under the License.
25.17 +
25.18 + The Original Code is the Open Hardware Monitor code.
25.19 +
25.20 + The Initial Developer of the Original Code is
25.21 + Roland Reinl <roland-reinl@gmx.de>.
25.22 + Portions created by the Initial Developer are Copyright (C) 2011
25.23 + the Initial Developer. All Rights Reserved.
25.24 +
25.25 + Contributor(s):
25.26 + Michael Möller <m.moeller@gmx.ch>
25.27 +
25.28 + Alternatively, the contents of this file may be used under the terms of
25.29 + either the GNU General Public License Version 2 or later (the "GPL"), or
25.30 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25.31 + in which case the provisions of the GPL or the LGPL are applicable instead
25.32 + of those above. If you wish to allow use of your version of this file only
25.33 + under the terms of either the GPL or the LGPL, and not to allow others to
25.34 + use your version of this file under the terms of the MPL, indicate your
25.35 + decision by deleting the provisions above and replace them with the notice
25.36 + and other provisions required by the GPL or the LGPL. If you do not delete
25.37 + the provisions above, a recipient may use your version of this file under
25.38 + the terms of any one of the MPL, the GPL or the LGPL.
25.39 +
25.40 +*/
25.41 +
25.42 +namespace OpenHardwareMonitor.Hardware.HDD {
25.43 + /// <summary>
25.44 + /// Localization class for SMART attribute names.
25.45 + /// </summary>
25.46 + internal static class SmartAttributeNames {
25.47 +
25.48 + public static string AirflowTemperature {
25.49 + get { return "Airflow Temperature"; }
25.50 + }
25.51 +
25.52 + public static string Temperature {
25.53 + get { return "Temperature"; }
25.54 + }
25.55 +
25.56 + public static string RetiredBlockCount {
25.57 + get { return "Retired Block Count"; }
25.58 + }
25.59 +
25.60 + public static string ProgramFailCount {
25.61 + get { return "Program Fail Count"; }
25.62 + }
25.63 +
25.64 + public static string EraseFailCount {
25.65 + get { return "Erase Fail Count"; }
25.66 + }
25.67 +
25.68 + public static string UnexpectedPowerLossCount {
25.69 + get { return "Unexpected Power Loss Count"; }
25.70 + }
25.71 +
25.72 + public static string WearRangeDelta {
25.73 + get { return "Wear Range Delta"; }
25.74 + }
25.75 +
25.76 + public static string AlternativeProgramFailCount {
25.77 + get { return "Alternative Program Fail Count"; }
25.78 + }
25.79 +
25.80 + public static string AlternativeEraseFailCount {
25.81 + get { return "Alternative Erase Fail Count"; }
25.82 + }
25.83 +
25.84 + public static string UnrecoverableEcc {
25.85 + get { return "Unrecoverable ECC"; }
25.86 + }
25.87 +
25.88 + public static string ReallocationEventCount {
25.89 + get { return "Reallocation Event Count"; }
25.90 + }
25.91 +
25.92 + public static string RemainingLife {
25.93 + get { return "Remaining Life"; }
25.94 + }
25.95 +
25.96 + public static string AvailableReservedSpace {
25.97 + get { return "Available Reserved Space"; }
25.98 + }
25.99 +
25.100 + public static string CalibrationRetryCount {
25.101 + get { return "Calibration Retry Count"; }
25.102 + }
25.103 +
25.104 + public static string CommandTimeout {
25.105 + get { return "Command Timeout"; }
25.106 + }
25.107 +
25.108 + public static string CurrentPendingSectorCount {
25.109 + get { return "Current Pending Sector Count"; }
25.110 + }
25.111 +
25.112 + public static string DataAddressMarkErrors {
25.113 + get { return "Data Address Mark errors"; }
25.114 + }
25.115 +
25.116 + public static string DiskShift {
25.117 + get { return "Disk Shift"; }
25.118 + }
25.119 +
25.120 + public static string DriveTemperature {
25.121 + get { return "Drive Temperature"; }
25.122 + }
25.123 +
25.124 + public static string EmergencyRetractCycleCount {
25.125 + get { return "Emergency Retract Cycle Count"; }
25.126 + }
25.127 +
25.128 + public static string EndToEndError {
25.129 + get { return "End-to-End error"; }
25.130 + }
25.131 +
25.132 + public static string EnduranceRemaining {
25.133 + get { return "Endurance Remaining"; }
25.134 + }
25.135 +
25.136 + public static string FlyingHeight {
25.137 + get { return "Flying Height"; }
25.138 + }
25.139 +
25.140 + public static string FreeFallProtection {
25.141 + get { return "Free Fall Protection"; }
25.142 + }
25.143 +
25.144 + public static string GmrHeadAmplitude {
25.145 + get { return "GMR Head Amplitude"; }
25.146 + }
25.147 +
25.148 + public static string GSenseErrorRate {
25.149 + get { return "G-sense Error Rate"; }
25.150 + }
25.151 +
25.152 + public static string HardwareEccRecovered {
25.153 + get { return "Hardware ECC Recovered"; }
25.154 + }
25.155 +
25.156 + public static string HeadFlyingHours {
25.157 + get { return "Head Flying Hours"; }
25.158 + }
25.159 +
25.160 + public static string HeadStability {
25.161 + get { return "Head Stability"; }
25.162 + }
25.163 +
25.164 + public static string HighFlyWrites {
25.165 + get { return "High Fly Writes"; }
25.166 + }
25.167 +
25.168 + public static string InducedOpVibrationDetection {
25.169 + get { return "Induced Op-Vibration Detection"; }
25.170 + }
25.171 +
25.172 + public static string LoadedHours {
25.173 + get { return "Loaded Hours"; }
25.174 + }
25.175 +
25.176 + public static string LoadFriction {
25.177 + get { return "Load Friction"; }
25.178 + }
25.179 +
25.180 + public static string LoadInTime {
25.181 + get { return "Load 'In'-time"; }
25.182 + }
25.183 +
25.184 + public static string LoadUnloadCycleCount {
25.185 + get { return "Load/Unload Cycle Count"; }
25.186 + }
25.187 +
25.188 + public static string LoadUnloadCycleCountFujitsu {
25.189 + get { return "Load/Unload Cycle Count (Fujitus)"; }
25.190 + }
25.191 +
25.192 + public static string LoadUnloadRetryCount {
25.193 + get { return "Load/Unload Retry Count"; }
25.194 + }
25.195 +
25.196 + public static string MediaWearoutIndicator {
25.197 + get { return "Media Wearout Indicator"; }
25.198 + }
25.199 +
25.200 + public static string MultiZoneErrorRate {
25.201 + get { return "Multi-Zone Error Rate"; }
25.202 + }
25.203 +
25.204 + public static string OfflineSeekPerformance {
25.205 + get { return "Offline Seek Performance"; }
25.206 + }
25.207 +
25.208 + public static string PowerCycleCount {
25.209 + get { return "Power Cycle Count"; }
25.210 + }
25.211 +
25.212 + public static string PowerOffRetractCycle {
25.213 + get { return "Power-Off Retract Cycle"; }
25.214 + }
25.215 +
25.216 + public static string PowerOnHours {
25.217 + get { return "Power-On Hours (POH)"; }
25.218 + }
25.219 +
25.220 + public static string ReadChannelMargin {
25.221 + get { return "Read Channel Margin"; }
25.222 + }
25.223 +
25.224 + public static string ReadErrorRate {
25.225 + get { return "Read Error Rate"; }
25.226 + }
25.227 +
25.228 + public static string ReadErrorRetryRate {
25.229 + get { return "Read Error Retry Rate"; }
25.230 + }
25.231 +
25.232 + public static string ReallocatedSectorsCount {
25.233 + get { return "Reallocated Sectors Count"; }
25.234 + }
25.235 +
25.236 + public static string ReportedUncorrectableErrors {
25.237 + get { return "Reported Uncorrectable Errors"; }
25.238 + }
25.239 +
25.240 + public static string RunOutCancel {
25.241 + get { return "Run Out Cancel"; }
25.242 + }
25.243 +
25.244 + public static string SataDownshiftErrorCount {
25.245 + get { return "SATA Downshift Error Count"; }
25.246 + }
25.247 +
25.248 + public static string SeekErrorRate {
25.249 + get { return "Seek Error Rate"; }
25.250 + }
25.251 +
25.252 + public static string SeekTimePerformance {
25.253 + get { return "Seek Time Performance"; }
25.254 + }
25.255 +
25.256 + public static string ShockDuringWrite {
25.257 + get { return "Shock During Write"; }
25.258 + }
25.259 +
25.260 + public static string SoftEccCorrection {
25.261 + get { return "Soft ECC Correction"; }
25.262 + }
25.263 +
25.264 + public static string SoftReadErrorRate {
25.265 + get { return "Soft Read Error Rate"; }
25.266 + }
25.267 +
25.268 + public static string SpinBuzz {
25.269 + get { return "Spin Buzz"; }
25.270 + }
25.271 +
25.272 + public static string SpinHighCurrent {
25.273 + get { return "Spin High Current"; }
25.274 + }
25.275 +
25.276 + public static string SpinRetryCount {
25.277 + get { return "Spin Retry Count"; }
25.278 + }
25.279 +
25.280 + public static string SpinUpTime {
25.281 + get { return "Spin-Up Time"; }
25.282 + }
25.283 +
25.284 + public static string StartStopCount {
25.285 + get { return "Start/Stop Count"; }
25.286 + }
25.287 +
25.288 + public static string TaCounterDetected {
25.289 + get { return "TA Counter Detected"; }
25.290 + }
25.291 +
25.292 + public static string TemperatureDifferenceFrom100 {
25.293 + get { return "Temperature Difference from 100"; }
25.294 + }
25.295 +
25.296 + public static string ThermalAsperityRate {
25.297 + get { return "Thermal Asperity Rate (TAR)"; }
25.298 + }
25.299 +
25.300 + public static string ThroughputPerformance {
25.301 + get { return "Throughput Performance"; }
25.302 + }
25.303 +
25.304 + public static string TorqueAmplificationCount {
25.305 + get { return "Torque Amplification Count"; }
25.306 + }
25.307 +
25.308 + public static string TotalLbasRead {
25.309 + get { return "Total LBAs Read"; }
25.310 + }
25.311 +
25.312 + public static string TotalLbasWritten {
25.313 + get { return "Total LBAs Written"; }
25.314 + }
25.315 +
25.316 + public static string TransferErrorRate {
25.317 + get { return "Transfer Error Rate"; }
25.318 + }
25.319 +
25.320 + public static string UltraDmaCrcErrorCount {
25.321 + get { return "UltraDMA CRC Error Count"; }
25.322 + }
25.323 +
25.324 + public static string UncorrectableSectorCount {
25.325 + get { return "Uncorrectable Sector Count"; }
25.326 + }
25.327 +
25.328 + public static string Unknown {
25.329 + get { return "Unknown"; }
25.330 + }
25.331 +
25.332 + public static string VibrationDuringWrite {
25.333 + get { return "Vibration During Write"; }
25.334 + }
25.335 +
25.336 + public static string WriteErrorRate {
25.337 + get { return "Write Error Rate"; }
25.338 + }
25.339 +
25.340 + public static string RecalibrationRetries {
25.341 + get { return "Recalibration Retries"; }
25.342 + }
25.343 +
25.344 + public static string LoadCycleCount {
25.345 + get { return "Load Cycle Count"; }
25.346 + }
25.347 +
25.348 + public static string AlternativeGSenseErrorRate {
25.349 + get { return "Alternative G-Sense Error Rate"; }
25.350 + }
25.351 +
25.352 + public static string InitialBadBlockCount {
25.353 + get { return "Initial Bad Block Count"; }
25.354 + }
25.355 +
25.356 + public static string ProgramFailure {
25.357 + get { return "Program Failure"; }
25.358 + }
25.359 +
25.360 + public static string EraseFailure {
25.361 + get { return "Erase Failure"; }
25.362 + }
25.363 +
25.364 + public static string ReadFailure {
25.365 + get { return "Read Failure"; }
25.366 + }
25.367 +
25.368 + public static string SectorsRead {
25.369 + get { return "Sectors Read"; }
25.370 + }
25.371 +
25.372 + public static string SectorsWritten {
25.373 + get { return "Sectors Written"; }
25.374 + }
25.375 +
25.376 + public static string ReadCommands {
25.377 + get { return "Read Commands"; }
25.378 + }
25.379 +
25.380 + public static string WriteCommands {
25.381 + get { return "Write Commands"; }
25.382 + }
25.383 +
25.384 + public static string BitErrors {
25.385 + get { return "Bit Errors"; }
25.386 + }
25.387 +
25.388 + public static string CorrectedErrors {
25.389 + get { return "Corrected Errors"; }
25.390 + }
25.391 +
25.392 + public static string BadBlockFullFlag {
25.393 + get { return "Bad Block Full Flag"; }
25.394 + }
25.395 +
25.396 + public static string MaxCellCycles {
25.397 + get { return "Max Cell Cycles"; }
25.398 + }
25.399 +
25.400 + public static string MinErase {
25.401 + get { return "Min Erase"; }
25.402 + }
25.403 +
25.404 + public static string MaxErase {
25.405 + get { return "Max Erase"; }
25.406 + }
25.407 +
25.408 + public static string AverageEraseCount {
25.409 + get { return "Average Erase Count"; }
25.410 + }
25.411 +
25.412 + public static string UnknownUnique {
25.413 + get { return "Unknown Unique"; }
25.414 + }
25.415 +
25.416 + public static string SataErrorCountCrc {
25.417 + get { return "SATA Error Count CRC"; }
25.418 + }
25.419 +
25.420 + public static string SataErrorCountHandshake {
25.421 + get { return "SATA Error Count Handshake"; }
25.422 + }
25.423 +
25.424 + public static string UnsafeShutdownCount {
25.425 + get { return "Unsafe Shutdown Count"; }
25.426 + }
25.427 +
25.428 + public static string HostWrites {
25.429 + get { return "Host Writes"; }
25.430 + }
25.431 +
25.432 + public static string UsedReservedBlockCountChip {
25.433 + get { return "Used Reserved Block Count Chip"; }
25.434 + }
25.435 +
25.436 + public static string UsedReservedBlockCountTotal {
25.437 + get { return "Used Reserved Block Count Total"; }
25.438 + }
25.439 +
25.440 + public static string RuntimeBadBlockTotal {
25.441 + get { return "Runtime Bad Block Total"; }
25.442 + }
25.443 +
25.444 + public static string HostReads {
25.445 + get { return "Host Reads"; }
25.446 + }
25.447 +
25.448 + public static string MediaWearOutIndicator {
25.449 + get { return "Media Wear Out Indicator"; }
25.450 + }
25.451 + }
25.452 +}
25.453 \ No newline at end of file
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/Hardware/HDD/WindowsSmart.cs Sat Dec 31 17:31:04 2011 +0000
26.3 @@ -0,0 +1,406 @@
26.4 +/*
26.5 +
26.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
26.7 +
26.8 + The contents of this file are subject to the Mozilla Public License Version
26.9 + 1.1 (the "License"); you may not use this file except in compliance with
26.10 + the License. You may obtain a copy of the License at
26.11 +
26.12 + http://www.mozilla.org/MPL/
26.13 +
26.14 + Software distributed under the License is distributed on an "AS IS" basis,
26.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
26.16 + for the specific language governing rights and limitations under the License.
26.17 +
26.18 + The Original Code is the Open Hardware Monitor code.
26.19 +
26.20 + The Initial Developer of the Original Code is
26.21 + Michael Möller <m.moeller@gmx.ch>.
26.22 + Portions created by the Initial Developer are Copyright (C) 2009-2011
26.23 + the Initial Developer. All Rights Reserved.
26.24 +
26.25 + Contributor(s):
26.26 + Paul Werelds
26.27 + Roland Reinl <roland-reinl@gmx.de>
26.28 +
26.29 + Alternatively, the contents of this file may be used under the terms of
26.30 + either the GNU General Public License Version 2 or later (the "GPL"), or
26.31 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26.32 + in which case the provisions of the GPL or the LGPL are applicable instead
26.33 + of those above. If you wish to allow use of your version of this file only
26.34 + under the terms of either the GPL or the LGPL, and not to allow others to
26.35 + use your version of this file under the terms of the MPL, indicate your
26.36 + decision by deleting the provisions above and replace them with the notice
26.37 + and other provisions required by the GPL or the LGPL. If you do not delete
26.38 + the provisions above, a recipient may use your version of this file under
26.39 + the terms of any one of the MPL, the GPL or the LGPL.
26.40 +
26.41 +*/
26.42 +
26.43 +using System;
26.44 +using System.Collections.Generic;
26.45 +using System.Runtime.InteropServices;
26.46 +
26.47 +namespace OpenHardwareMonitor.Hardware.HDD {
26.48 +
26.49 + internal class WindowsSmart : ISmart {
26.50 + [Flags]
26.51 + protected enum AccessMode : uint {
26.52 + Read = 0x80000000,
26.53 + Write = 0x40000000,
26.54 + Execute = 0x20000000,
26.55 + All = 0x10000000
26.56 + }
26.57 +
26.58 + [Flags]
26.59 + protected enum ShareMode : uint {
26.60 + None = 0,
26.61 + Read = 1,
26.62 + Write = 2,
26.63 + Delete = 4
26.64 + }
26.65 +
26.66 + protected enum CreationMode : uint {
26.67 + New = 1,
26.68 + CreateAlways = 2,
26.69 + OpenExisting = 3,
26.70 + OpenAlways = 4,
26.71 + TruncateExisting = 5
26.72 + }
26.73 +
26.74 + [Flags]
26.75 + protected enum FileAttribute : uint {
26.76 + Readonly = 0x00000001,
26.77 + Hidden = 0x00000002,
26.78 + System = 0x00000004,
26.79 + Directory = 0x00000010,
26.80 + Archive = 0x00000020,
26.81 + Device = 0x00000040,
26.82 + Normal = 0x00000080,
26.83 + Temporary = 0x00000100,
26.84 + SparseFile = 0x00000200,
26.85 + ReparsePoint = 0x00000400,
26.86 + Compressed = 0x00000800,
26.87 + Offline = 0x00001000,
26.88 + NotContentIndexed = 0x00002000,
26.89 + Encrypted = 0x00004000,
26.90 + }
26.91 +
26.92 + protected enum DriveCommand : uint {
26.93 + GetVersion = 0x00074080,
26.94 + SendDriveCommand = 0x0007c084,
26.95 + ReceiveDriveData = 0x0007c088
26.96 + }
26.97 +
26.98 + protected enum RegisterCommand : byte {
26.99 + /// <summary>
26.100 + /// SMART data requested.
26.101 + /// </summary>
26.102 + SmartCmd = 0xB0,
26.103 +
26.104 + /// <summary>
26.105 + /// Identify data is requested.
26.106 + /// </summary>
26.107 + IdCmd = 0xEC,
26.108 + }
26.109 +
26.110 + protected enum RegisterFeature : byte {
26.111 + /// <summary>
26.112 + /// Read SMART data.
26.113 + /// </summary>
26.114 + SmartReadData = 0xD0,
26.115 +
26.116 + /// <summary>
26.117 + /// Read SMART thresholds.
26.118 + /// </summary>
26.119 + SmartReadThresholds = 0xD1, /* obsolete */
26.120 +
26.121 + /// <summary>
26.122 + /// Autosave SMART data.
26.123 + /// </summary>
26.124 + SmartAutosave = 0xD2,
26.125 +
26.126 + /// <summary>
26.127 + /// Save SMART attributes.
26.128 + /// </summary>
26.129 + SmartSaveAttr = 0xD3,
26.130 +
26.131 + /// <summary>
26.132 + /// Set SMART to offline immediately.
26.133 + /// </summary>
26.134 + SmartImmediateOffline = 0xD4,
26.135 +
26.136 + /// <summary>
26.137 + /// Read SMART log.
26.138 + /// </summary>
26.139 + SmartReadLog = 0xD5,
26.140 +
26.141 + /// <summary>
26.142 + /// Write SMART log.
26.143 + /// </summary>
26.144 + SmartWriteLog = 0xD6,
26.145 +
26.146 + /// <summary>
26.147 + /// Write SMART thresholds.
26.148 + /// </summary>
26.149 + SmartWriteThresholds = 0xD7, /* obsolete */
26.150 +
26.151 + /// <summary>
26.152 + /// Enable SMART.
26.153 + /// </summary>
26.154 + SmartEnableOperations = 0xD8,
26.155 +
26.156 + /// <summary>
26.157 + /// Disable SMART.
26.158 + /// </summary>
26.159 + SmartDisableOperations = 0xD9,
26.160 +
26.161 + /// <summary>
26.162 + /// Get SMART status.
26.163 + /// </summary>
26.164 + SmartStatus = 0xDA,
26.165 +
26.166 + /// <summary>
26.167 + /// Set SMART to offline automatically.
26.168 + /// </summary>
26.169 + SmartAutoOffline = 0xDB, /* obsolete */
26.170 + }
26.171 +
26.172 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.173 + protected struct CommandBlockRegisters {
26.174 + public RegisterFeature Features;
26.175 + public byte SectorCount;
26.176 + public byte LBALow;
26.177 + public byte LBAMid;
26.178 + public byte LBAHigh;
26.179 + public byte Device;
26.180 + public RegisterCommand Command;
26.181 + public byte Reserved;
26.182 + }
26.183 +
26.184 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.185 + protected struct DriveCommandParameter {
26.186 + public uint BufferSize;
26.187 + public CommandBlockRegisters Registers;
26.188 + public byte DriveNumber;
26.189 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
26.190 + public byte[] Reserved;
26.191 + }
26.192 +
26.193 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.194 + protected struct DriverStatus {
26.195 + public byte DriverError;
26.196 + public byte IDEError;
26.197 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
26.198 + public byte[] Reserved;
26.199 + }
26.200 +
26.201 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.202 + protected struct DriveCommandResult {
26.203 + public uint BufferSize;
26.204 + public DriverStatus DriverStatus;
26.205 + }
26.206 +
26.207 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.208 + protected struct DriveSmartReadDataResult {
26.209 + public uint BufferSize;
26.210 + public DriverStatus DriverStatus;
26.211 + public byte Version;
26.212 + public byte Reserved;
26.213 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
26.214 + public DriveAttributeValue[] Attributes;
26.215 + }
26.216 +
26.217 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.218 + protected struct DriveSmartReadThresholdsResult {
26.219 + public uint BufferSize;
26.220 + public DriverStatus DriverStatus;
26.221 + public byte Version;
26.222 + public byte Reserved;
26.223 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
26.224 + public DriveThresholdValue[] Thresholds;
26.225 + }
26.226 +
26.227 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.228 + protected struct Identify {
26.229 + public ushort GeneralConfiguration;
26.230 + public ushort NumberOfCylinders;
26.231 + public ushort Reserved;
26.232 + public ushort NumberOfHeads;
26.233 + public ushort UnformattedBytesPerTrack;
26.234 + public ushort UnformattedBytesPerSector;
26.235 + public ushort SectorsPerTrack;
26.236 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
26.237 + public ushort[] VendorUnique;
26.238 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
26.239 + public byte[] SerialNumber;
26.240 + public ushort BufferType;
26.241 + public ushort BufferSectorSize;
26.242 + public ushort NumberOfEccBytes;
26.243 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
26.244 + public byte[] FirmwareRevision;
26.245 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
26.246 + public byte[] ModelNumber;
26.247 + public ushort MoreVendorUnique;
26.248 + public ushort DoubleWordIo;
26.249 + public ushort Capabilities;
26.250 + public ushort MoreReserved;
26.251 + public ushort PioCycleTimingMode;
26.252 + public ushort DmaCycleTimingMode;
26.253 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 406)]
26.254 + public byte[] More;
26.255 + }
26.256 +
26.257 + [StructLayout(LayoutKind.Sequential, Pack = 1)]
26.258 + protected struct DriveIdentifyResult {
26.259 + public uint BufferSize;
26.260 + public DriverStatus DriverStatus;
26.261 + public Identify Identify;
26.262 + }
26.263 +
26.264 + public IntPtr InvalidHandle { get { return (IntPtr)(-1); } }
26.265 +
26.266 + private const byte SMART_LBA_MID = 0x4F;
26.267 + private const byte SMART_LBA_HI = 0xC2;
26.268 +
26.269 + private const int MAX_DRIVE_ATTRIBUTES = 512;
26.270 +
26.271 + public IntPtr OpenDrive(int driveNumber) {
26.272 + return NativeMethods.CreateFile(@"\\.\PhysicalDrive" + driveNumber,
26.273 + AccessMode.Read | AccessMode.Write, ShareMode.Read | ShareMode.Write,
26.274 + IntPtr.Zero, CreationMode.OpenExisting, FileAttribute.Device,
26.275 + IntPtr.Zero);
26.276 + }
26.277 +
26.278 + public bool EnableSmart(IntPtr handle, int driveNumber) {
26.279 + DriveCommandParameter parameter = new DriveCommandParameter();
26.280 + DriveCommandResult result;
26.281 + uint bytesReturned;
26.282 +
26.283 + parameter.DriveNumber = (byte)driveNumber;
26.284 + parameter.Registers.Features = RegisterFeature.SmartEnableOperations;
26.285 + parameter.Registers.LBAMid = SMART_LBA_MID;
26.286 + parameter.Registers.LBAHigh = SMART_LBA_HI;
26.287 + parameter.Registers.Command = RegisterCommand.SmartCmd;
26.288 +
26.289 + return NativeMethods.DeviceIoControl(handle, DriveCommand.SendDriveCommand,
26.290 + ref parameter, Marshal.SizeOf(typeof(DriveCommandParameter)), out result,
26.291 + Marshal.SizeOf(typeof(DriveCommandResult)), out bytesReturned,
26.292 + IntPtr.Zero);
26.293 + }
26.294 +
26.295 + public DriveAttributeValue[] ReadSmartData(IntPtr handle, int driveNumber) {
26.296 + DriveCommandParameter parameter = new DriveCommandParameter();
26.297 + DriveSmartReadDataResult result;
26.298 + uint bytesReturned;
26.299 +
26.300 + parameter.DriveNumber = (byte)driveNumber;
26.301 + parameter.Registers.Features = RegisterFeature.SmartReadData;
26.302 + parameter.Registers.LBAMid = SMART_LBA_MID;
26.303 + parameter.Registers.LBAHigh = SMART_LBA_HI;
26.304 + parameter.Registers.Command = RegisterCommand.SmartCmd;
26.305 +
26.306 + bool isValid = NativeMethods.DeviceIoControl(handle,
26.307 + DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
26.308 + out result, Marshal.SizeOf(typeof(DriveSmartReadDataResult)),
26.309 + out bytesReturned, IntPtr.Zero);
26.310 +
26.311 + return (isValid) ? result.Attributes : new DriveAttributeValue[0];
26.312 + }
26.313 +
26.314 + public DriveThresholdValue[] ReadSmartThresholds(IntPtr handle,
26.315 + int driveNumber)
26.316 + {
26.317 + DriveCommandParameter parameter = new DriveCommandParameter();
26.318 + DriveSmartReadThresholdsResult result;
26.319 + uint bytesReturned = 0;
26.320 +
26.321 + parameter.DriveNumber = (byte)driveNumber;
26.322 + parameter.Registers.Features = RegisterFeature.SmartReadThresholds;
26.323 + parameter.Registers.LBAMid = SMART_LBA_MID;
26.324 + parameter.Registers.LBAHigh = SMART_LBA_HI;
26.325 + parameter.Registers.Command = RegisterCommand.SmartCmd;
26.326 +
26.327 + bool isValid = NativeMethods.DeviceIoControl(handle,
26.328 + DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
26.329 + out result, Marshal.SizeOf(typeof(DriveSmartReadThresholdsResult)),
26.330 + out bytesReturned, IntPtr.Zero);
26.331 +
26.332 + return (isValid) ? result.Thresholds : new DriveThresholdValue[0];
26.333 + }
26.334 +
26.335 + public string ReadName(IntPtr handle, int driveNumber) {
26.336 + DriveCommandParameter parameter = new DriveCommandParameter();
26.337 + DriveIdentifyResult result;
26.338 + uint bytesReturned;
26.339 +
26.340 + parameter.DriveNumber = (byte)driveNumber;
26.341 + parameter.Registers.Command = RegisterCommand.IdCmd;
26.342 +
26.343 + bool valid = NativeMethods.DeviceIoControl(handle,
26.344 + DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
26.345 + out result, Marshal.SizeOf(typeof(DriveIdentifyResult)),
26.346 + out bytesReturned, IntPtr.Zero);
26.347 +
26.348 + if (!valid)
26.349 + return null;
26.350 + else {
26.351 +
26.352 + byte[] bytes = result.Identify.ModelNumber;
26.353 + char[] chars = new char[bytes.Length];
26.354 + for (int i = 0; i < bytes.Length; i += 2) {
26.355 + chars[i] = (char)bytes[i + 1];
26.356 + chars[i + 1] = (char)bytes[i];
26.357 + }
26.358 +
26.359 + return new string(chars).Trim(new char[] {' ', '\0'});
26.360 + }
26.361 + }
26.362 +
26.363 + public void CloseHandle(IntPtr handle) {
26.364 + NativeMethods.CloseHandle(handle);
26.365 + }
26.366 +
26.367 + protected static class NativeMethods {
26.368 + private const string KERNEL = "kernel32.dll";
26.369 +
26.370 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
26.371 + CharSet = CharSet.Unicode)]
26.372 + public static extern IntPtr CreateFile(string fileName,
26.373 + AccessMode desiredAccess, ShareMode shareMode, IntPtr securityAttributes,
26.374 + CreationMode creationDisposition, FileAttribute flagsAndAttributes,
26.375 + IntPtr templateFilehandle);
26.376 +
26.377 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
26.378 + public static extern int CloseHandle(IntPtr handle);
26.379 +
26.380 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
26.381 + [return: MarshalAsAttribute(UnmanagedType.Bool)]
26.382 + public static extern bool DeviceIoControl(IntPtr handle,
26.383 + DriveCommand command, ref DriveCommandParameter parameter,
26.384 + int parameterSize, out DriveSmartReadDataResult result, int resultSize,
26.385 + out uint bytesReturned, IntPtr overlapped);
26.386 +
26.387 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
26.388 + [return: MarshalAsAttribute(UnmanagedType.Bool)]
26.389 + public static extern bool DeviceIoControl(IntPtr handle,
26.390 + DriveCommand command, ref DriveCommandParameter parameter,
26.391 + int parameterSize, out DriveSmartReadThresholdsResult result,
26.392 + int resultSize, out uint bytesReturned, IntPtr overlapped);
26.393 +
26.394 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
26.395 + [return: MarshalAsAttribute(UnmanagedType.Bool)]
26.396 + public static extern bool DeviceIoControl(IntPtr handle,
26.397 + DriveCommand command, ref DriveCommandParameter parameter,
26.398 + int parameterSize, out DriveCommandResult result, int resultSize,
26.399 + out uint bytesReturned, IntPtr overlapped);
26.400 +
26.401 + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
26.402 + [return: MarshalAsAttribute(UnmanagedType.Bool)]
26.403 + public static extern bool DeviceIoControl(IntPtr handle,
26.404 + DriveCommand command, ref DriveCommandParameter parameter,
26.405 + int parameterSize, out DriveIdentifyResult result, int resultSize,
26.406 + out uint bytesReturned, IntPtr overlapped);
26.407 + }
26.408 + }
26.409 +}
27.1 --- a/Hardware/ISensor.cs Wed Aug 31 22:48:49 2011 +0000
27.2 +++ b/Hardware/ISensor.cs Sat Dec 31 17:31:04 2011 +0000
27.3 @@ -42,15 +42,16 @@
27.4 namespace OpenHardwareMonitor.Hardware {
27.5
27.6 public enum SensorType {
27.7 - Voltage,
27.8 - Clock,
27.9 - Temperature,
27.10 - Load,
27.11 - Fan,
27.12 - Flow,
27.13 - Control,
27.14 - Level,
27.15 - Power
27.16 + Voltage, // V
27.17 + Clock, // MHz
27.18 + Temperature, // °C
27.19 + Load, // %
27.20 + Fan, // RPM
27.21 + Flow, // L/h
27.22 + Control, // %
27.23 + Level, // %
27.24 + Power, // W
27.25 + Data, // GB = 2^30 Bytes
27.26 }
27.27
27.28 public struct SensorValue {
28.1 --- a/OpenHardwareMonitor.csproj Wed Aug 31 22:48:49 2011 +0000
28.2 +++ b/OpenHardwareMonitor.csproj Sat Dec 31 17:31:04 2011 +0000
28.3 @@ -43,8 +43,9 @@
28.4 <DefineConstants>TRACE;DEBUG</DefineConstants>
28.5 <ErrorReport>prompt</ErrorReport>
28.6 <WarningLevel>4</WarningLevel>
28.7 - <UseVSHostingProcess>false</UseVSHostingProcess>
28.8 + <UseVSHostingProcess>true</UseVSHostingProcess>
28.9 <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
28.10 + <PlatformTarget>AnyCPU</PlatformTarget>
28.11 </PropertyGroup>
28.12 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
28.13 <DebugType>none</DebugType>
28.14 @@ -180,6 +181,7 @@
28.15 <ItemGroup>
28.16 <EmbeddedResource Include="GUI\MainForm.resx">
28.17 <DependentUpon>MainForm.cs</DependentUpon>
28.18 + <SubType>Designer</SubType>
28.19 </EmbeddedResource>
28.20 <EmbeddedResource Include="GUI\ReportForm.resx">
28.21 <DependentUpon>ReportForm.cs</DependentUpon>
28.22 @@ -220,6 +222,9 @@
28.23 <ItemGroup>
28.24 <EmbeddedResource Include="Resources\power.png" />
28.25 </ItemGroup>
28.26 + <ItemGroup>
28.27 + <EmbeddedResource Include="Resources\data.png" />
28.28 + </ItemGroup>
28.29 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
28.30 <ProjectExtensions>
28.31 <VisualStudio AllowExistingFolder="true" />
29.1 --- a/OpenHardwareMonitorLib.csproj Wed Aug 31 22:48:49 2011 +0000
29.2 +++ b/OpenHardwareMonitorLib.csproj Sat Dec 31 17:31:04 2011 +0000
29.3 @@ -56,12 +56,26 @@
29.4 <Reference Include="System.Management" />
29.5 </ItemGroup>
29.6 <ItemGroup>
29.7 + <Compile Include="Collections\Pair.cs" />
29.8 <Compile Include="Collections\RingCollection.cs" />
29.9 <Compile Include="Hardware\ATI\ADL.cs" />
29.10 <Compile Include="Hardware\ATI\ATIGPU.cs" />
29.11 <Compile Include="Hardware\ATI\ATIGroup.cs" />
29.12 <Compile Include="Hardware\Control.cs" />
29.13 <Compile Include="Hardware\FirmwareTable.cs" />
29.14 + <Compile Include="Hardware\HDD\DebugSmart.cs" />
29.15 + <Compile Include="Hardware\HDD\DriveAttributeValue.cs" />
29.16 + <Compile Include="Hardware\HDD\DriveThresholdValue.cs" />
29.17 + <Compile Include="Hardware\HDD\HDDGeneric.cs" />
29.18 + <Compile Include="Hardware\HDD\ISmart.cs" />
29.19 + <Compile Include="Hardware\HDD\SmartAttribute.cs" />
29.20 + <Compile Include="Hardware\HDD\SmartAttributeNames.cs" />
29.21 + <Compile Include="Hardware\HDD\RequireSmartAttribute.cs" />
29.22 + <Compile Include="Hardware\HDD\NamePrefixAttribute.cs" />
29.23 + <Compile Include="Hardware\HDD\SSDIndilinx.cs" />
29.24 + <Compile Include="Hardware\HDD\SSDIntel.cs" />
29.25 + <Compile Include="Hardware\HDD\SSDPlextor.cs" />
29.26 + <Compile Include="Hardware\HDD\SSDSandforce.cs" />
29.27 <Compile Include="Hardware\IControl.cs" />
29.28 <Compile Include="Hardware\IOControlCode.cs" />
29.29 <Compile Include="Hardware\Computer.cs" />
29.30 @@ -79,9 +93,9 @@
29.31 <Compile Include="Hardware\Ring0.cs" />
29.32 <Compile Include="Hardware\KernelDriver.cs" />
29.33 <Compile Include="Hardware\Hardware.cs" />
29.34 - <Compile Include="Hardware\HDD\HDD.cs" />
29.35 - <Compile Include="Hardware\HDD\HDDGroup.cs" />
29.36 - <Compile Include="Hardware\HDD\SMART.cs" />
29.37 + <Compile Include="Hardware\HDD\AbstractHarddrive.cs" />
29.38 + <Compile Include="Hardware\HDD\HarddriveGroup.cs" />
29.39 + <Compile Include="Hardware\HDD\WindowsSmart.cs" />
29.40 <Compile Include="Hardware\Heatmaster\Heatmaster.cs" />
29.41 <Compile Include="Hardware\Heatmaster\HeatmasterGroup.cs" />
29.42 <Compile Include="Hardware\IComputer.cs" />
30.1 Binary file Resources/data.png has changed