- Remove hacks
- Include alternate interface descriptors in the configuration descriptor

svn path=/trunk/; revision=55966
This commit is contained in:
Johannes Anderwald 2012-03-03 15:08:28 +00:00
parent 13daf0dd8a
commit 530db30b69
3 changed files with 82 additions and 102 deletions

View file

@ -220,76 +220,32 @@ USBCCGP_GetDescriptors(
return Status;
}
ULONG
CountInterfaceDescriptors(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PVOID CurrentPosition;
ULONG Count = 0;
//
// enumerate all interfaces
//
CurrentPosition = ConfigurationDescriptor;
do
{
//
// find next descriptor
//
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, CurrentPosition, -1, -1, -1, -1, -1);
if (!InterfaceDescriptor)
break;
//
// advance to next descriptor
//
CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
//
// increment descriptor count
//
Count++;
}while(TRUE);
//
// done
//
return Count;
}
NTSTATUS
AllocateInterfaceDescriptorsArray(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
OUT PUSB_INTERFACE_DESCRIPTOR **OutArray)
{
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PVOID CurrentPosition;
ULONG Count = 0;
PUSB_INTERFACE_DESCRIPTOR *Array;
Count = CountInterfaceDescriptors(ConfigurationDescriptor);
ASSERT(Count);
//
// allocate array
//
Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * Count);
Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * ConfigurationDescriptor->bNumInterfaces);
if (!Array)
return STATUS_INSUFFICIENT_RESOURCES;
//
// enumerate all interfaces
//
CurrentPosition = ConfigurationDescriptor;
Count = 0;
do
{
//
// find next descriptor
//
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, CurrentPosition, -1, -1, -1, -1, -1);
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, Count, 0, -1, -1, -1);
if (!InterfaceDescriptor)
break;
@ -299,11 +255,6 @@ AllocateInterfaceDescriptorsArray(
Array[Count] = InterfaceDescriptor;
Count++;
//
// advance to next descriptor
//
CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
}while(TRUE);
//

View file

@ -711,7 +711,6 @@ USBCCGP_EnumWithAudioLegacy(
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, FirstDescriptor = NULL;
PFDO_DEVICE_EXTENSION FDODeviceExtension;
NTSTATUS Status = STATUS_SUCCESS;
PVOID StartPosition;
//
// get device extension
@ -723,21 +722,15 @@ USBCCGP_EnumWithAudioLegacy(
//
// first check if all interfaces belong to the same audio class
//
StartPosition = FDODeviceExtension->ConfigurationDescriptor;
for(Index = 0; Index < CountInterfaceDescriptors(FDODeviceExtension->ConfigurationDescriptor); Index++)
for(Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++)
{
//
// get interface descriptor
//
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, StartPosition, -1, -1, -1, -1, -1);
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -1, -1, -1);
DPRINT1("Index %lu Descriptor %p\n", Index, InterfaceDescriptor);
ASSERT(InterfaceDescriptor);
//
// move to next descriptor
//
StartPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
if (InterfaceDescriptor->bInterfaceClass != 0x1)
{
//
@ -816,7 +809,7 @@ USBCCGP_EnumWithAudioLegacy(
//
// number of interfaces
//
FDODeviceExtension->FunctionDescriptor[0].NumberOfInterfaces = CountInterfaceDescriptors(FDODeviceExtension->ConfigurationDescriptor);
FDODeviceExtension->FunctionDescriptor[0].NumberOfInterfaces = FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces;
//
// store function count

View file

@ -460,6 +460,7 @@ USBCCGP_BuildConfigurationDescriptor(
PURB Urb;
PVOID Buffer;
PUCHAR BufferPtr;
UCHAR InterfaceNumber;
//
// get current stack location
@ -489,6 +490,7 @@ USBCCGP_BuildConfigurationDescriptor(
// get current interface descriptor
//
InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
//
// add to size and move to next descriptor
@ -513,10 +515,17 @@ USBCCGP_BuildConfigurationDescriptor(
{
if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
{
//
// reached next descriptor
//
break;
}
//
// reached next descriptor
// include alternate descriptor
//
break;
}
//
@ -557,6 +566,7 @@ USBCCGP_BuildConfigurationDescriptor(
// get current interface descriptor
//
InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
//
// copy descriptor and move to next descriptor
@ -582,10 +592,18 @@ USBCCGP_BuildConfigurationDescriptor(
{
if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
{
if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
{
//
// reached next descriptor
//
break;
}
//
// reached next descriptor
// include alternate descriptor
//
break;
DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bInterfaceNumber);
}
//
@ -645,7 +663,7 @@ USBCCGP_PDOSelectConfiguration(
PPDO_DEVICE_EXTENSION PDODeviceExtension;
PURB Urb, NewUrb;
PUSBD_INTERFACE_INFORMATION InterfaceInformation;
ULONG InterfaceInformationCount, Index, InterfaceIndex;
ULONG InterfaceIndex, Length;
PUSBD_INTERFACE_LIST_ENTRY Entry;
ULONG NeedSelect, FoundInterface;
NTSTATUS Status;
@ -677,28 +695,25 @@ USBCCGP_PDOSelectConfiguration(
return STATUS_SUCCESS;
}
//
// count interface information
//
InterfaceInformationCount = 0;
InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
do
{
InterfaceInformationCount++;
InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
}while((ULONG_PTR)InterfaceInformation < (ULONG_PTR)Urb + Urb->UrbSelectConfiguration.Hdr.Length);
// sanity checks
//C_ASSERT(sizeof(struct _URB_HEADER) == 16);
//C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
//C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
//C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
// available buffer length
Length = Urb->UrbSelectConfiguration.Hdr.Length - FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length);
//
// check all interfaces
//
InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
Index = 0;
Entry = NULL;
DPRINT("Count %x\n", InterfaceInformationCount);
do
{
DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting);
DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x Length %lu InterfaceInformation->Length %lu\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, Length, InterfaceInformation->Length);
ASSERT(InterfaceInformation->Length);
//
// search for the interface in the local interface list
//
@ -778,7 +793,19 @@ USBCCGP_PDOSelectConfiguration(
//
// interface is already selected
//
RtlCopyMemory(InterfaceInformation, Entry->Interface, min(InterfaceInformation->Length, Entry->Interface->Length));
ASSERT(Length >= Entry->Interface->Length);
RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
//
// adjust remaining buffer size
//
ASSERT(Entry->Interface->Length);
Length -= Entry->Interface->Length;
//
// move to next output interface information
//
InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
}
else
{
@ -811,36 +838,45 @@ USBCCGP_PDOSelectConfiguration(
Status = USBCCGP_SyncUrbRequest(PDODeviceExtension->NextDeviceObject, NewUrb);
DPRINT1("SelectInterface Status %x\n", Status);
//
// did it succeeed
//
if (NT_SUCCESS(Status))
if (!NT_SUCCESS(Status))
{
//
// update configuration info
//
ASSERT(Entry->Interface->Length == NewUrb->UrbSelectInterface.Interface.Length);
ASSERT(InterfaceInformation->Length == NewUrb->UrbSelectInterface.Interface.Length);
RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
//
// update provided interface information
//
RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
//
// failed
//
break;
}
//
// update configuration info
//
ASSERT(Entry->Interface->Length >= NewUrb->UrbSelectInterface.Interface.Length);
ASSERT(Length >= NewUrb->UrbSelectInterface.Interface.Length);
RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
//
// update provided interface information
//
ASSERT(Length >= Entry->Interface->Length);
RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
//
// decrement remaining buffer size
//
ASSERT(Entry->Interface->Length);
Length -= Entry->Interface->Length;
//
// adjust output buffer offset
//
InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
//
// free urb
//
FreeItem(NewUrb);
}
//
// move to next information
//
InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
Index++;
}while(Index < InterfaceInformationCount);
}while(Length);
//
// store configuration handle