Search code examples
c++winapiusbsata

How to differ between external HDD and internal ones?


I want to know whether device is connected via USB (meaning it is a removable hard drive) or SATA (meaning it is an internal hard drive). That is how I get a list of devices

SP_DEVINFO_DATA volumeData;
volumeData.cbSize = sizeof (SP_DEVINFO_DATA);
SP_DEVICE_INTERFACE_DATA volumeInterfaceData;
volumeInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
wchar_t buffer[1024];
PSP_DEVICE_INTERFACE_DETAIL_DATA volumeInterfaceDetail;
volumeInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer;
volumeInterfaceDetail->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
for (int j = 0; SetupDiEnumDeviceInterfaces (hVolumeInfo, 0, &GUID_DEVINTERFACE_VOLUME, j, &volumeInterfaceData); j++) {
    DWORD bufferPathSize = offsetof (SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath) + sizeof(TCHAR);
    SetupDiGetDeviceInterfaceDetail (
        hVolumeInfo,
        &volumeInterfaceData,
        volumeInterfaceDetail,
        bufferPathSize,
        &bufferPathSize,
        &volumeData
        ));
    <some actions here>
}

After such operations I get a kind of the following result for each connected volume:

volumeInterfaceDetail->DevicePath: "\\\\?\\storage#volume#{3ec3ba03-2789-11e4-8251-806e6f6e6963}#0000000015f00000#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}"

How can I detect an interface (USB, SATA) with which the considering device is connected? Or is there any other way to differ external and internal HDDs using WinAPI?


Solution

  • You need to do the following:

    1. Use CreateFile to get a handle on to the device.
    2. Use DeviceIoControl to send an IOCTL_STORAGE_QUERY_PROPERTY ioctl to the device to ask it to tell you its properties.
    3. The resulting STORAGE_DEVICE_DESCRIPTOR structure contains a BusType enumeration that tells you the bus to which it is attached.

    There's a small code snippet at the bottom of this page that you can use to get started.