Click here to Skip to main content
14,486,704 members
Rate this:
Please Sign up or sign in to vote.
See more:
As the title says it.

I need to get an output in a textbox with the size and rpm of a hdd, and in a different textbox if the drive is an ssd and the size.

I have searched the internet alot now, and i cannot find anything that works with vb.net.

Does anybody have a solution, or could help me with making one?

I have found some information about
MSStorageDriver_ATAPISmartData


I just cannot get any further.

I found out that Hard Disk Sentinel uses the SMART ssd life left code.

But i can't seem to access this in vb.net
Posted
Updated 18-Mar-20 17:51pm
v2
Rate this:
Please Sign up or sign in to vote.

Solution 1

I am not good at vb.net, but the code is simple. I think you can convert it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;

namespace Test_WMI
{
    class Program
    {
        static void Main(string[] args)
        {
            string query = "SELECT * FROM Win32_DiskDrive";
            ManagementObjectSearcher search = new ManagementObjectSearcher(query);
            ManagementObjectCollection col = search.Get();

            foreach (var item in col)
            {
                Console.WriteLine(item["Caption"]);
                foreach (var prop in item.Properties)
                {
                    Console.WriteLine("{0}: {1}", prop.Name, item[prop.Name]);
                }
                Console.WriteLine();
            }
        }
    }
}


see here for Win32_DiskDrive:
http://msdn.microsoft.com/en-us/library/aa394132%28v=vs.85%29.aspx[^]
   
Comments
Mr-HaXx 18-Feb-14 13:54pm
   
Well this is for the name, but not the RPM and Size i found out how to get that information now.

Also cannot find how to get a check if ur disk is SSD or not...
Vedat Ozan Oner 18-Feb-14 14:30pm
   
As far as I know, this is the only way to get info about a storage. I don't know if you check the link I provided, but you can see that size info exists. please refer to that link to see what you look for.
Mr-HaXx 18-Feb-14 14:32pm
   
I will look around some more, Size i found. RPM will be next to search then. and SSD well. Hopefully someone will be able to help me with this.
Mr-HaXx 20-Feb-14 17:14pm
   
I still cannot find out about the SSD... Anybody can help me? I know you can find it in "MSStorageDriver_ATAPISmartData"
[no name] 20-Feb-14 19:55pm
   
Has been answered before. Drive rotation speed = 0 or 1.
http://www.codeproject.com/Questions/167558/How-to-Detect-SSD-Drive
Mr-HaXx 21-Feb-14 9:28am
   
I know, but i don't know how to read disk rotation speed.

This is not vb.net and i don't have that much experience.
Member 8380348 9-Oct-14 4:15am
   
Caption - short description of the object. It doesn't provide info if it is ssd or hdd.
Rate this:
Please Sign up or sign in to vote.

Solution 2

Solved it myself so far.

I created a dll with c++

the code:

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace DetectSsd
{
    public class Program
    {
        // For CreateFile to get handle to drive
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const uint FILE_SHARE_READ = 0x00000001;
        public const uint FILE_SHARE_WRITE = 0x00000002;
        public const uint OPEN_EXISTING = 3;
        public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;

        // CreateFile to get handle to drive
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern SafeFileHandle CreateFileW(
            [MarshalAs(UnmanagedType.LPWStr)]
            string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr hTemplateFile);

        // For control codes
        public const uint FILE_DEVICE_MASS_STORAGE = 0x0000002d;
        public const uint IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
        public const uint FILE_DEVICE_CONTROLLER = 0x00000004;
        public const uint IOCTL_SCSI_BASE = FILE_DEVICE_CONTROLLER;
        public const uint METHOD_BUFFERED = 0;
        public const uint FILE_ANY_ACCESS = 0;
        public const uint FILE_READ_ACCESS = 0x00000001;
        public const uint FILE_WRITE_ACCESS = 0x00000002;

        public static uint CTL_CODE(uint DeviceType, uint Function,
                                     uint Method, uint Access)
        {
            return ((DeviceType << 16) | (Access << 14) |
                    (Function << 2) | Method);
        }

        // For DeviceIoControl to check no seek penalty
        public const uint StorageDeviceSeekPenaltyProperty = 7;
        public const uint PropertyStandardQuery = 0;

        [StructLayout(LayoutKind.Sequential)]
        public struct STORAGE_PROPERTY_QUERY
        {
            public uint PropertyId;
            public uint QueryType;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            public byte[] AdditionalParameters;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DEVICE_SEEK_PENALTY_DESCRIPTOR
        {
            public uint Version;
            public uint Size;
            [MarshalAs(UnmanagedType.U1)]
            public bool IncursSeekPenalty;
        }

        // DeviceIoControl to check no seek penalty
        [DllImport("kernel32.dll", EntryPoint = "DeviceIoControl",
                   SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool DeviceIoControl(
            SafeFileHandle hDevice,
            uint dwIoControlCode,
            ref STORAGE_PROPERTY_QUERY lpInBuffer,
            uint nInBufferSize,
            ref DEVICE_SEEK_PENALTY_DESCRIPTOR lpOutBuffer,
            uint nOutBufferSize,
            out uint lpBytesReturned,
            IntPtr lpOverlapped);

        // For DeviceIoControl to check nominal media rotation rate
        public const uint ATA_FLAGS_DATA_IN = 0x02;

        [StructLayout(LayoutKind.Sequential)]
        public struct ATA_PASS_THROUGH_EX
        {
            public ushort Length;
            public ushort AtaFlags;
            public byte PathId;
            public byte TargetId;
            public byte Lun;
            public byte ReservedAsUchar;
            public uint DataTransferLength;
            public uint TimeOutValue;
            public uint ReservedAsUlong;
            public IntPtr DataBufferOffset;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] PreviousTaskFile;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] CurrentTaskFile;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ATAIdentifyDeviceQuery
        {
            public ATA_PASS_THROUGH_EX header;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            public ushort[] data;
        }

        // DeviceIoControl to check nominal media rotation rate
        [DllImport("kernel32.dll", EntryPoint = "DeviceIoControl",
                   SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool DeviceIoControl(
            SafeFileHandle hDevice,
            uint dwIoControlCode,
            ref ATAIdentifyDeviceQuery lpInBuffer,
            uint nInBufferSize,
            ref ATAIdentifyDeviceQuery lpOutBuffer,
            uint nOutBufferSize,
            out uint lpBytesReturned,
            IntPtr lpOverlapped);

        // For error message
        public const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern uint FormatMessage(
            uint dwFlags,
            IntPtr lpSource,
            uint dwMessageId,
            uint dwLanguageId,
            StringBuilder lpBuffer,
            uint nSize,
            IntPtr Arguments);

       static void Main(string[] args)
        {

             string sDrive = "";


            HasNominalMediaRotationRate(sDrive);
        }

        public String HddIsSSD = "";
       
        // Method for nominal media rotation rate
        // (Administrative privilege is required)
        public static string 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);

            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);

            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 "Disk is SSD";
                }
                else
                {
                    return "Disk is non SSD";
                }

            }
        } 

        // Method for error message
        public static string GetErrorMessage(int code)
        {
            StringBuilder message = new StringBuilder(255);

            FormatMessage(
              FORMAT_MESSAGE_FROM_SYSTEM,
              IntPtr.Zero,
              (uint)code,
              0,
              message,
              (uint)message.Capacity,
              IntPtr.Zero);

            return message.ToString();
        }
    }




}


And at the end i added this line to my vb.net program.

tbHDD_1.Text = DetectSsd.Program.HasNominalMediaRotationRate("\\\\.\\PhysicalDrive0")
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month



CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100