return Status;
}
+NTSTATUS
+NTAPI
+USBCCGP_GetStringDescriptor(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG DescriptorLength,
+ IN UCHAR DescriptorIndex,
+ IN LANGID LanguageId,
+ OUT PVOID *OutDescriptor)
+{
+ NTSTATUS Status;
+ PUSB_STRING_DESCRIPTOR StringDescriptor;
+ ULONG Size;
+ PVOID Buffer;
+
+ // retrieve descriptor
+ Status = USBCCGP_GetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor);
+ if (!NT_SUCCESS(Status))
+ {
+ // failed
+ return Status;
+ }
+
+ // get descriptor structure
+ StringDescriptor = (PUSB_STRING_DESCRIPTOR)*OutDescriptor;
+
+ // sanity check
+ ASSERT(StringDescriptor->bLength < DescriptorLength - 2);
+
+ if (StringDescriptor->bLength == 2)
+ {
+ // invalid descriptor
+ FreeItem(StringDescriptor);
+ return STATUS_DEVICE_DATA_ERROR;
+ }
+
+ // calculate size
+ Size = StringDescriptor->bLength + sizeof(WCHAR);
+
+ // allocate buffer
+ Buffer = AllocateItem(NonPagedPool, Size);
+ if (!Buffer)
+ {
+ // no memory
+ FreeItem(StringDescriptor);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ // copy result
+ RtlCopyMemory(Buffer, StringDescriptor->bString, Size - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString));
+
+ // free buffer
+ FreeItem(StringDescriptor);
+
+ // store result
+ *OutDescriptor = (PVOID)Buffer;
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
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;
Array[Count] = InterfaceDescriptor;
Count++;
- //
- // advance to next descriptor
- //
- CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
-
}while(TRUE);
//
return STATUS_SUCCESS;
}
+VOID
+DumpFullConfigurationDescriptor(
+ IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
+ IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
+{
+ PUSB_COMMON_DESCRIPTOR Descriptor;
+
+ Descriptor = (PUSB_COMMON_DESCRIPTOR)ConfigurationDescriptor;
+
+ DbgPrint("Bogus ConfigurationDescriptor Found\n");
+ DbgPrint("InterfaceCount %x\n", ConfigurationDescriptor->bNumInterfaces);
+
+ do
+ {
+ if (((ULONG_PTR)Descriptor) >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
+ break;
+
+ DbgPrint("Descriptor Type %x Length %lu Offset %lu\n", Descriptor->bDescriptorType, Descriptor->bLength, ((ULONG_PTR)Descriptor - (ULONG_PTR)ConfigurationDescriptor));
+
+ // check for invalid descriptors
+ if (!Descriptor->bLength)
+ {
+ DbgPrint("Bogus Descriptor!!!\n");
+ break;
+ }
+
+ // advance to next descriptor
+ Descriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)Descriptor + Descriptor->bLength);
+
+ }while(TRUE);
+
+
+}
NTSTATUS
{
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
ULONG InterfaceIndex = 0;
- PVOID CurrentPosition;
ULONG DescriptorCount;
//
//
// count all interface descriptors
//
- DescriptorCount = CountInterfaceDescriptors(ConfigurationDescriptor);
+ DescriptorCount = ConfigurationDescriptor->bNumInterfaces;
//
// allocate array holding the interface descriptors
return STATUS_INSUFFICIENT_RESOURCES;
}
- CurrentPosition = ConfigurationDescriptor;
do
{
//
//
FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor;
FDODeviceExtension->InterfaceListCount++;
- CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
+ }
+ else
+ {
+ DumpConfigurationDescriptor(ConfigurationDescriptor);
+ DumpFullConfigurationDescriptor(FDODeviceExtension, ConfigurationDescriptor);
+
+ //
+ // see issue
+ // CORE-6574 Test 3 (USB Web Cam)
+ //
+ if (FDODeviceExtension->DeviceDescriptor && FDODeviceExtension->DeviceDescriptor->idVendor == 0x0458 && FDODeviceExtension->DeviceDescriptor->idProduct == 0x705f)
+ ASSERT(FALSE);
}
//
VOID
DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
{
- DPRINT1("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
- DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
- DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
- DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
- DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
- DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
- DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
- DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
- DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
+ DbgPrint("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
+ DbgPrint("bLength %x\n", ConfigurationDescriptor->bLength);
+ DbgPrint("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
+ DbgPrint("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
+ DbgPrint("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
+ DbgPrint("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
+ DbgPrint("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
+ DbgPrint("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
+ DbgPrint("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
}
NTSTATUS
//
// allocate urb
//
- Urb = AllocateItem(NonPagedPool, sizeof(struct _URB_SELECT_INTERFACE));
+ Urb = AllocateItem(NonPagedPool, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints));
if (!Urb)
{
//
//
UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bInterfaceNumber, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bAlternateSetting);
- //
- // copy interface information structure back - as offset for SelectConfiguration / SelectInterface request do differ
- //
- RtlCopyMemory(&Urb->UrbSelectInterface.Interface, DeviceExtension->InterfaceList[InterfaceIndex].Interface, DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length);
-
//
// now select the interface
//