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.
authormoel.mich
Sat, 31 Dec 2011 17:31:04 +0000
changeset 324c6ee430d6995
parent 323 3f2d9ebacf38
child 325 4c31341a4800
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.
Collections/Pair.cs
GUI/HardwareNode.cs
GUI/SensorGadget.cs
GUI/SensorNode.cs
GUI/SensorNotifyIcon.cs
GUI/TypeNode.cs
Hardware/Computer.cs
Hardware/HDD/AbstractHarddrive.cs
Hardware/HDD/DebugSmart.cs
Hardware/HDD/DriveAttributeValue.cs
Hardware/HDD/DriveThresholdValue.cs
Hardware/HDD/HDD.cs
Hardware/HDD/HDDGeneric.cs
Hardware/HDD/HDDGroup.cs
Hardware/HDD/HarddriveGroup.cs
Hardware/HDD/ISmart.cs
Hardware/HDD/NamePrefixAttribute.cs
Hardware/HDD/RequireSmartAttribute.cs
Hardware/HDD/SMART.cs
Hardware/HDD/SSDIndilinx.cs
Hardware/HDD/SSDIntel.cs
Hardware/HDD/SSDPlextor.cs
Hardware/HDD/SSDSandforce.cs
Hardware/HDD/SmartAttribute.cs
Hardware/HDD/SmartAttributeNames.cs
Hardware/HDD/WindowsSmart.cs
Hardware/ISensor.cs
OpenHardwareMonitor.csproj
OpenHardwareMonitorLib.csproj
Resources/data.png
     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