BOOL QueryDeviceEndpoints (WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid) { if (hDeviceHandle==INVALID_HANDLE_VALUE) { return FALSE; } BOOL bResult = TRUE; USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR)); WINUSB_PIPE_INFORMATION Pipe; ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION)); bResult = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &InterfaceDescriptor); if (bResult) { for (int index = 0; index < InterfaceDescriptor.bNumEndpoints; index++) { bResult = WinUsb_QueryPipe(hDeviceHandle, 0, index, &Pipe); if (bResult) { if (Pipe.PipeType == UsbdPipeTypeControl) { printf("Endpoint index: %d Pipe type: Control Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId); } if (Pipe.PipeType == UsbdPipeTypeIsochronous) { printf("Endpoint index: %d Pipe type: Isochronous Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId); } if (Pipe.PipeType == UsbdPipeTypeBulk) { if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) { printf("Endpoint index: %d Pipe type: Bulk IN Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId); pipeid->PipeInId = Pipe.PipeId; } if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)) { printf("Endpoint index: %d Pipe type: Bulk OUT Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId); pipeid->PipeOutId = Pipe.PipeId; } } if (Pipe.PipeType == UsbdPipeTypeInterrupt) { printf("Endpoint index: %d Pipe type: Interrupt Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId); } } else { continue; } } } //done: return bResult; } // End of QueryDeviceEndpoints()
XN_C_API XnStatus xnUSBOpenEndPoint(XN_USB_DEV_HANDLE pDevHandle, XnUInt16 nEndPointID, XnUSBEndPointType nEPType, XnUSBDirectionType nDirType, XN_USB_EP_HANDLE* pEPHandlePtr) { // Local variables XnBool bResult = TRUE; XnStatus nRetVal = XN_STATUS_OK; XnInt32 nRetBytes = 0; XnChar pConfigDescBuf[MAX_CONFIG_DESC_SIZE]; XnChar* pBuf = NULL; PUSB_CONFIGURATION_DESCRIPTOR pUSBConfigDesc = NULL; PUSB_INTERFACE_DESCRIPTOR pUSBInterfaceDesc = NULL; PUSB_ENDPOINT_DESCRIPTOR pUSBEndPointDesc = NULL; XN_USB_EP_HANDLE pEPHandle = NULL; XnChar cpPipeID[3]; // Validate xnUSB XN_VALIDATE_USB_INIT(); XN_VALIDATE_USB_PDEV_HANDLE(pDevHandle); // Validate the input/output pointers XN_VALIDATE_OUTPUT_PTR(pEPHandlePtr); // Allocate a new xnUSB EP handle XN_VALIDATE_ALIGNED_CALLOC(*pEPHandlePtr, xnUSBEPHandle, 1, XN_DEFAULT_MEM_ALIGN); pEPHandle = *pEPHandlePtr; // Read the config descriptor bResult = DeviceIoControl(pDevHandle->hUSBDevHandle, IOCTL_PSDRV_GET_CONFIG_DESCRIPTOR, pConfigDescBuf, sizeof(pConfigDescBuf), pConfigDescBuf, sizeof(pConfigDescBuf), (PULONG)&nRetBytes, NULL); if (bResult) { XnUInt32 nIFIdx = 0; UCHAR nEPIdx = 0; XnUInt32 nUBBEPType = 0; XnUInt32 nCurrIF = 0; pBuf = pConfigDescBuf; pUSBConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)pBuf; pBuf += pUSBConfigDesc->bLength; // Scan all the interfaces do { pUSBInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)pBuf; pBuf += pUSBInterfaceDesc->bLength; // Scan all the endpoints for (nEPIdx = 0; nEPIdx < pUSBInterfaceDesc->bNumEndpoints; nEPIdx++) { pUSBEndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)pBuf; // Is this the EP we're looking for? if ((pUSBEndPointDesc->bEndpointAddress == nEndPointID) && (pDevHandle->nAltInterface == nCurrIF)) { // Get the EP type nUBBEPType = pUSBEndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK; // Verify that the EP type matches the requested EP if (nEPType == XN_USB_EP_BULK) { if (nUBBEPType != USB_ENDPOINT_TYPE_BULK) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE); } } else if (nEPType == XN_USB_EP_INTERRUPT) { if (nUBBEPType != USB_ENDPOINT_TYPE_INTERRUPT) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE); } } else if (nEPType == XN_USB_EP_ISOCHRONOUS) { if (nUBBEPType != USB_ENDPOINT_TYPE_ISOCHRONOUS) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE); } } else { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_UNKNOWN_ENDPOINT_TYPE); } // Verify that the EP direction matches the requested direction if (nDirType == XN_USB_DIRECTION_IN) { if (USB_ENDPOINT_DIRECTION_IN(pUSBEndPointDesc->bEndpointAddress) == FALSE) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION); } } else if (nDirType == XN_USB_DIRECTION_OUT) { if (USB_ENDPOINT_DIRECTION_OUT(pUSBEndPointDesc->bEndpointAddress) == FALSE) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION); } } else { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_UNKNOWN_ENDPOINT_DIRECTION); } // Construct the pipe file name pEPHandle->cpPipeName[0] = 0; cpPipeID[0] = '0'; cpPipeID[1] = '0' + nEPIdx; cpPipeID[2] = 0; StringCchCopy(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, pDevHandle->cpDeviceName); StringCchCat(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, PSDRV_PIPE_PREFIX); StringCchCat(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, cpPipeID); // Open the regular pipe handle pEPHandle->hEPHandle = CreateFile(pEPHandle->cpPipeName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (pEPHandle->hEPHandle == INVALID_HANDLE_VALUE) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_OPEN_ENDPOINT_FAILED); } // Init the overlapped I/O structs nRetVal = xnUSBInitOvlp(pEPHandle); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_OPEN_ENDPOINT_FAILED); } // Init the ThreadData variables xnOSMemSet(&pEPHandle->ThreadData, 0, sizeof(xnUSBReadThreadData)); pEPHandle->ThreadData.bInUse = FALSE; // Init the default endpoint properties pEPHandle->nTimeOut = XN_USB_DEFAULT_EP_TIMEOUT; pEPHandle->nEPType = nEPType; pEPHandle->nEPDir = nDirType; pEPHandle->nEndPointID = nEndPointID; // Set the default endpoint timeout nRetVal = xnUSBSetPipeProperty(pEPHandle, PSUSBDRV_PIPE_PROPERTY_TIMEOUT, XN_USB_DEFAULT_EP_TIMEOUT); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (nRetVal); } if (nUBBEPType == USB_ENDPOINT_TYPE_ISOCHRONOUS) { // bits 11 and 12 mark the number of additional transactions, bits 0-10 mark the size XnUInt32 nAdditionalTransactions = pUSBEndPointDesc->wMaxPacketSize >> 11; XnUInt32 nPacketSize = pUSBEndPointDesc->wMaxPacketSize & 0x7FF; pEPHandle->nMaxPacketSize = (nAdditionalTransactions + 1) * (nPacketSize); } else { pEPHandle->nMaxPacketSize = pUSBEndPointDesc->wMaxPacketSize; } // Mark the endpoint as valid pEPHandle->bValid = TRUE; // The end... (Happy) return (XN_STATUS_OK); } pBuf += pUSBEndPointDesc->bLength; }
/*! \brief Open a communication channel to the given USB port name. */ XsResultValue UsbInterface::open(const XsPortInfo &portInfo, uint32_t, uint32_t) { d->m_endTime = 0; #ifdef USE_WINUSB JLDEBUG(gJournal, "Open usb port " << portInfo.portName().toStdString()); #else JLDEBUG(gJournal, "Open usb port " << portInfo.usbBus() << ":" << portInfo.usbAddress()); #endif if (isOpen()) { JLALERT(gJournal, "Port " << portInfo.portName().toStdString() << " already open"); return (d->m_lastResult = XRV_ALREADYOPEN); } #ifdef USE_WINUSB d->m_deviceHandle = CreateFileA(portInfo.portName().c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (d->m_deviceHandle == INVALID_HANDLE_VALUE) { d->m_deviceHandle = NULL; return (d->m_lastResult = XRV_PORTNOTFOUND); } BOOL result = FALSE; UCHAR speed = 0; ULONG length = 0; USB_INTERFACE_DESCRIPTOR interfaceDescriptor = {0,0,0,0,0,0,0,0,0}; WINUSB_PIPE_INFORMATION pipeInfo; result = d->m_winUsb.Initialize(d->m_deviceHandle, &d->m_usbHandle[0]); if (result) { result = d->m_winUsb.GetAssociatedInterface(d->m_usbHandle[0],0,&d->m_usbHandle[1]); } else { #ifdef XSENS_DEBUG DWORD err = GetLastError(); assert(result); #endif return (d->m_lastResult = XRV_ERROR); } for (int k = 0; k<2;k++) { if(result) { assert(d->m_usbHandle[k] != 0); length = sizeof(UCHAR); result = d->m_winUsb.QueryDeviceInformation(d->m_usbHandle[k], DEVICE_SPEED, &length, &speed); } if(result) { d->m_deviceSpeed = speed; result = d->m_winUsb.QueryInterfaceSettings(d->m_usbHandle[k], 0, &interfaceDescriptor); } if(result) { for(int i=0;i<interfaceDescriptor.bNumEndpoints;i++) { result = d->m_winUsb.QueryPipe(d->m_usbHandle[k], 0, (UCHAR) i, &pipeInfo); if(pipeInfo.PipeType == UsbdPipeTypeBulk && USB_ENDPOINT_DIRECTION_IN(pipeInfo.PipeId)) { d->m_bulkInPipe = pipeInfo.PipeId; d->m_bulkInPipePacketSize = pipeInfo.MaximumPacketSize; } else if(pipeInfo.PipeType == UsbdPipeTypeBulk && USB_ENDPOINT_DIRECTION_OUT(pipeInfo.PipeId)) { d->m_bulkOutPipe = pipeInfo.PipeId; } else if(pipeInfo.PipeType == UsbdPipeTypeInterrupt) { d->m_interruptPipe = pipeInfo.PipeId; } else { result = FALSE; break; } } } } setTimeout(0); //lint !e534 flushData(); //lint !e534 sprintf(d->m_portname, "%s", portInfo.portName().c_str()); // d->m_offset = 0; ::ResetEvent(&d->m_quitEvent); //lint !e534 d->m_threadHandle = xsStartThread(usbReadThreadFunc, d, &d->m_threadId); if (d->m_threadHandle == XSENS_INVALID_THREAD) { #ifdef XSENS_DEBUG assert(0); #endif return (d->m_lastResult = XRV_ERROR); } #else // !USE_WINUSB libusb_device **deviceList; ssize_t listLength = UsbInterfacePrivate::getContextManager().m_libUsb.get_device_list(UsbInterfacePrivate::getContextManager().m_usbContext, &deviceList); if (listLength < 0) return d->m_lastResult = d->libusbErrorToXrv((int)listLength); // "USBxxx:yyy" uint8_t bus = XsPortInfo_usbBus(&portInfo); uint8_t address = XsPortInfo_usbAddress(&portInfo); XsResultValue xrv = XRV_OK; int result; libusb_device *device = NULL; for (int i = 0; i < listLength && device == NULL; ++i) { libusb_device *dev = deviceList[i]; if (UsbInterfacePrivate::getContextManager().m_libUsb.get_bus_number(dev) != bus || UsbInterfacePrivate::getContextManager().m_libUsb.get_device_address(dev) != address) continue; libusb_device_descriptor desc; result = UsbInterfacePrivate::getContextManager().m_libUsb.get_device_descriptor(dev, &desc); if (result != LIBUSB_SUCCESS) break; libusb_config_descriptor *configDesc; result = UsbInterfacePrivate::getContextManager().m_libUsb.get_active_config_descriptor(dev, &configDesc); if (result != LIBUSB_SUCCESS) break; d->m_interface = -1; d->m_interfaceCount = configDesc->bNumInterfaces; // find the bulk transfer endpoints for (uint8_t ifCount = 0; ifCount < configDesc->bNumInterfaces && d->m_interface == -1; ++ifCount) { for (uint8_t altsettingCount = 0; altsettingCount < configDesc->interface[ifCount].num_altsetting; altsettingCount++) { const libusb_endpoint_descriptor *endpoints = configDesc->interface[ifCount].altsetting[altsettingCount].endpoint; int inEndpoint = -1, outEndpoint = -1; for (uint8_t i = 0; i < configDesc->interface[ifCount].altsetting[altsettingCount].bNumEndpoints; i++) { if ((endpoints[i].bmAttributes&LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK) continue; switch (endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_DIR_MASK) { case LIBUSB_ENDPOINT_IN: inEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK; break; case LIBUSB_ENDPOINT_OUT: outEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK; break; } } if (outEndpoint == -1 || inEndpoint == -1) continue; d->m_interface = ifCount; d->m_dataOutEndPoint = outEndpoint; d->m_dataInEndPoint = inEndpoint; } } if (d->m_interface == -1) { xrv = XRV_INPUTCANNOTBEOPENED; break; } UsbInterfacePrivate::getContextManager().m_libUsb.free_config_descriptor(configDesc); UsbInterfacePrivate::getContextManager().m_libUsb.ref_device(dev); device = dev; result = LIBUSB_SUCCESS; } UsbInterfacePrivate::getContextManager().m_libUsb.free_device_list(deviceList, 1); if (result != LIBUSB_SUCCESS) { UsbInterfacePrivate::getContextManager().m_libUsb.unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } if (xrv != XRV_OK) { UsbInterfacePrivate::getContextManager().m_libUsb.unref_device(device); return d->m_lastResult = xrv; } libusb_device_handle *handle; result = UsbInterfacePrivate::getContextManager().m_libUsb.open(device, &handle); if (result != LIBUSB_SUCCESS) { UsbInterfacePrivate::getContextManager().m_libUsb.unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } // be rude and claim all interfaces for (int i = 0; i < d->m_interfaceCount; i++) { result = UsbInterfacePrivate::getContextManager().m_libUsb.kernel_driver_active(handle, i); if (result > 0) result = UsbInterfacePrivate::getContextManager().m_libUsb.detach_kernel_driver(handle, i); if (result == LIBUSB_SUCCESS) result = UsbInterfacePrivate::getContextManager().m_libUsb.claim_interface(handle, i); if (result != LIBUSB_SUCCESS) { for (int j = 0; j < i; j++) { while (result != LIBUSB_SUCCESS) { result = UsbInterfacePrivate::getContextManager().m_libUsb.release_interface(handle, j); UsbInterfacePrivate::getContextManager().m_libUsb.attach_kernel_driver(handle, j); } } UsbInterfacePrivate::getContextManager().m_libUsb.close(handle); UsbInterfacePrivate::getContextManager().m_libUsb.unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } } d->m_deviceHandle = handle; sprintf(d->m_portname, "%s", portInfo.portName().c_str()); flushData(); #endif // !USE_WINUSB JLDEBUG(gJournal, "USB Port opened"); return (d->m_lastResult = XRV_OK); }
VOID PipeQueue_OnWrite(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in size_t InputBufferLength) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_CONTEXT deviceContext; PREQUEST_CONTEXT requestContext; PQUEUE_CONTEXT queueContext = NULL; UNREFERENCED_PARAMETER(InputBufferLength); deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); requestContext = GetRequestContext(Request); VALIDATE_REQUEST_CONTEXT(requestContext, status); if (!NT_SUCCESS(status)) goto Done; if ((queueContext = GetQueueContext(Queue)) == NULL) { status = STATUS_INVALID_DEVICE_REQUEST; USBERRN("Invalid queue context"); goto Done; } if (!queueContext->PipeHandle) { USBERR("null pipe handle\n"); status = STATUS_INVALID_HANDLE; goto Done; } switch(queueContext->Info.PipeType) { case WdfUsbPipeTypeIsochronous: if (USB_ENDPOINT_DIRECTION_OUT(queueContext->Info.EndpointAddress)) { XferIsoWrite(Queue, Request); return; } break; case WdfUsbPipeTypeBulk: case WdfUsbPipeTypeInterrupt: if (USB_ENDPOINT_DIRECTION_IN(queueContext->Info.EndpointAddress)) { status = STATUS_INVALID_DEVICE_REQUEST; USBERRN("Cannot write to an IN pipe."); goto Done; } if(requestContext->Policies.RawIO) Xfer_WriteBulkRaw(Queue, Request); else Xfer_WriteBulk(Queue, Request); } status = STATUS_INVALID_DEVICE_REQUEST; USBERRN("PipeID=%02Xh Invalid request", queueContext->Info.EndpointAddress); Done: WdfRequestCompleteWithInformation(Request, status, 0); }
bool USBAudioDevice::InitDevice() { if(!USBDevice::InitDevice()) return FALSE; if(m_useInput) { USBAudioStreamingInterface * iface = m_asInterfaceList.First(); while(iface) { USBAudioStreamingEndpoint * epoint = iface->m_endpointsList.First(); while(epoint) { if(USB_ENDPOINT_DIRECTION_IN(epoint->m_descriptor.bEndpointAddress) && (epoint->m_descriptor.bmAttributes & 0x03) == USB_ENDPOINT_TYPE_ISOCHRONOUS && (epoint->m_descriptor.bmAttributes & 0x0C) != 0) //not feedback { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Found input endpoint 0x%X\n", (int)epoint->m_descriptor.bEndpointAddress); #endif int channelNumber = 2; USBAudioOutTerminal* outTerm = FindOutTerminal(iface->m_asgDescriptor.bTerminalLink); if(outTerm) { USBAudioFeatureUnit* unit = FindFeatureUnit(outTerm->m_outTerminal.bSourceID); if(unit) { USBAudioInTerminal* inTerm = FindInTerminal(unit->m_featureUnit.bSourceID); if(inTerm) channelNumber = inTerm->m_inTerminal.bNrChannels; } } m_adc = new AudioADC(); m_adc->Init(this, &m_fbInfo, epoint->m_descriptor.bEndpointAddress, epoint->m_descriptor.wMaxPacketSize, epoint->m_descriptor.bInterval, channelNumber, iface->m_formatDescriptor.bSubslotSize); m_adcEndpoint = epoint; break; } epoint = iface->m_endpointsList.Next(epoint); } if(m_adc != NULL) break; iface = m_asInterfaceList.Next(iface); } if(m_adc == NULL) m_useInput = FALSE; } if(m_adc == NULL) { USBAudioStreamingInterface * iface = m_asInterfaceList.First(); while(iface) { USBAudioStreamingEndpoint * epoint = iface->m_endpointsList.First(); while(epoint) { if(USB_ENDPOINT_DIRECTION_IN(epoint->m_descriptor.bEndpointAddress) && (epoint->m_descriptor.bmAttributes & 0x03) == USB_ENDPOINT_TYPE_ISOCHRONOUS && (epoint->m_descriptor.bmAttributes & 0x0C) == 0) //feedback { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Found feedback endpoint 0x%X\n", (int)epoint->m_descriptor.bEndpointAddress); #endif m_feedback = new AudioFeedback(); m_feedback->Init(this, &m_fbInfo, epoint->m_descriptor.bEndpointAddress, epoint->m_descriptor.wMaxPacketSize, epoint->m_descriptor.bInterval, 4); m_fbEndpoint = epoint; break; } epoint = iface->m_endpointsList.Next(epoint); } if(m_feedback != NULL) break; iface = m_asInterfaceList.Next(iface); } } // return TRUE; USBAudioStreamingInterface * iface = m_asInterfaceList.First(); while(iface) { if(!m_fbEndpoint || m_fbEndpoint->m_interface == iface) //out endpoint and feedback endpoint in same interface { USBAudioStreamingEndpoint * epoint = iface->m_endpointsList.First(); while(epoint) { if(USB_ENDPOINT_DIRECTION_OUT(epoint->m_descriptor.bEndpointAddress) && (epoint->m_descriptor.bmAttributes & 0x03) == USB_ENDPOINT_TYPE_ISOCHRONOUS) { #ifdef _ENABLE_TRACE debugPrintf("ASIOUAC: Found output endpoint 0x%X\n", (int)epoint->m_descriptor.bEndpointAddress); #endif int channelNumber = 2; USBAudioInTerminal* inTerm = FindInTerminal(iface->m_asgDescriptor.bTerminalLink); if(inTerm) channelNumber = inTerm->m_inTerminal.bNrChannels; m_dac = new AudioDAC(); m_dac->Init(this, &m_fbInfo, epoint->m_descriptor.bEndpointAddress, epoint->m_descriptor.wMaxPacketSize, epoint->m_descriptor.bInterval, channelNumber, iface->m_formatDescriptor.bSubslotSize); m_dacEndpoint = epoint; break; } epoint = iface->m_endpointsList.Next(epoint); } } if(m_dac != NULL) break; iface = m_asInterfaceList.Next(iface); } return TRUE; }
bool QUsbDevice::queryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hWinUSBHandle, QUsbDevice::PIPE_ID *pipeId) { UsbPrintFuncName(); if (hWinUSBHandle==INVALID_HANDLE_VALUE) { return false; } bool bResult = true; if (!WinUsb_SetCurrentAlternateSetting(hWinUSBHandle, mConfig.alternate)) { return false; } if (mDebug) qDebug("Alternate setting: %d.", mConfig.alternate); USB_INTERFACE_DESCRIPTOR InterfaceDescriptor; ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR)); WINUSB_PIPE_INFORMATION pipe; ZeroMemory(&pipe, sizeof(WINUSB_PIPE_INFORMATION)); bResult = WinUsb_QueryInterfaceSettings(hWinUSBHandle, mConfig.interface, &InterfaceDescriptor); if (bResult) { for (int index = 0; index < InterfaceDescriptor.bNumEndpoints; index++) { bResult = WinUsb_QueryPipe(hWinUSBHandle, mConfig.interface, index, &pipe); if (bResult) { if (pipe.PipeType == UsbdPipeTypeControl) { if (mDebug) qDebug("Endpoint index: %d Pipe type: Control Pipe ID: 0x%02x.", index, pipe.PipeId); } if (pipe.PipeType == UsbdPipeTypeIsochronous) { if (mDebug) qDebug("Endpoint index: %d Pipe type: Isochronous Pipe ID: 0x%02x.", index, pipe.PipeId); } if (pipe.PipeType == UsbdPipeTypeBulk) { if (USB_ENDPOINT_DIRECTION_IN(pipe.PipeId)) { if (mDebug) qDebug("Bulk IN Endpoint index: %d Pipe type: Bulk Pipe ID: 0x%02x.", index, pipe.PipeId); pipeId->pipeInId = pipe.PipeId; } if (USB_ENDPOINT_DIRECTION_OUT(pipe.PipeId)) { if (mDebug) qDebug("Bulk OUT Endpoint index: %d Pipe type: Bulk Pipe ID: 0x%02x.", index, pipe.PipeId); pipeId->pipeOutId = pipe.PipeId; } } if (pipe.PipeType == UsbdPipeTypeInterrupt) { if (mDebug) qDebug("Endpoint index: %d Pipe type: Interrupt Pipe ID: 0x%02x.", index, pipe.PipeId); } } else { continue; } } } else { return false; } return true; }