1.1 --- a/Hardware/HDD/SMART.cs Wed Aug 31 22:48:49 2011 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,508 +0,0 @@
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) 2009-2011
1.23 - the Initial Developer. All Rights Reserved.
1.24 -
1.25 - Contributor(s): Paul Werelds
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 -using System.Runtime.InteropServices;
1.44 -
1.45 -namespace OpenHardwareMonitor.Hardware.HDD {
1.46 -
1.47 - internal class SMART {
1.48 -
1.49 - [Flags]
1.50 - public enum Status : ushort {
1.51 - PreFailureWarranty = 0x01,
1.52 - OnLineCollection = 0x02,
1.53 - Performance = 0x04,
1.54 - ErrorRate = 0x08,
1.55 - EventCount = 0x10,
1.56 - SelfPreserving = 0x20
1.57 - }
1.58 -
1.59 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.60 - public struct AttributeID {
1.61 - private byte value;
1.62 -
1.63 - public AttributeID(byte value) {
1.64 - this.value = value;
1.65 - }
1.66 -
1.67 - public override bool Equals(Object obj) {
1.68 - return obj is AttributeID && this == (AttributeID)obj;
1.69 - }
1.70 - public override int GetHashCode() {
1.71 - return value.GetHashCode() ^ value.GetHashCode();
1.72 - }
1.73 - public static bool operator ==(AttributeID a, AttributeID b) {
1.74 - return a.value == b.value;
1.75 - }
1.76 - public static bool operator !=(AttributeID a, AttributeID b) {
1.77 - return !(a == b);
1.78 - }
1.79 -
1.80 - public string ToString(string format) {
1.81 - return value.ToString(format);
1.82 - }
1.83 -
1.84 - public static readonly AttributeID None = new AttributeID(0x00);
1.85 - }
1.86 -
1.87 - // These are the more-or-less standard S.M.A.R.T attributes
1.88 - // TODO: Filter out unused/obscure ones; some are interpreted differently
1.89 - // between manufacturers
1.90 - public static class CommonAttributes {
1.91 - public static readonly AttributeID
1.92 - ReadErrorRate = new AttributeID(0x01),
1.93 - ThroughputPerformance = new AttributeID(0x02),
1.94 - SpinUpTime = new AttributeID(0x03),
1.95 - StartStopCount = new AttributeID(0x04),
1.96 - ReallocatedSectorsCount = new AttributeID(0x05),
1.97 - ReadChannelMargin = new AttributeID(0x06),
1.98 - SeekErrorRate = new AttributeID(0x07),
1.99 - SeekTimePerformance = new AttributeID(0x08),
1.100 - PowerOnHours = new AttributeID(0x09),
1.101 - SpinRetryCount = new AttributeID(0x0A),
1.102 - RecalibrationRetries = new AttributeID(0x0B),
1.103 - PowerCycleCount = new AttributeID(0x0C),
1.104 - SoftReadErrorRate = new AttributeID(0x0D),
1.105 - SataDownshiftErrorCount = new AttributeID(0xB7),
1.106 - EndToEndError = new AttributeID(0xB8),
1.107 - HeadStability = new AttributeID(0xB9),
1.108 - InducedOpVibrationDetection = new AttributeID(0xBA),
1.109 - ReportedUncorrectableErrors = new AttributeID(0xBB),
1.110 - CommandTimeout = new AttributeID(0xBC),
1.111 - HighFlyWrites = new AttributeID(0xBD),
1.112 - AirflowTemperature = new AttributeID(0xBE),
1.113 - GSenseErrorRate = new AttributeID(0xBF),
1.114 - PowerOffRetractCount = new AttributeID(0xC0),
1.115 - LoadCycleCount = new AttributeID(0xC1),
1.116 - Temperature = new AttributeID(0xC2),
1.117 - HardwareEccRecovered = new AttributeID(0xC3),
1.118 - ReallocationEventCount = new AttributeID(0xC4),
1.119 - CurrentPendingSectorCount = new AttributeID(0xC5),
1.120 - UncorrectableSectorCount = new AttributeID(0xC6),
1.121 - UltraDmaCrcErrorCount = new AttributeID(0xC7),
1.122 - WriteErrorRate = new AttributeID(0xC8),
1.123 - DataAddressMarkerrors = new AttributeID(0xCA),
1.124 - RunOutCancel = new AttributeID(0xCB),
1.125 - SoftEccCorrection = new AttributeID(0xCC),
1.126 - ThermalAsperityRate = new AttributeID(0xCD),
1.127 - FlyingHeight = new AttributeID(0xCE),
1.128 - SpinHighCurrent = new AttributeID(0xCF),
1.129 - SpinBuzz = new AttributeID(0xD0),
1.130 - OfflineSeekPerformance = new AttributeID(0xD1),
1.131 - VibrationDuringWrite = new AttributeID(0xD3),
1.132 - ShockDuringWrite = new AttributeID(0xD4),
1.133 - DiskShift = new AttributeID(0xDC),
1.134 - GSenseErrorRateAlt = new AttributeID(0xDD), // Alternative to 0xBF
1.135 - LoadedHours = new AttributeID(0xDE),
1.136 - LoadUnloadRetryCount = new AttributeID(0xDF),
1.137 - LoadFriction = new AttributeID(0xE0),
1.138 - LoadUnloadCycleCount = new AttributeID(0xE1),
1.139 - LoadInTime = new AttributeID(0xE2),
1.140 - TorqueAmplificationCount = new AttributeID(0xE3),
1.141 - PowerOffRetractCycle = new AttributeID(0xE4),
1.142 - GMRHeadAmplitude = new AttributeID(0xE6),
1.143 - DriveTemperature = new AttributeID(0xE7),
1.144 - HeadFlyingHours = new AttributeID(0xF0),
1.145 - LBAsWrittenTotal = new AttributeID(0xF1),
1.146 - LBAsReadTotal = new AttributeID(0xF2),
1.147 - ReadErrorRetryRate = new AttributeID(0xFA),
1.148 - FreeFallProtection = new AttributeID(0xFE)
1.149 - ;
1.150 - }
1.151 -
1.152 - // Indilinx SSD SMART attributes
1.153 - // TODO: Find out the purpose of attribute 0xD2
1.154 - // Seems to be unique to Indilinx drives, hence its name of UnknownUnique.
1.155 - public static class IndilinxAttributes {
1.156 - public static readonly AttributeID
1.157 - ReadErrorRate = CommonAttributes.ReadErrorRate,
1.158 - PowerOnHours = CommonAttributes.PowerOnHours,
1.159 - PowerCycleCount = CommonAttributes.PowerCycleCount,
1.160 - InitialBadBlockCount = new AttributeID(0xB8),
1.161 - RemainingLife = new AttributeID(0xD1),
1.162 - ProgramFailure = new AttributeID(0xC3),
1.163 - EraseFailure = new AttributeID(0xC4),
1.164 - ReadFailure = new AttributeID(0xC5),
1.165 - SectorsRead = new AttributeID(0xC6),
1.166 - SectorsWritten = new AttributeID(0xC7),
1.167 - ReadCommands = new AttributeID(0xC8),
1.168 - WriteCommands = new AttributeID(0xC9),
1.169 - BitErrors = new AttributeID(0xCA),
1.170 - CorrectedErrors = new AttributeID(0xCB),
1.171 - BadBlockFullFlag = new AttributeID(0xCC),
1.172 - MaxCellcycles = new AttributeID(0xCD),
1.173 - MinErase = new AttributeID(0xCE),
1.174 - MaxErase = new AttributeID(0xCF),
1.175 - AverageEraseCount = new AttributeID(0xD0),
1.176 - UnknownUnique = new AttributeID(0xD2),
1.177 - SataErrorCountCRC = new AttributeID(0xD3),
1.178 - SataErrorCountHandshake = new AttributeID(0xD4)
1.179 - ;
1.180 - }
1.181 -
1.182 - // Intel SSD SMART attributes
1.183 - // TODO: Find out the meaning behind 0xE2, 0xE3 and 0xE4
1.184 - public static class IntelAttributes {
1.185 - public static readonly AttributeID
1.186 - ReadErrorRate = CommonAttributes.ReadErrorRate,
1.187 - SpinUpTime = CommonAttributes.SpinUpTime,
1.188 - StartStopCount = CommonAttributes.StartStopCount,
1.189 - ReallocatedSectorsCount = CommonAttributes.ReallocatedSectorsCount,
1.190 - PowerOnHours = CommonAttributes.PowerOnHours,
1.191 - PowerCycleCount = CommonAttributes.PowerCycleCount,
1.192 - EndToEndError = CommonAttributes.EndToEndError, // Only on G2 drives!
1.193 -
1.194 - // Different from the common attribute PowerOffRetractCount, same ID
1.195 - UnsafeShutdownCount = new AttributeID(0xC0),
1.196 - HostWrites = new AttributeID(0xE1),
1.197 - RemainingLife = new AttributeID(0xE8),
1.198 - MediaWearOutIndicator = new AttributeID(0xE9)
1.199 - ;
1.200 - }
1.201 -
1.202 - // Samsung SSD SMART attributes
1.203 - // TODO: AF, B0, B1, B5, B6, BB, C3, C6, C7, E8, E9
1.204 - public static class SamsungAttributes {
1.205 - public static readonly AttributeID
1.206 - PowerOnHours = CommonAttributes.PowerOnHours,
1.207 - PowerCycleCount = CommonAttributes.PowerCycleCount,
1.208 - UsedReservedBlockCountChip = new AttributeID(0xB2), // Unique
1.209 - UsedReservedBlockCountTotal = new AttributeID(0xB3), // Unique
1.210 - RemainingLife = new AttributeID(0xB4), // Unique
1.211 - RuntimeBadBlockTotal = new AttributeID(0xB7)
1.212 - ;
1.213 - }
1.214 -
1.215 - // SandForce SSD SMART attributes
1.216 - // Note: 0xE9 and 0xEA are reserved attributes and unique
1.217 - public static class SandForceAttributes {
1.218 - public static readonly AttributeID
1.219 - ReadErrorRate = CommonAttributes.ReadErrorRate,
1.220 - RetiredBlockCount = new AttributeID(0x05),
1.221 - PowerOnHours = CommonAttributes.PowerOnHours,
1.222 - PowerCycleCount = CommonAttributes.PowerCycleCount,
1.223 - ProgramFailCount = new AttributeID(0xAB), // Unique
1.224 - EraseFailCount = new AttributeID(0xAC), // Unique
1.225 - UnexpectedPowerLossCount = new AttributeID(0xAE), // Unique
1.226 - WearRangeDelta = new AttributeID(0xB1), // Unique
1.227 - ProgramFailCountAlt = new AttributeID(0xB5), // Same as 0xAB
1.228 - EraseFailCountAlt = new AttributeID(0xB6), // Same as 0xAC
1.229 - ReportedUncorrectableErrors =
1.230 - CommonAttributes.ReportedUncorrectableErrors,
1.231 -
1.232 - Temperature = CommonAttributes.Temperature, // SF-1500 only!
1.233 -
1.234 - // Opposite of the common attribute HardwareECCRecovered
1.235 - UnrecoverableECC = new AttributeID(0xC3),
1.236 - ReallocationEventCount = new AttributeID(0xC4),
1.237 - RemainingLife = new AttributeID(0xE7),
1.238 - LifetimeWrites = new AttributeID(0xF1),
1.239 - LifetimeReads = new AttributeID(0xF2)
1.240 - ;
1.241 - }
1.242 -
1.243 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.244 - public struct DriveAttribute {
1.245 - public AttributeID ID;
1.246 - public Status StatusFlags;
1.247 - public byte AttrValue;
1.248 - public byte WorstValue;
1.249 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
1.250 - public byte[] RawValue;
1.251 - public byte Reserved;
1.252 - };
1.253 -
1.254 - [Flags]
1.255 - protected enum AccessMode : uint {
1.256 - Read = 0x80000000,
1.257 - Write = 0x40000000,
1.258 - Execute = 0x20000000,
1.259 - All = 0x10000000
1.260 - }
1.261 -
1.262 - [Flags]
1.263 - protected enum ShareMode : uint {
1.264 - None = 0,
1.265 - Read = 1,
1.266 - Write = 2,
1.267 - Delete = 4
1.268 - }
1.269 -
1.270 - protected enum CreationMode : uint {
1.271 - New = 1,
1.272 - CreateAlways = 2,
1.273 - OpenExisting = 3,
1.274 - OpenAlways = 4,
1.275 - TruncateExisting = 5
1.276 - }
1.277 -
1.278 - [Flags]
1.279 - protected enum FileAttribute : uint {
1.280 - Readonly = 0x00000001,
1.281 - Hidden = 0x00000002,
1.282 - System = 0x00000004,
1.283 - Directory = 0x00000010,
1.284 - Archive = 0x00000020,
1.285 - Device = 0x00000040,
1.286 - Normal = 0x00000080,
1.287 - Temporary = 0x00000100,
1.288 - SparseFile = 0x00000200,
1.289 - ReparsePoint = 0x00000400,
1.290 - Compressed = 0x00000800,
1.291 - Offline = 0x00001000,
1.292 - NotContentIndexed = 0x00002000,
1.293 - Encrypted = 0x00004000,
1.294 - }
1.295 -
1.296 - protected enum DriveCommand : uint {
1.297 - GetVersion = 0x00074080,
1.298 - SendDriveCommand = 0x0007c084,
1.299 - ReceiveDriveData = 0x0007c088
1.300 - }
1.301 -
1.302 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.303 - protected struct CommandBlockRegisters {
1.304 - public byte Features;
1.305 - public byte SectorCount;
1.306 - public byte LBALow;
1.307 - public byte LBAMid;
1.308 - public byte LBAHigh;
1.309 - public byte Device;
1.310 - public byte Command;
1.311 - public byte Reserved;
1.312 - }
1.313 -
1.314 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.315 - protected struct DriveCommandParameter {
1.316 - public uint BufferSize;
1.317 - public CommandBlockRegisters Registers;
1.318 - public byte DriveNumber;
1.319 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
1.320 - public byte[] Reserved;
1.321 - }
1.322 -
1.323 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.324 - protected struct DriverStatus {
1.325 - public byte DriverError;
1.326 - public byte IDEError;
1.327 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
1.328 - public byte[] Reserved;
1.329 - }
1.330 -
1.331 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.332 - protected struct DriveCommandResult {
1.333 - public uint BufferSize;
1.334 - public DriverStatus DriverStatus;
1.335 - }
1.336 -
1.337 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.338 - protected struct DriveSmartReadResult {
1.339 - public uint BufferSize;
1.340 - public DriverStatus DriverStatus;
1.341 - public byte Version;
1.342 - public byte Reserved;
1.343 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DRIVE_ATTRIBUTES)]
1.344 - public DriveAttribute[] Attributes;
1.345 - }
1.346 -
1.347 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.348 - protected struct Identify {
1.349 - public ushort GeneralConfiguration;
1.350 - public ushort NumberOfCylinders;
1.351 - public ushort Reserved;
1.352 - public ushort NumberOfHeads;
1.353 - public ushort UnformattedBytesPerTrack;
1.354 - public ushort UnformattedBytesPerSector;
1.355 - public ushort SectorsPerTrack;
1.356 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
1.357 - public ushort[] VendorUnique;
1.358 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
1.359 - public byte[] SerialNumber;
1.360 - public ushort BufferType;
1.361 - public ushort BufferSectorSize;
1.362 - public ushort NumberOfEccBytes;
1.363 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
1.364 - public byte[] FirmwareRevision;
1.365 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
1.366 - public byte[] ModelNumber;
1.367 - public ushort MoreVendorUnique;
1.368 - public ushort DoubleWordIo;
1.369 - public ushort Capabilities;
1.370 - public ushort MoreReserved;
1.371 - public ushort PioCycleTimingMode;
1.372 - public ushort DmaCycleTimingMode;
1.373 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 406)]
1.374 - public byte[] More;
1.375 - }
1.376 -
1.377 - [StructLayout(LayoutKind.Sequential, Pack = 1)]
1.378 - protected struct DriveIdentifyResult {
1.379 - public uint BufferSize;
1.380 - public DriverStatus DriverStatus;
1.381 - public Identify Identify;
1.382 - }
1.383 -
1.384 - public static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);
1.385 -
1.386 - private const byte SMART_CMD = 0xB0;
1.387 - private const byte ID_CMD = 0xEC;
1.388 -
1.389 - private const byte SMART_READ_DATA = 0xD0;
1.390 - private const byte SMART_ENABLE_OPERATIONS = 0xD8;
1.391 -
1.392 - private const byte SMART_LBA_MID = 0x4F;
1.393 - private const byte SMART_LBA_HI = 0xC2;
1.394 -
1.395 - private const int MAX_DRIVE_ATTRIBUTES = 512;
1.396 -
1.397 - private SMART() { }
1.398 -
1.399 - public static IntPtr OpenPhysicalDrive(int driveNumber) {
1.400 - return NativeMethods.CreateFile(@"\\.\PhysicalDrive" + driveNumber,
1.401 - AccessMode.Read | AccessMode.Write, ShareMode.Read | ShareMode.Write,
1.402 - IntPtr.Zero, CreationMode.OpenExisting, FileAttribute.Device,
1.403 - IntPtr.Zero);
1.404 - }
1.405 -
1.406 - public static bool EnableSmart(IntPtr handle, int driveNumber) {
1.407 - DriveCommandParameter parameter = new DriveCommandParameter();
1.408 - DriveCommandResult result;
1.409 - uint bytesReturned;
1.410 -
1.411 - parameter.DriveNumber = (byte)driveNumber;
1.412 - parameter.Registers.Features = SMART_ENABLE_OPERATIONS;
1.413 - parameter.Registers.LBAMid = SMART_LBA_MID;
1.414 - parameter.Registers.LBAHigh = SMART_LBA_HI;
1.415 - parameter.Registers.Command = SMART_CMD;
1.416 -
1.417 - return NativeMethods.DeviceIoControl(handle, DriveCommand.SendDriveCommand,
1.418 - ref parameter, Marshal.SizeOf(typeof(DriveCommandParameter)), out result,
1.419 - Marshal.SizeOf(typeof(DriveCommandResult)), out bytesReturned,
1.420 - IntPtr.Zero);
1.421 - }
1.422 -
1.423 - public static DriveAttribute[] ReadSmart(IntPtr handle,
1.424 - int driveNumber)
1.425 - {
1.426 - DriveCommandParameter parameter = new DriveCommandParameter();
1.427 - DriveSmartReadResult result;
1.428 - uint bytesReturned;
1.429 -
1.430 - parameter.DriveNumber = (byte)driveNumber;
1.431 - parameter.Registers.Features = SMART_READ_DATA;
1.432 - parameter.Registers.LBAMid = SMART_LBA_MID;
1.433 - parameter.Registers.LBAHigh = SMART_LBA_HI;
1.434 - parameter.Registers.Command = SMART_CMD;
1.435 -
1.436 - bool isValid = NativeMethods.DeviceIoControl(handle,
1.437 - DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
1.438 - out result, Marshal.SizeOf(typeof(DriveSmartReadResult)),
1.439 - out bytesReturned, IntPtr.Zero);
1.440 -
1.441 - return (isValid) ? result.Attributes : new DriveAttribute[0];
1.442 - }
1.443 -
1.444 - public static string ReadName(IntPtr handle, int driveNumber) {
1.445 - DriveCommandParameter parameter = new DriveCommandParameter();
1.446 - DriveIdentifyResult result;
1.447 - uint bytesReturned;
1.448 -
1.449 - parameter.DriveNumber = (byte)driveNumber;
1.450 - parameter.Registers.Command = ID_CMD;
1.451 -
1.452 - bool valid = NativeMethods.DeviceIoControl(handle,
1.453 - DriveCommand.ReceiveDriveData, ref parameter, Marshal.SizeOf(parameter),
1.454 - out result, Marshal.SizeOf(typeof(DriveIdentifyResult)),
1.455 - out bytesReturned, IntPtr.Zero);
1.456 -
1.457 - if (!valid)
1.458 - return null;
1.459 - else {
1.460 -
1.461 - byte[] bytes = result.Identify.ModelNumber;
1.462 - char[] chars = new char[bytes.Length];
1.463 - for (int i = 0; i < bytes.Length; i += 2) {
1.464 - chars[i] = (char)bytes[i + 1];
1.465 - chars[i + 1] = (char)bytes[i];
1.466 - }
1.467 -
1.468 - return new string(chars).Trim(new char[] {' ', '\0'});
1.469 - }
1.470 - }
1.471 -
1.472 - public static int CloseHandle(IntPtr handle) {
1.473 - return NativeMethods.CloseHandle(handle);
1.474 - }
1.475 -
1.476 - protected static class NativeMethods {
1.477 - private const string KERNEL = "kernel32.dll";
1.478 -
1.479 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi,
1.480 - CharSet = CharSet.Unicode)]
1.481 - public static extern IntPtr CreateFile(string fileName,
1.482 - AccessMode desiredAccess, ShareMode shareMode, IntPtr securityAttributes,
1.483 - CreationMode creationDisposition, FileAttribute flagsAndAttributes,
1.484 - IntPtr templateFilehandle);
1.485 -
1.486 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
1.487 - public static extern int CloseHandle(IntPtr handle);
1.488 -
1.489 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
1.490 - [return: MarshalAsAttribute(UnmanagedType.Bool)]
1.491 - public static extern bool DeviceIoControl(IntPtr handle,
1.492 - DriveCommand command, ref DriveCommandParameter parameter,
1.493 - int parameterSize, out DriveSmartReadResult result, int resultSize,
1.494 - out uint bytesReturned, IntPtr overlapped);
1.495 -
1.496 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
1.497 - [return: MarshalAsAttribute(UnmanagedType.Bool)]
1.498 - public static extern bool DeviceIoControl(IntPtr handle,
1.499 - DriveCommand command, ref DriveCommandParameter parameter,
1.500 - int parameterSize, out DriveCommandResult result, int resultSize,
1.501 - out uint bytesReturned, IntPtr overlapped);
1.502 -
1.503 - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
1.504 - [return: MarshalAsAttribute(UnmanagedType.Bool)]
1.505 - public static extern bool DeviceIoControl(IntPtr handle,
1.506 - DriveCommand command, ref DriveCommandParameter parameter,
1.507 - int parameterSize, out DriveIdentifyResult result, int resultSize,
1.508 - out uint bytesReturned, IntPtr overlapped);
1.509 - }
1.510 - }
1.511 -}