⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umss.c

📁 usb海量存储的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:

    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 + -