/// <summary> /// Check if the drive has a seek penalty. /// </summary> /// <param name="physicalDriveName">A valid physicalDriveName.</param> /// <returns><c> true </c> if the drive has a seek penalty otherwise, <c> false </c></returns> /// <remarks>Administrative privilege is required!</remarks> /// <exception cref="DetectionFailedException"></exception> private static bool HasDriveSeekPenalty(string physicalDriveName) { var hDrive = CreateFileW( physicalDriveName, 0, // No access to drive FileShareRead | FileShareWrite, IntPtr.Zero, OpenExisting, FileAttributeNormal, IntPtr.Zero); if (hDrive == null || hDrive.IsInvalid) { throw new DetectionFailedException(string.Format("Could not detect SeekPenalty of {0}", physicalDriveName)); } var ioctlStorageQueryProperty = CTL_CODE( IoctlStorageBase, 0x500, MethodBuffered, FileAnyAccess); // From winioctl.h var querySeekPenalty = new StoragePropertyQuery { PropertyId = StorageDeviceSeekPenaltyProperty, QueryType = PropertyStandardQuery }; var querySeekPenaltyDesc = new DeviceSeekPenaltyDescriptor(); uint returnedQuerySeekPenaltySize; var querySeekPenaltyResult = DeviceIoControl( hDrive, ioctlStorageQueryProperty, ref querySeekPenalty, (uint)Marshal.SizeOf(querySeekPenalty), ref querySeekPenaltyDesc, (uint)Marshal.SizeOf(querySeekPenaltyDesc), out returnedQuerySeekPenaltySize, IntPtr.Zero); hDrive.Close(); if (querySeekPenaltyResult == false) { throw new DetectionFailedException(string.Format("Could not detect SeekPenalty of {0}", physicalDriveName)); } if (querySeekPenaltyDesc.IncursSeekPenalty == false) { //This drive has NO SEEK penalty return(false); } //This drive has SEEK penalty return(true); }
private static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, ref StoragePropertyQuery lpInBuffer, uint nInBufferSize, ref DeviceSeekPenaltyDescriptor lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped);
/// <summary> /// Check if the drive has a seek penalty. /// </summary> /// <param name="physicalDriveName">A valid physicalDriveName.</param> /// <returns><c> true </c> if the drive has a seek penalty otherwise, <c> false </c></returns> /// <remarks>Administrative privilege is required!</remarks> /// <exception cref="DetectionFailedException"></exception> private static bool HasDriveSeekPenalty(string physicalDriveName) { var hDrive = CreateFileW( physicalDriveName, 0, // No access to drive FileShareRead | FileShareWrite, IntPtr.Zero, OpenExisting, FileAttributeNormal, IntPtr.Zero); if (hDrive == null || hDrive.IsInvalid) { throw new DetectionFailedException(string.Format("Could not detect SeekPenalty of {0}", physicalDriveName)); } var ioctlStorageQueryProperty = CTL_CODE( IoctlStorageBase, 0x500, MethodBuffered, FileAnyAccess); // From winioctl.h var querySeekPenalty = new StoragePropertyQuery { PropertyId = StorageDeviceSeekPenaltyProperty, QueryType = PropertyStandardQuery }; var querySeekPenaltyDesc = new DeviceSeekPenaltyDescriptor(); uint returnedQuerySeekPenaltySize; var querySeekPenaltyResult = DeviceIoControl( hDrive, ioctlStorageQueryProperty, ref querySeekPenalty, (uint) Marshal.SizeOf(querySeekPenalty), ref querySeekPenaltyDesc, (uint) Marshal.SizeOf(querySeekPenaltyDesc), out returnedQuerySeekPenaltySize, IntPtr.Zero); hDrive.Close(); if (querySeekPenaltyResult == false) { throw new DetectionFailedException(string.Format("Could not detect SeekPenalty of {0}", physicalDriveName)); } if (querySeekPenaltyDesc.IncursSeekPenalty == false) { //This drive has NO SEEK penalty return false; } //This drive has SEEK penalty return true; }