2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbccgp/descriptor.c
5 * PURPOSE: USB device driver.
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
18 USBCCGP_QueryInterface(
19 IN PDEVICE_OBJECT DeviceObject
,
20 OUT PUSBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface
)
25 IO_STATUS_BLOCK IoStatus
;
26 PIO_STACK_LOCATION Stack
;
31 /* Initialize event */
32 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
35 RtlZeroMemory(BusInterface
, sizeof(USBC_DEVICE_CONFIGURATION_INTERFACE_V1
));
36 BusInterface
->Version
= USBC_DEVICE_CONFIGURATION_INTERFACE_VERSION_1
;
37 BusInterface
->Size
= sizeof(USBC_DEVICE_CONFIGURATION_INTERFACE_V1
);
40 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
56 return STATUS_INSUFFICIENT_RESOURCES
;
62 Stack
= IoGetNextIrpStackLocation(Irp
);
63 Stack
->MajorFunction
= IRP_MJ_PNP
;
64 Stack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
65 Stack
->Parameters
.QueryInterface
.Size
= sizeof(BUS_INTERFACE_STANDARD
);
66 Stack
->Parameters
.QueryInterface
.InterfaceType
= (LPGUID
)&USB_BUS_INTERFACE_USBC_CONFIGURATION_GUID
;
67 Stack
->Parameters
.QueryInterface
.Version
= 2;
68 Stack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)&BusInterface
;
69 Stack
->Parameters
.QueryInterface
.InterfaceSpecificData
= NULL
;
70 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
75 Status
= IoCallDriver(DeviceObject
, Irp
);
78 // did operation complete
80 if (Status
== STATUS_PENDING
)
83 // wait for completion
85 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
90 Status
= IoStatus
.Status
;
97 USBCCGP_CustomEnumWithInterface(
98 IN PDEVICE_OBJECT DeviceObject
)
100 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
101 ULONG FunctionDescriptorBufferLength
= 0;
103 PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptorBuffer
= NULL
;
106 // get device extension
108 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
109 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
111 if (FDODeviceExtension
->BusInterface
.StartDeviceCallback
== NULL
)
116 return STATUS_NOT_SUPPORTED
;
122 Status
= FDODeviceExtension
->BusInterface
.StartDeviceCallback(FDODeviceExtension
->DeviceDescriptor
,
123 FDODeviceExtension
->ConfigurationDescriptor
,
124 &FunctionDescriptorBuffer
,
125 &FunctionDescriptorBufferLength
,
127 FDODeviceExtension
->PhysicalDeviceObject
);
129 DPRINT("USBCCGP_CustomEnumWithInterface Status %lx\n", Status
);
130 if (!NT_SUCCESS(Status
))
138 DPRINT("FunctionDescriptorBufferLength %lu\n", FunctionDescriptorBufferLength
);
139 DPRINT("FunctionDescriptorBuffer %p\n", FunctionDescriptorBuffer
);
142 // assume length % function buffer size
144 ASSERT(FunctionDescriptorBufferLength
);
145 ASSERT(FunctionDescriptorBufferLength
% sizeof(USBC_FUNCTION_DESCRIPTOR
) == 0);
150 FDODeviceExtension
->FunctionDescriptor
= FunctionDescriptorBuffer
;
151 FDODeviceExtension
->FunctionDescriptorCount
= FunctionDescriptorBufferLength
/ sizeof(USBC_FUNCTION_DESCRIPTOR
);
156 return STATUS_SUCCESS
;
160 USBCCGP_CountAssociationDescriptors(
161 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
163 PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor
;
170 Offset
= (PUCHAR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->bLength
;
171 End
= (PUCHAR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
;
176 // get association descriptor
178 Descriptor
= (PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR
)Offset
;
180 if (Descriptor
->bLength
== sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR
) && Descriptor
->bDescriptorType
== USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
189 // move to next descriptor
191 Offset
+= Descriptor
->bLength
;
200 PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR
201 USBCCGP_GetAssociationDescriptorAtIndex(
202 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
205 PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor
;
212 Offset
= (PUCHAR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->bLength
;
213 End
= (PUCHAR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
;
218 // get association descriptor
220 Descriptor
= (PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR
)Offset
;
222 if (Descriptor
->bLength
== sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR
) && Descriptor
->bDescriptorType
== USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
233 // not the searched one
239 // move to next descriptor
241 Offset
+= Descriptor
->bLength
;
245 // failed to find descriptor at the specified index
251 USBCCGP_InitInterfaceListOfFunctionDescriptor(
252 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
253 IN PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR AssociationDescriptor
,
254 OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor
)
256 PUSB_INTERFACE_DESCRIPTOR Descriptor
;
263 Offset
= (PUCHAR
)AssociationDescriptor
+ AssociationDescriptor
->bLength
;
264 End
= (PUCHAR
)ConfigurationDescriptor
+ ConfigurationDescriptor
->wTotalLength
;
269 // get association descriptor
271 Descriptor
= (PUSB_INTERFACE_DESCRIPTOR
)Offset
;
273 if (Descriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
) && Descriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
276 // store interface descriptor
278 FunctionDescriptor
->InterfaceDescriptorList
[Count
] = Descriptor
;
281 if (Count
== AssociationDescriptor
->bInterfaceCount
)
284 // got all interfaces
286 return STATUS_SUCCESS
;
290 if (Descriptor
->bLength
== sizeof(USB_INTERFACE_ASSOCIATION_DESCRIPTOR
) && Descriptor
->bDescriptorType
== USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE
)
293 // WTF? a association descriptor which overlaps the next association descriptor
295 DPRINT1("Invalid association descriptor\n");
297 return STATUS_UNSUCCESSFUL
;
301 // move to next descriptor
303 Offset
+= Descriptor
->bLength
;
307 // invalid association descriptor
309 DPRINT1("Invalid association descriptor\n");
310 return STATUS_UNSUCCESSFUL
;
314 USBCCGP_InitFunctionDescriptor(
315 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
316 IN ULONG FunctionNumber
,
317 OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor
)
319 PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor
;
321 LPWSTR DescriptionBuffer
;
325 // init function number
326 FunctionDescriptor
->FunctionNumber
= (UCHAR
)FunctionNumber
;
328 // get association descriptor
329 Descriptor
= USBCCGP_GetAssociationDescriptorAtIndex(FDODeviceExtension
->ConfigurationDescriptor
, FunctionNumber
);
332 // store number interfaces
333 FunctionDescriptor
->NumberOfInterfaces
= Descriptor
->bInterfaceCount
;
335 // allocate array for interface count
336 FunctionDescriptor
->InterfaceDescriptorList
= AllocateItem(NonPagedPool
, sizeof(PUSB_INTERFACE_DESCRIPTOR
) * Descriptor
->bInterfaceCount
);
337 if (!FunctionDescriptor
->InterfaceDescriptorList
)
342 return STATUS_INSUFFICIENT_RESOURCES
;
345 // init interface list
346 Status
= USBCCGP_InitInterfaceListOfFunctionDescriptor(FDODeviceExtension
->ConfigurationDescriptor
, Descriptor
, FunctionDescriptor
);
347 if (!NT_SUCCESS(Status
))
356 // now init interface description
358 if (Descriptor
->iFunction
)
361 // get interface description
363 Status
= USBCCGP_GetStringDescriptor(FDODeviceExtension
->NextDeviceObject
,
365 Descriptor
->iFunction
,
367 (PVOID
*)&DescriptionBuffer
);
368 if (!NT_SUCCESS(Status
))
373 RtlInitUnicodeString(&FunctionDescriptor
->FunctionDescription
, L
"");
380 RtlInitUnicodeString(&FunctionDescriptor
->FunctionDescription
, DescriptionBuffer
);
382 DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor
->FunctionDescription
);
386 // now init hardware id
388 Index
= swprintf(Buffer
, L
"USB\\VID_%04x&PID_%04x&Rev_%04x&MI_%02x", FDODeviceExtension
->DeviceDescriptor
->idVendor
,
389 FDODeviceExtension
->DeviceDescriptor
->idProduct
,
390 FDODeviceExtension
->DeviceDescriptor
->bcdDevice
,
391 Descriptor
->bFirstInterface
) + 1;
392 Index
+= swprintf(&Buffer
[Index
], L
"USB\\VID_%04x&PID_%04x&MI_%02x", FDODeviceExtension
->DeviceDescriptor
->idVendor
,
393 FDODeviceExtension
->DeviceDescriptor
->idProduct
,
394 Descriptor
->bFirstInterface
) + 1;
396 // allocate result buffer
397 DescriptionBuffer
= AllocateItem(NonPagedPool
, (Index
+ 1) * sizeof(WCHAR
));
398 if (!DescriptionBuffer
)
401 // failed to allocate memory
403 return STATUS_INSUFFICIENT_RESOURCES
;
407 RtlCopyMemory(DescriptionBuffer
, Buffer
, (Index
+ 1) * sizeof(WCHAR
));
408 FunctionDescriptor
->HardwareId
.Buffer
= DescriptionBuffer
;
409 FunctionDescriptor
->HardwareId
.Length
= Index
* sizeof(WCHAR
);
410 FunctionDescriptor
->HardwareId
.MaximumLength
= (Index
+ 1) * sizeof(WCHAR
);
413 // now init the compatible id
415 Index
= swprintf(Buffer
, L
"USB\\Class_%02x&SubClass_%02x&Prot_%02x", Descriptor
->bFunctionClass
, Descriptor
->bFunctionSubClass
, Descriptor
->bFunctionProtocol
) + 1;
416 Index
+= swprintf(&Buffer
[Index
], L
"USB\\Class_%02x&SubClass_%02x", Descriptor
->bFunctionClass
, Descriptor
->bFunctionSubClass
) + 1;
417 Index
+= swprintf(&Buffer
[Index
], L
"USB\\Class_%02x", Descriptor
->bFunctionClass
) + 1;
419 // allocate result buffer
420 DescriptionBuffer
= AllocateItem(NonPagedPool
, (Index
+ 1) * sizeof(WCHAR
));
421 if (!DescriptionBuffer
)
424 // failed to allocate memory
426 return STATUS_INSUFFICIENT_RESOURCES
;
430 RtlCopyMemory(DescriptionBuffer
, Buffer
, (Index
+ 1) * sizeof(WCHAR
));
431 FunctionDescriptor
->CompatibleId
.Buffer
= DescriptionBuffer
;
432 FunctionDescriptor
->CompatibleId
.Length
= Index
* sizeof(WCHAR
);
433 FunctionDescriptor
->CompatibleId
.MaximumLength
= (Index
+ 1) * sizeof(WCHAR
);
438 return STATUS_SUCCESS
;
442 USBCCGP_EnumWithAssociationDescriptor(
443 IN PDEVICE_OBJECT DeviceObject
)
445 ULONG DescriptorCount
, Index
;
446 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
447 NTSTATUS Status
= STATUS_SUCCESS
;
450 // get device extension
452 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
453 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
456 // count association descriptors
458 DescriptorCount
= USBCCGP_CountAssociationDescriptors(FDODeviceExtension
->ConfigurationDescriptor
);
459 if (!DescriptorCount
)
462 // no descriptors found
464 return STATUS_NOT_SUPPORTED
;
468 // allocate function descriptor array
470 FDODeviceExtension
->FunctionDescriptor
= AllocateItem(NonPagedPool
, sizeof(USBC_FUNCTION_DESCRIPTOR
) * DescriptorCount
);
471 if (!FDODeviceExtension
->FunctionDescriptor
)
476 DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count %x\n", DescriptorCount
);
477 return STATUS_INSUFFICIENT_RESOURCES
;
480 for (Index
= 0; Index
< DescriptorCount
; Index
++)
483 // init function descriptors
485 Status
= USBCCGP_InitFunctionDescriptor(FDODeviceExtension
, Index
, &FDODeviceExtension
->FunctionDescriptor
[Index
]);
486 if (!NT_SUCCESS(Status
))
496 // store function descriptor count
498 FDODeviceExtension
->FunctionDescriptorCount
= DescriptorCount
;
507 USBCCG_InitIdsWithInterfaceDescriptor(
508 IN PFDO_DEVICE_EXTENSION FDODeviceExtension
,
509 IN PUSB_INTERFACE_DESCRIPTOR Descriptor
,
510 IN ULONG FunctionIndex
,
511 OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor
)
515 LPWSTR DescriptionBuffer
;
519 // now init interface description
521 if (Descriptor
->iInterface
)
524 // get interface description
526 Status
= USBCCGP_GetStringDescriptor(FDODeviceExtension
->NextDeviceObject
,
528 Descriptor
->iInterface
,
530 (PVOID
*)&DescriptionBuffer
);
531 if (!NT_SUCCESS(Status
))
536 RtlInitUnicodeString(&FunctionDescriptor
->FunctionDescription
, L
"");
543 RtlInitUnicodeString(&FunctionDescriptor
->FunctionDescription
, DescriptionBuffer
);
545 DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor
->FunctionDescription
);
550 // now init hardware id
552 Index
= swprintf(Buffer
, L
"USB\\VID_%04x&PID_%04x&Rev_%04x&MI_%02x", FDODeviceExtension
->DeviceDescriptor
->idVendor
,
553 FDODeviceExtension
->DeviceDescriptor
->idProduct
,
554 FDODeviceExtension
->DeviceDescriptor
->bcdDevice
,
556 Index
+= swprintf(&Buffer
[Index
], L
"USB\\VID_%04x&PID_%04x&MI_%02x", FDODeviceExtension
->DeviceDescriptor
->idVendor
,
557 FDODeviceExtension
->DeviceDescriptor
->idProduct
,
560 // allocate result buffer
561 DescriptionBuffer
= AllocateItem(NonPagedPool
, (Index
+ 1) * sizeof(WCHAR
));
562 if (!DescriptionBuffer
)
565 // failed to allocate memory
567 return STATUS_INSUFFICIENT_RESOURCES
;
571 RtlCopyMemory(DescriptionBuffer
, Buffer
, (Index
+ 1) * sizeof(WCHAR
));
572 FunctionDescriptor
->HardwareId
.Buffer
= DescriptionBuffer
;
573 FunctionDescriptor
->HardwareId
.Length
= Index
* sizeof(WCHAR
);
574 FunctionDescriptor
->HardwareId
.MaximumLength
= (Index
+ 1) * sizeof(WCHAR
);
577 // now init the compatible id
579 Index
= swprintf(Buffer
, L
"USB\\Class_%02x&SubClass_%02x&Prot_%02x", Descriptor
->bInterfaceClass
, Descriptor
->bInterfaceSubClass
, Descriptor
->bInterfaceProtocol
) + 1;
580 Index
+= swprintf(&Buffer
[Index
], L
"USB\\Class_%02x&SubClass_%02x", Descriptor
->bInterfaceClass
, Descriptor
->bInterfaceSubClass
) + 1;
581 Index
+= swprintf(&Buffer
[Index
], L
"USB\\Class_%02x", Descriptor
->bInterfaceClass
) + 1;
583 // allocate result buffer
584 DescriptionBuffer
= AllocateItem(NonPagedPool
, (Index
+ 1) * sizeof(WCHAR
));
585 if (!DescriptionBuffer
)
588 // failed to allocate memory
590 return STATUS_INSUFFICIENT_RESOURCES
;
594 RtlCopyMemory(DescriptionBuffer
, Buffer
, (Index
+ 1) * sizeof(WCHAR
));
595 FunctionDescriptor
->CompatibleId
.Buffer
= DescriptionBuffer
;
596 FunctionDescriptor
->CompatibleId
.Length
= Index
* sizeof(WCHAR
);
597 FunctionDescriptor
->CompatibleId
.MaximumLength
= (Index
+ 1) * sizeof(WCHAR
);
602 return STATUS_SUCCESS
;
608 IN PDEVICE_OBJECT DeviceObject
)
611 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
612 NTSTATUS Status
= STATUS_SUCCESS
;
613 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
616 // get device extension
618 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
619 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
624 ASSERT(FDODeviceExtension
->ConfigurationDescriptor
->bNumInterfaces
);
627 // allocate function array
629 FDODeviceExtension
->FunctionDescriptor
= AllocateItem(NonPagedPool
, sizeof(USBC_FUNCTION_DESCRIPTOR
) * FDODeviceExtension
->ConfigurationDescriptor
->bNumInterfaces
);
630 if (!FDODeviceExtension
->FunctionDescriptor
)
635 DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor %lu\n", FDODeviceExtension
->ConfigurationDescriptor
->bNumInterfaces
);
636 return STATUS_INSUFFICIENT_RESOURCES
;
640 // init function descriptors
642 for (Index
= 0; Index
< FDODeviceExtension
->ConfigurationDescriptor
->bNumInterfaces
; Index
++)
644 // get interface descriptor
645 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(FDODeviceExtension
->ConfigurationDescriptor
, FDODeviceExtension
->ConfigurationDescriptor
, Index
, 0, -1, -1, -1);
646 if (InterfaceDescriptor
== NULL
)
649 // failed to find interface descriptor
651 DPRINT1("[USBCCGP] Failed to find interface descriptor index %lu\n", Index
);
653 return STATUS_UNSUCCESSFUL
;
657 // init function descriptor
659 FDODeviceExtension
->FunctionDescriptor
[Index
].FunctionNumber
= Index
;
660 FDODeviceExtension
->FunctionDescriptor
[Index
].NumberOfInterfaces
= 1;
661 FDODeviceExtension
->FunctionDescriptor
[Index
].InterfaceDescriptorList
= AllocateItem(NonPagedPool
, sizeof(PUSB_INTERFACE_DESCRIPTOR
) * 1);
662 if (!FDODeviceExtension
->FunctionDescriptor
[Index
].InterfaceDescriptorList
)
667 return STATUS_INSUFFICIENT_RESOURCES
;
671 // store interface descriptor
673 FDODeviceExtension
->FunctionDescriptor
[Index
].InterfaceDescriptorList
[0] = InterfaceDescriptor
;
676 // now init the device ids
678 Status
= USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension
, InterfaceDescriptor
, Index
, &FDODeviceExtension
->FunctionDescriptor
[Index
]);
679 if (!NT_SUCCESS(Status
))
682 // failed to init ids
684 DPRINT1("[USBCCGP] Failed to init ids with %lx\n", Status
);
689 // store function count
691 FDODeviceExtension
->FunctionDescriptorCount
++;
701 USBCCGP_EnumWithUnionFunctionDescriptors(
702 IN PDEVICE_OBJECT DeviceObject
)
705 return STATUS_NOT_IMPLEMENTED
;
709 USBCCGP_EnumWithAudioLegacy(
710 IN PDEVICE_OBJECT DeviceObject
)
713 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
, FirstDescriptor
= NULL
;
714 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
715 NTSTATUS Status
= STATUS_SUCCESS
;
718 // get device extension
720 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
721 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
725 // first check if all interfaces belong to the same audio class
727 for (Index
= 0; Index
< FDODeviceExtension
->ConfigurationDescriptor
->bNumInterfaces
; Index
++)
730 // get interface descriptor
732 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(FDODeviceExtension
->ConfigurationDescriptor
, FDODeviceExtension
->ConfigurationDescriptor
, Index
, 0, -1, -1, -1);
733 DPRINT1("Index %lu Descriptor %p\n", Index
, InterfaceDescriptor
);
734 ASSERT(InterfaceDescriptor
);
736 if (InterfaceDescriptor
->bInterfaceClass
!= 0x1)
739 // collection contains non audio class
741 return STATUS_UNSUCCESSFUL
;
744 if (FirstDescriptor
== NULL
)
747 // store interface descriptor
749 FirstDescriptor
= InterfaceDescriptor
;
753 if (FirstDescriptor
->bInterfaceSubClass
== InterfaceDescriptor
->bInterfaceSubClass
)
756 // interface subclass must be different from the first interface
758 return STATUS_UNSUCCESSFUL
;
763 // this is an composite audio device
765 DPRINT("[USBCCGP] Audio Composite Device detected\n");
768 // audio interfaces are all grouped into one single function
770 FDODeviceExtension
->FunctionDescriptor
= AllocateItem(NonPagedPool
, sizeof(USBC_FUNCTION_DESCRIPTOR
));
771 if (!FDODeviceExtension
->FunctionDescriptor
)
776 DPRINT1("USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count\n");
777 return STATUS_INSUFFICIENT_RESOURCES
;
781 // init function number
783 FDODeviceExtension
->FunctionDescriptor
[0].FunctionNumber
= 0;
788 Status
= AllocateInterfaceDescriptorsArray(FDODeviceExtension
->ConfigurationDescriptor
, &FDODeviceExtension
->FunctionDescriptor
[0].InterfaceDescriptorList
);
789 if (!NT_SUCCESS(Status
))
792 // failed to allocate descriptor array
794 DPRINT1("[USBCCGP] Failed to allocate descriptor array %lx\n", Status
);
799 // now init the device ids
801 Status
= USBCCG_InitIdsWithInterfaceDescriptor(FDODeviceExtension
, FirstDescriptor
, 0, &FDODeviceExtension
->FunctionDescriptor
[0]);
802 if (!NT_SUCCESS(Status
))
805 // failed to init ids
807 DPRINT1("[USBCCGP] Failed to init ids with %lx\n", Status
);
812 // number of interfaces
814 FDODeviceExtension
->FunctionDescriptor
[0].NumberOfInterfaces
= FDODeviceExtension
->ConfigurationDescriptor
->bNumInterfaces
;
817 // store function count
819 FDODeviceExtension
->FunctionDescriptorCount
= 1;
824 return STATUS_SUCCESS
;
828 USBCCGP_EnumerateFunctions(
829 IN PDEVICE_OBJECT DeviceObject
)
832 PFDO_DEVICE_EXTENSION FDODeviceExtension
;
835 // get device extension
837 FDODeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
838 ASSERT(FDODeviceExtension
->Common
.IsFDO
);
841 // first try with filter driver
843 Status
= USBCCGP_CustomEnumWithInterface(DeviceObject
);
844 if (NT_SUCCESS(Status
))
853 // enumerate functions with interface association descriptor
855 Status
= USBCCGP_EnumWithAssociationDescriptor(DeviceObject
);
856 if (NT_SUCCESS(Status
))
866 // try with union function descriptors
868 Status
= USBCCGP_EnumWithUnionFunctionDescriptors(DeviceObject
);
869 if (NT_SUCCESS(Status
))
879 // try with legacy audio methods
881 Status
= USBCCGP_EnumWithAudioLegacy(DeviceObject
);
882 if (NT_SUCCESS(Status
))
891 // try with legacy enumeration
893 return USBCCGP_LegacyEnum(DeviceObject
);