Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.117.70.132] |
|
Сообщ.
#1
,
|
|
|
Итак, есть WinUSB устройство (китайский телефон, на самом деле это COM-порты, и в линуксе можно одной строчкой форсировать ему serial-драйвер (пробовал - работает), но в винде не получается это сделать - в винде приходится искать решение на базе WinUSB API).
Устройство составное - USB Composite Device, и у него два дочерних WinUSB-устройства (к которым мне и надо как-то добраться). В свойствах в диспетчере устройств у них GUID класса {88bae032-5a81-49f0-bc3d-a4ff138216d6} - судя по гуглу это GUID_DEVCLASS_WINUSB И вот проблема в том что я не могу пронумеровать этот класс (чтобы найти DevicePath для CreateFile). Хотя с другими классами у меня проблем нет - всё получалось. А с этим - облом непонятный. HANDLE DeviceHandle; GUID usbdev_guid = { 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED }; // GUID_USB_DEVICE GUID winusb_guid = { 0x88bae032L, 0x5a81, 0x49f0, 0xbc, 0x3d, 0xa4, 0xff, 0x13, 0x82, 0x16, 0xd6 }; // GUID_DEVCLASS_WINUSB HDEVINFO deviceInfo; SP_DEVICE_INTERFACE_DATA interfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; DWORD GLE_result; SP_DEVINFO_DATA devinfo; BYTE devdetailbuffer[4096]; Вот пробую пронумеровать GUID_DEVCLASS_WINUSB - ошибка 0x103 ERROR_NO_MORE_ITEMS deviceInfo = SetupDiGetClassDevs(&winusb_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfo == INVALID_HANDLE_VALUE) { return false; } for (UINT n = 0;; n++) { interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &winusb_guid, n, &interfaceData)) { GLE_result = GetLastError(); // <-- тут оно и встаёт сразу, с ошибкой 0x103 - ERROR_NO_MORE_ITEMS break; } detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer; detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); devinfo.cbSize = sizeof(devinfo); SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, sizeof(devdetailbuffer), NULL, &devinfo); } Меняю GUID на GUID_USB_DEVICE - и успешно нахожу корневое композитное устройство (но дочерних WinUSB-устройств - нету): deviceInfo = SetupDiGetClassDevs(&usbdev_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfo == INVALID_HANDLE_VALUE) { return false; } for (UINT n = 0;; n++) { interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &usbdev_guid, n, &interfaceData)) { GLE_result = GetLastError(); break; } detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)devdetailbuffer; detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); devinfo.cbSize = sizeof(devinfo); SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, sizeof(devdetailbuffer), NULL, &devinfo); // ошибки нет, однако находится только корневое устройство: // detailData->DevicePath \\\\?\\usb#vid_0421&pid_069a#5&13a74b18&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} } И как мне добраться до его дочерних устройств? Как пронумеровать их или как в итоге получить хэндл для WinUSB API? Смотрел в реестре HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB - композитное устройство там есть и у него SymbolicName = \??\USB#VID_0421&PID_069A#5&13a74b18&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed} Его дочерние устройства тоже есть, однако у них нет SymbolicName и ничего похожего. Можно по веткам реестра понять что имена у них должны быть: \\\\?\\USB#VID_0421&PID_069A&MI_00#6&7a466bf&0&0000 \\\\?\\USB#VID_0421&PID_069A&MI_01#6&7a466bf&0&0001 Однако они не открываются (ERROR_FILE_NOT_FOUND)… Приделать к ним ещё GUID (GUID_USB_DEVICE или GUID_DEVCLASS_WINUSB) ? "\\\\?\\usb#vid_0421&pid_069a&mi_01#6&7a466bf&0&0001#{88bae032-5a81-49f0-bc3d-a4ff138216d6}" "\\\\?\\usb#vid_0421&pid_069a&mi_01#6&7a466bf&0&0001#{a5dcbf10-6530-11d2-901f-00c04fb951ed}" - но с GUID тоже не открывается - ERROR_FILE_NOT_FOUND Попытка хоть как-то открыть композитный девайс (для которого есть DevicePath) в WinUSB - обламывается очень неожиданной ошибкой ERROR_NOT_ENOUGH_MEMORY DeviceHandle = CreateFile("\\\\?\\usb#vid_0421&pid_069a#5&13a74b18&0&2#{a5dcbf10-6530-11d2-901f-00c04fb951ed}", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (INVALID_HANDLE_VALUE == DeviceHandle) { GLE_result = GetLastError(); return false; } if (!WinUsb_Initialize(DeviceHandle, &WinusbHandle)) { GLE_result = GetLastError(); // <-- ошибка 0x8 - ERROR_NOT_ENOUGH_MEMORY CloseHandle(DeviceHandle); return false; } Я абсолютно не представляю где тут памяти не хватает. Вот реально простой код с подставленным уникальным именем девайса в CreateFile - девайс открывается нормально. Но WinUsb_Initialize очевидно его не признаёт. Причём несколько дней копаю гугл - все эти проблемы с WinUSB встречаются у людей - и пронумеровать WinUSB-девайсы не получается, и ошибки ERROR_NOT_ENOUGH_MEMORY в WinUsb_Initialize. Но никаких решений нет. Есть заведомо рабочие примеры (с другими GUID/PID/VID - для конкретных девайсов), но при попытке очевидным образом адаптировать их под свои GUID/PID/VID - такие же проблемы… Краткий итог: Стандартным образом (SetupDiGetClassDevs - SetupDiEnumDeviceInterfaces - SetupDiGetDeviceInterfaceDetail - DevicePath) найти WinUSB-девайсы не могу: их похоже там нет, только их корневой хаб виден. Найти и открыть хаб могу, однако WinUsb_Initialize с ним работать не хочет. Что делать? Такое впечатление что тут какой-то совсем другой алгоритм работы нужен, либо это неполноценные WinUSB которые умышленно таким образом не хотят работать. |