/// <summary> /// Get the Media Rotation Rate of the Harddrive. If the Result is 1 then it is a SSD /// !This method needs Administrator-Rights. Set this in app.manifest! /// </summary> /// <param name="diskindex">The Drive-Index</param> /// <returns></returns> public static string HasNominalMediaRotationRate(byte diskindex) { string sDrive = @"\\.\PhysicalDrive" + diskindex.ToString(); SafeFileHandle hDrive = WinAPI.CreateFileW(sDrive, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); // Administrative privilege is required if (hDrive == null || hDrive.IsInvalid) { string message = GetErrorMessage(Marshal.GetLastWin32Error()); return("CreateFile failed. " + message); } uint IOCTL_ATA_PASS_THROUGH = CTL_CODE(IOCTL_SCSI_BASE, 0x40b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS); // From ntddscsi.h WinAPI.ATAIdentifyDeviceQuery id_query = new WinAPI.ATAIdentifyDeviceQuery(); id_query.data = new ushort[256]; id_query.header.Length = Convert.ToUInt16(Marshal.SizeOf(id_query.header)); id_query.header.AtaFlags = Convert.ToUInt16(ATA_FLAGS_DATA_IN); id_query.header.DataTransferLength = Convert.ToUInt32(id_query.data.Length * 2); // Size of "data" in bytes id_query.header.TimeOutValue = 3; // Sec id_query.header.DataBufferOffset = (IntPtr)Marshal.OffsetOf(typeof(WinAPI.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 = 0; bool result = WinAPI.DeviceIoControl(hDrive, IOCTL_ATA_PASS_THROUGH, ref id_query, Convert.ToUInt32(Marshal.SizeOf(id_query)), ref id_query, Convert.ToUInt32(Marshal.SizeOf(id_query)), ref retval_size, IntPtr.Zero); hDrive.Close(); if (result == false) { string message = GetErrorMessage(Marshal.GetLastWin32Error()); return("DeviceIoControl failed. " + message); } else { // Word index of nominal media rotation rate // (1 means non-rotate device) const int kNominalMediaRotRateWordIndex = 217; if (id_query.data[kNominalMediaRotRateWordIndex] == 1) { return("Result: This drive is NON-ROTATE device."); } else { return("Result: This drive is ROTATE device."); } } }
/// <summary> /// Get the Media Rotation Rate of the Harddrive. If the Result is 1 then it is a SSD /// !This method needs Administrator-Rights. Set this in app.manifest! /// </summary> /// <param name="diskindex">The Drive-Index</param> /// <returns></returns> public static string HasNominalMediaRotationRate(byte diskindex) { string sDrive = @"\\.\PhysicalDrive" + diskindex.ToString(); SafeFileHandle hDrive = WinAPI.CreateFileW(sDrive, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); // Administrative privilege is required if (hDrive == null || hDrive.IsInvalid) { string message = GetErrorMessage(Marshal.GetLastWin32Error()); return "CreateFile failed. " + message; } uint IOCTL_ATA_PASS_THROUGH = CTL_CODE(IOCTL_SCSI_BASE, 0x40b, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS); // From ntddscsi.h WinAPI.ATAIdentifyDeviceQuery id_query = new WinAPI.ATAIdentifyDeviceQuery(); id_query.data = new ushort[256]; id_query.header.Length = Convert.ToUInt16(Marshal.SizeOf(id_query.header)); id_query.header.AtaFlags = Convert.ToUInt16(ATA_FLAGS_DATA_IN); id_query.header.DataTransferLength = Convert.ToUInt32(id_query.data.Length * 2); // Size of "data" in bytes id_query.header.TimeOutValue = 3; // Sec id_query.header.DataBufferOffset = (IntPtr)Marshal.OffsetOf(typeof(WinAPI.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 = 0; bool result = WinAPI.DeviceIoControl(hDrive, IOCTL_ATA_PASS_THROUGH, ref id_query, Convert.ToUInt32(Marshal.SizeOf(id_query)), ref id_query, Convert.ToUInt32(Marshal.SizeOf(id_query)), ref retval_size, IntPtr.Zero); hDrive.Close(); if (result == false) { string message = GetErrorMessage(Marshal.GetLastWin32Error()); return "DeviceIoControl failed. " + message; } else { // Word index of nominal media rotation rate // (1 means non-rotate device) const int kNominalMediaRotRateWordIndex = 217; if (id_query.data[kNominalMediaRotRateWordIndex] == 1) { return "Result: This drive is NON-ROTATE device."; } else { return "Result: This drive is ROTATE device."; } } }