NTSTATUS abort_endpoint(libusb_device_t *dev, int endpoint, int timeout) { NTSTATUS status = STATUS_SUCCESS; URB urb; USBMSG("endpoint: 0x%02x timeout: %d\n", endpoint, timeout); memset(&urb, 0, sizeof(struct _URB_PIPE_REQUEST)); if (!dev->config.value) { USBERR0("invalid configuration 0\n"); return STATUS_INVALID_DEVICE_STATE; } if (!get_pipe_handle(dev, endpoint, &urb.UrbPipeRequest.PipeHandle)) { USBERR0("getting endpoint pipe failed\n"); return STATUS_INVALID_PARAMETER; } urb.UrbHeader.Length = (USHORT) sizeof(struct _URB_PIPE_REQUEST); urb.UrbHeader.Function = URB_FUNCTION_ABORT_PIPE; status = call_usbd(dev, &urb, IOCTL_INTERNAL_USB_SUBMIT_URB, timeout); if (!NT_SUCCESS(status) || !USBD_SUCCESS(urb.UrbHeader.Status)) { USBERR("request failed: status: 0x%x, urb-status: 0x%x\n", status, urb.UrbHeader.Status); } return status; }
static NTSTATUS create_urb(libusb_device_t *dev, URB **urb, int direction, int urb_function, int endpoint, int packet_size, MDL *buffer, int size) { USBD_PIPE_HANDLE pipe_handle = NULL; int num_packets = 0; int i, urb_size; *urb = NULL; if(!get_pipe_handle(dev, endpoint, &pipe_handle)) { DEBUG_ERROR("create_urb(): getting endpoint pipe failed"); return STATUS_INVALID_PARAMETER; } /* isochronous transfer */ if(urb_function == URB_FUNCTION_ISOCH_TRANSFER) { num_packets = (size + packet_size - 1) / packet_size; if(num_packets > 255) { DEBUG_ERROR("create_urb(): transfer size too large"); return STATUS_INVALID_PARAMETER; } urb_size = sizeof(struct _URB_ISOCH_TRANSFER) + sizeof(USBD_ISO_PACKET_DESCRIPTOR) * num_packets; } else /* bulk or interrupt transfer */ { urb_size = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); } *urb = ExAllocatePool(NonPagedPool, urb_size); if(!*urb) { DEBUG_ERROR("create_urb(): memory allocation error"); return STATUS_NO_MEMORY; } memset(*urb, 0, urb_size); (*urb)->UrbHeader.Length = (USHORT)urb_size; (*urb)->UrbHeader.Function = (USHORT)urb_function; /* isochronous transfer */ if(urb_function == URB_FUNCTION_ISOCH_TRANSFER) { (*urb)->UrbIsochronousTransfer.PipeHandle = pipe_handle; (*urb)->UrbIsochronousTransfer.TransferFlags = direction | USBD_SHORT_TRANSFER_OK | USBD_START_ISO_TRANSFER_ASAP; (*urb)->UrbIsochronousTransfer.TransferBufferLength = size; (*urb)->UrbIsochronousTransfer.TransferBufferMDL = buffer; (*urb)->UrbIsochronousTransfer.NumberOfPackets = num_packets; for(i = 0; i < num_packets; i++) { (*urb)->UrbIsochronousTransfer.IsoPacket[i].Offset = i * packet_size; (*urb)->UrbIsochronousTransfer.IsoPacket[i].Length = packet_size; } } /* bulk or interrupt transfer */ else { (*urb)->UrbBulkOrInterruptTransfer.PipeHandle = pipe_handle; (*urb)->UrbBulkOrInterruptTransfer.TransferFlags = direction | USBD_SHORT_TRANSFER_OK; (*urb)->UrbBulkOrInterruptTransfer.TransferBufferLength = size; (*urb)->UrbBulkOrInterruptTransfer.TransferBufferMDL = buffer; } return STATUS_SUCCESS; }