WinAPI-шная функция GetDriveType() имеет существенный недостаток - она определяет USB hard drive'ы как фиксированные диски DRIVE_FIXED. Недавно мне понадобился функционал, который бы отличал настоящие жесткие диски от USB. Как оказалось, задача почему-то решается нетривиально - либо через WMI, либо через SetupAPI. WMI не подходил всвязи со спецификой проекта, оставался SetupAPI. Полдня изучения основ SetupApi и полдня гугления, изучения экзэмплов и чтения форумов привели меня на CodeProject, где я и нашел решение. Так вот хочу я вам сказать, мои дорогие друзья, я бы в жизни не подумал, что эта задача решается настолько через жопу!
Но нашелся у меня в тиме человек, который буквально за полтора часа родил компактное и лаконичное решение. Собственно, не могу не поделится.
Но нашелся у меня в тиме человек, который буквально за полтора часа родил компактное и лаконичное решение. Собственно, не могу не поделится.
bool IsUsbDevice( wchar_t letter ) { wchar_t volumeAccessPath[] = L"\\\\.\\X:"; volumeAccessPath[4] = letter; HANDLE deviceHandle = CreateFileW( volumeAccessPath, 0, // no access to the drive FILE_SHARE_READ | // share mode FILE_SHARE_WRITE, NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL); // do not copy file attributes // setup query STORAGE_PROPERTY_QUERY query; memset(&query, 0, sizeof(query)); query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; // issue query DWORD bytes; STORAGE_DEVICE_DESCRIPTOR devd; STORAGE_BUS_TYPE busType = BusTypeUnknown; if (DeviceIoControl(deviceHandle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &devd, sizeof(devd), &bytes, NULL)) { busType = devd.BusType; } else { std::wcout << L"Failed to define bus type for: " << letter; } CloseHandle(deviceHandle); return BusTypeUsb == busType; }
Хороший и рабочий пример. Только открытые хэндлы нужно закрывать, блин: CloseHandle(deviceHandle);
ОтветитьУдалитьауч! таки да. спасибо за дельное замечание
ОтветитьУдалитьThanks! I don't know a single word in Russian man, but this is an effective code.
ОтветитьУдалитьThe complications of WinAPI'sGetDriveType()/GetVolumeInformation()/QueryDosDevice() don't always reflect accurate results. This DeviceIoControl() approach simply saved some time for me, and works great on my PC so far. Perhaps you should post that somewhere in English as well...
you are welcome. may be some time... :)
Удалить