First you need to get the type of drive (GetDriveTypeA). If the result is DRIVE_REMOVABLE, the letter drive will either point to a removable flash drive (or possibly another type of removable drive). If the result is not DRIVE_REMOVABLE, there is no chance that it is a removable flash drive. However, beware from a Window's perspective, the difference between an external USB hard drive and a removable flash drive is not significant (I think the only difference is that there is no partition table on the removable flash drive, so it will only have one partition - although I not very sure).
In any case, for the DRIVE_REMOVABLE type, you need to request additional device properties. To do this, you first need to open the physical device with the following value:
hDevice = CreateFileA("\\\\?\\X:", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL)
If the opening is successful, you need to issue the DeviceIoControl command for this device:
STORAGE_PROPERTY_QUERY Query; Query.PropertyId = StorageDeviceProperty; Query.QueryType = PropertyStandardQuery; bResult = DeviceIoControl( hDevice, // device handle IOCTL_STORAGE_QUERY_PROPERTY, // info of device property &Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer pDevDesc, pDevDesc->Size, // output data buffer &dwOutBytes, // out length (LPOVERLAPPED)NULL );
STORAGE_PROPERTY_QUERY Query; Query.PropertyId = StorageDeviceProperty; Query.QueryType = PropertyStandardQuery; bResult = DeviceIoControl( hDevice, // device handle IOCTL_STORAGE_QUERY_PROPERTY, // info of device property &Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer pDevDesc, pDevDesc->Size, // output data buffer &dwOutBytes, // out length (LPOVERLAPPED)NULL );
If pDevDesc-> BusType == BusTypeUsb, then X: indicates a removable USB flash drive. The code works, however you need to read the documentation for DeviceIoControl to configure the pDevDesc parameter. If you have problems with this, I can give you all the code.