[USBD]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Wed, 1 Feb 2012 16:59:13 +0000 (16:59 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Wed, 1 Feb 2012 16:59:13 +0000 (16:59 +0000)
- 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

drivers/usb/usbd/usbd.c

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