📄 umss.c
字号:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus, status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension;
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION nextStack;
ENTER(UMSS_CallUSBD);
deviceExtension = DeviceObject->DeviceExtension;
//
// issue a synchronous request
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_USB_SUBMIT_URB,
deviceExtension->TopOfStackDeviceObject, //Points to the next-lower driver's device object
NULL, // optional input bufer; none needed here
0, // input buffer len if used
NULL, // optional output bufer; none needed here
0, // output buffer len if used
TRUE, // If InternalDeviceControl is TRUE the target driver's Dispatch
// outine for IRP_MJ_INTERNAL_DEVICE_CONTROL or IRP_MJ_SCSI
// is called; otherwise, the Dispatch routine for
// IRP_MJ_DEVICE_CONTROL is called.
&event, // event to be signalled on completion
&ioStatus); // Specifies an I/O status block to be set when the request is completed the lower driver.
//
// Call the class driver to perform the operation. If the returned status
// is PENDING, wait for the request to complete.
//
nextStack = IoGetNextIrpStackLocation(irp);
UMSS_ASSERT(nextStack != NULL);
//
// pass the URB to the USB driver stack
//
nextStack->Parameters.Others.Argument1 = Urb;
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
UMSS_KdPrint( DBGLVL_MAXIMUM,("UMSS_CallUSBD() return from IoCallDriver USBD %x\n", ntStatus));
if (ntStatus == STATUS_PENDING)
{
status = KeWaitForSingleObject(
&event,
Suspended,
KernelMode,
FALSE,
NULL);
} else
{
ioStatus.Status = ntStatus;
}
UMSS_KdPrint( DBGLVL_MAXIMUM,("UMSS_CallUSBD() URB status = %x status = %x irp status %x\n",
Urb->UrbHeader.Status, status, ioStatus.Status));
//
// USBD maps the error code for us
//
ntStatus = ioStatus.Status;
RETURN(ntStatus, UMSS_CallUSBD);
}
NTSTATUS
UMSS_ConfigureDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Initializes a given instance of the device on the USB and
selects and saves the configuration.
Arguments:
DeviceObject - pointer to the physical device object for this instance of
the device.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PURB urb;
ULONG siz;
ENTER(UMSS_ConfigureDevice);
deviceExtension = DeviceObject->DeviceExtension;
UMSS_ASSERT( deviceExtension->UsbConfigurationDescriptor == NULL );
urb = UMSS_ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
if ( !urb )
return STATUS_INSUFFICIENT_RESOURCES;
// When USB_CONFIGURATION_DESCRIPTOR_TYPE is specified for DescriptorType
// in a call to UsbBuildGetDescriptorRequest(),
// all interface, endpoint, class-specific, and vendor-specific descriptors
// for the configuration also are retrieved.
// The caller must allocate a buffer large enough to hold all of this
// information or the data is truncated without error.
// Therefore the 'siz' set below is just a 'good guess', and we may have to retry
siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 512;
// We will break out of this 'retry loop' when UsbBuildGetDescriptorRequest()
// has a big enough deviceExtension->UsbConfigurationDescriptor buffer not to truncate
while( 1 )
{
deviceExtension->UsbConfigurationDescriptor = UMSS_ExAllocatePool(NonPagedPool, siz);
if ( !deviceExtension->UsbConfigurationDescriptor )
{
UMSS_ExFreePool(urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
UsbBuildGetDescriptorRequest(
urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_CONFIGURATION_DESCRIPTOR_TYPE,
0,
0,
deviceExtension->UsbConfigurationDescriptor,
NULL,
siz,
NULL
);
ntStatus = UMSS_CallUSBD(DeviceObject, urb);
UMSS_KdPrint( DBGLVL_HIGH,("UMSS_CallUSBD() Configuration Descriptor = %x, len %x\n",
deviceExtension->UsbConfigurationDescriptor,
urb->UrbControlDescriptorRequest.TransferBufferLength));
//
// if we got some data see if it was enough.
// NOTE: we may get an error in URB because of buffer overrun
if (urb->UrbControlDescriptorRequest.TransferBufferLength>0 &&
deviceExtension->UsbConfigurationDescriptor->wTotalLength > siz)
{
siz = deviceExtension->UsbConfigurationDescriptor->wTotalLength;
UMSS_ExFreePool(deviceExtension->UsbConfigurationDescriptor);
deviceExtension->UsbConfigurationDescriptor = NULL;
}
else
{
break; // we got it on the first try
}
} // end, while (retry loop )
UMSS_ExFreePool(urb);
UMSS_ASSERT( deviceExtension->UsbConfigurationDescriptor );
//
// We have the configuration descriptor for the configuration we want.
// Now we issue the select configuration command to get
// the pipes associated with this configuration.
//
ntStatus = UMSS_SelectInterface(
DeviceObject,
deviceExtension->UsbConfigurationDescriptor
);
RETURN(ntStatus, UMSS_ConfigureDevice);
}
NTSTATUS
UMSS_SelectInterface(
IN PDEVICE_OBJECT DeviceObject,
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
)
/*++
Routine Description:
Initializes an device with (possibly) multiple interfaces;
This minidriver only supports one interface (with multiple endpoints).
Arguments:
DeviceObject - pointer to the device object for this instance of the
device.
ConfigurationDescriptor - pointer to the USB configuration
descriptor containing the interface and endpoint
descriptors.
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus;
PURB urb = NULL;
ULONG i;
PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
PUSBD_INTERFACE_INFORMATION Interface = NULL;
USHORT siz;
ENTER(UMSS_SelectInterface);
deviceExtension = DeviceObject->DeviceExtension;
UMSS_KdPrint( DBGLVL_HIGH,("UMSS_SelectInterface() called with NULL Interface\n"));
//
// BulkUsb driver only supports one interface, we must parse
// the configuration descriptor for the interface
// and remember the pipes.
//
urb = USBD_CreateConfigurationRequest(ConfigurationDescriptor, &siz);
if (urb)
{
//
// USBD_ParseConfigurationDescriptorEx searches a given configuration
// descriptor and returns a pointer to an interface that matches the
// given search criteria. We only support one interface on this device
//
interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
ConfigurationDescriptor,
ConfigurationDescriptor, //search from start of config descriptro
-1, // interface number not a criteria; we only support one interface
-1, // not interested in alternate setting here either
-1, // interface class not a criteria
-1, // interface subclass not a criteria
-1 // interface protocol not a criteria
);
if ( !interfaceDescriptor )
{
UMSS_KdPrint( DBGLVL_HIGH,("UMSS_SelectInterface() ParseConfigurationDescriptorEx() failed\n returning STATUS_INSUFFICIENT_RESOURCES\n"));
UMSS_ExFreePool(urb);
return STATUS_INSUFFICIENT_RESOURCES;
}
Interface = &urb->UrbSelectConfiguration.Interface;
for (i=0; i< Interface->NumberOfPipes; i++)
{
//
// perform any pipe initialization here
//
Interface->Pipes[i].MaximumTransferSize = deviceExtension->MaximumTransferSize;
Interface->Pipes[i].PipeFlags = 0;
}
UsbBuildSelectConfigurationRequest(
urb,
(USHORT) siz,
ConfigurationDescriptor);
ntStatus = UMSS_CallUSBD(DeviceObject, urb);
deviceExtension->UsbConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
}
else
{
UMSS_KdPrint( DBGLVL_HIGH,("UMSS_SelectInterface() USBD_CreateConfigurationRequest() failed\n returning STATUS_INSUFFICIENT_RESOURCES\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(ntStatus))
{
//
// Save the configuration handle for this device
//
deviceExtension->UsbConfigurationHandle =
urb->UrbSelectConfiguration.ConfigurationHandle;
deviceExtension->UsbInterface = UMSS_ExAllocatePool(
NonPagedPool,
Interface->Length
);
if (deviceExtension->UsbInterface)
{
ULONG j;
//
// save a copy of the interface information returned
//
RtlCopyMemory(deviceExtension->UsbInterface, Interface, Interface->Length);
//
// Dump the interface to the debugger
//
UMSS_KdPrint( 1,("---------\n"));
UMSS_KdPrint( 1,("NumberOfPipes 0x%x\n", deviceExtension->UsbInterface->NumberOfPipes));
UMSS_KdPrint( 1,("Length 0x%x\n", deviceExtension->UsbInterface->Length));
UMSS_KdPrint( 1,("Alt Setting 0x%x\n", deviceExtension->UsbInterface->AlternateSetting));
UMSS_KdPrint( 1,("Interface Number 0x%x\n", deviceExtension->UsbInterface->InterfaceNumber));
UMSS_KdPrint( 1,("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
deviceExtension->UsbInterface->Class,
deviceExtension->UsbInterface->SubClass,
deviceExtension->UsbInterface->Protocol));
// Dump the pipe info
for (j=0; j<Interface->NumberOfPipes; j++)
{
PUSBD_PIPE_INFORMATION pipeInformation;
pipeInformation = &deviceExtension->UsbInterface->Pipes[j];
UMSS_KdPrint( 1,("---------\n"));
UMSS_KdPrint( 1,("PipeType 0x%x\n", pipeInformation->PipeType));
UMSS_KdPrint( 1,("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
UMSS_KdPrint( 1,("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
UMSS_KdPrint( 1,("Interval 0x%x\n", pipeInformation->Interval));
UMSS_KdPrint( 1,("Handle 0x%x\n", pipeInformation->PipeHandle));
UMSS_KdPrint( 1,("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
switch (pipeInformation->PipeType)
{
case UsbdPipeTypeBulk:
if (USBD_PIPE_DIRECTION_IN(pipeInformation))
{
UMSS_KdPrint( 1,("DataInPipe 0x%x\n", j));
deviceExtension->DataInPipe = j;
}
else
{
UMSS_KdPrint( 1,("DataOutPipe 0x%x\n", j));
deviceExtension->DataOutPipe = j;
}
break;
case UsbdPipeTypeInterrupt:
UMSS_KdPrint( 1,("StatusPipe 0x%x\n", j));
deviceExtension->StatusPipe = j;
break;
default:
UMSS_KdPrint( 1,("Unknown pipe 0x%x\n", j));
break;
}
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -