[ros-diffs] [janderwald] 55992: [LIBUSB] - Fix bug while scanning endpoint descriptors - Do not assume interface info has the correct number of pipes set - Fix alternate interface handling - Tested in VBox + U...
janderwald at svn.reactos.org
janderwald at svn.reactos.org
Sun Mar 4 11:07:15 UTC 2012
Author: janderwald
Date: Sun Mar 4 11:07:13 2012
New Revision: 55992
URL: http://svn.reactos.org/svn/reactos?rev=55992&view=rev
Log:
[LIBUSB]
- Fix bug while scanning endpoint descriptors
- Do not assume interface info has the correct number of pipes set
- Fix alternate interface handling
- Tested in VBox + USB Audio Device
Modified:
trunk/reactos/lib/drivers/libusb/hub_controller.cpp
trunk/reactos/lib/drivers/libusb/libusb.h
trunk/reactos/lib/drivers/libusb/usb_device.cpp
Modified: trunk/reactos/lib/drivers/libusb/hub_controller.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/libusb/hub_controller.cpp?rev=55992&r1=55991&r2=55992&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/libusb/hub_controller.cpp [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/libusb/hub_controller.cpp [iso-8859-1] Sun Mar 4 11:07:13 2012
@@ -798,6 +798,7 @@
// sanity checks
//
ASSERT(EndPointDesc);
+ DPRINT("HandleIsochronousTransfer EndPointDesc %p Address %x bmAttributes %x\n", EndPointDesc, EndPointDesc->bEndpointAddress, EndPointDesc->bmAttributes);
ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS);
//
Modified: trunk/reactos/lib/drivers/libusb/libusb.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/libusb/libusb.h?rev=55992&r1=55991&r2=55992&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/libusb/libusb.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/libusb/libusb.h [iso-8859-1] Sun Mar 4 11:07:13 2012
@@ -12,7 +12,6 @@
{
#include <usbdlib.h>
}
-
//
// FIXME:
Modified: trunk/reactos/lib/drivers/libusb/usb_device.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/libusb/usb_device.cpp?rev=55992&r1=55991&r2=55992&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/libusb/usb_device.cpp [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/libusb/usb_device.cpp [iso-8859-1] Sun Mar 4 11:07:13 2012
@@ -65,6 +65,8 @@
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
virtual NTSTATUS GetConfigurationDescriptor(UCHAR ConfigurationIndex, USHORT BufferSize, PVOID Buffer);
+ virtual NTSTATUS BuildInterfaceDescriptor(IN ULONG ConfigurationIndex, IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo, OUT PUSB_INTERFACE *OutUsbInterface);
+
// constructor / destructor
CUSBDevice(IUnknown *OuterUnknown){}
@@ -916,6 +918,92 @@
//
return Status;
}
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::BuildInterfaceDescriptor(
+ IN ULONG ConfigurationIndex,
+ IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
+ OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo,
+ OUT PUSB_INTERFACE *OutUsbInterface)
+{
+ PUSB_INTERFACE UsbInterface;
+ PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ ULONG PipeIndex;
+
+ // allocate interface handle
+ UsbInterface = (PUSB_INTERFACE)ExAllocatePool(NonPagedPool, sizeof(USB_INTERFACE) + (InterfaceDescriptor->bNumEndpoints - 1) * sizeof(USB_ENDPOINT));
+ if (!UsbInterface)
+ {
+ // failed to allocate memory
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ // zero descriptor
+ RtlZeroMemory(UsbInterface, sizeof(USB_INTERFACE) + (InterfaceDescriptor->bNumEndpoints - 1) * sizeof(USB_ENDPOINT));
+
+ // store handle
+ InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)UsbInterface;
+ InterfaceInfo->Class = InterfaceDescriptor->bInterfaceClass;
+ InterfaceInfo->SubClass = InterfaceDescriptor->bInterfaceSubClass;
+ InterfaceInfo->Protocol = InterfaceDescriptor->bInterfaceProtocol;
+ InterfaceInfo->Reserved = 0;
+
+
+ // init interface handle
+ UsbInterface->InterfaceDescriptor = InterfaceDescriptor;
+ InsertTailList(&m_ConfigurationDescriptors[ConfigurationIndex].InterfaceList, &UsbInterface->ListEntry);
+
+ // grab first endpoint descriptor
+ EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) (InterfaceDescriptor + 1);
+
+ // now copy all endpoint information
+ for(PipeIndex = 0; PipeIndex < InterfaceDescriptor->bNumEndpoints; PipeIndex++)
+ {
+ while(EndpointDescriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE)
+ {
+ // skip intermediate descriptors
+ if (EndpointDescriptor->bLength == 0 || EndpointDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
+ {
+ // bogus configuration descriptor
+ DPRINT1("[USBEHCI] Bogus descriptor found in InterfaceNumber %x Alternate %x EndpointIndex %x bLength %x bDescriptorType %x\n", InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, PipeIndex,
+ EndpointDescriptor->bLength, EndpointDescriptor->bDescriptorType);
+
+ // failed
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ // move to next descriptor
+ EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndpointDescriptor + EndpointDescriptor->bLength);
+ }
+
+ // store in interface info
+ RtlCopyMemory(&UsbInterface->EndPoints[PipeIndex].EndPointDescriptor, EndpointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
+
+ DPRINT("Configuration Descriptor %p Length %lu\n", m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor, m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor->wTotalLength);
+ DPRINT("EndpointDescriptor %p DescriptorType %x bLength %x\n", EndpointDescriptor, EndpointDescriptor->bDescriptorType, EndpointDescriptor->bLength);
+ DPRINT("EndpointDescriptorHandle %p bAddress %x bmAttributes %x\n",&UsbInterface->EndPoints[PipeIndex], UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress,
+ UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bmAttributes);
+
+ // copy pipe info
+ InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize;
+ InterfaceInfo->Pipes[PipeIndex].EndpointAddress = UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress;
+ InterfaceInfo->Pipes[PipeIndex].Interval = UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bInterval;
+ InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bmAttributes;
+ InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&UsbInterface->EndPoints[PipeIndex];
+
+ // move to next descriptor
+ EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndpointDescriptor + EndpointDescriptor->bLength);
+ }
+
+ if (OutUsbInterface)
+ {
+ // output result
+ *OutUsbInterface = UsbInterface;
+ }
+ return STATUS_SUCCESS;
+
+}
+
//----------------------------------------------------------------------------------------
NTSTATUS
@@ -924,7 +1012,7 @@
IN PUSBD_INTERFACE_INFORMATION InterfaceInfo,
OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle)
{
- ULONG InterfaceIndex, PipeIndex;
+ ULONG InterfaceIndex;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
NTSTATUS Status;
UCHAR bConfigurationValue = 0;
@@ -932,7 +1020,6 @@
UCHAR Found = FALSE;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PUSB_INTERFACE UsbInterface;
- PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
PLIST_ENTRY Entry;
if (ConfigurationDescriptor)
@@ -1029,61 +1116,11 @@
ASSERT(InterfaceInfo->NumberOfPipes == InterfaceDescriptor->bNumEndpoints);
// copy interface info
- InterfaceInfo->Class = InterfaceDescriptor->bInterfaceClass;
- InterfaceInfo->SubClass = InterfaceDescriptor->bInterfaceSubClass;
- InterfaceInfo->Protocol = InterfaceDescriptor->bInterfaceProtocol;
- InterfaceInfo->Reserved = 0;
-
- // allocate interface handle
- UsbInterface = (PUSB_INTERFACE)ExAllocatePool(NonPagedPool, sizeof(USB_INTERFACE) + (InterfaceInfo->NumberOfPipes - 1) * sizeof(USB_ENDPOINT));
- if (!UsbInterface)
+ Status = BuildInterfaceDescriptor(ConfigurationIndex, InterfaceDescriptor, InterfaceInfo, NULL);
+ if (!NT_SUCCESS(Status))
{
- // failed to allocate memory
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // store handle
- InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)UsbInterface;
-
- // init interface handle
- UsbInterface->InterfaceDescriptor = InterfaceDescriptor;
- InsertTailList(&m_ConfigurationDescriptors[ConfigurationIndex].InterfaceList, &UsbInterface->ListEntry);
-
- // grab first endpoint descriptor
- EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) (InterfaceDescriptor + 1);
-
- // now copy all endpoint information
- for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
- {
- while(EndpointDescriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE && EndpointDescriptor->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR))
- {
- // skip intermediate descriptors
- if (EndpointDescriptor->bLength == 0 || EndpointDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
- {
- // bogus configuration descriptor
- DPRINT1("[USBEHCI] Bogus descriptor found in InterfaceNumber %x Alternate %x EndpointIndex %x bLength %x bDescriptorType %x\n", InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, PipeIndex,
- EndpointDescriptor->bLength, EndpointDescriptor->bDescriptorType);
-
- // failed
- return STATUS_UNSUCCESSFUL;
- }
-
- // move to next descriptor
- EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndpointDescriptor + EndpointDescriptor->bLength);
- }
-
- // store in interface info
- RtlCopyMemory(&UsbInterface->EndPoints[PipeIndex].EndPointDescriptor, EndpointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
-
- // copy pipe info
- InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize;
- InterfaceInfo->Pipes[PipeIndex].EndpointAddress = UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress;
- InterfaceInfo->Pipes[PipeIndex].Interval = UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bInterval;
- InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)UsbInterface->EndPoints[PipeIndex].EndPointDescriptor.bmAttributes;
- InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&UsbInterface->EndPoints[PipeIndex];
-
- // move to next descriptor
- EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndpointDescriptor + EndpointDescriptor->bLength);
+ // failed
+ break;
}
// move offset
@@ -1108,6 +1145,7 @@
ULONG Index, ConfigurationIndex = 0, Found = FALSE;
PUSB_INTERFACE UsbInterface;
PLIST_ENTRY Entry;
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
// check if handle is valid
for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++)
@@ -1171,17 +1209,35 @@
if (!Found)
{
- // selected interface but interface not found
- // something is really wrong
- DPRINT1("[USBEHCI] Error: interface not found!!!\n");
- return STATUS_UNSUCCESSFUL;
+ // find interface descriptor
+ InterfaceDescriptor = USBD_ParseConfigurationDescriptor(m_ConfigurationDescriptors[ConfigurationIndex].ConfigurationDescriptor, InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting);
+ if (!InterfaceDescriptor)
+ {
+ DPRINT1("[LIBUSB] No such interface Alternate %x InterfaceNumber %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ // build interface descriptor
+ Status = BuildInterfaceDescriptor(ConfigurationIndex, InterfaceDescriptor, InterfaceInfo, &UsbInterface);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed
+ DPRINT1("[LIBUSB] Failed to build interface descriptor Status %x\n", Status);
+ return Status;
+ }
}
// assert on pipe length mismatch
- ASSERT(InterfaceInfo->NumberOfPipes == UsbInterface->InterfaceDescriptor->bNumEndpoints);
+ DPRINT1("NumberOfPipes %lu Endpoints %lu Length %lu\n", InterfaceInfo->NumberOfPipes, UsbInterface->InterfaceDescriptor->bNumEndpoints, InterfaceInfo->Length);
+
+ // sanity check
+ ASSERT(GET_USBD_INTERFACE_SIZE(UsbInterface->InterfaceDescriptor->bNumEndpoints) == InterfaceInfo->Length);
+
+ // store number of pipes
+ InterfaceInfo->NumberOfPipes = UsbInterface->InterfaceDescriptor->bNumEndpoints;
// copy pipe handles
- for(PipeIndex = 0; PipeIndex < min(InterfaceInfo->NumberOfPipes, UsbInterface->InterfaceDescriptor->bNumEndpoints); PipeIndex++)
+ for(PipeIndex = 0; PipeIndex < UsbInterface->InterfaceDescriptor->bNumEndpoints; PipeIndex++)
{
// copy pipe handle
DPRINT1("PipeIndex %lu\n", PipeIndex);
More information about the Ros-diffs
mailing list