int NiashLibUsbOpen(char const * const pszName, EScannerModel* const peModel) { //Open a handle to the device (FILE_FLAG_OVERLAPPED for WinUSB) s_hDevice = CreateFileA(pszName, GENERIC_READ|GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); //s_hDevice = CreateFileA("\\\\.\\Usbscan0", GENERIC_READ|GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if(s_hDevice == INVALID_HANDLE_VALUE) { wprintf_s(L"CreateFile: %s\n", _com_error(GetLastError()).ErrorMessage()); return -1; } //Open a WinUSB handle if(!WinUsb_Initialize(s_hDevice,&s_hWinUSB)) { wprintf_s(L"WinUsb_Initialize: %s\n", _com_error(GetLastError()).ErrorMessage()); return -1; } //Get interface descriptor USB_INTERFACE_DESCRIPTOR USBInterfaceDescriptor; if(!WinUsb_QueryInterfaceSettings(s_hWinUSB,0,&USBInterfaceDescriptor)) { wprintf_s(L"WinUsb_QueryInterfaceSettings: %s\n", _com_error(GetLastError()).ErrorMessage()); return -1; } //Find pipes for(UCHAR i = 0;i < USBInterfaceDescriptor.bNumEndpoints;i++) { WINUSB_PIPE_INFORMATION Pipe; WinUsb_QueryPipe(s_hWinUSB,0,i,&Pipe); if(Pipe.PipeType == UsbdPipeTypeInterrupt) { s_Pipes.Interrupt = Pipe.PipeId; } else if(Pipe.PipeType == UsbdPipeTypeBulk) { if(USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) { s_Pipes.BulkIn = Pipe.PipeId; } else { s_Pipes.BulkOut = Pipe.PipeId; } } } if(!s_Pipes.Interrupt || !s_Pipes.BulkIn || !s_Pipes.BulkOut) { puts("Not all required pipes found."); return -1; } assert(s_pScannerModel); *peModel = s_pScannerModel->eModel; return 1; }
BOOL ChinavisionAPI::init(HANDLE threadExit) { //========================================== USB_INTERFACE_DESCRIPTOR ifaceDescriptor; WINUSB_PIPE_INFORMATION pipeInfo; //========================================== m_usbHandle = NULL; m_deviceHandle = NULL; m_inPipeId = 0; m_irCode = 0; m_dataReadyEvent = CreateEvent(NULL,TRUE,FALSE,NULL); m_threadExitEvent = threadExit; findDevice(); if(!_tcslen(m_deviceName)) { return FALSE; // failed to find device name } m_deviceHandle = CreateFile(m_deviceName,GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if(m_deviceHandle==NULL) { return FALSE; } if(!WinUsb_Initialize(m_deviceHandle, &m_usbHandle)) { cleanUp(); return FALSE; } if(!WinUsb_QueryInterfaceSettings(m_usbHandle, 0, &ifaceDescriptor)) { cleanUp(); return FALSE; } for (int i=0; i<ifaceDescriptor.bNumEndpoints; i++) { if(!WinUsb_QueryPipe(m_usbHandle, 0, (UCHAR) i, &pipeInfo)) { cleanUp(); return FALSE; } if (USB_ENDPOINT_DIRECTION_IN(pipeInfo.PipeId)) { m_inPipeId = pipeInfo.PipeId; } } if (m_inPipeId==0) { cleanUp(); return FALSE; } m_threadHandle = CreateThread(NULL,0,SZThread,(void *)this,0,NULL); if(m_threadHandle) return TRUE; return FALSE; }
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()
void print_USB_ENDPOINT_DESCRIPTOR(PUSB_ENDPOINT_DESCRIPTOR ed, int i) /*++ Routine Description: Called to do formatted ascii dump to console of a USB endpoint descriptor Arguments: ptr to USB endpoint descriptor, index of this endpt in interface desc Return Value: none --*/ { printf( "------------------------------\nUSB_ENDPOINT_DESCRIPTOR for Pipe%02d\n", i ); printf( "bLength = 0x%x\n", ed->bLength ); printf( "bDescriptorType = 0x%x ( %s )\n", ed->bDescriptorType, usbDescriptorTypeString( ed->bDescriptorType ) ); if ( USB_ENDPOINT_DIRECTION_IN( ed->bEndpointAddress ) ) { printf( "bEndpointAddress= 0x%x ( INPUT )\n", ed->bEndpointAddress ); } else { printf( "bEndpointAddress= 0x%x ( OUTPUT )\n", ed->bEndpointAddress ); } printf( "bmAttributes= 0x%x ( %s )\n", ed->bmAttributes, usbEndPointTypeString ( ed->bmAttributes ) ); printf( "wMaxPacketSize= 0x%x, decimal %d\n", ed->wMaxPacketSize, ed->wMaxPacketSize ); printf( "bInterval = 0x%x, decimal %d\n", ed->bInterval, ed->bInterval ); }
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; }
VOID Pipe_InitQueueConfig( __in PPIPE_CONTEXT pipeContext, __out WDF_IO_QUEUE_CONFIG* queueConfig) { WDF_DRIVER_VERSION_AVAILABLE_PARAMS verParams; if (!pipeContext->Pipe) { // Default (Control) pipe WDF_IO_QUEUE_CONFIG_INIT(queueConfig, WdfIoQueueDispatchSequential); queueConfig->EvtIoDeviceControl = PipeQueue_OnIoControl; return; } if (pipeContext->PipeInformation.PipeType == WdfUsbPipeTypeIsochronous || pipeContext->Policies.RawIO) { USBDBGN("Configuring parallel queue.."); WDF_IO_QUEUE_CONFIG_INIT(queueConfig, WdfIoQueueDispatchParallel); /* NOTE: WinUSB does not support RawIO OUT transfers; libusbK does. http://msdn.microsoft.com/en-us/library/windows/hardware/ff728833%28v=vs.85%29.aspx In libusbK, RawIO means we use a parallel queue. Any pipe policies or functionality that could cause multiple IO transactions per request are no longer supported. IE: Transfer splitting, ALLOW_ARTIAL_READS, AUTO_FLUSH, IGNORE_SHORT_PACKETS, SHORT_PACKET_TERMINATE. */ WDF_DRIVER_VERSION_AVAILABLE_PARAMS_INIT(&verParams, KMDF_MAJOR_VERSION, KMDF_MINOR_VERSION); if (WdfDriverIsVersionAvailable(gWdfDriver, &verParams)) { # if ((KMDF_MAJOR_VERSION==1 && KMDF_MINOR_VERSION >= 9) || (KMDF_MAJOR_VERSION > 1)) if (pipeContext->SimulParallelRequests) queueConfig->Settings.Parallel.NumberOfPresentedRequests = pipeContext->SimulParallelRequests; # endif } else { DbgPrint("Expected library version %u.%u!\n",KMDF_MAJOR_VERSION, KMDF_MINOR_VERSION); } } else { USBDBGN("Configuring sequential queue.."); WDF_IO_QUEUE_CONFIG_INIT(queueConfig, WdfIoQueueDispatchSequential); queueConfig->EvtIoStop = Queue_OnStop; queueConfig->EvtIoResume = Queue_OnResume; } queueConfig->EvtIoDeviceControl = PipeQueue_OnIoControl; if (USB_ENDPOINT_DIRECTION_IN(pipeContext->PipeInformation.EndpointAddress)) { queueConfig->EvtIoRead = PipeQueue_OnRead; } else { queueConfig->EvtIoWrite = PipeQueue_OnWrite; queueConfig->AllowZeroLengthRequests = TRUE; } }
/*! \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); }
DWORD __cdecl main(int argc, char* argv[]) { DWORD errorCode = ERROR_SUCCESS; BOOL success; KLST_HANDLE deviceList = NULL; KLST_DEVINFO_HANDLE deviceInfo = NULL; KUSB_HANDLE usbHandle = NULL; UCHAR myBuffer[4096]; BM_TEST_TYPE testType = USB_ENDPOINT_DIRECTION_IN(EP_ADDRESS) ? BM_TEST_TYPE_READ : BM_TEST_TYPE_WRITE; ULONG totalLength = 0; ULONG transferredLength; ULONG transferIndex; /* Find the test device. Uses "vid=hhhh pid=hhhh" arguments supplied on the command line. (default is: vid=04D8 pid=FA2E) */ if (!Examples_GetTestDevice(&deviceList, &deviceInfo, argc, argv)) return GetLastError(); /* This example will use the dynamic driver api so that it can be used with all supported drivers. */ LibK_LoadDriverAPI(&Usb, deviceInfo->DriverID); /* Initialize the device. This creates the physical usb handle. */ if (!Usb.Init(&usbHandle, deviceInfo)) { errorCode = GetLastError(); printf("Init device failed. ErrorCode: %08Xh\n", errorCode); goto Done; } printf("Device opened successfully!\n"); success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, &Usb, &testType); if (!success) printf("Bench_Configure failed.\n"); /* Submit and complete SYNC_TRANSFER_COUNT number of transfers. */ transferIndex = (DWORD) - 1; while (++transferIndex < SYNC_TRANSFER_COUNT) { // This examples works the same fo reading and writing. The endpoint address is used to // determine which. if (USB_ENDPOINT_DIRECTION_IN(EP_ADDRESS)) success = Usb.ReadPipe(usbHandle, EP_ADDRESS, myBuffer, sizeof(myBuffer), &transferredLength, NULL); else success = Usb.WritePipe(usbHandle, EP_ADDRESS, myBuffer, sizeof(myBuffer), &transferredLength, NULL); if (!success) { errorCode = GetLastError(); break; } totalLength += transferredLength; printf("Transfer #%u completed with %u bytes.\n", transferIndex, transferredLength); } printf("Transferred %u bytes in %u transfers. errorCode=%08Xh\n", totalLength, transferIndex, errorCode); Done: /* Close the usb handle. */ if (usbHandle) Usb.Free(usbHandle); /* Free the device list. */ LstK_Free(deviceList); return errorCode; }
VOID PipeQueue_OnIoControl(__in WDFQUEUE Queue, __in WDFREQUEST Request, __in size_t OutputBufferLength, __in size_t InputBufferLength, __in ULONG IoControlCode) { NTSTATUS status; ULONG length = 0; PREQUEST_CONTEXT requestContext = GetRequestContext(Request); PQUEUE_CONTEXT queueContext = NULL; 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; } switch(IoControlCode) { case LIBUSB_IOCTL_ISOCHRONOUS_READ: case LIBUSB_IOCTL_ISOCHRONOUS_WRITE: case LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE: case LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ: switch (queueContext->Info.PipeType) { case WdfUsbPipeTypeIsochronous: if (USB_ENDPOINT_DIRECTION_IN(queueContext->Info.EndpointAddress)) { XferIsoRead(Queue, Request); return; } XferIsoWrite(Queue, Request); return; case WdfUsbPipeTypeBulk: case WdfUsbPipeTypeInterrupt: if(requestContext->Policies.RawIO) { if (USB_ENDPOINT_DIRECTION_IN(queueContext->Info.EndpointAddress)) Xfer_ReadBulkRaw(Queue, Request); else Xfer_WriteBulkRaw(Queue, Request); } else { if (USB_ENDPOINT_DIRECTION_IN(queueContext->Info.EndpointAddress)) Xfer_ReadBulk(Queue, Request); else Xfer_WriteBulk(Queue, Request); } return; default: status = STATUS_INVALID_PARAMETER; USBERRN("Invalid PipeType=%s\n", GetPipeTypeString(queueContext->Info.PipeType)); break; } case LIBUSBK_IOCTL_ISOEX_READ: case LIBUSBK_IOCTL_ISOEX_WRITE: if (queueContext->Info.PipeType == WdfUsbPipeTypeIsochronous) { XferIsoEx(Queue, Request); return; } status = STATUS_INVALID_PARAMETER; USBERRN("Invalid PipeType=%s\n", GetPipeTypeString(queueContext->Info.PipeType)); break; /* case LIBUSBK_IOCTL_AUTOISOEX_READ: case LIBUSBK_IOCTL_AUTOISOEX_WRITE: if (queueContext->Info.PipeType == WdfUsbPipeTypeIsochronous) { XferAutoIsoEx(Queue, Request); return; } status = STATUS_INVALID_PARAMETER; USBERRN("Invalid PipeType=%s\n", GetPipeTypeString(queueContext->Info.PipeType)); break; */ case LIBUSB_IOCTL_SET_FEATURE: case LIBUSB_IOCTL_CLEAR_FEATURE: case LIBUSB_IOCTL_GET_DESCRIPTOR: case LIBUSB_IOCTL_SET_DESCRIPTOR: case LIBUSB_IOCTL_VENDOR_WRITE: case LIBUSB_IOCTL_VENDOR_READ: case LIBUSB_IOCTL_CONTROL_READ: case LIBUSB_IOCTL_CONTROL_WRITE: XferCtrl(Queue, Request, InputBufferLength, OutputBufferLength); return; default: USBERR("unknown IoControlCode %Xh (function=%04Xh)\n", IoControlCode, FUNCTION_FROM_CTL_CODE(IoControlCode)); status = STATUS_INVALID_DEVICE_REQUEST; WdfRequestCompleteWithInformation(Request, status, 0); return; } Done: WdfRequestCompleteWithInformation(Request, status, length); return; }
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; }
DWORD __cdecl main(int argc, char* argv[]) { KLST_HANDLE deviceList = NULL; KLST_DEVINFO_HANDLE deviceInfo = NULL; KUSB_HANDLE usbHandle = NULL; DWORD errorCode = ERROR_SUCCESS; BM_TEST_TYPE testType; UCHAR interfaceIndex; BOOL success; memset(&gXfers, 0, sizeof(gXfers)); #ifdef ISO_LOG_FILENAME // Create a new log file. gOutFile = fopen("xfer-iso-read.txt", "w"); #else gOutFile = NULL; #endif /* Find the test device. Uses "vid=hhhh pid=hhhh" arguments supplied on the command line. (default is: vid=04D8 pid=FA2E) */ if (!Examples_GetTestDevice(&deviceList, &deviceInfo, argc, argv)) return GetLastError(); /* Initialize the device. This creates the physical usb handle. */ if (!UsbK_Init(&usbHandle, deviceInfo)) { errorCode = GetLastError(); printf("UsbK_Init failed. ErrorCode: %08Xh\n", errorCode); goto Done; } printf("Device opened successfully!\n"); /* Select interface by pipe id and get descriptors. */ interfaceIndex = (UCHAR) - 1; while(UsbK_SelectInterface(usbHandle, ++interfaceIndex, TRUE)) { memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor)); memset(&gPipeInfo, 0, sizeof(gPipeInfo)); gAltsettingNumber = (UCHAR) - 1; while(UsbK_QueryInterfaceSettings(usbHandle, ++gAltsettingNumber, &gInterfaceDescriptor)) { UCHAR pipeIndex = (UCHAR) - 1; if (EP_ALTF == -1 || gInterfaceDescriptor.bAlternateSetting == EP_ALTF) { while(UsbK_QueryPipe(usbHandle, gAltsettingNumber, ++pipeIndex, &gPipeInfo)) { if (gPipeInfo.PipeType == UsbdPipeTypeIsochronous && gPipeInfo.MaximumPacketSize && (gPipeInfo.PipeId & 0x80)) { if (EP_READ== -1 || EP_READ == gPipeInfo.PipeId) break; } memset(&gPipeInfo, 0, sizeof(gPipeInfo)); } } if (gPipeInfo.PipeId) break; memset(&gInterfaceDescriptor, 0, sizeof(gInterfaceDescriptor)); } } if (!gPipeInfo.PipeId) { printf("Pipe not found.\n"); goto Done; } /* Set the desired alternate setting. */ success = UsbK_SetAltInterface( usbHandle, gInterfaceDescriptor.bInterfaceNumber, FALSE, gInterfaceDescriptor.bAlternateSetting); if (!success) { printf("UsbK_SetAltInterface failed.\n"); goto Done; } // Configure the benchmark test device to send data. testType = USB_ENDPOINT_DIRECTION_IN(gPipeInfo.PipeId) ? BM_TEST_TYPE_READ : BM_TEST_TYPE_WRITE; success = Bench_Configure(usbHandle, BM_COMMAND_SET_TEST, 0, NULL, &testType); if (!success) { errorCode = GetLastError(); printf("Bench_Configure failed. ErrorCode: %08Xh\n", errorCode); goto Done; } printf("Device hardware fully prepared..\n"); /* Allocate the iso buffer resources. */ do { int pos; gXfers.DataBufferSize = ISO_PACKETS_PER_TRANSFER * gPipeInfo.MaximumPacketSize; success = OvlK_Init(&gXfers.OvlPool, usbHandle, MAX_OUTSTANDING_TRANSFERS, KOVL_POOL_FLAG_NONE); for (pos = 0; pos < MAX_OUTSTANDING_TRANSFERS; pos++) { PMY_ISO_BUFFER_EL bufferEL = malloc(sizeof(MY_ISO_BUFFER_EL)); memset(bufferEL, 0, sizeof(*bufferEL)); bufferEL->DataBuffer = malloc(gXfers.DataBufferSize); IsoK_Init(&bufferEL->IsoContext, ISO_PACKETS_PER_TRANSFER, 0); IsoK_SetPackets(bufferEL->IsoContext, gPipeInfo.MaximumPacketSize); //bufferEL->IsoContext->Flags = KISO_FLAG_SET_START_FRAME; bufferEL->IsoPackets = bufferEL->IsoContext->IsoPackets; OvlK_Acquire(&bufferEL->OvlHandle, gXfers.OvlPool); DL_APPEND(gXfers.BufferList, bufferEL); DL_APPEND(gXfers.Completed, bufferEL); } } while(0); /* Reset the pipe. */ UsbK_ResetPipe(usbHandle, (UCHAR)gPipeInfo.PipeId); /* Set a start frame (not used) see KISO_FLAG_SET_START_FRAME. */ UsbK_GetCurrentFrameNumber(usbHandle, &gXfers.FrameNumber); gXfers.FrameNumber += ISO_PACKETS_PER_TRANSFER * 2; gXfers.FrameNumber -= gXfers.FrameNumber % ISO_PACKETS_PER_TRANSFER; mDcs_Init(&Dcs); /* Start reading until an error occurs or MAX_TRANSFERS_TOTAL is reached. */ do { PMY_ISO_BUFFER_EL nextXfer; ULONG transferred; while(errorCode == ERROR_SUCCESS && gXfers.Completed && gXfers.SubmittedCount < MAX_TRANSFERS_TOTAL) { nextXfer = gXfers.Completed; DL_DELETE(gXfers.Completed, nextXfer); DL_APPEND(gXfers.Outstanding, nextXfer); OvlK_ReUse(nextXfer->OvlHandle); SetNextFrameNumber(&gXfers, nextXfer); success = UsbK_IsoReadPipe( usbHandle, gPipeInfo.PipeId, nextXfer->DataBuffer, gXfers.DataBufferSize, nextXfer->OvlHandle, nextXfer->IsoContext); errorCode = GetLastError(); if (errorCode != ERROR_IO_PENDING) { printf("UsbK_IsoReadPipe failed. ErrorCode: %08Xh\n", errorCode); goto Done; } gXfers.SubmittedCount++; errorCode = ERROR_SUCCESS; } nextXfer = gXfers.Outstanding; if (!nextXfer) { printf("Done!\n"); goto Done; } success = OvlK_Wait(nextXfer->OvlHandle, 1000, KOVL_WAIT_FLAG_NONE, &transferred); if (!success) { errorCode = GetLastError(); printf("OvlK_Wait failed. ErrorCode: %08Xh\n", errorCode); goto Done; } DL_DELETE(gXfers.Outstanding, nextXfer); DL_APPEND(gXfers.Completed, nextXfer); IsoXferComplete(&gXfers, nextXfer, transferred); } while(errorCode == ERROR_SUCCESS); Done: /* Cancel all transfers left outstanding. */ while(gXfers.Outstanding) { PMY_ISO_BUFFER_EL nextBufferEL = gXfers.Outstanding; ULONG transferred; OvlK_WaitOrCancel(nextBufferEL->OvlHandle, 0, &transferred); DL_DELETE(gXfers.Outstanding, nextBufferEL); } /* Free the iso buffer resources. */ while(gXfers.BufferList) { PMY_ISO_BUFFER_EL nextBufferEL = gXfers.BufferList; DL_DELETE(gXfers.BufferList, nextBufferEL); OvlK_Release(nextBufferEL->OvlHandle); IsoK_Free(nextBufferEL->IsoContext); free(nextBufferEL->DataBuffer); free(nextBufferEL); } // Free the overlapped pool. OvlK_Free(gXfers.OvlPool); // Close the device handle. UsbK_Free(usbHandle); // Free the device list. LstK_Free(deviceList); // Close the log file. if (gOutFile) { fflush(gOutFile); fclose(gOutFile); gOutFile = NULL; } return errorCode; }
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; }
NTSTATUS NTAPI USBSTOR_ScanConfigurationDescriptor( IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PUSB_INTERFACE_DESCRIPTOR * OutInterfaceDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR * InEndpointDescriptor, OUT PUSB_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor) { PUSB_CONFIGURATION_DESCRIPTOR CurrentDescriptor; PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor; // // sanity checks // ASSERT(ConfigurationDescriptor); ASSERT(OutInterfaceDescriptor); ASSERT(InEndpointDescriptor); ASSERT(OutEndpointDescriptor); // // nullify pointers // *OutInterfaceDescriptor = NULL; *InEndpointDescriptor = NULL; *OutEndpointDescriptor = NULL; // // start scanning // CurrentDescriptor = ConfigurationDescriptor; do { // // check current descriptor type // if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { // // found interface descriptor // if (*OutInterfaceDescriptor) { // // we only process the first interface descriptor as ms does -> see documentation // break; } // // store interface descriptor // *OutInterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)CurrentDescriptor; } else if (CurrentDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) { // // convert to endpoint descriptor // EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CurrentDescriptor; // // sanity check // ASSERT(*OutInterfaceDescriptor); // // get endpoint type // if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) { // // bulk endpoint type // if (USB_ENDPOINT_DIRECTION_IN(EndpointDescriptor->bEndpointAddress)) { // // bulk in // *InEndpointDescriptor = EndpointDescriptor; } else { // // bulk out // *OutEndpointDescriptor = EndpointDescriptor; } } else if ((EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT) { // // interrupt endpoint type // UNIMPLEMENTED } } // // move to next descriptor // CurrentDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)((ULONG_PTR)CurrentDescriptor + CurrentDescriptor->bLength); // // was it the last descriptor // if ((ULONG_PTR)CurrentDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) { // // reached last descriptor // break; } }while(TRUE);
DWORD CSTDevice::OpenPipes() { CString PipeSymbName; int i; DWORD nRet; BOOL bTmp; UINT _uiNbOfInterfaces = 0; UINT _uiNbOfEndpointsTmp = 0; UINT _j = 0, _k = 0; ClosePipes(); // Fake open bTmp=m_bDeviceIsOpen; m_bDeviceIsOpen=TRUE; /*### ===> DE-1184 du 08/03/2009 ML */ // We must open all the endpoints available on all the configured interfaces nRet = GetNbOfInterfaces(m_CurrentConfig, &_uiNbOfInterfaces); if (nRet!=STDEVICE_NOERROR) { m_bDeviceIsOpen=bTmp; return nRet; } for(_j=0; _j<_uiNbOfInterfaces; _j++) { nRet=GetNbOfEndPoints(m_CurrentConfig, _j, m_CurrentAltSet, &_uiNbOfEndpointsTmp); if (nRet!=STDEVICE_NOERROR) { m_bDeviceIsOpen=bTmp; return nRet; } m_nbEndPoints += _uiNbOfEndpointsTmp; } m_pPipeHandles=new HANDLE[m_nbEndPoints]; for(_j=0; _j<_uiNbOfInterfaces; _j++) { nRet=GetNbOfEndPoints(m_CurrentConfig, _j, m_CurrentAltSet, &_uiNbOfEndpointsTmp); if (nRet!=STDEVICE_NOERROR) { m_bDeviceIsOpen=bTmp; return nRet; } for (i=0;i<(int)_uiNbOfEndpointsTmp;i++) { // Get endpoint description to see if it's an input or output pipe, and get its address USB_ENDPOINT_DESCRIPTOR Desc; nRet=GetEndPointDescriptor(m_CurrentConfig, m_CurrentInterf, m_CurrentAltSet, _k, &Desc); if (nRet==STDEVICE_NOERROR) { PipeSymbName.Format("%s\\%02x", m_SymbolicName, Desc.bEndpointAddress); m_pPipeHandles[_k]= CreateFile( PipeSymbName, (USB_ENDPOINT_DIRECTION_IN(Desc.bEndpointAddress))?GENERIC_READ:GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if ( (!m_pPipeHandles[_k]) || (m_pPipeHandles[_k]==INVALID_HANDLE_VALUE) ) { while (_k>0) { _k--; CloseHandle(m_pPipeHandles[_k]); m_pPipeHandles[_k]=INVALID_HANDLE_VALUE; } delete[] m_pPipeHandles; m_pPipeHandles=NULL; nRet=STDEVICE_PIPECREATIONERROR; break; } else { // reset the pipe BYTE InBuffer[2]; DWORD ByteCount; InBuffer[0]=Desc.bEndpointAddress; InBuffer[1]=1; // Reset pipe if (!DeviceIoControl(m_DeviceHandle, PU_PIPE_CONTROL, InBuffer, 2, NULL, 0, &ByteCount, NULL)) { while (_k>0) { _k--; CloseHandle(m_pPipeHandles[_k]); m_pPipeHandles[_k]=INVALID_HANDLE_VALUE; } delete[] m_pPipeHandles; m_pPipeHandles=NULL; nRet=STDEVICE_PIPERESETERROR; break; } else { // Abort any transfer BYTE InBuffer[2]; DWORD ByteCount; InBuffer[0]=Desc.bEndpointAddress; InBuffer[1]=0; // Abort if (!DeviceIoControl(m_DeviceHandle, PU_PIPE_CONTROL, InBuffer, 2, NULL, 0, &ByteCount, NULL)) { while (_k>0) { _k--; CloseHandle(m_pPipeHandles[_k]); m_pPipeHandles[_k]=INVALID_HANDLE_VALUE; } delete[] m_pPipeHandles; m_pPipeHandles=NULL; nRet=STDEVICE_PIPEABORTERROR; break; } } } } else { while (_k>0) { _k--; CloseHandle(m_pPipeHandles[_k]); m_pPipeHandles[_k]=INVALID_HANDLE_VALUE; } delete[] m_pPipeHandles; m_pPipeHandles=NULL; nRet=STDEVICE_PIPECREATIONERROR; break; } _k++; } } /*### <=== DE-1184 */ m_bDeviceIsOpen=bTmp; return nRet; }