Converted project to VisualStudio 2012.
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
8 Copyright (C) 2010 Paul Werelds
9 Copyright (C) 2011 Roland Reinl <roland-reinl@gmx.de>
14 using System.Collections.Generic;
15 using System.Management;
16 using System.Runtime.InteropServices;
18 namespace OpenHardwareMonitor.Hardware.HDD {
20 internal class WindowsSmart : ISmart {
22 protected enum AccessMode : uint {
30 protected enum ShareMode : uint {
37 protected enum CreationMode : uint {
46 protected enum FileAttribute : uint {
47 Readonly = 0x00000001,
50 Directory = 0x00000010,
54 Temporary = 0x00000100,
55 SparseFile = 0x00000200,
56 ReparsePoint = 0x00000400,
57 Compressed = 0x00000800,
59 NotContentIndexed = 0x00002000,
60 Encrypted = 0x00004000,
63 protected enum DriveCommand : uint {
64 GetVersion = 0x00074080,
65 SendDriveCommand = 0x0007c084,
66 ReceiveDriveData = 0x0007c088
69 protected enum RegisterCommand : byte {
71 /// SMART data requested.
76 /// Identify data is requested.
81 protected enum RegisterFeature : byte {
88 /// Read SMART thresholds.
90 SmartReadThresholds = 0xD1, /* obsolete */
93 /// Autosave SMART data.
98 /// Save SMART attributes.
100 SmartSaveAttr = 0xD3,
103 /// Set SMART to offline immediately.
105 SmartImmediateOffline = 0xD4,
115 SmartWriteLog = 0xD6,
118 /// Write SMART thresholds.
120 SmartWriteThresholds = 0xD7, /* obsolete */
125 SmartEnableOperations = 0xD8,
130 SmartDisableOperations = 0xD9,
133 /// Get SMART status.
138 /// Set SMART to offline automatically.
140 SmartAutoOffline = 0xDB, /* obsolete */
143 [StructLayout(LayoutKind.Sequential, Pack = 1)]
144 protected struct CommandBlockRegisters {
145 public RegisterFeature Features;
146 public byte SectorCount;
151 public RegisterCommand Command;
152 public byte Reserved;
155 [StructLayout(LayoutKind.Sequential, Pack = 1)]
156 protected struct DriveCommandParameter {
157 public uint BufferSize;
158 public CommandBlockRegisters Registers;
159 public byte DriveNumber;
160 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
161 public byte[] Reserved;
164 [StructLayout(LayoutKind.Sequential, Pack = 1)]
165 protected struct DriverStatus {
166 public byte DriverError;
167 public byte IDEError;
168 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
169 public byte[] Reserved;
172 [StructLayout(LayoutKind.Sequential, Pack = 1)]
173 protected struct DriveCommandResult {
174 public uint BufferSize;
175 public DriverStatus DriverStatus;
178 [StructLayout(LayoutKind.Sequential, Pack = 1)]
179 protected struct DriveSmartReadDataResult {
180 public uint BufferSize;
181 public DriverStatus DriverStatus;
183 public byte Reserved;
184 [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
185 public DriveAttributeValue[] Attributes;
188 [StructLayout(LayoutKind.Sequential, Pack = 1)]
189 protected struct DriveSmartReadThresholdsResult {
190 public uint BufferSize;
191 public DriverStatus DriverStatus;
193 public byte Reserved;
194 [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
195 public DriveThresholdValue[] Thresholds;
198 [StructLayout(LayoutKind.Sequential, Pack = 1)]
199 protected struct Identify {
200 public ushort GeneralConfiguration;
201 public ushort NumberOfCylinders;
202 public ushort Reserved;
203 public ushort NumberOfHeads;
204 public ushort UnformattedBytesPerTrack;
205 public ushort UnformattedBytesPerSector;
206 public ushort SectorsPerTrack;
207 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
208 public ushort[] VendorUnique;
209 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
210 public byte[] SerialNumber;
211 public ushort BufferType;
212 public ushort BufferSectorSize;
213 public ushort NumberOfEccBytes;
214 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
215 public byte[] FirmwareRevision;
216 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
217 public byte[] ModelNumber;
218 public ushort MoreVendorUnique;
219 public ushort DoubleWordIo;
220 public ushort Capabilities;
221 public ushort MoreReserved;
222 public ushort PioCycleTimingMode;
223 public ushort DmaCycleTimingMode;
224 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 406)]
228 [StructLayout(LayoutKind.Sequential, Pack = 1)]
229 protected struct DriveIdentifyResult {
230 public uint BufferSize;
231 public DriverStatus DriverStatus;
232 public Identify Identify;
235 public IntPtr InvalidHandle { get { return (IntPtr)(-1); } }
237 private const byte SMART_LBA_MID = 0x4F;
238 private const byte SMART_LBA_HI = 0xC2;
240 private const int MAX_DRIVE_ATTRIBUTES = 512;
242 public IntPtr OpenDrive(int driveNumber) {
243 return NativeMethods.CreateFile(@"\\.\PhysicalDrive" + driveNumber,
244 AccessMode.Read | AccessMode.Write, ShareMode.Read | ShareMode.Write,
245 IntPtr.Zero, CreationMode.OpenExisting, FileAttribute.Device,
249 public bool EnableSmart(IntPtr handle, int driveNumber) {
250 DriveCommandParameter parameter = new DriveCommandParameter();
251 DriveCommandResult result;
254 parameter.DriveNumber = (byte)driveNumber;
255 parameter.Registers.Features = RegisterFeature.SmartEnableOperations;
256 parameter.Registers.LBAMid = SMART_LBA_MID;
257 parameter.Registers.LBAHigh = SMART_LBA_HI;
258 parameter.Registers.Command = RegisterCommand.SmartCmd;
260 return NativeMethods.DeviceIoControl(handle, DriveCommand.SendDriveCommand,
261 ref parameter, Marshal.SizeOf(typeof(DriveCommandParameter)), out result,
262 Marshal.SizeOf(typeof(DriveCommandResult)), out bytesReturned,
266 public DriveAttributeValue[] ReadSmartData(IntPtr handle, int driveNumber) {
267 DriveCommandParameter parameter = new DriveCommandParameter();
268 DriveSmartReadDataResult result;
271 parameter.DriveNumber = (byte)driveNumber;
272 parameter.Registers.Features = RegisterFeature.SmartReadData;
273 parameter.Registers.LBAMid = SMART_LBA_MID;
274 parameter.Registers.LBAHigh = SMART_LBA_HI;
275 parameter.Registers.Command = RegisterCommand.SmartCmd;
277 bool isValid = NativeMethods.DeviceIoControl(handle,
278 DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
279 out result, Marshal.SizeOf(typeof(DriveSmartReadDataResult)),
280 out bytesReturned, IntPtr.Zero);
282 return (isValid) ? result.Attributes : new DriveAttributeValue[0];
285 public DriveThresholdValue[] ReadSmartThresholds(IntPtr handle,
288 DriveCommandParameter parameter = new DriveCommandParameter();
289 DriveSmartReadThresholdsResult result;
290 uint bytesReturned = 0;
292 parameter.DriveNumber = (byte)driveNumber;
293 parameter.Registers.Features = RegisterFeature.SmartReadThresholds;
294 parameter.Registers.LBAMid = SMART_LBA_MID;
295 parameter.Registers.LBAHigh = SMART_LBA_HI;
296 parameter.Registers.Command = RegisterCommand.SmartCmd;
298 bool isValid = NativeMethods.DeviceIoControl(handle,
299 DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
300 out result, Marshal.SizeOf(typeof(DriveSmartReadThresholdsResult)),
301 out bytesReturned, IntPtr.Zero);
303 return (isValid) ? result.Thresholds : new DriveThresholdValue[0];
306 private string GetString(byte[] bytes) {
307 char[] chars = new char[bytes.Length];
308 for (int i = 0; i < bytes.Length; i += 2) {
309 chars[i] = (char)bytes[i + 1];
310 chars[i + 1] = (char)bytes[i];
312 return new string(chars).Trim(new char[] { ' ', '\0' });
315 public bool ReadNameAndFirmwareRevision(IntPtr handle, int driveNumber,
316 out string name, out string firmwareRevision)
318 DriveCommandParameter parameter = new DriveCommandParameter();
319 DriveIdentifyResult result;
322 parameter.DriveNumber = (byte)driveNumber;
323 parameter.Registers.Command = RegisterCommand.IdCmd;
325 bool valid = NativeMethods.DeviceIoControl(handle,
326 DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
327 out result, Marshal.SizeOf(typeof(DriveIdentifyResult)),
328 out bytesReturned, IntPtr.Zero);
332 firmwareRevision = null;
336 name = GetString(result.Identify.ModelNumber);
337 firmwareRevision = GetString(result.Identify.FirmwareRevision);
341 public void CloseHandle(IntPtr handle) {
342 NativeMethods.CloseHandle(handle);
345 public string[] GetLogicalDrives(int driveIndex) {
346 List<string> list = new List<string>();
348 using (ManagementObjectSearcher s = new ManagementObjectSearcher(
350 "SELECT * FROM Win32_DiskPartition " +
351 "WHERE DiskIndex = " + driveIndex))
352 using (ManagementObjectCollection dpc = s.Get())
353 foreach (ManagementObject dp in dpc)
354 using (ManagementObjectCollection ldc =
355 dp.GetRelated("Win32_LogicalDisk"))
356 foreach (ManagementBaseObject ld in ldc)
357 list.Add(((string)ld["Name"]).TrimEnd(':'));
359 return list.ToArray();
362 protected static class NativeMethods {
363 private const string KERNEL = "kernel32.dll";
365 [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
366 CharSet = CharSet.Unicode)]
367 public static extern IntPtr CreateFile(string fileName,
368 AccessMode desiredAccess, ShareMode shareMode, IntPtr securityAttributes,
369 CreationMode creationDisposition, FileAttribute flagsAndAttributes,
370 IntPtr templateFilehandle);
372 [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
373 public static extern int CloseHandle(IntPtr handle);
375 [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
376 [return: MarshalAsAttribute(UnmanagedType.Bool)]
377 public static extern bool DeviceIoControl(IntPtr handle,
378 DriveCommand command, ref DriveCommandParameter parameter,
379 int parameterSize, out DriveSmartReadDataResult result, int resultSize,
380 out uint bytesReturned, IntPtr overlapped);
382 [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
383 [return: MarshalAsAttribute(UnmanagedType.Bool)]
384 public static extern bool DeviceIoControl(IntPtr handle,
385 DriveCommand command, ref DriveCommandParameter parameter,
386 int parameterSize, out DriveSmartReadThresholdsResult result,
387 int resultSize, out uint bytesReturned, IntPtr overlapped);
389 [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
390 [return: MarshalAsAttribute(UnmanagedType.Bool)]
391 public static extern bool DeviceIoControl(IntPtr handle,
392 DriveCommand command, ref DriveCommandParameter parameter,
393 int parameterSize, out DriveCommandResult result, int resultSize,
394 out uint bytesReturned, IntPtr overlapped);
396 [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
397 [return: MarshalAsAttribute(UnmanagedType.Bool)]
398 public static extern bool DeviceIoControl(IntPtr handle,
399 DriveCommand command, ref DriveCommandParameter parameter,
400 int parameterSize, out DriveIdentifyResult result, int resultSize,
401 out uint bytesReturned, IntPtr overlapped);