2012-01-26 13:45:59 +00:00
/*
* PROJECT : ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
* LICENSE : GPL - See COPYING in the top level directory
* FILE : drivers / usb / usbccgp / descriptor . c
* PURPOSE : USB device driver .
* PROGRAMMERS :
* Michael Martin ( michael . martin @ reactos . org )
* Johannes Anderwald ( johannes . anderwald @ reactos . org )
* Cameron Gutman
*/
# include "usbccgp.h"
2014-01-02 14:14:39 +00:00
# define NDEBUG
# include <debug.h>
2012-01-26 13:45:59 +00:00
NTSTATUS
USBCCGP_QueryInterface (
IN PDEVICE_OBJECT DeviceObject ,
OUT PUSBC_DEVICE_CONFIGURATION_INTERFACE_V1 BusInterface )
{
KEVENT Event ;
NTSTATUS Status ;
PIRP Irp ;
IO_STATUS_BLOCK IoStatus ;
PIO_STACK_LOCATION Stack ;
2012-02-25 00:35:40 +00:00
/* Sanity checks */
2012-01-26 13:45:59 +00:00
ASSERT ( DeviceObject ) ;
2012-02-25 00:35:40 +00:00
/* Initialize event */
2012-01-26 13:45:59 +00:00
KeInitializeEvent ( & Event , NotificationEvent , FALSE ) ;
2012-02-25 00:35:40 +00:00
/* Init interface */
2012-01-26 13:45:59 +00:00
RtlZeroMemory ( BusInterface , sizeof ( USBC_DEVICE_CONFIGURATION_INTERFACE_V1 ) ) ;
BusInterface - > Version = USBC_DEVICE_CONFIGURATION_INTERFACE_VERSION_1 ;
BusInterface - > Size = sizeof ( USBC_DEVICE_CONFIGURATION_INTERFACE_V1 ) ;
2012-02-25 00:35:40 +00:00
/* Create irp */
2012-01-26 13:45:59 +00:00
Irp = IoBuildSynchronousFsdRequest ( IRP_MJ_PNP ,
DeviceObject ,
NULL ,
0 ,
NULL ,
& Event ,
& IoStatus ) ;
//
// was irp built
//
if ( Irp = = NULL )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// initialize request
//
2012-05-28 10:49:44 +00:00
Stack = IoGetNextIrpStackLocation ( Irp ) ;
2012-01-26 13:45:59 +00:00
Stack - > MajorFunction = IRP_MJ_PNP ;
Stack - > MinorFunction = IRP_MN_QUERY_INTERFACE ;
Stack - > Parameters . QueryInterface . Size = sizeof ( BUS_INTERFACE_STANDARD ) ;
Stack - > Parameters . QueryInterface . InterfaceType = ( LPGUID ) & USB_BUS_INTERFACE_USBC_CONFIGURATION_GUID ;
Stack - > Parameters . QueryInterface . Version = 2 ;
Stack - > Parameters . QueryInterface . Interface = ( PINTERFACE ) & BusInterface ;
Stack - > Parameters . QueryInterface . InterfaceSpecificData = NULL ;
Irp - > IoStatus . Status = STATUS_NOT_SUPPORTED ;
//
// call driver
//
2012-05-28 10:49:44 +00:00
Status = IoCallDriver ( DeviceObject , Irp ) ;
2012-01-26 13:45:59 +00:00
//
// did operation complete
//
if ( Status = = STATUS_PENDING )
{
//
// wait for completion
//
KeWaitForSingleObject ( & Event , Executive , KernelMode , FALSE , NULL ) ;
//
// collect status
//
Status = IoStatus . Status ;
}
return Status ;
}
NTSTATUS
USBCCGP_CustomEnumWithInterface (
IN PDEVICE_OBJECT DeviceObject )
{
PFDO_DEVICE_EXTENSION FDODeviceExtension ;
ULONG FunctionDescriptorBufferLength = 0 ;
NTSTATUS Status ;
PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptorBuffer = NULL ;
//
// get device extension
//
FDODeviceExtension = ( PFDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
ASSERT ( FDODeviceExtension - > Common . IsFDO ) ;
if ( FDODeviceExtension - > BusInterface . StartDeviceCallback = = NULL )
{
//
// not supported
//
return STATUS_NOT_SUPPORTED ;
}
//
// invoke callback
//
2012-05-28 10:49:44 +00:00
Status = FDODeviceExtension - > BusInterface . StartDeviceCallback ( FDODeviceExtension - > DeviceDescriptor ,
FDODeviceExtension - > ConfigurationDescriptor ,
2012-01-26 13:45:59 +00:00
& FunctionDescriptorBuffer ,
& FunctionDescriptorBufferLength ,
DeviceObject ,
FDODeviceExtension - > PhysicalDeviceObject ) ;
2012-05-28 10:49:44 +00:00
DPRINT ( " USBCCGP_CustomEnumWithInterface Status %lx \n " , Status ) ;
2012-01-26 13:45:59 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed
//
return Status ;
}
2012-02-12 02:53:34 +00:00
DPRINT ( " FunctionDescriptorBufferLength %lu \n " , FunctionDescriptorBufferLength ) ;
DPRINT ( " FunctionDescriptorBuffer %p \n " , FunctionDescriptorBuffer ) ;
2012-01-26 13:45:59 +00:00
//
// assume length % function buffer size
//
ASSERT ( FunctionDescriptorBufferLength ) ;
ASSERT ( FunctionDescriptorBufferLength % sizeof ( USBC_FUNCTION_DESCRIPTOR ) = = 0 ) ;
//
// store result
//
FDODeviceExtension - > FunctionDescriptor = FunctionDescriptorBuffer ;
FDODeviceExtension - > FunctionDescriptorCount = FunctionDescriptorBufferLength / sizeof ( USBC_FUNCTION_DESCRIPTOR ) ;
//
// success
//
return STATUS_SUCCESS ;
}
ULONG
USBCCGP_CountAssociationDescriptors (
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor )
{
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor ;
PUCHAR Offset , End ;
ULONG Count = 0 ;
//
// init offsets
//
Offset = ( PUCHAR ) ConfigurationDescriptor + ConfigurationDescriptor - > bLength ;
End = ( PUCHAR ) ConfigurationDescriptor + ConfigurationDescriptor - > wTotalLength ;
2012-05-28 10:49:44 +00:00
while ( Offset < End )
2012-01-26 13:45:59 +00:00
{
//
// get association descriptor
//
Descriptor = ( PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR ) Offset ;
if ( Descriptor - > bLength = = sizeof ( USB_INTERFACE_ASSOCIATION_DESCRIPTOR ) & & Descriptor - > bDescriptorType = = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE )
{
//
// found descriptor
//
Count + + ;
}
//
// move to next descriptor
//
Offset + = Descriptor - > bLength ;
}
//
// done
//
return Count ;
}
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR
USBCCGP_GetAssociationDescriptorAtIndex (
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ,
IN ULONG Index )
{
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor ;
PUCHAR Offset , End ;
ULONG Count = 0 ;
//
// init offsets
//
Offset = ( PUCHAR ) ConfigurationDescriptor + ConfigurationDescriptor - > bLength ;
End = ( PUCHAR ) ConfigurationDescriptor + ConfigurationDescriptor - > wTotalLength ;
2012-05-28 10:49:44 +00:00
while ( Offset < End )
2012-01-26 13:45:59 +00:00
{
//
// get association descriptor
//
Descriptor = ( PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR ) Offset ;
if ( Descriptor - > bLength = = sizeof ( USB_INTERFACE_ASSOCIATION_DESCRIPTOR ) & & Descriptor - > bDescriptorType = = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE )
{
if ( Index = = Count )
{
//
// found descriptor
//
return Descriptor ;
}
//
// not the searched one
//
Count + + ;
}
//
// move to next descriptor
//
Offset + = Descriptor - > bLength ;
}
//
// failed to find descriptor at the specified index
//
return NULL ;
}
NTSTATUS
USBCCGP_InitInterfaceListOfFunctionDescriptor (
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ,
IN PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR AssociationDescriptor ,
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor )
{
PUSB_INTERFACE_DESCRIPTOR Descriptor ;
PUCHAR Offset , End ;
ULONG Count = 0 ;
//
// init offsets
//
Offset = ( PUCHAR ) AssociationDescriptor + AssociationDescriptor - > bLength ;
End = ( PUCHAR ) ConfigurationDescriptor + ConfigurationDescriptor - > wTotalLength ;
2012-05-28 10:49:44 +00:00
while ( Offset < End )
2012-01-26 13:45:59 +00:00
{
//
// get association descriptor
//
Descriptor = ( PUSB_INTERFACE_DESCRIPTOR ) Offset ;
if ( Descriptor - > bLength = = sizeof ( USB_INTERFACE_DESCRIPTOR ) & & Descriptor - > bDescriptorType = = USB_INTERFACE_DESCRIPTOR_TYPE )
{
//
// store interface descriptor
//
FunctionDescriptor - > InterfaceDescriptorList [ Count ] = Descriptor ;
Count + + ;
if ( Count = = AssociationDescriptor - > bInterfaceCount )
{
//
// got all interfaces
//
return STATUS_SUCCESS ;
}
}
if ( Descriptor - > bLength = = sizeof ( USB_INTERFACE_ASSOCIATION_DESCRIPTOR ) & & Descriptor - > bDescriptorType = = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE )
{
//
// WTF? a association descriptor which overlaps the next association descriptor
//
DPRINT1 ( " Invalid association descriptor \n " ) ;
ASSERT ( FALSE ) ;
return STATUS_UNSUCCESSFUL ;
}
//
// move to next descriptor
//
Offset + = Descriptor - > bLength ;
}
//
// invalid association descriptor
//
DPRINT1 ( " Invalid association descriptor \n " ) ;
return STATUS_UNSUCCESSFUL ;
}
NTSTATUS
USBCCGP_InitFunctionDescriptor (
IN PFDO_DEVICE_EXTENSION FDODeviceExtension ,
IN ULONG FunctionNumber ,
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor )
{
PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR Descriptor ;
NTSTATUS Status ;
LPWSTR DescriptionBuffer ;
WCHAR Buffer [ 100 ] ;
ULONG Index ;
// init function number
FunctionDescriptor - > FunctionNumber = ( UCHAR ) FunctionNumber ;
// get association descriptor
Descriptor = USBCCGP_GetAssociationDescriptorAtIndex ( FDODeviceExtension - > ConfigurationDescriptor , FunctionNumber ) ;
ASSERT ( Descriptor ) ;
// store number interfaces
FunctionDescriptor - > NumberOfInterfaces = Descriptor - > bInterfaceCount ;
// allocate array for interface count
FunctionDescriptor - > InterfaceDescriptorList = AllocateItem ( NonPagedPool , sizeof ( PUSB_INTERFACE_DESCRIPTOR ) * Descriptor - > bInterfaceCount ) ;
2012-06-01 18:59:22 +00:00
if ( ! FunctionDescriptor - > InterfaceDescriptorList )
2012-01-26 13:45:59 +00:00
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
// init interface list
Status = USBCCGP_InitInterfaceListOfFunctionDescriptor ( FDODeviceExtension - > ConfigurationDescriptor , Descriptor , FunctionDescriptor ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed
//
return Status ;
}
//
// now init interface description
//
if ( Descriptor - > iFunction )
{
//
// get interface description
//
2012-02-22 21:26:36 +00:00
Status = USBCCGP_GetStringDescriptor ( FDODeviceExtension - > NextDeviceObject ,
2012-05-28 10:49:44 +00:00
100 * sizeof ( WCHAR ) ,
Descriptor - > iFunction ,
2012-02-25 00:35:40 +00:00
0x0409 , //FIXME
( PVOID * ) & DescriptionBuffer ) ;
2012-01-26 13:45:59 +00:00
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 - > bFirstInterface ) + 1 ;
2012-05-28 10:15:58 +00:00
Index + = swprintf ( & Buffer [ Index ] , L " USB \\ VID_%04x&PID_%04x&MI_%02x " , FDODeviceExtension - > DeviceDescriptor - > idVendor ,
FDODeviceExtension - > DeviceDescriptor - > idProduct ,
Descriptor - > bFirstInterface ) + 1 ;
2012-01-26 13:45:59 +00:00
// allocate result buffer
DescriptionBuffer = AllocateItem ( NonPagedPool , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
if ( ! DescriptionBuffer )
{
//
// failed to allocate memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
// copy description
2012-05-28 10:15:58 +00:00
RtlCopyMemory ( DescriptionBuffer , Buffer , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
2012-01-27 18:04:39 +00:00
FunctionDescriptor - > HardwareId . Buffer = DescriptionBuffer ;
FunctionDescriptor - > HardwareId . Length = Index * sizeof ( WCHAR ) ;
FunctionDescriptor - > HardwareId . MaximumLength = ( Index + 1 ) * sizeof ( WCHAR ) ;
2012-01-26 13:45:59 +00:00
//
// now init the compatible id
//
Index = swprintf ( Buffer , L " USB \\ Class_%02x&SubClass_%02x&Prot_%02x " , Descriptor - > bFunctionClass , Descriptor - > bFunctionSubClass , Descriptor - > bFunctionProtocol ) + 1 ;
2012-05-28 10:15:58 +00:00
Index + = swprintf ( & Buffer [ Index ] , L " USB \\ Class_%02x&SubClass_%02x " , Descriptor - > bFunctionClass , Descriptor - > bFunctionSubClass ) + 1 ;
Index + = swprintf ( & Buffer [ Index ] , L " USB \\ Class_%02x " , Descriptor - > bFunctionClass ) + 1 ;
2012-01-26 13:45:59 +00:00
// allocate result buffer
DescriptionBuffer = AllocateItem ( NonPagedPool , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
if ( ! DescriptionBuffer )
{
//
// failed to allocate memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
// copy description
2012-05-28 10:15:58 +00:00
RtlCopyMemory ( DescriptionBuffer , Buffer , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
2012-01-27 18:04:39 +00:00
FunctionDescriptor - > CompatibleId . Buffer = DescriptionBuffer ;
FunctionDescriptor - > CompatibleId . Length = Index * sizeof ( WCHAR ) ;
FunctionDescriptor - > CompatibleId . MaximumLength = ( Index + 1 ) * sizeof ( WCHAR ) ;
2012-01-26 13:45:59 +00:00
//
// done
//
return STATUS_SUCCESS ;
}
NTSTATUS
USBCCGP_EnumWithAssociationDescriptor (
IN PDEVICE_OBJECT DeviceObject )
{
ULONG DescriptorCount , Index ;
PFDO_DEVICE_EXTENSION FDODeviceExtension ;
NTSTATUS Status = STATUS_SUCCESS ;
//
// get device extension
//
FDODeviceExtension = ( PFDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
ASSERT ( FDODeviceExtension - > Common . IsFDO ) ;
//
// count association descriptors
//
DescriptorCount = USBCCGP_CountAssociationDescriptors ( FDODeviceExtension - > ConfigurationDescriptor ) ;
if ( ! DescriptorCount )
{
//
// no descriptors found
//
return STATUS_NOT_SUPPORTED ;
}
//
// allocate function descriptor array
//
FDODeviceExtension - > FunctionDescriptor = AllocateItem ( NonPagedPool , sizeof ( USBC_FUNCTION_DESCRIPTOR ) * DescriptorCount ) ;
2012-12-24 09:56:28 +00:00
if ( ! FDODeviceExtension - > FunctionDescriptor )
2012-01-26 13:45:59 +00:00
{
//
// no memory
//
DPRINT1 ( " USBCCGP_EnumWithAssociationDescriptor failed to allocate function descriptor count %x \n " , DescriptorCount ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
2012-05-28 10:49:44 +00:00
for ( Index = 0 ; Index < DescriptorCount ; Index + + )
2012-01-26 13:45:59 +00:00
{
//
// init function descriptors
//
Status = USBCCGP_InitFunctionDescriptor ( FDODeviceExtension , Index , & FDODeviceExtension - > FunctionDescriptor [ Index ] ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed
//
return Status ;
}
}
//
// store function descriptor count
//
FDODeviceExtension - > FunctionDescriptorCount = DescriptorCount ;
//
// done
//
return Status ;
}
2012-01-27 18:04:39 +00:00
NTSTATUS
USBCCG_InitIdsWithInterfaceDescriptor (
IN PFDO_DEVICE_EXTENSION FDODeviceExtension ,
IN PUSB_INTERFACE_DESCRIPTOR Descriptor ,
2012-01-27 18:33:41 +00:00
IN ULONG FunctionIndex ,
2012-01-27 18:04:39 +00:00
OUT PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor )
{
ULONG Index ;
WCHAR Buffer [ 200 ] ;
LPWSTR DescriptionBuffer ;
NTSTATUS Status ;
//
// now init interface description
//
if ( Descriptor - > iInterface )
{
//
// get interface description
//
2012-02-22 21:26:36 +00:00
Status = USBCCGP_GetStringDescriptor ( FDODeviceExtension - > NextDeviceObject ,
2012-02-25 00:35:40 +00:00
100 * sizeof ( WCHAR ) ,
Descriptor - > iInterface ,
0x0409 , //FIXME
( PVOID * ) & DescriptionBuffer ) ;
2012-01-27 18:04:39 +00:00
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 ,
2012-01-27 18:33:41 +00:00
FunctionIndex ) + 1 ;
2012-01-27 18:04:39 +00:00
Index + = swprintf ( & Buffer [ Index ] , L " USB \\ VID_%04x&PID_%04x&MI_%02x " , FDODeviceExtension - > DeviceDescriptor - > idVendor ,
2012-05-28 10:49:44 +00:00
FDODeviceExtension - > DeviceDescriptor - > idProduct ,
FunctionIndex ) + 1 ;
2012-01-27 18:04:39 +00:00
// allocate result buffer
DescriptionBuffer = AllocateItem ( NonPagedPool , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
if ( ! DescriptionBuffer )
{
//
// failed to allocate memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
// copy description
2012-05-28 10:15:58 +00:00
RtlCopyMemory ( DescriptionBuffer , Buffer , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
2012-01-27 18:04:39 +00:00
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 ;
2012-01-27 18:33:41 +00:00
Index + = swprintf ( & Buffer [ Index ] , L " USB \\ Class_%02x&SubClass_%02x " , Descriptor - > bInterfaceClass , Descriptor - > bInterfaceSubClass ) + 1 ;
Index + = swprintf ( & Buffer [ Index ] , L " USB \\ Class_%02x " , Descriptor - > bInterfaceClass ) + 1 ;
2012-01-27 18:04:39 +00:00
// allocate result buffer
DescriptionBuffer = AllocateItem ( NonPagedPool , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
if ( ! DescriptionBuffer )
{
//
// failed to allocate memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
// copy description
2012-05-28 10:15:58 +00:00
RtlCopyMemory ( DescriptionBuffer , Buffer , ( Index + 1 ) * sizeof ( WCHAR ) ) ;
2012-01-27 18:04:39 +00:00
FunctionDescriptor - > CompatibleId . Buffer = DescriptionBuffer ;
FunctionDescriptor - > CompatibleId . Length = Index * sizeof ( WCHAR ) ;
FunctionDescriptor - > CompatibleId . MaximumLength = ( Index + 1 ) * sizeof ( WCHAR ) ;
2012-01-27 18:33:41 +00:00
//
// done
//
return STATUS_SUCCESS ;
2012-01-27 18:04:39 +00:00
}
2012-01-26 13:45:59 +00:00
NTSTATUS
2012-01-27 18:04:39 +00:00
USBCCGP_LegacyEnum (
2012-01-26 13:45:59 +00:00
IN PDEVICE_OBJECT DeviceObject )
{
2012-01-27 18:04:39 +00:00
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
//
2015-06-24 10:31:50 +00:00
FDODeviceExtension - > FunctionDescriptorCount = 0 ;
2012-05-28 10:49:44 +00:00
for ( Index = 0 ; Index < FDODeviceExtension - > ConfigurationDescriptor - > bNumInterfaces ; Index + + )
2012-01-27 18:04:39 +00:00
{
// get interface descriptor
2012-01-30 10:41:52 +00:00
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx ( FDODeviceExtension - > ConfigurationDescriptor , FDODeviceExtension - > ConfigurationDescriptor , Index , 0 , - 1 , - 1 , - 1 ) ;
2012-01-27 18:04:39 +00:00
if ( InterfaceDescriptor = = NULL )
{
//
// failed to find interface descriptor
//
DPRINT1 ( " [USBCCGP] Failed to find interface descriptor index %lu \n " , Index ) ;
2012-01-30 10:41:52 +00:00
ASSERT ( FALSE ) ;
2012-01-27 18:04:39 +00:00
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
//
2012-01-27 18:33:41 +00:00
Status = USBCCG_InitIdsWithInterfaceDescriptor ( FDODeviceExtension , InterfaceDescriptor , Index , & FDODeviceExtension - > FunctionDescriptor [ Index ] ) ;
2012-01-27 18:04:39 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to init ids
//
2012-05-28 10:49:44 +00:00
DPRINT1 ( " [USBCCGP] Failed to init ids with %lx \n " , Status ) ;
2012-01-27 18:04:39 +00:00
return Status ;
}
//
// store function count
//
FDODeviceExtension - > FunctionDescriptorCount + + ;
}
//
// done
//
return Status ;
2012-01-26 13:45:59 +00:00
}
NTSTATUS
USBCCGP_EnumWithUnionFunctionDescriptors (
IN PDEVICE_OBJECT DeviceObject )
{
2017-02-06 15:49:23 +00:00
UNIMPLEMENTED ;
2012-01-26 13:45:59 +00:00
return STATUS_NOT_IMPLEMENTED ;
}
2012-01-27 18:04:39 +00:00
NTSTATUS
USBCCGP_EnumWithAudioLegacy (
IN PDEVICE_OBJECT DeviceObject )
{
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
//
2012-05-28 10:49:44 +00:00
for ( Index = 0 ; Index < FDODeviceExtension - > ConfigurationDescriptor - > bNumInterfaces ; Index + + )
2012-01-27 18:04:39 +00:00
{
//
// get interface descriptor
//
2012-03-03 15:08:28 +00:00
InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx ( FDODeviceExtension - > ConfigurationDescriptor , FDODeviceExtension - > ConfigurationDescriptor , Index , 0 , - 1 , - 1 , - 1 ) ;
2012-01-30 10:41:52 +00:00
DPRINT1 ( " Index %lu Descriptor %p \n " , Index , InterfaceDescriptor ) ;
ASSERT ( InterfaceDescriptor ) ;
2012-01-27 18:04:39 +00:00
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
//
2012-02-12 02:53:34 +00:00
DPRINT ( " [USBCCGP] Audio Composite Device detected \n " ) ;
2012-01-27 18:04:39 +00:00
//
// 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 ;
//
2012-01-27 20:58:58 +00:00
// store interfaces
2012-01-27 18:04:39 +00:00
//
2012-01-27 20:58:58 +00:00
Status = AllocateInterfaceDescriptorsArray ( FDODeviceExtension - > ConfigurationDescriptor , & FDODeviceExtension - > FunctionDescriptor [ 0 ] . InterfaceDescriptorList ) ;
if ( ! NT_SUCCESS ( Status ) )
2012-01-27 18:04:39 +00:00
{
//
2012-01-27 20:58:58 +00:00
// failed to allocate descriptor array
2012-01-27 18:04:39 +00:00
//
2012-05-28 10:49:44 +00:00
DPRINT1 ( " [USBCCGP] Failed to allocate descriptor array %lx \n " , Status ) ;
2012-01-27 20:58:58 +00:00
return Status ;
2012-01-27 18:04:39 +00:00
}
//
// now init the device ids
//
2012-01-27 18:33:41 +00:00
Status = USBCCG_InitIdsWithInterfaceDescriptor ( FDODeviceExtension , FirstDescriptor , 0 , & FDODeviceExtension - > FunctionDescriptor [ 0 ] ) ;
2012-01-27 18:04:39 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to init ids
//
2012-05-28 10:49:44 +00:00
DPRINT1 ( " [USBCCGP] Failed to init ids with %lx \n " , Status ) ;
2012-01-27 18:04:39 +00:00
return Status ;
}
2012-01-27 20:58:58 +00:00
//
// number of interfaces
//
2012-03-03 15:08:28 +00:00
FDODeviceExtension - > FunctionDescriptor [ 0 ] . NumberOfInterfaces = FDODeviceExtension - > ConfigurationDescriptor - > bNumInterfaces ;
2012-01-27 20:58:58 +00:00
2012-01-27 18:04:39 +00:00
//
// store function count
//
FDODeviceExtension - > FunctionDescriptorCount = 1 ;
//
// done
//
return STATUS_SUCCESS ;
}
2012-01-26 13:45:59 +00:00
NTSTATUS
USBCCGP_EnumerateFunctions (
IN PDEVICE_OBJECT DeviceObject )
{
NTSTATUS Status ;
PFDO_DEVICE_EXTENSION FDODeviceExtension ;
//
// get device extension
//
FDODeviceExtension = ( PFDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
ASSERT ( FDODeviceExtension - > Common . IsFDO ) ;
//
// first try with filter driver
//
Status = USBCCGP_CustomEnumWithInterface ( DeviceObject ) ;
if ( NT_SUCCESS ( Status ) )
{
//
// succeeded
//
return Status ;
}
//
// enumerate functions with interface association descriptor
//
Status = USBCCGP_EnumWithAssociationDescriptor ( DeviceObject ) ;
if ( NT_SUCCESS ( Status ) )
{
//
// succeeded
//
return Status ;
}
2012-01-27 18:04:39 +00:00
#if 0
2012-01-26 13:45:59 +00:00
//
// try with union function descriptors
//
Status = USBCCGP_EnumWithUnionFunctionDescriptors ( DeviceObject ) ;
if ( NT_SUCCESS ( Status ) )
{
//
// succeeded
//
return Status ;
}
2012-01-27 18:04:39 +00:00
# endif
2012-01-26 13:45:59 +00:00
//
// try with legacy audio methods
//
2012-01-27 18:04:39 +00:00
Status = USBCCGP_EnumWithAudioLegacy ( DeviceObject ) ;
if ( NT_SUCCESS ( Status ) )
{
//
// succeeded
//
return Status ;
}
//
// try with legacy enumeration
//
return USBCCGP_LegacyEnum ( DeviceObject ) ;
2012-01-26 13:45:59 +00:00
}