- In 2012 a long protected natural resource for bugs was shutdown due to popular usb device support demand
- Fix length check in USBD_ParseDescriptors. (PLONG)Descriptor + TotalLength is not the length of the configuration descriptor but twice the configuration descriptor
- Reset found variable in the loop. This fixes finding of interfaces which are not the first one in the configuration descriptor
- Again moving to next usb descriptor was broken. UsbDeviceDescriptor = UsbDeviceDescriptor + UsbDeviceDescriptor->bLength does not move to the next but to next XX descriprors specified by bLength
- Introduced in rev 17382 (14/08/2005)
 

svn path=/branches/usb-bringup-trunk/; revision=55370
This commit is contained in:
Johannes Anderwald 2012-02-01 16:59:13 +00:00
parent 55cb471b4f
commit aa485d63fd

View file

@ -32,9 +32,9 @@
* USBD_GetPdoRegistryParameters (implemented) * USBD_GetPdoRegistryParameters (implemented)
*/ */
#include <wdm.h> #include <ntddk.h>
#include <usbdi.h> #include <usbdi.h>
#include <debug.h>
#ifndef PLUGPLAY_REGKEY_DRIVER #ifndef PLUGPLAY_REGKEY_DRIVER
#define PLUGPLAY_REGKEY_DRIVER 2 #define PLUGPLAY_REGKEY_DRIVER 2
#endif #endif
@ -324,8 +324,8 @@ USBD_CreateConfigurationRequestEx(
InterfaceList[InterfaceCount].InterfaceDescriptor != NULL; InterfaceList[InterfaceCount].InterfaceDescriptor != NULL;
InterfaceCount++) InterfaceCount++)
{ {
UrbSize += FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes); UrbSize += sizeof(USBD_INTERFACE_INFORMATION);
UrbSize += (InterfaceList[InterfaceCount].InterfaceDescriptor->bNumEndpoints) * sizeof(USBD_PIPE_INFORMATION); UrbSize += (InterfaceList[InterfaceCount].InterfaceDescriptor->bNumEndpoints - 1) * sizeof(USBD_PIPE_INFORMATION);
} }
UrbSize += sizeof(URB) + sizeof(USBD_INTERFACE_INFORMATION); UrbSize += sizeof(URB) + sizeof(USBD_INTERFACE_INFORMATION);
@ -410,16 +410,39 @@ USBD_ParseDescriptors(
LONG DescriptorType LONG DescriptorType
) )
{ {
PUSB_COMMON_DESCRIPTOR PComDes = StartPosition; PUSB_COMMON_DESCRIPTOR CommonDescriptor;
while(PComDes) /* use start position */
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)StartPosition;
/* find next available descriptor */
while(CommonDescriptor)
{ {
if (PComDes >= (PUSB_COMMON_DESCRIPTOR) if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)DescriptorBuffer + TotalLength))
((PLONG)DescriptorBuffer + TotalLength) ) break; {
if (PComDes->bDescriptorType == DescriptorType) return PComDes; /* end reached */
if (PComDes->bLength == 0) break; DPRINT1("End reached %p\n", CommonDescriptor);
PComDes = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)PComDes + PComDes->bLength); return NULL;
}
DPRINT("CommonDescriptor Type %x Length %x\n", CommonDescriptor->bDescriptorType, CommonDescriptor->bLength);
/* is the requested one */
if (CommonDescriptor->bDescriptorType == DescriptorType)
{
/* it is */
return CommonDescriptor;
}
/* sanity check */
ASSERT(CommonDescriptor->bLength);
/* move to next descriptor */
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
} }
/* no descriptor found */
return NULL; return NULL;
} }
@ -438,45 +461,97 @@ USBD_ParseConfigurationDescriptorEx(
LONG InterfaceProtocol LONG InterfaceProtocol
) )
{ {
int x = 0; BOOLEAN Found;
PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDesc = StartPosition; PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
while(UsbInterfaceDesc) /* set to start position */
InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)StartPosition;
DPRINT("USBD_ParseConfigurationDescriptorEx\n");
DPRINT("ConfigurationDescriptor %p Length %lu\n", ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength);
DPRINT("CurrentOffset %p Offset %lu\n", StartPosition, ((ULONG_PTR)StartPosition - (ULONG_PTR)ConfigurationDescriptor));
while(InterfaceDescriptor)
{ {
UsbInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) /* get interface descriptor */
USBD_ParseDescriptors(ConfigurationDescriptor, InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, InterfaceDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE);
ConfigurationDescriptor->wTotalLength, if (!InterfaceDescriptor)
UsbInterfaceDesc, {
USB_INTERFACE_DESCRIPTOR_TYPE); /* no more descriptors available */
break;
}
if (!UsbInterfaceDesc) break; DPRINT("InterfaceDescriptor %p InterfaceNumber %x AlternateSetting %x Length %lu\n", InterfaceDescriptor, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bLength);
/* set found */
Found = TRUE;
/* is there an interface number provided */
if(InterfaceNumber != -1) if(InterfaceNumber != -1)
{ {
if(InterfaceNumber != UsbInterfaceDesc->bInterfaceNumber) x = 1; if(InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
{
/* interface number does not match */
Found = FALSE;
}
} }
/* is there an alternate setting provided */
if(AlternateSetting != -1) if(AlternateSetting != -1)
{ {
if(AlternateSetting != UsbInterfaceDesc->bAlternateSetting) x = 1; if(AlternateSetting != InterfaceDescriptor->bAlternateSetting)
{
/* alternate setting does not match */
Found = FALSE;
}
} }
/* match on interface class */
if(InterfaceClass != -1) if(InterfaceClass != -1)
{ {
if(InterfaceClass != UsbInterfaceDesc->bInterfaceClass) x = 1; if(InterfaceClass != InterfaceDescriptor->bInterfaceClass)
{
/* no match with interface class criteria */
Found = FALSE;
}
} }
/* match on interface sub class */
if(InterfaceSubClass != -1) if(InterfaceSubClass != -1)
{ {
if(InterfaceSubClass != UsbInterfaceDesc->bInterfaceSubClass) x = 1; if(InterfaceSubClass != InterfaceDescriptor->bInterfaceSubClass)
{
/* no interface sub class match */
Found = FALSE;
}
} }
/* interface protocol criteria */
if(InterfaceProtocol != -1) if(InterfaceProtocol != -1)
{ {
if(InterfaceProtocol != UsbInterfaceDesc->bInterfaceProtocol) x = 1; if(InterfaceProtocol != InterfaceDescriptor->bInterfaceProtocol)
{
/* no interface protocol match */
Found = FALSE;
}
} }
if (!x) return UsbInterfaceDesc; if (Found)
{
/* the choosen one */
return InterfaceDescriptor;
}
if (UsbInterfaceDesc->bLength == 0) break; /* sanity check */
UsbInterfaceDesc = UsbInterfaceDesc + UsbInterfaceDesc->bLength; ASSERT(InterfaceDescriptor->bLength);
/* move to next descriptor */
InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
} }
DPRINT("No Descriptor With InterfaceNumber %ld AlternateSetting %ld InterfaceClass %ld InterfaceSubClass %ld InterfaceProtocol %ld found\n", InterfaceNumber,
AlternateSetting, InterfaceClass, InterfaceSubClass, InterfaceProtocol);
return NULL; return NULL;
} }