- 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; 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 NTSTATUS
AllocateInterfaceDescriptorsArray( AllocateInterfaceDescriptorsArray(
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
OUT PUSB_INTERFACE_DESCRIPTOR **OutArray) OUT PUSB_INTERFACE_DESCRIPTOR **OutArray)
{ {
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PVOID CurrentPosition;
ULONG Count = 0; ULONG Count = 0;
PUSB_INTERFACE_DESCRIPTOR *Array; PUSB_INTERFACE_DESCRIPTOR *Array;
Count = CountInterfaceDescriptors(ConfigurationDescriptor);
ASSERT(Count);
// //
// allocate array // allocate array
// //
Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * Count); Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * ConfigurationDescriptor->bNumInterfaces);
if (!Array) if (!Array)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
// //
// enumerate all interfaces // enumerate all interfaces
// //
CurrentPosition = ConfigurationDescriptor;
Count = 0; Count = 0;
do do
{ {
// //
// find next descriptor // 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) if (!InterfaceDescriptor)
break; break;
@ -299,11 +255,6 @@ AllocateInterfaceDescriptorsArray(
Array[Count] = InterfaceDescriptor; Array[Count] = InterfaceDescriptor;
Count++; Count++;
//
// advance to next descriptor
//
CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
}while(TRUE); }while(TRUE);
// //

View file

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

View file

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