Вот так отправлял пакетик, и это, в своё время, работало:
NTSTATUS SendAwaitUrb(PDEVICE_OBJECT fdo, PURB urb)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IO_STATUS_BLOCK iostatus;
PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,pdx->LowerDeviceObject, NULL, 0, NULL, 0, TRUE, &event, &iostatus);
if (!Irp)
{
KdPrint(("Unable to allocate IRP"));
return STATUS_INSUFFICIENT_RESOURCES;
};
PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
stack->Parameters.Others.Argument1 = (PVOID)urb;
NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (status == STATUS_PENDING)
{
LARGE_INTEGER interval;
interval.LowPart = (ULONG)(-9000000); // 900 ms
interval.HighPart = -1;
BOOLEAN cancelled = FALSE;
while (STATUS_TIMEOUT == KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, &interval))
{
KdPrint(("SendAwaitUrb() wait too long..."));
if (!cancelled)
{
KdPrint(("...cancel irp"));
IoCancelIrp(Irp);
cancelled = TRUE;
};
};
status = iostatus.Status;
};
return status;
};
И кусок с подготовкой urb на чтение осьмибайтного пакетика:
URB urb;
UCHAR data[8];
// .......
RtlZeroMemory(data,sizeof(data));
UsbBuildInterruptOrBulkTransferRequest(&urb,
(USHORT)sizeof(_URB_BULK_OR_INTERRUPT_TRANSFER),
pdx->PIPE1, // IN pipe
data,NULL,sizeof(data),USBD_TRANSFER_DIRECTION_IN,NULL);
status = SendAwaitUrb(pdx->Pdo,&urb);
if (!NT_SUCCESS(status))
{ // Неудачное чтение
KdPrint(("PIPE1 read error"));
ResetPipe(pdx->Pdo,pdx->PIPE1);
// ............