Author: janderwald Date: Fri Jan 27 18:04:39 2012 New Revision: 55253
URL: http://svn.reactos.org/svn/reactos?rev=55253&view=rev Log: [USBCCGP] - Implement counting interface descriptors - Fix allocating interface list - Fix multiple bugs when copying interface information - Implement support function to dump function descriptor - Fix multiple bugs when creating compatible / hardware id string - Implement legacy enumerator, which will be used for HID composite devices - Implement special enumerator for audio devices - Display static GenericCompositeUSBDeviceString, needs to be read from registry in order to be MUI aware - Device initializes and device wizard pops up - Tested in XP with Ros USB stack + USB Audio Microphone
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c branches/usb-bringup-trunk/drivers/usb/usbccgp/misc.c branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c [iso-8859-1] Fri Jan 27 18:04:39 2012 @@ -162,6 +162,45 @@ 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 NTAPI USBCCGP_ScanConfigurationDescriptor( @@ -170,6 +209,8 @@ { PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; ULONG InterfaceIndex = 0; + PVOID CurrentPosition; + ULONG DescriptorCount;
// // sanity checks @@ -178,9 +219,14 @@ ASSERT(ConfigurationDescriptor->bNumInterfaces);
// + // count all interface descriptors + // + DescriptorCount = CountInterfaceDescriptors(ConfigurationDescriptor); + + // // allocate array holding the interface descriptors // - FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USB_CONFIGURATION_DESCRIPTOR) * (ConfigurationDescriptor->bNumInterfaces + 1)); + FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (DescriptorCount + 1)); if (!FDODeviceExtension->InterfaceList) { // @@ -189,12 +235,13 @@ return STATUS_INSUFFICIENT_RESOURCES; }
+ CurrentPosition = ConfigurationDescriptor; do { // // parse configuration descriptor // - InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, 0, -1, -1, -1); + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, CurrentPosition, -1, -1, -1, -1, -1); if (InterfaceDescriptor) { // @@ -202,6 +249,7 @@ // FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor; FDODeviceExtension->InterfaceListCount++; + CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); }
// @@ -209,7 +257,7 @@ // InterfaceIndex++;
- }while(InterfaceIndex < ConfigurationDescriptor->bNumInterfaces); + }while(InterfaceIndex < DescriptorCount);
// // sanity check @@ -347,13 +395,12 @@ // get interface information // InterfaceInformation = &Urb->UrbSelectConfiguration.Interface; - for(Index = 0; Index < DeviceExtension->InterfaceListCount; Index++) { // // allocate buffer to store interface information // - DeviceExtension->InterfaceList[Index].Interface = AllocateItem(NonPagedPool, InterfaceInformation[Index].Length); + DeviceExtension->InterfaceList[Index].Interface = AllocateItem(NonPagedPool, InterfaceInformation->Length); if (!DeviceExtension->InterfaceList[Index].Interface) { // @@ -366,7 +413,13 @@ // copy interface information // RtlCopyMemory(DeviceExtension->InterfaceList[Index].Interface, InterfaceInformation, InterfaceInformation->Length); - } + + // + // move to next interface + // + InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length); + } +
// // store pipe handle
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] Fri Jan 27 18:04:39 2012 @@ -138,7 +138,6 @@ // FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- // // get current irp stack location // @@ -376,6 +375,7 @@ // ASSERT(FDODeviceExtension->FunctionDescriptorCount); ASSERT(FDODeviceExtension->FunctionDescriptor); + DumpFunctionDescriptor(FDODeviceExtension->FunctionDescriptor, FDODeviceExtension->FunctionDescriptorCount);
// // now create the pdo
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c [iso-8859-1] Fri Jan 27 18:04:39 2012 @@ -411,7 +411,10 @@
// copy description RtlCopyMemory(DescriptionBuffer, Buffer, Index * sizeof(WCHAR)); - RtlInitUnicodeString(&FunctionDescriptor->HardwareId, DescriptionBuffer); + FunctionDescriptor->HardwareId.Buffer = DescriptionBuffer; + FunctionDescriptor->HardwareId.Length = Index * sizeof(WCHAR); + FunctionDescriptor->HardwareId.MaximumLength = (Index + 1) * sizeof(WCHAR); +
// // now init the compatible id @@ -431,9 +434,10 @@ }
// copy description - // copy description RtlCopyMemory(DescriptionBuffer, Buffer, Index * sizeof(WCHAR)); - RtlInitUnicodeString(&FunctionDescriptor->CompatibleId, DescriptionBuffer); + FunctionDescriptor->CompatibleId.Buffer = DescriptionBuffer; + FunctionDescriptor->CompatibleId.Length = Index * sizeof(WCHAR); + FunctionDescriptor->CompatibleId.MaximumLength = (Index + 1) * sizeof(WCHAR);
// // done @@ -506,23 +510,319 @@ return Status; }
+NTSTATUS +USBCCG_InitIdsWithInterfaceDescriptor( + IN PFDO_DEVICE_EXTENSION FDODeviceExtension, + IN PUSB_INTERFACE_DESCRIPTOR Descriptor, + OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor) +{ + ULONG Index; + WCHAR Buffer[200]; + LPWSTR DescriptionBuffer; + NTSTATUS Status; + + // + // now init interface description + // + if (Descriptor->iInterface) + { + // + // get interface description + // + Status = USBCCGP_GetDescriptor(FDODeviceExtension->NextDeviceObject, + USB_STRING_DESCRIPTOR_TYPE, + 100 * sizeof(WCHAR), + Descriptor->iInterface, + 0x0409, //FIXME + (PVOID*)&DescriptionBuffer); + if (!NT_SUCCESS(Status)) + { + // + // no description + // + RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, L""); + } + else + { + // + // init description + // + RtlInitUnicodeString(&FunctionDescriptor->FunctionDescription, DescriptionBuffer); + } + DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor->FunctionDescription); + } + + + + // + // now init hardware id + // + Index = swprintf(Buffer, L"USB\VID_%04x&PID_%04x&Rev_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor, + FDODeviceExtension->DeviceDescriptor->idProduct, + FDODeviceExtension->DeviceDescriptor->bcdDevice, + Descriptor->bInterfaceNumber) + 1; + Index += swprintf(&Buffer[Index], L"USB\VID_%04x&PID_%04x&MI_%02x", FDODeviceExtension->DeviceDescriptor->idVendor, + FDODeviceExtension->DeviceDescriptor->idProduct, + Descriptor->bInterfaceNumber) + 1; + + // allocate result buffer + DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR)); + if (!DescriptionBuffer) + { + // + // failed to allocate memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // copy description + RtlCopyMemory(DescriptionBuffer, Buffer, Index * sizeof(WCHAR)); + FunctionDescriptor->HardwareId.Buffer = DescriptionBuffer; + FunctionDescriptor->HardwareId.Length = Index * sizeof(WCHAR); + FunctionDescriptor->HardwareId.MaximumLength = (Index + 1) * sizeof(WCHAR); + + + // + // now init the compatible id + // + Index = swprintf(Buffer, L"USB\Class_%02x&SubClass_%02x&Prot_%02x", Descriptor->bInterfaceClass, Descriptor->bInterfaceSubClass, Descriptor->bInterfaceProtocol) + 1; + Index += swprintf(&Buffer[Index], L"USB\Class_%04x&SubClass_%04x", Descriptor->bInterfaceClass, Descriptor->bInterfaceSubClass) + 1; + Index += swprintf(&Buffer[Index], L"USB\Class_%04x", Descriptor->bInterfaceClass) + 1; + + // allocate result buffer + DescriptionBuffer = AllocateItem(NonPagedPool, (Index + 1) * sizeof(WCHAR)); + if (!DescriptionBuffer) + { + // + // failed to allocate memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // copy description + RtlCopyMemory(DescriptionBuffer, Buffer, Index * sizeof(WCHAR)); + FunctionDescriptor->CompatibleId.Buffer = DescriptionBuffer; + FunctionDescriptor->CompatibleId.Length = Index * sizeof(WCHAR); + FunctionDescriptor->CompatibleId.MaximumLength = (Index + 1) * sizeof(WCHAR); +} + + +NTSTATUS +USBCCGP_LegacyEnum( + IN PDEVICE_OBJECT DeviceObject) +{ + ULONG Index; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + NTSTATUS Status = STATUS_SUCCESS; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // sanity check + // + ASSERT(FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces); + + // + // allocate function array + // + FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR) * FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces); + if (!FDODeviceExtension->FunctionDescriptor) + { + // + // no memory + // + DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor %lu\n", FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // init function descriptors + // + for(Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++) + { + // get interface descriptor + InterfaceDescriptor = USBD_ParseConfigurationDescriptor(FDODeviceExtension->ConfigurationDescriptor, Index, 0); + if (InterfaceDescriptor == NULL) + { + // + // failed to find interface descriptor + // + DPRINT1("[USBCCGP] Failed to find interface descriptor index %lu\n", Index); + return STATUS_UNSUCCESSFUL; + } + + // + // init function descriptor + // + FDODeviceExtension->FunctionDescriptor[Index].FunctionNumber = Index; + FDODeviceExtension->FunctionDescriptor[Index].NumberOfInterfaces = 1; + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * 1); + if (!FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // store interface descriptor + // + FDODeviceExtension->FunctionDescriptor[Index].InterfaceDescriptorList[0] = InterfaceDescriptor; + + // + // now init the device ids + // + Status = USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension, InterfaceDescriptor, &FDODeviceExtension->FunctionDescriptor[Index]); + if (!NT_SUCCESS(Status)) + { + // + // failed to init ids + // + DPRINT1("[USBCCGP] Failed to init ids with %x\n", Status); + return Status; + } + + // + // store function count + // + FDODeviceExtension->FunctionDescriptorCount++; + } + + // + // done + // + return Status; +} + +NTSTATUS +USBCCGP_EnumWithUnionFunctionDescriptors( + IN PDEVICE_OBJECT DeviceObject) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +}
NTSTATUS USBCCGP_EnumWithAudioLegacy( IN PDEVICE_OBJECT DeviceObject) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -USBCCGP_EnumWithUnionFunctionDescriptors( - IN PDEVICE_OBJECT DeviceObject) -{ - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - + ULONG Index; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, FirstDescriptor = NULL; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + NTSTATUS Status = STATUS_SUCCESS; + + // + // get device extension + // + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + + // + // first check if all interfaces belong to the same audio class + // + for(Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++) + { + // + // get interface descriptor + // + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, -1, -1, -1, -1); + if (InterfaceDescriptor->bInterfaceClass != 0x1) + { + // + // collection contains non audio class + // + return STATUS_UNSUCCESSFUL; + } + + if (FirstDescriptor == NULL) + { + // + // store interface descriptor + // + FirstDescriptor = InterfaceDescriptor; + continue; + } + + if (FirstDescriptor->bInterfaceSubClass == InterfaceDescriptor->bInterfaceSubClass) + { + // + // interface subclass must be different from the first interface + // + return STATUS_UNSUCCESSFUL; + } + } + + // + // this is an composite audio device + // + DPRINT1("[USBCCGP] Audio Composite Device detected\n"); + + // + // audio interfaces are all grouped into one single function + // + FDODeviceExtension->FunctionDescriptor = AllocateItem(NonPagedPool, sizeof(USBC_FUNCTION_DESCRIPTOR)); + if (!FDODeviceExtension->FunctionDescriptor) + { + // + // no memory + // + DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // init function number + // + FDODeviceExtension->FunctionDescriptor[0].FunctionNumber = 0; + + // + // FIXME: how many interfaces should be stored? + // + + FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * 1); + if (!FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // store interface descriptor + // + FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList[0] = InterfaceDescriptor; + + // + // now init the device ids + // + Status = USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension, InterfaceDescriptor, &FDODeviceExtension->FunctionDescriptor[0]); + if (!NT_SUCCESS(Status)) + { + // + // failed to init ids + // + DPRINT1("[USBCCGP] Failed to init ids with %x\n", Status); + return Status; + } + + // + // store function count + // + FDODeviceExtension->FunctionDescriptorCount = 1; + + // + // done + // + return STATUS_SUCCESS; +}
NTSTATUS USBCCGP_EnumerateFunctions( @@ -561,6 +861,7 @@ return Status; }
+#if 0 // // try with union function descriptors // @@ -572,9 +873,22 @@ // return Status; } +#endif
// // try with legacy audio methods // - return USBCCGP_EnumWithAudioLegacy(DeviceObject); -} + Status = USBCCGP_EnumWithAudioLegacy(DeviceObject); + if (NT_SUCCESS(Status)) + { + // + // succeeded + // + return Status; + } + + // + // try with legacy enumeration + // + return USBCCGP_LegacyEnum(DeviceObject); +}
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/misc.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/misc.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/misc.c [iso-8859-1] Fri Jan 27 18:04:39 2012 @@ -195,3 +195,23 @@ ExFreePoolWithTag(Item, USBCCPG_TAG); }
+VOID +DumpFunctionDescriptor( + IN PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor, + IN ULONG FunctionDescriptorCount) +{ + ULONG Index; + + + DPRINT1("FunctionCount %lu\n", FunctionDescriptorCount); + for(Index = 0; Index < FunctionDescriptorCount; Index++) + { + DPRINT1("Function %lu\n", Index); + DPRINT1("FunctionNumber %lu\n", FunctionDescriptor[Index].FunctionNumber); + DPRINT1("HardwareId %wZ\n", &FunctionDescriptor[Index].HardwareId); + DPRINT1("CompatibleId %wZ\n", &FunctionDescriptor[Index].CompatibleId); + DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor[Index].FunctionDescription); + DPRINT1("NumInterfaces %lu\n", FunctionDescriptor[Index].NumberOfInterfaces); + } + +}
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] Fri Jan 27 18:04:39 2012 @@ -18,7 +18,7 @@ { LPWSTR Buffer; PPDO_DEVICE_EXTENSION PDODeviceExtension; - + LPWSTR GenericString = L"Composite USB Device"; // // get device extension // @@ -53,7 +53,18 @@ // FIXME use GenericCompositeUSBDeviceString // UNIMPLEMENTED - return Irp->IoStatus.Status; + Buffer = AllocateItem(PagedPool, (wcslen(GenericString) + 1) * sizeof(WCHAR)); + if (!Buffer) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlCopyMemory(Buffer, GenericString, (wcslen(GenericString) + 1) * sizeof(WCHAR)); + Irp->IoStatus.Information = (ULONG_PTR)Buffer; + + return STATUS_SUCCESS; }
NTSTATUS @@ -145,7 +156,7 @@ // // FIXME append interface id // - ASSERT(FALSE); + UNIMPLEMENTED return Status; } else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] Fri Jan 27 18:04:39 2012 @@ -95,6 +95,11 @@ FreeItem( IN PVOID Item);
+VOID +DumpFunctionDescriptor( + IN PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor, + IN ULONG FunctionDescriptorCount); + /* fdo.c */
NTSTATUS