public static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, ref ATAIdentifyDeviceQuery lpInBuffer, // To get nominal media rotation rate uint nInBufferSize, ref ATAIdentifyDeviceQuery lpOutBuffer, // To get nominal media rotation rate uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped);
private static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, ref ATAIdentifyDeviceQuery lpInBuffer, uint nInBufferSize, ref ATAIdentifyDeviceQuery lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped);
//method for nominal media rotation rate //(administrative privilege is required) private static DriveType HasNominalMediaRotationRate(string sDrive) { var hDrive = CreateFileW(sDrive, GENERIC_READ | GENERIC_WRITE, //administrative privilege is required FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hDrive == null || hDrive.IsInvalid) { var message = GetErrorMessage(Marshal.GetLastWin32Error()); if (log.IsDebugEnabled) { log.Debug("CreateFile failed. " + message); } return(DriveType.Unknown); } var ioctlAtaPassThrough = CTL_CODE(IOCTL_SCSI_BASE, 0x040b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS); // From ntddscsi.h var id_query = new ATAIdentifyDeviceQuery(); id_query.data = new ushort[256]; id_query.header.Length = (ushort)Marshal.SizeOf(id_query.header); id_query.header.AtaFlags = (ushort)ATA_FLAGS_DATA_IN; id_query.header.DataTransferLength = (uint)(id_query.data.Length * 2); // Size of "data" in bytes id_query.header.TimeOutValue = 3; // Sec id_query.header.DataBufferOffset = (IntPtr)Marshal.OffsetOf(typeof(ATAIdentifyDeviceQuery), "data"); id_query.header.PreviousTaskFile = new byte[8]; id_query.header.CurrentTaskFile = new byte[8]; id_query.header.CurrentTaskFile[6] = 0xec; // ATA IDENTIFY DEVICE uint retvalSize; var result = DeviceIoControl(hDrive, ioctlAtaPassThrough, ref id_query, (uint)Marshal.SizeOf(id_query), ref id_query, (uint)Marshal.SizeOf(id_query), out retvalSize, IntPtr.Zero); hDrive.Close(); if (result == false) { var message = GetErrorMessage(Marshal.GetLastWin32Error()); if (log.IsDebugEnabled) { log.Debug("DeviceIoControl failed. " + message); } return(DriveType.Unknown); } //word index of nominal media rotation rate //(1 means non-rotate device) const int kNominalMediaRotRateWordIndex = 217; return(id_query.data[kNominalMediaRotRateWordIndex] == 1 ? DriveType.SSD : DriveType.HDD); }
/// <summary> /// Method for nominal media rotation rate. /// </summary> /// <remarks> /// Administrative privilege is required! /// </remarks> /// <param name="sDrive"></param> /// <returns></returns> public static DriveType HasNominalMediaRotationRate(string sDrive) { SafeFileHandle hDrive = CreateFileW( sDrive, GENERIC_READ | GENERIC_WRITE, // Administrative privilege is required FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hDrive == null || hDrive.IsInvalid) { string message = GetErrorMessage(Marshal.GetLastWin32Error()); //Console.WriteLine("CreateFile failed. " + message); return(DriveType.Unknown); } uint IOCTL_ATA_PASS_THROUGH = CTL_CODE( IOCTL_SCSI_BASE, 0x040b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS); // From ntddscsi.h ATAIdentifyDeviceQuery id_query = new ATAIdentifyDeviceQuery(); id_query.data = new ushort[256]; id_query.header.Length = (ushort)Marshal.SizeOf(id_query.header); id_query.header.AtaFlags = (ushort)ATA_FLAGS_DATA_IN; id_query.header.DataTransferLength = (uint)(id_query.data.Length * 2); // Size of "data" in bytes id_query.header.TimeOutValue = 3; // Sec id_query.header.DataBufferOffset = (IntPtr)Marshal.OffsetOf( typeof(ATAIdentifyDeviceQuery), "data"); id_query.header.PreviousTaskFile = new byte[8]; id_query.header.CurrentTaskFile = new byte[8]; id_query.header.CurrentTaskFile[6] = 0xec; // ATA IDENTIFY DEVICE uint retval_size; bool result = DeviceIoControl( hDrive, IOCTL_ATA_PASS_THROUGH, ref id_query, (uint)Marshal.SizeOf(id_query), ref id_query, (uint)Marshal.SizeOf(id_query), out retval_size, IntPtr.Zero); if (result == false) { string message = GetErrorMessage(Marshal.GetLastWin32Error()); //Console.WriteLine("DeviceIoControl failed. " + message); } hDrive.Close(); if (result == false) { return(DriveType.Unknown); } // Word index of nominal media rotation rate // (1 means non-rotate device) const int kNominalMediaRotRateWordIndex = 217; if (id_query.data[kNominalMediaRotRateWordIndex] == 1) { //Console.WriteLine("This drive is NON-ROTATE device."); return(DriveType.SSD); } else { //Console.WriteLine("This drive is ROTATE device."); return(DriveType.Rotational); } }
public static extern bool DeviceIoControl(SafeFileHandle hDevice, uint dwIoControlCode, ref ATAIdentifyDeviceQuery lpInBuffer, uint nInBufferSize, ref ATAIdentifyDeviceQuery lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped);