Testing for GetDriveType==DRIVE_REMOVABLE is wrong. Testing for BusTypeUsb is right.
Here is some code to get the BusType by a given drive letter.
typedef struct _STORAGE_PROPERTY_QUERY {
int PropertyId;
int QueryType;
UCHAR AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
typedef enum _STORAGE_BUS_TYPE {
BusTypeUnknown = 0x00,
BusTypeScsi,
BusTypeAtapi,
BusTypeAta,
BusType1394,
BusTypeSsa,
BusTypeFibre,
BusTypeUsb,
BusTypeRAID,
BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
ULONG Version;
ULONG Size;
UCHAR DeviceType;
UCHAR DeviceTypeModifier;
BYTE RemovableMedia;
BYTE CommandQueueing;
ULONG VendorIdOffset;
ULONG ProductIdOffset;
ULONG ProductRevisionOffset;
ULONG SerialNumberOffset;
STORAGE_BUS_TYPE BusType;
ULONG RawPropertiesLength;
UCHAR RawDeviceProperties[1];
WCHAR wszExtendedBuffer[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
define IOCTL_STORAGE_QUERY_PROPERTY ((DWORD)0x2D1400L)
int GetBusType(char DriveLetter)
{
char szDevice[] = { '', '', '.', '', DriveLetter, ':', '\0' };
HANDLE hDevice = CreateFile(szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if ( hDevice == INVALID_HANDLE_VALUE ) {
return 0;
}
DWORD dwOutBytes = 0;
STORAGE_PROPERTY_QUERY Query = {0}; // input param for query, wee need all zero
char OutBuf[256] = {0};
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)OutBuf;
pDevDesc->Size = sizeof(OutBuf);
// Query using IOCTL_STORAGE_QUERY_PROPERTY
BOOL bRes = DeviceIoControl(hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&Query, sizeof(STORAGE_PROPERTY_QUERY),
pDevDesc, pDevDesc->Size,
&dwOutBytes, NULL);
CloseHandle(hDevice);
if ( bRes ) {
return pDevDesc->BusType;
}
return 0;
}