2012-01-26 03:42:56 +00:00
/*
* PROJECT : ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
* LICENSE : GPL - See COPYING in the top level directory
2012-01-26 13:45:59 +00:00
* FILE : drivers / usb / usbccgp / pdo . c
2012-01-26 03:42:56 +00:00
* PURPOSE : USB device driver .
* PROGRAMMERS :
* Michael Martin ( michael . martin @ reactos . org )
* Johannes Anderwald ( johannes . anderwald @ reactos . org )
* Cameron Gutman
*/
# include "usbccgp.h"
2012-01-26 19:11:44 +00:00
NTSTATUS
USBCCGP_PdoHandleQueryDeviceText (
IN PDEVICE_OBJECT DeviceObject ,
IN OUT PIRP Irp )
{
LPWSTR Buffer ;
PPDO_DEVICE_EXTENSION PDODeviceExtension ;
2012-01-27 18:04:39 +00:00
LPWSTR GenericString = L " Composite USB Device " ;
2012-01-26 19:11:44 +00:00
//
// get device extension
//
PDODeviceExtension = ( PPDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
//
// is there a device description
//
if ( PDODeviceExtension - > FunctionDescriptor - > FunctionDescription . Length )
{
//
// allocate buffer
//
Buffer = AllocateItem ( NonPagedPool , PDODeviceExtension - > FunctionDescriptor - > FunctionDescription . Length + sizeof ( WCHAR ) ) ;
if ( ! Buffer )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// copy buffer
//
Irp - > IoStatus . Information = ( ULONG_PTR ) Buffer ;
RtlCopyMemory ( Buffer , PDODeviceExtension - > FunctionDescriptor - > FunctionDescription . Buffer , PDODeviceExtension - > FunctionDescriptor - > FunctionDescription . Length ) ;
return STATUS_SUCCESS ;
}
//
// FIXME use GenericCompositeUSBDeviceString
//
UNIMPLEMENTED
2012-01-27 18:04:39 +00:00
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 ;
2012-01-26 19:11:44 +00:00
}
NTSTATUS
USBCCGP_PdoHandleDeviceRelations (
IN PDEVICE_OBJECT DeviceObject ,
IN OUT PIRP Irp )
{
PDEVICE_RELATIONS DeviceRelations ;
PIO_STACK_LOCATION IoStack ;
2012-02-12 02:53:34 +00:00
DPRINT ( " USBCCGP_PdoHandleDeviceRelations \n " ) ;
2012-01-26 19:11:44 +00:00
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
//
// check if relation type is BusRelations
//
if ( IoStack - > Parameters . QueryDeviceRelations . Type ! = TargetDeviceRelation )
{
//
// PDO handles only target device relation
//
return Irp - > IoStatus . Status ;
}
//
// allocate device relations
//
DeviceRelations = ( PDEVICE_RELATIONS ) AllocateItem ( PagedPool , sizeof ( DEVICE_RELATIONS ) ) ;
if ( ! DeviceRelations )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// initialize device relations
//
DeviceRelations - > Count = 1 ;
DeviceRelations - > Objects [ 0 ] = DeviceObject ;
ObReferenceObject ( DeviceObject ) ;
//
// store result
//
Irp - > IoStatus . Information = ( ULONG_PTR ) DeviceRelations ;
//
// completed successfully
//
return STATUS_SUCCESS ;
}
2012-01-30 12:42:05 +00:00
NTSTATUS
USBCCGP_PdoAppendInterfaceNumber (
IN LPWSTR DeviceId ,
IN ULONG InterfaceNumber ,
OUT LPWSTR * OutString )
{
ULONG Length = 0 , StringLength ;
LPWSTR String ;
//
// count length of string
//
String = DeviceId ;
2012-05-28 10:49:44 +00:00
while ( * String )
2012-01-30 12:42:05 +00:00
{
StringLength = wcslen ( String ) + 1 ;
Length + = StringLength ;
Length + = 6 ; //&MI_XX
String + = StringLength ;
}
//
// now allocate the buffer
//
String = AllocateItem ( NonPagedPool , ( Length + 2 ) * sizeof ( WCHAR ) ) ;
if ( ! String )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// store result
//
* OutString = String ;
2012-05-28 10:49:44 +00:00
while ( * DeviceId )
2012-01-30 12:42:05 +00:00
{
2012-02-23 00:37:41 +00:00
StringLength = swprintf ( String , L " %s&MI_%02x " , DeviceId , InterfaceNumber ) + 1 ;
2012-01-30 12:42:05 +00:00
Length = wcslen ( DeviceId ) + 1 ;
2012-02-12 02:53:34 +00:00
DPRINT ( " String %p \n " , String ) ;
2012-01-30 12:42:05 +00:00
//
// next string
//
String + = StringLength ;
DeviceId + = Length ;
}
//
// success
//
return STATUS_SUCCESS ;
}
2012-01-26 19:11:44 +00:00
NTSTATUS
USBCCGP_PdoHandleQueryId (
PDEVICE_OBJECT DeviceObject ,
PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
PUNICODE_STRING DeviceString = NULL ;
PPDO_DEVICE_EXTENSION PDODeviceExtension ;
NTSTATUS Status ;
LPWSTR Buffer ;
//
// get current irp stack location
//
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
//
// get device extension
//
PDODeviceExtension = ( PPDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
if ( IoStack - > Parameters . QueryId . IdType = = BusQueryDeviceID )
{
//
// handle query device id
//
Status = USBCCGP_SyncForwardIrp ( PDODeviceExtension - > NextDeviceObject , Irp ) ;
2012-01-30 12:42:05 +00:00
if ( NT_SUCCESS ( Status ) )
{
//
// allocate buffer
//
Buffer = AllocateItem ( NonPagedPool , ( wcslen ( ( LPWSTR ) Irp - > IoStatus . Information ) + 7 ) * sizeof ( WCHAR ) ) ;
if ( Buffer )
{
//
// append interface number
//
ASSERT ( Irp - > IoStatus . Information ) ;
swprintf ( Buffer , L " %s&MI_%02x " , ( LPWSTR ) Irp - > IoStatus . Information , PDODeviceExtension - > FunctionDescriptor - > FunctionNumber ) ;
2012-02-12 02:53:34 +00:00
DPRINT ( " BusQueryDeviceID %S \n " , Buffer ) ;
2012-01-26 19:11:44 +00:00
2012-01-30 12:42:05 +00:00
ExFreePool ( ( PVOID ) Irp - > IoStatus . Information ) ;
2012-05-28 10:49:44 +00:00
Irp - > IoStatus . Information = ( ULONG_PTR ) Buffer ;
2012-01-30 12:42:05 +00:00
}
else
{
//
// no memory
//
Status = STATUS_INSUFFICIENT_RESOURCES ;
}
}
2012-01-26 19:11:44 +00:00
return Status ;
}
else if ( IoStack - > Parameters . QueryId . IdType = = BusQueryHardwareIDs )
{
//
// handle instance id
//
DeviceString = & PDODeviceExtension - > FunctionDescriptor - > HardwareId ;
}
else if ( IoStack - > Parameters . QueryId . IdType = = BusQueryInstanceID )
{
//
// handle instance id
//
2012-01-30 12:42:05 +00:00
Buffer = AllocateItem ( NonPagedPool , 5 * sizeof ( WCHAR ) ) ;
if ( ! Buffer )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// use function number
//
swprintf ( Buffer , L " %04x " , PDODeviceExtension - > FunctionDescriptor - > FunctionNumber ) ;
Irp - > IoStatus . Information = ( ULONG_PTR ) Buffer ;
return STATUS_SUCCESS ;
2012-01-26 19:11:44 +00:00
}
else if ( IoStack - > Parameters . QueryId . IdType = = BusQueryCompatibleIDs )
{
//
// handle instance id
//
DeviceString = & PDODeviceExtension - > FunctionDescriptor - > CompatibleId ;
}
2012-05-28 10:15:58 +00:00
else
{
//
// unsupported query
//
return Irp - > IoStatus . Status ;
}
2012-01-26 19:11:44 +00:00
//
// sanity check
//
ASSERT ( DeviceString ! = NULL ) ;
//
// allocate buffer
//
Buffer = AllocateItem ( NonPagedPool , DeviceString - > Length + sizeof ( WCHAR ) ) ;
if ( ! Buffer )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// copy buffer
//
RtlCopyMemory ( Buffer , DeviceString - > Buffer , DeviceString - > Length ) ;
2012-05-28 10:15:58 +00:00
Buffer [ DeviceString - > Length / sizeof ( WCHAR ) ] = UNICODE_NULL ;
2012-01-30 12:42:05 +00:00
Irp - > IoStatus . Information = ( ULONG_PTR ) Buffer ;
2012-01-26 19:11:44 +00:00
return STATUS_SUCCESS ;
}
NTSTATUS
PDO_HandlePnp (
PDEVICE_OBJECT DeviceObject ,
PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
PPDO_DEVICE_EXTENSION PDODeviceExtension ;
NTSTATUS Status ;
2012-02-05 15:36:00 +00:00
ULONG Index , bFound ;
2012-01-26 19:11:44 +00:00
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
//
// get device extension
//
PDODeviceExtension = ( PPDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
//
// sanity check
//
ASSERT ( PDODeviceExtension - > Common . IsFDO = = FALSE ) ;
switch ( IoStack - > MinorFunction )
{
2012-05-28 10:49:44 +00:00
case IRP_MN_QUERY_DEVICE_RELATIONS :
{
//
// handle device relations
//
Status = USBCCGP_PdoHandleDeviceRelations ( DeviceObject , Irp ) ;
break ;
}
case IRP_MN_QUERY_DEVICE_TEXT :
{
//
// handle query device text
//
Status = USBCCGP_PdoHandleQueryDeviceText ( DeviceObject , Irp ) ;
break ;
}
case IRP_MN_QUERY_ID :
{
//
// handle request
//
Status = USBCCGP_PdoHandleQueryId ( DeviceObject , Irp ) ;
break ;
}
case IRP_MN_REMOVE_DEVICE :
{
//
// remove us from the fdo's pdo list
//
bFound = FALSE ;
for ( Index = 0 ; Index < PDODeviceExtension - > FDODeviceExtension - > FunctionDescriptorCount ; Index + + )
{
if ( PDODeviceExtension - > FDODeviceExtension - > ChildPDO [ Index ] = = DeviceObject )
{
//
// remove us
//
PDODeviceExtension - > FDODeviceExtension - > ChildPDO [ Index ] = NULL ;
bFound = TRUE ;
break ;
}
}
//
// Complete the IRP
//
Irp - > IoStatus . Status = STATUS_SUCCESS ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
if ( bFound )
{
//
// Delete the device object
//
IoDeleteDevice ( DeviceObject ) ;
}
return STATUS_SUCCESS ;
}
case IRP_MN_QUERY_CAPABILITIES :
{
//
// copy device capabilities
//
RtlCopyMemory ( IoStack - > Parameters . DeviceCapabilities . Capabilities , & PDODeviceExtension - > Capabilities , sizeof ( DEVICE_CAPABILITIES ) ) ;
/* Complete the IRP */
Irp - > IoStatus . Status = STATUS_SUCCESS ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return STATUS_SUCCESS ;
}
2012-02-03 22:59:53 +00:00
case IRP_MN_QUERY_REMOVE_DEVICE :
case IRP_MN_QUERY_STOP_DEVICE :
{
//
// sure
//
Status = STATUS_SUCCESS ;
break ;
}
2012-05-28 10:49:44 +00:00
case IRP_MN_START_DEVICE :
{
//
// no-op for PDO
//
DPRINT ( " [USBCCGP] PDO IRP_MN_START \n " ) ;
Status = STATUS_SUCCESS ;
break ;
}
case IRP_MN_QUERY_INTERFACE :
{
//
// forward to lower device object
//
IoSkipCurrentIrpStackLocation ( Irp ) ;
return IoCallDriver ( PDODeviceExtension - > NextDeviceObject , Irp ) ;
}
default :
2012-01-26 19:11:44 +00:00
{
//
// do nothing
//
Status = Irp - > IoStatus . Status ;
2012-02-03 22:59:53 +00:00
break ;
2012-01-26 19:11:44 +00:00
}
}
//
// complete request
//
if ( Status ! = STATUS_PENDING )
{
//
// store result
//
Irp - > IoStatus . Status = Status ;
//
// complete request
//
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
}
//
// done processing
//
return Status ;
}
2012-01-26 03:42:56 +00:00
2012-01-27 20:58:58 +00:00
NTSTATUS
USBCCGP_BuildConfigurationDescriptor (
2012-05-28 10:49:44 +00:00
PDEVICE_OBJECT DeviceObject ,
2012-01-27 20:58:58 +00:00
PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
PPDO_DEVICE_EXTENSION PDODeviceExtension ;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor ;
ULONG TotalSize , Index ;
2012-05-28 10:34:45 +00:00
ULONG Size ;
2012-01-27 20:58:58 +00:00
PURB Urb ;
PVOID Buffer ;
PUCHAR BufferPtr ;
2012-03-03 15:08:28 +00:00
UCHAR InterfaceNumber ;
2012-01-27 20:58:58 +00:00
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
2012-02-12 02:53:34 +00:00
DPRINT ( " USBCCGP_BuildConfigurationDescriptor \n " ) ;
2012-01-27 20:58:58 +00:00
//
// get device extension
//
PDODeviceExtension = ( PPDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
//
// get configuration descriptor
//
ConfigurationDescriptor = PDODeviceExtension - > ConfigurationDescriptor ;
//
// calculate size of configuration descriptor
//
TotalSize = sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ;
2012-05-28 10:49:44 +00:00
for ( Index = 0 ; Index < PDODeviceExtension - > FunctionDescriptor - > NumberOfInterfaces ; Index + + )
2012-01-27 20:58:58 +00:00
{
//
// get current interface descriptor
//
InterfaceDescriptor = PDODeviceExtension - > FunctionDescriptor - > InterfaceDescriptorList [ Index ] ;
2012-03-03 15:08:28 +00:00
InterfaceNumber = InterfaceDescriptor - > bInterfaceNumber ;
2012-01-27 20:58:58 +00:00
//
// add to size and move to next descriptor
//
TotalSize + = InterfaceDescriptor - > bLength ;
InterfaceDescriptor = ( PUSB_INTERFACE_DESCRIPTOR ) ( ( ULONG_PTR ) InterfaceDescriptor + InterfaceDescriptor - > bLength ) ;
do
{
if ( ( ULONG_PTR ) InterfaceDescriptor > = ( ( ULONG_PTR ) ConfigurationDescriptor + ConfigurationDescriptor - > wTotalLength ) )
{
//
// reached end of configuration descriptor
//
break ;
}
//
// association descriptors are removed
//
if ( InterfaceDescriptor - > bDescriptorType ! = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE )
{
if ( InterfaceDescriptor - > bDescriptorType = = USB_INTERFACE_DESCRIPTOR_TYPE )
{
2012-03-03 15:08:28 +00:00
if ( InterfaceNumber ! = InterfaceDescriptor - > bInterfaceNumber )
{
//
// reached next descriptor
//
break ;
}
2012-01-27 20:58:58 +00:00
//
2012-03-03 15:08:28 +00:00
// include alternate descriptor
2012-01-27 20:58:58 +00:00
//
}
//
// append size
//
TotalSize + = InterfaceDescriptor - > bLength ;
}
//
// move to next descriptor
//
InterfaceDescriptor = ( PUSB_INTERFACE_DESCRIPTOR ) ( ( ULONG_PTR ) InterfaceDescriptor + InterfaceDescriptor - > bLength ) ;
2012-05-28 10:49:44 +00:00
} while ( TRUE ) ;
2012-01-27 20:58:58 +00:00
}
//
// now allocate temporary buffer for the configuration descriptor
//
Buffer = AllocateItem ( NonPagedPool , TotalSize ) ;
if ( ! Buffer )
{
//
// failed to allocate buffer
//
DPRINT1 ( " [USBCCGP] Failed to allocate %lu Bytes \n " , TotalSize ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// first copy the configuration descriptor
//
RtlCopyMemory ( Buffer , ConfigurationDescriptor , sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ) ;
BufferPtr = ( PUCHAR ) ( ( ULONG_PTR ) Buffer + ConfigurationDescriptor - > bLength ) ;
2012-05-28 10:49:44 +00:00
for ( Index = 0 ; Index < PDODeviceExtension - > FunctionDescriptor - > NumberOfInterfaces ; Index + + )
2012-01-27 20:58:58 +00:00
{
//
// get current interface descriptor
//
InterfaceDescriptor = PDODeviceExtension - > FunctionDescriptor - > InterfaceDescriptorList [ Index ] ;
2012-03-03 15:08:28 +00:00
InterfaceNumber = InterfaceDescriptor - > bInterfaceNumber ;
2012-01-27 20:58:58 +00:00
//
// copy descriptor and move to next descriptor
//
RtlCopyMemory ( BufferPtr , InterfaceDescriptor , InterfaceDescriptor - > bLength ) ;
BufferPtr + = InterfaceDescriptor - > bLength ;
InterfaceDescriptor = ( PUSB_INTERFACE_DESCRIPTOR ) ( ( ULONG_PTR ) InterfaceDescriptor + InterfaceDescriptor - > bLength ) ;
do
{
if ( ( ULONG_PTR ) InterfaceDescriptor > = ( ( ULONG_PTR ) ConfigurationDescriptor + ConfigurationDescriptor - > wTotalLength ) )
{
//
// reached end of configuration descriptor
//
break ;
}
//
// association descriptors are removed
//
if ( InterfaceDescriptor - > bDescriptorType ! = USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE )
{
if ( InterfaceDescriptor - > bDescriptorType = = USB_INTERFACE_DESCRIPTOR_TYPE )
{
2012-03-03 15:08:28 +00:00
if ( InterfaceNumber ! = InterfaceDescriptor - > bInterfaceNumber )
{
//
// reached next descriptor
//
break ;
}
2012-01-27 20:58:58 +00:00
//
2012-03-03 15:08:28 +00:00
// include alternate descriptor
2012-01-27 20:58:58 +00:00
//
2012-03-03 15:08:28 +00:00
DPRINT ( " InterfaceDescriptor %p Alternate %x InterfaceNumber %x \n " , InterfaceDescriptor , InterfaceDescriptor - > bAlternateSetting , InterfaceDescriptor - > bInterfaceNumber ) ;
2012-01-27 20:58:58 +00:00
}
//
// copy descriptor
//
RtlCopyMemory ( BufferPtr , InterfaceDescriptor , InterfaceDescriptor - > bLength ) ;
BufferPtr + = InterfaceDescriptor - > bLength ;
}
//
// move to next descriptor
//
InterfaceDescriptor = ( PUSB_INTERFACE_DESCRIPTOR ) ( ( ULONG_PTR ) InterfaceDescriptor + InterfaceDescriptor - > bLength ) ;
2012-05-28 10:49:44 +00:00
} while ( TRUE ) ;
2012-01-27 20:58:58 +00:00
}
//
// modify configuration descriptor
//
ConfigurationDescriptor = Buffer ;
2012-05-28 10:34:45 +00:00
ConfigurationDescriptor - > wTotalLength = ( USHORT ) TotalSize ;
2012-01-27 20:58:58 +00:00
ConfigurationDescriptor - > bNumInterfaces = PDODeviceExtension - > FunctionDescriptor - > NumberOfInterfaces ;
//
// get urb
//
Urb = ( PURB ) IoStack - > Parameters . Others . Argument1 ;
ASSERT ( Urb ) ;
//
// copy descriptor
//
2012-05-28 10:34:45 +00:00
Size = min ( TotalSize , Urb - > UrbControlDescriptorRequest . TransferBufferLength ) ;
RtlCopyMemory ( Urb - > UrbControlDescriptorRequest . TransferBuffer , Buffer , Size ) ;
2012-01-27 20:58:58 +00:00
//
// store final size
//
2012-05-28 10:34:45 +00:00
Urb - > UrbControlDescriptorRequest . TransferBufferLength = Size ;
2012-01-27 20:58:58 +00:00
//
// free buffer
//
FreeItem ( Buffer ) ;
//
// done
//
return STATUS_SUCCESS ;
}
2012-01-28 19:49:53 +00:00
NTSTATUS
USBCCGP_PDOSelectConfiguration (
2012-05-28 10:49:44 +00:00
PDEVICE_OBJECT DeviceObject ,
2012-01-28 19:49:53 +00:00
PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
PPDO_DEVICE_EXTENSION PDODeviceExtension ;
2012-02-01 01:44:21 +00:00
PURB Urb , NewUrb ;
2012-01-28 19:49:53 +00:00
PUSBD_INTERFACE_INFORMATION InterfaceInformation ;
2012-03-03 15:08:28 +00:00
ULONG InterfaceIndex , Length ;
2012-01-28 19:49:53 +00:00
PUSBD_INTERFACE_LIST_ENTRY Entry ;
2012-01-30 10:41:52 +00:00
ULONG NeedSelect , FoundInterface ;
2012-02-01 01:44:21 +00:00
NTSTATUS Status ;
2012-01-28 19:49:53 +00:00
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
//
// get device extension
//
PDODeviceExtension = ( PPDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
//
// get urb
//
Urb = ( PURB ) IoStack - > Parameters . Others . Argument1 ;
ASSERT ( Urb ) ;
//
// is there already an configuration handle
//
if ( Urb - > UrbSelectConfiguration . ConfigurationHandle )
{
//
// nothing to do
//
return STATUS_SUCCESS ;
}
2012-03-03 15:08:28 +00:00
// 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 ) ;
2012-01-28 19:49:53 +00:00
//
// check all interfaces
//
InterfaceInformation = & Urb - > UrbSelectConfiguration . Interface ;
2012-03-03 15:08:28 +00:00
2012-01-28 19:49:53 +00:00
Entry = NULL ;
do
{
2012-03-03 15:08:28 +00:00
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 ) ;
2012-01-28 19:49:53 +00:00
//
2012-01-30 10:41:52 +00:00
// search for the interface in the local interface list
2012-01-28 19:49:53 +00:00
//
2012-01-30 10:41:52 +00:00
FoundInterface = FALSE ;
2012-05-28 10:49:44 +00:00
for ( InterfaceIndex = 0 ; InterfaceIndex < PDODeviceExtension - > FunctionDescriptor - > NumberOfInterfaces ; InterfaceIndex + + )
2012-01-28 19:49:53 +00:00
{
2012-01-30 10:41:52 +00:00
if ( PDODeviceExtension - > FunctionDescriptor - > InterfaceDescriptorList [ InterfaceIndex ] - > bInterfaceNumber = = InterfaceInformation - > InterfaceNumber )
2012-01-28 19:49:53 +00:00
{
// found interface entry
2012-01-30 10:41:52 +00:00
FoundInterface = TRUE ;
2012-01-28 19:49:53 +00:00
break ;
}
}
2012-01-30 10:41:52 +00:00
if ( ! FoundInterface )
2012-01-28 19:49:53 +00:00
{
//
// invalid parameter
//
2012-01-30 10:41:52 +00:00
DPRINT1 ( " InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found \n " , InterfaceInformation - > InterfaceNumber , InterfaceInformation - > AlternateSetting , InterfaceInformation - > NumberOfPipes ) ;
2012-01-28 19:49:53 +00:00
ASSERT ( FALSE ) ;
return STATUS_INVALID_PARAMETER ;
}
2012-01-30 10:41:52 +00:00
//
// now query the total interface list
//
Entry = NULL ;
2012-05-28 10:49:44 +00:00
for ( InterfaceIndex = 0 ; InterfaceIndex < PDODeviceExtension - > InterfaceListCount ; InterfaceIndex + + )
2012-01-30 10:41:52 +00:00
{
if ( PDODeviceExtension - > InterfaceList [ InterfaceIndex ] . Interface - > InterfaceNumber = = InterfaceInformation - > InterfaceNumber )
{
//
// found entry
//
Entry = & PDODeviceExtension - > InterfaceList [ InterfaceIndex ] ;
}
}
//
// sanity check
//
ASSERT ( Entry ) ;
if ( ! Entry )
{
//
// corruption detected
//
KeBugCheck ( 0 ) ;
}
2012-01-28 19:49:53 +00:00
NeedSelect = FALSE ;
if ( Entry - > InterfaceDescriptor - > bAlternateSetting = = InterfaceInformation - > AlternateSetting )
{
2012-02-01 01:44:21 +00:00
for ( InterfaceIndex = 0 ; InterfaceIndex < InterfaceInformation - > NumberOfPipes ; InterfaceIndex + + )
2012-01-28 19:49:53 +00:00
{
if ( InterfaceInformation - > Pipes [ InterfaceIndex ] . MaximumTransferSize ! = Entry - > Interface - > Pipes [ InterfaceIndex ] . MaximumTransferSize )
{
//
// changed interface
//
NeedSelect = TRUE ;
}
}
}
else
{
//
2012-01-30 10:41:52 +00:00
// need select as the interface number differ
2012-01-28 19:49:53 +00:00
//
NeedSelect = TRUE ;
}
if ( ! NeedSelect )
{
//
// interface is already selected
//
2012-03-03 15:08:28 +00:00
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 ) ;
2012-01-28 19:49:53 +00:00
}
else
{
//
2012-02-01 01:44:21 +00:00
// select interface
2012-01-28 19:49:53 +00:00
//
2012-02-01 01:44:21 +00:00
DPRINT1 ( " Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu \n " , InterfaceInformation - > InterfaceNumber , InterfaceInformation - > AlternateSetting , InterfaceInformation - > NumberOfPipes ) ;
ASSERT ( InterfaceInformation - > Length = = Entry - > Interface - > Length ) ;
//
// build urb
//
NewUrb = AllocateItem ( NonPagedPool , GET_SELECT_INTERFACE_REQUEST_SIZE ( InterfaceInformation - > NumberOfPipes ) ) ;
if ( ! NewUrb )
{
//
// no memory
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// now prepare interface urb
//
2012-05-28 10:34:45 +00:00
UsbBuildSelectInterfaceRequest ( NewUrb , ( USHORT ) GET_SELECT_INTERFACE_REQUEST_SIZE ( InterfaceInformation - > NumberOfPipes ) , PDODeviceExtension - > ConfigurationHandle , InterfaceInformation - > InterfaceNumber , InterfaceInformation - > AlternateSetting ) ;
2012-02-01 01:44:21 +00:00
//
// now select the interface
//
Status = USBCCGP_SyncUrbRequest ( PDODeviceExtension - > NextDeviceObject , NewUrb ) ;
DPRINT1 ( " SelectInterface Status %x \n " , Status ) ;
2012-03-03 15:08:28 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed
//
break ;
}
2012-02-01 01:44:21 +00:00
//
2012-03-03 15:08:28 +00:00
// update configuration info
2012-02-01 01:44:21 +00:00
//
2012-03-03 15:08:28 +00:00
ASSERT ( Entry - > Interface - > Length > = NewUrb - > UrbSelectInterface . Interface . Length ) ;
ASSERT ( Length > = NewUrb - > UrbSelectInterface . Interface . Length ) ;
RtlCopyMemory ( Entry - > Interface , & NewUrb - > UrbSelectInterface . Interface , NewUrb - > UrbSelectInterface . Interface . Length ) ;
2012-02-01 01:44:21 +00:00
2012-03-03 15:08:28 +00:00
//
// 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 ) ;
2012-02-01 01:44:21 +00:00
//
// free urb
//
FreeItem ( NewUrb ) ;
2012-01-28 19:49:53 +00:00
}
2012-05-28 10:49:44 +00:00
} while ( Length ) ;
2012-01-28 19:49:53 +00:00
2012-01-30 10:41:52 +00:00
//
// store configuration handle
//
Urb - > UrbSelectConfiguration . ConfigurationHandle = PDODeviceExtension - > ConfigurationHandle ;
DPRINT1 ( " [USBCCGP] SelectConfiguration Function %x Completed \n " , PDODeviceExtension - > FunctionDescriptor - > FunctionNumber ) ;
//
// done
//
2012-01-28 19:49:53 +00:00
return STATUS_SUCCESS ;
}
2012-01-27 20:58:58 +00:00
NTSTATUS
PDO_HandleInternalDeviceControl (
2012-05-28 10:49:44 +00:00
PDEVICE_OBJECT DeviceObject ,
2012-01-27 20:58:58 +00:00
PIRP Irp )
{
PIO_STACK_LOCATION IoStack ;
PPDO_DEVICE_EXTENSION PDODeviceExtension ;
NTSTATUS Status ;
PURB Urb ;
//
// get current stack location
//
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
//
// get device extension
//
PDODeviceExtension = ( PPDO_DEVICE_EXTENSION ) DeviceObject - > DeviceExtension ;
if ( IoStack - > Parameters . DeviceIoControl . IoControlCode = = IOCTL_INTERNAL_USB_SUBMIT_URB )
{
//
// get urb
//
Urb = ( PURB ) IoStack - > Parameters . Others . Argument1 ;
ASSERT ( Urb ) ;
2012-02-01 13:34:20 +00:00
DPRINT ( " IOCTL_INTERNAL_USB_SUBMIT_URB Function %x \n " , Urb - > UrbHeader . Function ) ;
2012-01-27 20:58:58 +00:00
2012-01-28 19:49:53 +00:00
if ( Urb - > UrbHeader . Function = = URB_FUNCTION_SELECT_CONFIGURATION )
{
//
// select configuration
//
Status = USBCCGP_PDOSelectConfiguration ( DeviceObject , Irp ) ;
Irp - > IoStatus . Status = Status ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return Status ;
}
else if ( Urb - > UrbHeader . Function = = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE )
2012-01-27 20:58:58 +00:00
{
2012-05-28 10:49:44 +00:00
if ( Urb - > UrbControlDescriptorRequest . DescriptorType = = USB_DEVICE_DESCRIPTOR_TYPE )
2012-01-27 20:58:58 +00:00
{
//
// is the buffer big enough
//
if ( Urb - > UrbControlDescriptorRequest . TransferBufferLength < sizeof ( USB_DEVICE_DESCRIPTOR ) )
{
//
// invalid buffer size
//
DPRINT1 ( " [USBCCGP] invalid device descriptor size %lu \n " , Urb - > UrbControlDescriptorRequest . TransferBufferLength ) ;
Urb - > UrbControlDescriptorRequest . TransferBufferLength = sizeof ( USB_DEVICE_DESCRIPTOR ) ;
Irp - > IoStatus . Status = STATUS_INVALID_BUFFER_SIZE ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return STATUS_INVALID_BUFFER_SIZE ;
}
//
// copy device descriptor
//
ASSERT ( Urb - > UrbControlDescriptorRequest . TransferBuffer ) ;
RtlCopyMemory ( Urb - > UrbControlDescriptorRequest . TransferBuffer , & PDODeviceExtension - > DeviceDescriptor , sizeof ( USB_DEVICE_DESCRIPTOR ) ) ;
Irp - > IoStatus . Status = STATUS_SUCCESS ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return STATUS_SUCCESS ;
}
else if ( Urb - > UrbControlDescriptorRequest . DescriptorType = = USB_CONFIGURATION_DESCRIPTOR_TYPE )
{
//
// build configuration descriptor
//
Status = USBCCGP_BuildConfigurationDescriptor ( DeviceObject , Irp ) ;
Irp - > IoStatus . Status = Status ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return Status ;
}
2012-03-03 21:23:04 +00:00
else if ( Urb - > UrbControlDescriptorRequest . DescriptorType = = USB_STRING_DESCRIPTOR_TYPE )
{
PUSB_STRING_DESCRIPTOR StringDescriptor ;
//
// get the requested string descriptor
//
ASSERT ( Urb - > UrbControlDescriptorRequest . TransferBuffer ) ;
Status = USBCCGP_GetDescriptor ( PDODeviceExtension - > FDODeviceExtension - > NextDeviceObject ,
USB_STRING_DESCRIPTOR_TYPE ,
Urb - > UrbControlDescriptorRequest . TransferBufferLength ,
Urb - > UrbControlDescriptorRequest . Index ,
Urb - > UrbControlDescriptorRequest . LanguageId ,
( PVOID * ) & StringDescriptor ) ;
if ( NT_SUCCESS ( Status ) )
{
if ( StringDescriptor - > bLength = = 2 )
{
FreeItem ( StringDescriptor ) ;
Status = STATUS_DEVICE_DATA_ERROR ;
}
else
{
RtlCopyMemory ( Urb - > UrbControlDescriptorRequest . TransferBuffer ,
StringDescriptor - > bString ,
StringDescriptor - > bLength + sizeof ( WCHAR ) ) ;
FreeItem ( StringDescriptor ) ;
Status = STATUS_SUCCESS ;
}
}
Irp - > IoStatus . Status = Status ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return Status ;
}
2012-01-27 20:58:58 +00:00
}
2012-01-30 13:31:05 +00:00
else
2012-01-30 10:41:52 +00:00
{
IoSkipCurrentIrpStackLocation ( Irp ) ;
Status = IoCallDriver ( PDODeviceExtension - > NextDeviceObject , Irp ) ;
return Status ;
}
2012-01-27 20:58:58 +00:00
}
2012-02-03 16:03:42 +00:00
else if ( IoStack - > Parameters . DeviceIoControl . IoControlCode = = IOCTL_INTERNAL_USB_GET_PORT_STATUS )
{
IoSkipCurrentIrpStackLocation ( Irp ) ;
Status = IoCallDriver ( PDODeviceExtension - > NextDeviceObject , Irp ) ;
return Status ;
}
else if ( IoStack - > Parameters . DeviceIoControl . IoControlCode = = IOCTL_INTERNAL_USB_RESET_PORT )
{
IoSkipCurrentIrpStackLocation ( Irp ) ;
Status = IoCallDriver ( PDODeviceExtension - > NextDeviceObject , Irp ) ;
return Status ;
}
else if ( IoStack - > Parameters . DeviceIoControl . IoControlCode = = IOCTL_INTERNAL_USB_CYCLE_PORT )
{
IoSkipCurrentIrpStackLocation ( Irp ) ;
Status = IoCallDriver ( PDODeviceExtension - > NextDeviceObject , Irp ) ;
return Status ;
}
2012-01-27 20:58:58 +00:00
DPRINT1 ( " IOCTL %x \n " , IoStack - > Parameters . DeviceIoControl . IoControlCode ) ;
DPRINT1 ( " InputBufferLength %lu \n " , IoStack - > Parameters . DeviceIoControl . InputBufferLength ) ;
DPRINT1 ( " OutputBufferLength %lu \n " , IoStack - > Parameters . DeviceIoControl . OutputBufferLength ) ;
DPRINT1 ( " Type3InputBuffer %p \n " , IoStack - > Parameters . DeviceIoControl . Type3InputBuffer ) ;
ASSERT ( FALSE ) ;
Irp - > IoStatus . Status = STATUS_NOT_IMPLEMENTED ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return STATUS_NOT_IMPLEMENTED ;
}
2012-01-26 03:42:56 +00:00
NTSTATUS
PDO_Dispatch (
2012-05-28 10:49:44 +00:00
PDEVICE_OBJECT DeviceObject ,
2012-01-26 03:42:56 +00:00
PIRP Irp )
{
2012-01-26 19:11:44 +00:00
PIO_STACK_LOCATION IoStack ;
NTSTATUS Status ;
/* get stack location */
IoStack = IoGetCurrentIrpStackLocation ( Irp ) ;
switch ( IoStack - > MajorFunction )
{
case IRP_MJ_PNP :
return PDO_HandlePnp ( DeviceObject , Irp ) ;
2012-01-27 20:58:58 +00:00
case IRP_MJ_INTERNAL_DEVICE_CONTROL :
return PDO_HandleInternalDeviceControl ( DeviceObject , Irp ) ;
2013-05-24 17:36:14 +00:00
case IRP_MJ_POWER :
PoStartNextPowerIrp ( Irp ) ;
Irp - > IoStatus . Status = STATUS_SUCCESS ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return STATUS_SUCCESS ;
2012-01-26 19:11:44 +00:00
default :
DPRINT1 ( " PDO_Dispatch Function %x not implemented \n " , IoStack - > MajorFunction ) ;
Status = Irp - > IoStatus . Status ;
IoCompleteRequest ( Irp , IO_NO_INCREMENT ) ;
return Status ;
}
2012-01-26 03:42:56 +00:00
}