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

📄 umsspnp.c

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

            // We don't explicitly wait for the below driver to complete, but just make
            // the call and go on, finishing cleanup
            IoCopyCurrentIrpStackLocationToNext(Irp);

            ntStatus = IoCallDriver(stackDeviceObject, Irp);

            RETURN(ntStatus, UMSS_ProcessPnPIrp);


        case IRP_MN_REMOVE_DEVICE:

            // The PnP Manager uses this IRP to direct drivers to remove a device. 
            // For a "polite" device removal, the PnP Manager sends an 
            // IRP_MN_QUERY_REMOVE_DEVICE prior to the remove IRP. In this case, 
            // the device is in the remove-pending state when the remove IRP arrives.
            // For a surprise-style device removal ( i.e. sudden cord yank ), 
            // the physical device has already been removed and the PnP Manager may not 
            //  have sent IRP_MN_SURPRISE_REMOVAL. A device can be in any state
            // when it receives a remove IRP as a result of a surprise-style removal.

            UMSS_KdPrint( DBGLVL_MINIMUM,("IRP_MN_REMOVE_DEVICE\n"));

            // match the inc at the begining of the dispatch routine
            UMSS_DecrementIoCount(DeviceObject);

            //
            // Once DeviceRemoved is set no new IOCTL or read/write irps will be passed
            // down the stack to lower drivers; all will be quickly failed
            //
            deviceExtension->DeviceRemoved = TRUE;

            // If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
            // This call will also close the pipes; if any user close calls get through,
            // they will be noops
            UMSS_AbortPipes( DeviceObject );
    
            // We don't explicitly wait for the below driver to complete, but just make
            // the call and go on, finishing cleanup
            IoCopyCurrentIrpStackLocationToNext(Irp);

            ntStatus = IoCallDriver(stackDeviceObject, Irp);

            //
            // The final decrement to device extension PendingIoCount == 0
            // will set deviceExtension->RemoveEvent, enabling device removal.
            // If there is no pending IO at this point, the below decrement will be it.
            //
            UMSS_DecrementIoCount(DeviceObject);
      

            // wait for any io request pending in our driver to
            // complete for finishing the remove

            KeWaitForSingleObject(
                &deviceExtension->RemoveEvent,
                Suspended,
                KernelMode,
                FALSE,
                NULL
                );

            //
            // Delete the link and FDO we created
            //
            UMSS_RemoveDevice(DeviceObject);
    

            UMSS_KdPrint( DBGLVL_DEFAULT,("UMSS_ProcessPnPIrp() Detaching from %08X\n",
                              deviceExtension->TopOfStackDeviceObject));

            IoDetachDevice(deviceExtension->TopOfStackDeviceObject);

            UMSS_KdPrint( DBGLVL_DEFAULT,("UMSS_ProcessPnPIrp() Deleting %08X\n",
                              DeviceObject));

            IoDeleteDevice (DeviceObject);

            RETURN(ntStatus, UMSS_ProcessPnPIrp);


        default:
            UMSS_KdPrint( DBGLVL_MAXIMUM,("UMSS_ProcessPnPIrp() Minor PnP IOCTL not handled\n"));

    } /* case MinorFunction  */


    if (!NT_SUCCESS(ntStatus))
    {
        // if anything went wrong, return failure  without passing Irp down
        Irp->IoStatus.Status = ntStatus;
        IoCompleteRequest (Irp,
            IO_NO_INCREMENT
            );

        UMSS_DecrementIoCount(DeviceObject);

        RETURN(ntStatus, UMSS_ProcessPnPIrp);
    }

    IoCopyCurrentIrpStackLocationToNext(Irp);

    //
    // All PNP_POWER messages get passed to the TopOfStackDeviceObject
    // we were given in PnPAddDevice
    //

    UMSS_KdPrint( DBGLVL_MAXIMUM,("UMSS_ProcessPnPIrp() Passing PnP Irp down, status = %x\n", ntStatus));

    ntStatus = IoCallDriver(stackDeviceObject, Irp);

    UMSS_DecrementIoCount(DeviceObject);

    RETURN(ntStatus, UMSS_ProcessPnPIrp);
}


NTSTATUS
UMSS_PnPAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++
Routine Description:

    This routine is called to create and initialize our Functional Device Object (FDO).
    For monolithic drivers, this is done in DriverEntry(), but Plug and Play devices
    wait for a PnP event

Arguments:

    DriverObject - pointer to the driver object for this instance of BulkUsb
    PhysicalDeviceObject - pointer to a device object created by the bus

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/

{
    NTSTATUS                ntStatus = STATUS_SUCCESS;
    PDEVICE_OBJECT          deviceObject = NULL;
    PDEVICE_EXTENSION       deviceExtension;
    USBD_VERSION_INFORMATION versionInformation;
    ULONG i;


    ENTER(UMSS_PnPAddDevice);

    //
    // create our funtional device object (FDO)
    //

    ntStatus =
        UMSS_CreateDeviceObject(DriverObject, PhysicalDeviceObject, &deviceObject);

    if (NT_SUCCESS(ntStatus))
    {
        deviceExtension = deviceObject->DeviceExtension;

        deviceExtension->Fdo = deviceObject;

        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

        //
        // we do not support direct io for read/write
        //
        // deviceObject->Flags |= DO_DIRECT_IO;

        // Storage devices are flushed by VPOWERED shortly after resuming
        // from a standby.  This means we can get I/O requests after resume
        // even if the device was removed while we were suspended.  To avoid
        // this we will *not* set the DO_POWER_PAGABLE flag.  This is
        // interpreted by Win98 as meaning we only support D0, and will
        // cause our driver to be removed during suspend, and reloaded
        // after resume.
        // deviceObject->Flags |= DO_POWER_PAGABLE;

        // initialize our device extension
        //
        // remember the Physical device Object
        //
        deviceExtension->PhysicalDeviceObject=PhysicalDeviceObject;

        //
        // Attach to the PDO
        //
        deviceExtension->TopOfStackDeviceObject =
            IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);


        // Initialize the DPC we use to schedule data transfers to/from the device
        deviceExtension->CbiTransferDataDpc = (PRKDPC)UMSS_ExAllocatePool(
                                                       NonPagedPool,
                                                       sizeof(KDPC)
                                                       );

        KeInitializeDpc(
            deviceExtension->CbiTransferDataDpc,
            UMSS_CbiTransferDataDPC,
            NULL
            );


        // Get a copy of the physical device's capabilities into a
        // DEVICE_CAPABILITIES struct in our device extension;
        // We are most interested in learning which system power states
        // are to be mapped to which device power states for handling
        // IRP_MJ_SET_POWER Irps.
        UMSS_QueryCapabilities(PhysicalDeviceObject,
            &deviceExtension->DeviceCapabilities
            );


        // We want to determine what level to auto-powerdown to; This is the lowest
        //  sleeping level that is LESS than D3; 
        // If all are set to D3, auto powerdown/powerup will be disabled.

        deviceExtension->PowerDownLevel = PowerDeviceUnspecified; // init to disabled

        for (i=PowerSystemSleeping1; i<= PowerSystemSleeping3; i++)
        {
            if ( deviceExtension->DeviceCapabilities.DeviceState[i] < PowerDeviceD3 )
                deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceState[i];
        }

#if DBG

        // May want override auto power-down level from registry;
        // ( CurrentControlSet\Services\BulkUsb\Parameters )
        // Setting to 0 or 1 in registry disables auto power-down
        UMSS_GetRegistryDword( UMSS_REGISTRY_PARAMETERS_PATH,
            L"PowerDownLevel",
            &(deviceExtension->PowerDownLevel)
            );



        //
        // display the device  caps
        //
        UMSS_KdPrint( DBGLVL_MEDIUM,(" >>>>>> DeviceCaps\n"));
        UMSS_KdPrint( DBGLVL_MEDIUM,(" SystemWake = %s\n",
        UMSS_StringForSysState( deviceExtension->DeviceCapabilities.SystemWake ) ));
        UMSS_KdPrint( DBGLVL_MEDIUM,(" DeviceWake = %s\n",
        UMSS_StringForDevState( deviceExtension->DeviceCapabilities.DeviceWake) ));

        for (i=PowerSystemUnspecified; i< PowerSystemMaximum; i++)
        {
            UMSS_KdPrint( DBGLVL_MEDIUM,(" Device State Map: sysstate %s = devstate %s\n",
                UMSS_StringForSysState( i ),
                UMSS_StringForDevState( deviceExtension->DeviceCapabilities.DeviceState[i] ) ));
        }
        UMSS_KdPrint( DBGLVL_MEDIUM,(" <<<<<<<<DeviceCaps\n"));
#endif

        // We keep a pending IO count ( extension->PendingIoCount )  in the device extension.
        // The first increment of this count is done on adding the device.
        // Subsequently, the count is incremented for each new IRP received and
        // decremented when each IRP is completed or passed on.

        // Transition to 'one' therefore indicates no IO is pending and signals
        // deviceExtension->NoPendingIoEvent. This is needed for processing
        // IRP_MN_QUERY_REMOVE_DEVICE

        // Transition to 'zero' signals an event ( deviceExtension->RemoveEvent )
        // to enable device removal. This is used in processing for IRP_MN_REMOVE_DEVICE
        //
        UMSS_IncrementIoCount(deviceObject);

    }

    USBD_GetUSBDIVersion(&versionInformation);

    if( NT_SUCCESS( ntStatus ) )  
    {
        NTSTATUS actStat;
        // try to power down device until IO actually requested
        actStat = UMSS_SelfSuspendOrActivate( deviceObject, TRUE );
    }

    RETURN(ntStatus, UMSS_PnPAddDevice);
}



NTSTATUS
UMSS_StartDevice(
    IN  PDEVICE_OBJECT DeviceObject
    )
/*++
Routine Description:

    Called from UMSS_ProcessPnPIrp(), the dispatch routine for IRP_MJ_PNP.
    Initializes a given instance of the device on the USB.
    USB client drivers such as us set up URBs (USB Request Packets) to send requests
    to the host controller driver (HCD). The URB structure defines a format for all
    possible commands that can be sent to a USB device.
    Here, we request the device descriptor and store it, and configure the device.


Arguments:

    DeviceObject - pointer to the FDO (Functional Device Object)

Return Value:

    NT status code

--*/

{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    PURB urb;
    ULONG siz;

    ENTER(UMSS_StartDevice);

    deviceExtension = DeviceObject->DeviceExtension;

    urb = UMSS_ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

    UMSS_KdPrintCond( DBGLVL_HIGH,!urb, ("UMSS_StartDevice() FAILED UMSS_ExAllocatePool() for URB\n"));

    if (urb)
    {
        siz = sizeof(USB_DEVICE_DESCRIPTOR);

        deviceDescriptor = UMSS_ExAllocatePool(NonPagedPool, siz);

        UMSS_KdPrintCond( DBGLVL_HIGH, !deviceDescriptor, ("UMSS_StartDevice() FAILED UMSS_ExAllocatePool() for deviceDescriptor\n"));

        if (deviceDescriptor)
        {
            UsbBuildGetDescriptorRequest(urb,
                (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                USB_DEVICE_DESCRIPTOR_TYPE,
                0,
                0,
                deviceDescriptor,
                NULL,
                siz,
                NULL
                );


            ntStatus = UMSS_CallUSBD(DeviceObject, urb);

            UMSS_KdPrintCond( DBGLVL_DEFAULT, !NT_SUCCESS(ntStatus), ("UMSS_StartDevice() FAILED UMSS_CallUSBD(DeviceObject, urb)\n"));

            if (NT_SUCCESS(ntStatus))
            {
                UMSS_KdPrint( DBGLVL_MEDIUM,("Device Descriptor = %x, len %x\n",
                    deviceDescriptor,
                    urb->UrbControlDescriptorRequest.TransferBufferLength)
                    );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -