How detect disk drive media type in win32

drjackool 1,016 Reputation points
2026-09-15T09:35:17.07+00:00

hi

In Win32 API, how get drive media types? I need to know thecdrive is hdd or ssd, AI said use seek penalty property is it only way?

Also how detect each drive belong to whitch physical disk

Thanks

Windows development | Windows API - Win32
0 comments No comments

Answer accepted by question author

AI answer

2026-09-15T09:35:36.93+00:00

For Win32, there is no single API that directly tells whether a file or directory is on an HDD or SSD.

DEVICE_SEEK_PENALTY_DESCRIPTOR from IOCTL_STORAGE_QUERY_PROPERTY is one supported way to determine whether a device incurs a seek penalty:

  • IncursSeekPenalty = TRUE typically indicates rotating media behavior.
  • IncursSeekPenalty = FALSE indicates no seek penalty.

That is the API in the provided Win32 context that is relevant to distinguishing storage behavior.

For media type information, these APIs and classes are available:

  • SHGetDriveMedia returns the type of media in a given drive, as ARCONTENT flags.
  • DEVICE_MEDIA_INFO contains MediaType for disk and removable disk media.
  • Win32_DiskDrive.MediaType can report values such as:
    • External hard disk media
    • Removable media
    • Fixed hard disk
    • Unknown

Those describe media category, but the provided context does not state that they reliably distinguish HDD versus SSD.

To determine which physical disk a drive or path belongs to, the documented Win32 method is:

  1. Call GetVolumePathName with the file or directory path to get the mount point.
  2. Call GetVolumeNameForVolumeMountPoint with that mount point to get the volume name.
  3. Remove the trailing backslash from the volume name.
  4. Call CreateFile on the volume name to open the volume.
  5. Send IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS to get the disk numbers.
  6. Build physical disk paths such as \\?\PhysicalDriveX.
  7. Call CreateFile on each physical disk path.
  8. Send IOCTL_DISK_GET_DRIVE_LAYOUT_EX to get the partition list.
  9. Inspect the returned partition entries as needed.

If only fixed versus removable is needed, WMI can also help:

  • Query Win32_LogicalDisk
  • Check DriveType
    • 2 = Removable drive
    • 3 = Local hard disk

AI-generated content may be incorrect. Read our transparency notes for more information.

Was this answer helpful?

1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Taki Ly (WICLOUD CORPORATION) 4,450 Reputation points Microsoft External Staff Moderator
    2026-09-15T10:46:42.1433333+00:00

    Hello @drjackool ,

    Seek penalty is one possible indicator, but there are several other options to consider.

    HDD vs SSD

    • WMI MSFT_PhysicalDisk.MediaType (root\Microsoft\Windows\Storage): 3=HDD, 4=SSD, 5=SCM. Most reliable on real hardware. Quick test: Get-PhysicalDisk | Select FriendlyName, MediaType.
    • IOCTL_STORAGE_QUERY_PROPERTY + DEVICE_SEEK_PENALTY_DESCRIPTOR: IncursSeekPenalty=TRUE -> HDD, FALSE -> SSD.
    • Supporting hints: StorageDeviceTrimProperty and BusType (NVMe implies SSD). Note Win32_DiskDrive.MediaType only tells fixed vs removable.

    One caveat I confirmed by testing: on a VM (Msft Virtual Disk, SAS), the seek-penalty IOCTL returns "not supported" and MediaType returns Unspecified. On virtualized/RAID/Storage Spaces disks you often can't distinguish HDD vs SSD at all, this is expected, not a code defect.

    Logical drive -> physical disk

    GetVolumePathName -> build \\.\C: -> IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS -> read each DISK_EXTENT.DiskNumber -> \\?\PhysicalDriveN.

    #include <windows.h>
    #include <winioctl.h>
    #include <cstdio>
    #include <vector>
    
    int GetSeekPenalty(HANDLE h) {                 // 1=HDD, 0=SSD, -1=unknown
        STORAGE_PROPERTY_QUERY q{ StorageDeviceSeekPenaltyProperty, PropertyStandardQuery };
        DEVICE_SEEK_PENALTY_DESCRIPTOR r{}; DWORD n = 0;
        if (DeviceIoControl(h, IOCTL_STORAGE_QUERY_PROPERTY, &q, sizeof(q), &r, sizeof(r), &n, nullptr))
            return r.IncursSeekPenalty ? 1 : 0;
        return -1;
    }
    
    int main() {
        // Map C: to its physical disk(s), then classify each.
        HANDLE v = CreateFileW(L"\\\\.\\C:", 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
                               nullptr, OPEN_EXISTING, 0, nullptr);
        BYTE buf[sizeof(VOLUME_DISK_EXTENTS) + 32 * sizeof(DISK_EXTENT)]{}; DWORD n = 0;
        DeviceIoControl(v, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nullptr, 0, buf, sizeof(buf), &n, nullptr);
        auto* e = reinterpret_cast<VOLUME_DISK_EXTENTS*>(buf);
        for (DWORD i = 0; i < e->NumberOfDiskExtents; ++i) {
            DWORD disk = e->Extents[i].DiskNumber;
            wchar_t path[64]; swprintf(path, 64, L"\\\\.\\PhysicalDrive%lu", disk);
            HANDLE h = CreateFileW(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
                                   nullptr, OPEN_EXISTING, 0, nullptr);
            int s = GetSeekPenalty(h);
            printf("C: -> PhysicalDrive%lu : %s\n", disk,
                   s == 1 ? "HDD" : s == 0 ? "SSD" : "Unknown");
            CloseHandle(h);
        }
        CloseHandle(v);
    }
    

    For the most reliable HDD/SSD result on physical hardware, use MSFT_PhysicalDisk.MediaType.

    References:

    I hope this information helps, and I would be glad to look further into any specific part if it would be useful. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation.

    Thank you.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.