This IOCTL command is used to request Bulk, Interrupt or Isochronous data transfers across corresponding USB device endpoints.
Regardless of whether the endpoint is an IN or an OUT endpoint, a pointer to a single data structure is passed to DeviceIoControl( ) as both the lpInBuffer and lpOutBuffer parameters. The driver expects that the pointer references a SINGLE_TRANSFER structure, followed by a data buffer. In the case of OUT endpoints, the buffer is expected to contain the data bytes to be transmitted. In the case of an IN endpoint, the buffer is expected to be the writeable memory for received data bytes.
Special ISOC Constraints
The endpoint maximum transfer size and buffer length parameter must both be a multiple of the endpoint's MaxPacketSize.
For ISOC transfers on a device operating at High speed or Super Speed, the following constraints apply to this command:
1) The buffer length parameter (bufLen in the below examples) must also be a multiple of the endpoint's MaxPacketSize * 8. Please also note that last packet is allow to send with partial size(less than Max packet) for both super and high speed Isochronous transfer.
2) For Super speed Isochronous endpoint only , if device define the MaxBurst in the super speed endpoint companion descriptor then Maxburst should be used to calculate the packet size=(MaxpacketSize * (MaxBurst+1). This packet length data will be sent over one micro frame interval.
PUCHAR CCyBulkEndPoint::BeginDataXfer(PCHAR buf, LONG bufLen, OVERLAPPED *ov)
if (hDevice == INVALID_HANDLE_VALUE) return NULL;
int iXmitBufSize = sizeof (SINGLE_TRANSFER) + bufLen;
PUCHAR pXmitBuf = new UCHAR[iXmitBufSize];
PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER)pXmitBuf;
pTransfer->Reserved = 0;
pTransfer->ucEndpointAddress = Address;
pTransfer->IsoPacketLength = 0;
pTransfer->BufferOffset = sizeof (SINGLE_TRANSFER);
pTransfer->BufferLength = bufLen;
// Copy buf into pXmitBuf
UCHAR *ptr = (PUCHAR) pTransfer + pTransfer->BufferOffset;
memcpy(ptr, buf, bufLen);