Манник
Интересующийся
Offline
Пол:
|
|
« : 09-03-2016 11:30 » |
|
Здравствуйте! Помогите, пожалуйста, разобраться! Требуется послать вендор-команды устройству, в Numega DS это задача реализована с помощью данной функции: pUrb = m_Lower.BuildVendorRequest( NULL, // transfer buffer 0, // transfer buffer size 0, // request reserved bits 1, // request 0, // Value FALSE, // In FALSE, // Short Ok NULL, // link urb 0, // index URB_FUNCTION_VENDOR_DEVICE // function ); Этот код замечательно работает, переписала с помощью библиотек WinDDK: WDF_REQUEST_SEND_OPTIONS_INIT(
WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, 1, // Request 0, // Value 0); // Index
status = WdfUsbTargetDeviceSendControlTransferSynchronously( pDevContext->UsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST NULL,// &controlSetupPacket, NULL, // MemoryDescriptor NULL); // BytesTransferred Но в моей интерпретации посылка запроса работать не хочет, выдает статус unsuccessful, в usblyzer пишет STALL PID (это, как я понимаю, говорит о том, что устройство не понимает запрос). Не знаю,что и делать, возможно упускаю какую-то деталь...
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #1 : 09-03-2016 14:38 » |
|
проверьте WdfRequestGetCompletionParams Params->Parameters.Usb.Completion->UsbdStatus? а у вас его нет.... хм
не обязательно - не понимает. устройство может решить это по своему состоянию. может быть просто не выполнены какие то еще условия. неверное состояние устройства или еще какая то предварительная инициализация требуется. может еще WDF_REQUEST_SEND_OPTION_TIMEOUT добавить - мало ли что.. но вряд ли поможет.
посмотрите повнимательней - одинаковое ли состояние вашего устройства перед этим запросом в обоих вариантах вашего драйвера?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #2 : 10-03-2016 11:40 » |
|
Статус я проверяю так: if (!NT_SUCCESS(status)) {DbgPrint("send failed- 0x%x \n", status);} Код статуса выдает 0xC0000001 (STATUS_UNSUCCESSFUL), хотя при первом подключении запрос работает...а потом никак С таймаутом экспериментировала, результат также отрицательный) Единственное подозрение вызывает результат в usblyzer. В рабочем варианте В моей модификации такой результат setup packet в обоих случаях одинаковый Программой для устройства пользуюсь одной, то есть состояние устройства вроде как должно быть одно и то же, если только в самом драйвере что-то неверно, хотя пыталась все делать аналогично, насколько это возможно Смущает этот vendor device и как его можно получить...
|
2.jpg (46.29 Кб - загружено 1263 раз.)
3.jpg (46.88 Кб - загружено 1340 раз.)
1.jpg (19.7 Кб - загружено 1349 раз.)
|
« Последнее редактирование: 10-03-2016 11:43 от Манник »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 10-03-2016 11:54 » |
|
немного не понял - вы про пакет 7928?
Добавлено через 1 минуту и 26 секунд: посмотрите что внутри, разберите по полям пакет
|
|
« Последнее редактирование: 10-03-2016 11:55 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #4 : 10-03-2016 12:31 » |
|
Да, я про пакет 7928. Спасибо за подсказку! Только вот теперь понять, что там к чему нужно... Еще стала сравнивать 0016 с 7929, есть некоторые отличия, правда, в тех вещах, что мне пока неведомы... Попробую разобраться. И 7928 я разобрала,все равно остается загадкой, как получить этот таинственный запрос vendor device вместо control transfer. Там используется структура _URB_CONTROL_VENDOR_OR_CLASS_REQUEST, чтобы задать ее параметры раньше пробовала делать так UsbBuildVendorRequest(urb, URB_FUNCTION_VENDOR_DEVICE, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), ( USBD_TRANSFER_DIRECTION_OUT| USBD_SHORT_TRANSFER_OK), 0, 1, 0, // value 0, // index NULL, NULL, 0, NULL ); status = WdfUsbTargetDeviceSendUrbSynchronously(pDevContext->UsbDevice, NULL, NULL, &urb); В этом случае, статус был 0xC000000D (STATUS_INVALID_PARAMETER) и в usblyzer никак не отображалось это действие, то есть никакого control transfer не было
|
|
« Последнее редактирование: 10-03-2016 12:33 от Манник »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #5 : 10-03-2016 15:44 » |
|
я где то ссылку про USB кидал в списке литературы. там коротенечко про аппаратный протокол. проглядите. может натолкнет на мысль) вообще может вы все таки сравните то что нумега делает и что в в WDF перевели? там наверное по умолчанию какие нить свойства читаются или еще что...
PS не, ну если это REQUEST то наверное надо что-то где-то заполнить в URB_CONTROL_VENDOR_OR_CLASS_REQUEST)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #6 : 11-03-2016 05:14 » |
|
Да-да,я как раз думаю в том направлении. Спасибо за подсказку, и литературу обязательно посмотрю! Буду пока разбираться)
|
|
|
Записан
|
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #7 : 17-03-2016 06:22 » |
|
Спасибо за Ваши советы! Все получилось! Ура!) Я воспользовалась UsbBuildVendorRequest, только посылала WdfRequestSend'ом. Единственное,ну вот совсем элементарная вещь ну никак у меня не получается! мне нужно один байт, полученный от устройства, передать приложению, как я только не пробовала, последние два варианта, вроде как более вменяемые, оборачиваются BSOD (KMODE_EXCEPTION_NOT_HANDLED) на процедуре копирования в outputbuffer. Что ж тут я не так делаю? Все из примеров взято Это первый вариант status = WdfRequestRetrieveOutputMemory( Request, &mem ); if (!NT_SUCCESS(status)){ DbgPrint("WdfRequestRetrieveOutputMemory failed\n"); goto Exit; }
status = WdfMemoryCopyFromBuffer( mem, 0, buffer, length ); if (!NT_SUCCESS(status)) { DbgPrint("WdfMemoryCopyFromBuffer failed\n"); goto Exit; } Второй status = WdfRequestRetrieveOutputBuffer(Request, length, &bufferIO, &buflength); if (!NT_SUCCESS(status)){ DbgPrint("WdfRequestRetrieveInputBuffer failed\n"); goto Exit; } RtlCopyMemory(&bufferIO, &buffer, length); На форуме все уже по этой теме прочитала, в интернете обыскалась,предлагаются эти варианты везде, но у меня что-то идет не так..
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #8 : 17-03-2016 15:28 » |
|
а на какой строке то падает? на WdfMemoryCopyFromBuffer и RtlCopyMemory? может быть с выравниванием что то ? IRQL?
Добавлено через 51 секунду: проверяйте buflength?
Добавлено через 2 минуты и 26 секунд: Request у вас существует на момент после выполнения запроса вообще?
|
|
« Последнее редактирование: 17-03-2016 15:31 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #9 : 18-03-2016 11:00 » |
|
Да, падает на этих строках.
Честно говоря, про выравнивание не знаю...как это проверить можно?
Насчет IRQL сомневаюсь, я так понимаю, тогда в bsod система вылетела бы с ошибкой об irql.
buflength=1, как и полагается, насчет Request засомневалась, попробовала создать новый запрос (можно же так?), тот же самый результат. После status = WdfRequestRetrieveOutputMemory(Request, &mem) вывела параметр mem, dbgprint показал число, значит же, что память выделяется, я так понимаю? и status=success.
|
|
|
Записан
|
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #10 : 21-03-2016 11:33 » |
|
Пробовала много вариантов, вот так bsod не вылетает, но и не передает значение приложению status = WdfRequestRetrieveOutputBuffer(Request, sizeof(buffer), &bufferIO, &buflength); if (!NT_SUCCESS(status)){ DbgPrint("WdfRequestRetrieveOUtputBuffer failed\n"); break; } RtlZeroMemory(&bufferIO, buflength); RtlCopyMemory(&bufferIO, &buffer, OutputBufferLength); А сейчас смущают указатели, так как во всех примерах, что я видела, обходятся без них, а без них bsod...
|
|
« Последнее редактирование: 21-03-2016 12:46 от Манник »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #11 : 21-03-2016 19:26 » |
|
уууу... в WdfRequestRetrieveOutputBuffer - &bufferIO - адрес переменной bufferIO, где будет лежать указатель на буфер. в RtlZeroMemory и RtlCopyMemory - не нужен указатель на указатель. тут просто адрес буфера.
Добавлено через 6 минут и 46 секунд: указатель это ж простая вещь. есть место в памяти где хранится допустим массив. у этого места есть адрес(он же указатель). но адрес может выделяться динамически и его тоже надо где то хранить! когда мы это адрес буфера(указатель) пытаемся передать наружу из функции - мы его должны положить в переменную. а чтобы функция знала куда положить адрес буфера - мы ей должны сказать адрес переменной в которую она положит нам нам адрес буфера. это и получается указатель на указатель. PS главное не путать указатели со ссылками)
|
|
« Последнее редактирование: 21-03-2016 19:36 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Манник
Интересующийся
Offline
Пол:
|
|
« Ответ #12 : 22-03-2016 08:22 » |
|
уууу... Совсем все плохо, да?) Что такое указатель, я понимаю) И теперь я ощутила всю-всю его важность! status = WdfMemoryCopyFromBuffer( mem, 0, &buffer, length ); Все заработало)Спасибо огромное за Ваши советы!)
|
|
|
Записан
|
|
|
|
|