Windows не монтирует диски; это монтирует объемы. Однако том для устройства класса USBSTOR не указан как дочерний узел в дереве устройств. Следовательно, вам нужно перечислить все тома и выполнить несколько манипуляций и сравнений строк, чтобы сопоставить узлы STORAGE \ VOLUME с узлами USBSTOR.
Все значения GUID тома перечислены с набором функций FindFirstVolume . Начальные символы "\. \" И завершающие "\" могут быть удалены, а полученная строка затем передана в QueryDosDevice . Это обеспечивает имя устройства.
Далее необходимо перечислить все тома, используя GUID_DEVINTERFACE_VOLUME с SetupDiGetClassDevs и друзьями. Сравните тип устройства и номер каждого тома с устройством USBSTOR, которое вы ищете, используя IOCTL_STORAGE_GET_DEVICE_NUMBER . Как только они будут сопоставлены, вы можете получить имя устройства из тома и сравнить его с другим списком имен устройств, чтобы найти GUID тома.
Наконец, GUID тома может быть успешно использован с SetVolumeMountPoint .
Спасибо Гейбу за его очень полезную помощь в комментариях к моему вопросу.
Фрагменты кода
Получить тип и номер устройства из пути к устройству:
STORAGE_DEVICE_NUMBER sdn;
HANDLE handle = CreateFile(devInterfaceDetail->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
DWORD len = 0;
DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof (sdn), &len, NULL);
Найдите имя устройства для соответствующего экземпляра USBSTOR, выполнив итерацию по всем интерфейсам томов и сравнив номер диска из приведенного выше фрагмента:
std::string deviceName;
HDEVINFO devInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_DEVICE_INTERFACE_DATA devInterface = { 0 };
devInterface.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
for (int i = 0; SetupDiEnumDeviceInterfaces(devInfoSet, NULL, &GUID_DEVINTERFACE_VOLUME, i, &devInterface); ++i) {
SP_DEVINFO_DATA devInfoData = { 0 };
devInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
DWORD len;
SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterface, NULL, 0, &len, &devInfoData);
std::vector<char> buf(len);
SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA *) &buf[0];
devInterfaceDetail->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterface, devInterfaceDetail, len, NULL, &devInfoData)) {
if (DEVICE_NUMBER == this->getDeviceNumber(devInterfaceDetail->DevicePath)) {
std::vector<BYTE> buf(MAX_PATH + 1);
DWORD type, len;
if (SetupDiGetDeviceRegistryProperty(devInfoSet, &devInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &type, &buf[0], buf.size(), &len)) {
deviceName.assign(buf.begin(), buf.begin() + len);
break;
}
}
}
}