[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
This commit is contained in:
Michael Martin 2010-09-19 00:30:49 +00:00
parent cf913565c0
commit 3a615a70fb

View file

@ -5,6 +5,7 @@
* PURPOSE: Helper Library for USB
* PROGRAMMERS:
* Filip Navara <xnavara@volny.cz>
* Michael Martin <michael.martin@reactos.org>
*
*/
@ -33,6 +34,7 @@
#include <ntddk.h>
#include <usbdi.h>
#include <debug.h>
#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;
}