diff --git a/reactos/drivers/usb/usbccgp/descriptor.c b/reactos/drivers/usb/usbccgp/descriptor.c index 2a9e4953887..5841dd31d92 100644 --- a/reactos/drivers/usb/usbccgp/descriptor.c +++ b/reactos/drivers/usb/usbccgp/descriptor.c @@ -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); // diff --git a/reactos/drivers/usb/usbccgp/function.c b/reactos/drivers/usb/usbccgp/function.c index 2526cb0cba0..2c2f8c96653 100644 --- a/reactos/drivers/usb/usbccgp/function.c +++ b/reactos/drivers/usb/usbccgp/function.c @@ -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 diff --git a/reactos/drivers/usb/usbccgp/pdo.c b/reactos/drivers/usb/usbccgp/pdo.c index e7a52b8a1ac..2c247725486 100644 --- a/reactos/drivers/usb/usbccgp/pdo.c +++ b/reactos/drivers/usb/usbccgp/pdo.c @@ -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