From 3a615a70fb073bf321f5b07b8acebaacd0b5c4a7 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 19 Sep 2010 00:30:49 +0000 Subject: [PATCH] [usb/usbd] - Fix calculation bug in USBD_ParseDescriptors which caused descriptors to be skipped and all Parse functions to return bad information. - USBD_CreateConfigurationRequestEx: Fix calculation for the size of the URB. Dont copy the InterfaceList to the Urbs Interface member as they are not the same structures. Instead loop through each interface and endpoint to get the data needed for the Interface member of URB. - USBD_GetInterfaceLength: Add missing brackets for the FOR LOOP. The first descriptors length is part of the Length regardless of what it is. If bDescriptorType of USB_INTERFACE_DESCRIPTOR_TYPE is reached a second time then break from the loop, as the length calculation is done. svn path=/trunk/; revision=48810 --- reactos/drivers/usb/usbd/usbd.c | 81 +++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/reactos/drivers/usb/usbd/usbd.c b/reactos/drivers/usb/usbd/usbd.c index 2f5fac136a4..ce183c30819 100644 --- a/reactos/drivers/usb/usbd/usbd.c +++ b/reactos/drivers/usb/usbd/usbd.c @@ -5,6 +5,7 @@ * PURPOSE: Helper Library for USB * PROGRAMMERS: * Filip Navara + * Michael Martin * */ @@ -33,6 +34,7 @@ #include #include +#include #ifndef PLUGPLAY_REGKEY_DRIVER #define PLUGPLAY_REGKEY_DRIVER 2 #endif @@ -71,7 +73,7 @@ DllUnload(VOID) */ PVOID NTAPI USBD_Debug_GetHeap(ULONG Unknown1, POOL_TYPE PoolType, ULONG NumberOfBytes, - ULONG Tag) + ULONG Tag) { return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); } @@ -305,43 +307,56 @@ USBD_RegisterHcDeviceCapabilities(ULONG Unknown1, ULONG Unknown2, /* * @implemented - * FIXME: Test */ -PURB -NTAPI +PURB NTAPI USBD_CreateConfigurationRequestEx( PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSBD_INTERFACE_LIST_ENTRY InterfaceList ) { PURB Urb; - ULONG UrbSize; + ULONG UrbSize = 0; ULONG InterfaceCount; + ULONG InterfaceNumber, EndPointNumber; + PUSBD_INTERFACE_INFORMATION InterfaceInfo; for (InterfaceCount = 0; InterfaceList[InterfaceCount].InterfaceDescriptor != NULL; - ++InterfaceCount) - ; - /* Include the NULL entry */ - ++InterfaceCount; + InterfaceCount++) + { + UrbSize += sizeof(USBD_INTERFACE_INFORMATION); + UrbSize += (InterfaceList[InterfaceCount].InterfaceDescriptor->bNumEndpoints - 1) * sizeof(USBD_PIPE_INFORMATION); + } + + UrbSize += sizeof(URB) + sizeof(USBD_INTERFACE_INFORMATION); - UrbSize = sizeof(Urb->UrbSelectConfiguration) + - (InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY)); Urb = ExAllocatePool(NonPagedPool, UrbSize); - Urb->UrbSelectConfiguration.Hdr.Function = - URB_FUNCTION_SELECT_CONFIGURATION; - Urb->UrbSelectConfiguration.Hdr.Length = - sizeof(Urb->UrbSelectConfiguration); - Urb->UrbSelectConfiguration.ConfigurationDescriptor = - ConfigurationDescriptor; - memcpy((PVOID)&Urb->UrbSelectConfiguration.Interface, (PVOID)InterfaceList, - InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY)); + RtlZeroMemory(Urb, UrbSize); + Urb->UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION; + Urb->UrbSelectConfiguration.Hdr.Length = sizeof(Urb->UrbSelectConfiguration); + Urb->UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor; + + InterfaceInfo = &Urb->UrbSelectConfiguration.Interface; + for (InterfaceNumber = 0; InterfaceNumber < InterfaceCount; InterfaceNumber++) + { + InterfaceList[InterfaceNumber].Interface = InterfaceInfo; + InterfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION) + + ((InterfaceList[InterfaceNumber].InterfaceDescriptor->bNumEndpoints - 1) * sizeof(USBD_PIPE_INFORMATION)); + InterfaceInfo->InterfaceNumber = InterfaceList[InterfaceNumber].InterfaceDescriptor->bInterfaceNumber; + InterfaceInfo->AlternateSetting = InterfaceList[InterfaceNumber].InterfaceDescriptor->bAlternateSetting; + InterfaceInfo->NumberOfPipes = InterfaceList[InterfaceNumber].InterfaceDescriptor->bNumEndpoints; + for (EndPointNumber = 0; EndPointNumber < InterfaceInfo->NumberOfPipes; EndPointNumber++) + { + InterfaceInfo->Pipes[EndPointNumber].MaximumTransferSize = PAGE_SIZE; + } + InterfaceInfo = (PUSBD_INTERFACE_INFORMATION) ((ULONG_PTR)InterfaceInfo + InterfaceInfo->Length); + } return Urb; } /* - * @unimplemented + * @implemented */ PURB NTAPI USBD_CreateConfigurationRequest( @@ -349,11 +364,12 @@ USBD_CreateConfigurationRequest( PUSHORT Size ) { + /* WindowsXP returns NULL */ return NULL; } /* - * @unimplemented + * @implemented */ ULONG NTAPI USBD_GetInterfaceLength( @@ -363,18 +379,23 @@ USBD_GetInterfaceLength( { ULONG_PTR Current; PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor = InterfaceDescriptor; - ULONG Length = CurrentDescriptor->bLength; + ULONG Length = 0; + BOOLEAN InterfaceFound = FALSE; - // USB_ENDPOINT_DESCRIPTOR_TYPE - if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) + for (Current = (ULONG_PTR)CurrentDescriptor; + Current < (ULONG_PTR)BufferEnd; + Current += CurrentDescriptor->bLength) { - for (Current = (ULONG_PTR)CurrentDescriptor; - Current < (ULONG_PTR)BufferEnd; - Current += CurrentDescriptor->bLength) - CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current; - Length += CurrentDescriptor->bLength; + CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current; + if ((CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) && (InterfaceFound)) + break; + else if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) + InterfaceFound = TRUE; + + Length += CurrentDescriptor->bLength; } + return Length; } @@ -397,7 +418,7 @@ USBD_ParseDescriptors( ((PLONG)DescriptorBuffer + TotalLength) ) break; if (PComDes->bDescriptorType == DescriptorType) return PComDes; if (PComDes->bLength == 0) break; - PComDes = PComDes + PComDes->bLength; + PComDes = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)PComDes + PComDes->bLength); } return NULL; }