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

📄 usb.c

📁 usb2.0 驱动; 包括SYS目录
💻 C
📖 第 1 页 / 共 5 页
字号:
                                                      ); // returns TRUE for D0

                IoCopyCurrentIrpStackLocationToNext(Irp);

                if (fGoingToD0) {
                    USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set PowerIrp Completion Routine, fGoingToD0 =%d\n", fGoingToD0));
                    IoSetCompletionRoutine(Irp,
                           USB_PowerIrp_Complete,
                           // Always pass FDO to completion routine as its Context;
                           // This is because the DriverObject passed by the system to the routine
                           // is the Physical Device Object ( PDO ) not the Functional Device Object ( FDO )
                           DeviceObject,
                           TRUE,            // invoke on success
                           TRUE,            // invoke on error
                           TRUE);           // invoke on cancellation of the Irp
                }

                PoStartNextPowerIrp(Irp);
                ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
                                        Irp);

                if ( !fGoingToD0 ) // completion routine will decrement
                    USB_DecrementIoCount(DeviceObject);

                USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Exit IRP_MN_SET_POWER\n"));
                break;
            } /* case irpStack->Parameters.Power.Type */

        }
        break; /* IRP_MN_SET_POWER */

    case IRP_MN_QUERY_POWER:
                //
                // A power policy manager sends this IRP to determine whether it can change
                // the system or device power state, typically to go to sleep.
                //

        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() IRP_MN_QUERY_POWER\n"));

        // We do nothing special here, just let the PDO handle it
        IoCopyCurrentIrpStackLocationToNext(Irp);
        PoStartNextPowerIrp(Irp);
        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
                                Irp);


        USB_DecrementIoCount(DeviceObject);

        break; /* IRP_MN_QUERY_POWER */

    default:

        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() UNKNOWN POWER MESSAGE (%x)\n", irpStack->MinorFunction));

        //
        // All unhandled power messages are passed on to the PDO
        //

        IoCopyCurrentIrpStackLocationToNext(Irp);
        PoStartNextPowerIrp(Irp);
        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

        USB_DecrementIoCount(DeviceObject);

    } /* irpStack->MinorFunction */

    USB_KdPrint( DBGLVL_MEDIUM,  ( "Exit USB_ProcessPowerIrp()  ntStatus = 0x%x\n", ntStatus ) );
    return ntStatus;
}


NTSTATUS
USB_PoRequestCompletion(
    IN PDEVICE_OBJECT       DeviceObject,
    IN UCHAR                MinorFunction,
    IN POWER_STATE          PowerState,
    IN PVOID                Context,
    IN PIO_STATUS_BLOCK     IoStatus
    )

{
    PIRP irp;
    PDEVICE_EXTENSION deviceExtension;
    PDEVICE_OBJECT deviceObject = Context;
    NTSTATUS ntStatus;

    deviceExtension = deviceObject->DeviceExtension;

        // Get the Irp we saved for later processing in USB_ProcessPowerIrp()
        // when we decided to request the Power Irp that this routine
        // is the completion routine for.
    irp = deviceExtension->PowerIrp;

        // We will return the status set by the PDO for the power request we're completing
    ntStatus = IoStatus->Status;

    USB_KdPrint( DBGLVL_HIGH,("Enter USB_PoRequestCompletion()\n"));

    // we should not be in the midst of handling a self-generated power irp
    USB_ASSERT( !deviceExtension->SelfPowerIrp );

    // we must pass down to the next driver in the stack
    IoCopyCurrentIrpStackLocationToNext(irp);


    PoStartNextPowerIrp(irp);


    PoCallDriver(deviceExtension->TopOfStackDeviceObject,
                 irp);

    USB_DecrementIoCount(deviceObject);

    USB_KdPrint( DBGLVL_MEDIUM,("USB_PoRequestCompletion() Exit IRP_MN_SET_POWER\n"));

    deviceExtension->PowerIrp = NULL;

    return ntStatus;
}




NTSTATUS
USB_PowerIrp_Complete(
    IN PDEVICE_OBJECT NullDeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )

{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_OBJECT deviceObject;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION deviceExtension;

    USB_KdPrint( DBGLVL_HIGH,("enter USB_PowerIrp_Complete\n"));

    deviceObject = (PDEVICE_OBJECT) Context;

    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;

    //  If the lower driver returned PENDING, mark our stack location as pending also.
    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }

    irpStack = IoGetCurrentIrpStackLocation (Irp);

    // We can assert that we're a  device powerup-to D0 request,
    // because that was the only type of request we set a completion routine
    // for in the first place
    USB_ASSERT(irpStack->MajorFunction == IRP_MJ_POWER);
    USB_ASSERT(irpStack->MinorFunction == IRP_MN_SET_POWER);
    USB_ASSERT(irpStack->Parameters.Power.Type==DevicePowerState);
    USB_ASSERT(irpStack->Parameters.Power.State.DeviceState==PowerDeviceD0);

    // Now that we know we've let the lower drivers do what was needed to power up,
    //  we can set our device extension flags accordingly
    deviceExtension->CurrentDevicePowerState = PowerDeviceD0;

    Irp->IoStatus.Status = ntStatus;

    USB_DecrementIoCount(deviceObject);

    USB_KdPrint( DBGLVL_MEDIUM,("exit USB_PowerIrp_Complete Exit IRP_MN_SET_POWER D0 complete\n"));
    return ntStatus;
}



NTSTATUS
USB_SelfSuspendOrActivate(
    IN PDEVICE_OBJECT DeviceObject,
    IN BOOLEAN fSuspend
    )

{
    NTSTATUS ntStatus = STATUS_SUCCESS;

    POWER_STATE PowerState;
    PDEVICE_EXTENSION deviceExtension;


    deviceExtension = DeviceObject->DeviceExtension;
    USB_KdPrint( DBGLVL_MAXIMUM,("Enter USB_SelfSuspendOrActivate(),fSuspend = %d\n", fSuspend));

    return STATUS_SUCCESS;
    if ( !USB_CanAcceptIoRequests( DeviceObject ) ) {
        ntStatus = STATUS_DELETE_PENDING;

                USB_KdPrint( DBGLVL_MEDIUM,("ABORTING USB_SelfSuspendOrActivate()\n"));
        return ntStatus;
    }


    // don't do anything if any System-generated Device Pnp irps are pending
    if ( NULL != deviceExtension->PowerIrp ) {
        USB_KdPrint( DBGLVL_MAXIMUM,("Exit USB_SelfSuspendOrActivate(),refusing on pending deviceExtension->PowerIrp 0x%x\n", deviceExtension->PowerIrp));
        return ntStatus;
    }

    // don't do anything if any self-generated Device Pnp irps are pending
    if ( deviceExtension->SelfPowerIrp ) {
        USB_KdPrint( DBGLVL_MAXIMUM,("Exit USB_SelfSuspendOrActivate(),refusing on pending deviceExtension->SelfPowerIrp\n" ));
        return ntStatus;
    }

    // don't auto-suspend if any pipes are open
    if ( fSuspend && ( 0 != deviceExtension->OpenPipeCount ) ) {
        USB_KdPrint( DBGLVL_MAXIMUM,("Exit USB_SelfSuspendOrActivate(),refusing to self-suspend on OpenPipeCount %d\n", deviceExtension->OpenPipeCount));
        return ntStatus;
    }

    // don't auto-activate if no pipes are open
    if ( !fSuspend && ( 0 == deviceExtension->OpenPipeCount ) ) {
        USB_KdPrint( DBGLVL_MAXIMUM,("Exit USB_SelfSuspendOrActivate(),refusing to self-activate, no pipes open\n"));
        return ntStatus;
    }

    // dont do anything if registry CurrentControlSet\Services\USB\Parameters\PowerDownLevel
    //  has been set to  zero, PowerDeviceD0 ( 1 ), or a bogus high value
    if ( ( deviceExtension->PowerDownLevel == PowerDeviceD0 ) ||
         ( deviceExtension->PowerDownLevel == PowerDeviceUnspecified)  ||
         ( deviceExtension->PowerDownLevel >= PowerDeviceMaximum ) ) {
        USB_KdPrint( DBGLVL_MAXIMUM,("Exit USB_SelfSuspendOrActivate(), refusing on deviceExtension->PowerDownLevel == %d\n", deviceExtension->PowerDownLevel));
        return ntStatus;
    }

    if ( fSuspend )
        PowerState.DeviceState = deviceExtension->PowerDownLevel;
    else
        PowerState.DeviceState = PowerDeviceD0;  // power up all the way; we're probably just about to do some IO

    ntStatus = USB_SelfRequestPowerIrp( DeviceObject, PowerState );

    USB_KdPrint( DBGLVL_MAXIMUM,("USB_SelfSuspendOrActivate() status 0x%x on setting dev state %s\n", ntStatus, USB_StringForDevState(PowerState.DeviceState ) ));

    return ntStatus;

}


NTSTATUS
USB_SelfRequestPowerIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN POWER_STATE PowerState
    )

{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension;
    PIRP pIrp = NULL;

    deviceExtension =  DeviceObject->DeviceExtension;

    // This should have been reset in completion routine
    USB_ASSERT( !deviceExtension->SelfPowerIrp );

    if (  deviceExtension->CurrentDevicePowerState ==  PowerState.DeviceState )
        return STATUS_SUCCESS;  // nothing to do

    USB_KdPrint( DBGLVL_HIGH,("Enter USB_SelfRequestPowerIrp() will request power irp to state %s\n",
        USB_StringForDevState( PowerState.DeviceState )));

    USB_IncrementIoCount(DeviceObject);

        // flag we're handling a self-generated power irp
    deviceExtension->SelfPowerIrp = TRUE;

        // actually request the Irp
    ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject,
                         IRP_MN_SET_POWER,
                         PowerState,
                         USB_PoSelfRequestCompletion,
                         DeviceObject,
                         NULL);


    if  ( ntStatus == STATUS_PENDING ) {
        // status pending is the return code we wanted

        // We only need to wait for completion if we're powering up
        if ( (ULONG) PowerState.DeviceState < deviceExtension->PowerDownLevel ) {

            NTSTATUS waitStatus;

            waitStatus = KeWaitForSingleObject(
                           &deviceExtension->SelfRequestedPowerIrpEvent,
                           Suspended,
                           KernelMode,
                           FALSE,
                           NULL);

        }

        ntStatus = STATUS_SUCCESS;

        deviceExtension->SelfPowerIrp = FALSE;

        USB_KdPrint( DBGLVL_HIGH, ("USB_SelfRequestPowerIrp() SUCCESS\n    IRP 0x%x to state %s\n",
            pIrp, USB_StringForDevState(PowerState.DeviceState) ));


    }
    else {
        // The return status was not STATUS_PENDING; any other codes must be considered in error here;
        //  i.e., it is not possible to get a STATUS_SUCCESS  or any other non-error return from this call;
        USB_KdPrint( DBGLVL_HIGH, ("USB_SelfRequestPowerIrp() to state %s FAILED, status = 0x%x\n",
            USB_StringForDevState( PowerState.DeviceState ),ntStatus));
    }

    return ntStatus;
}



NTSTATUS
USB_PoSelfRequestCompletion(
    IN PDEVICE_OBJECT       DeviceObject,
    IN UCHAR                MinorFunction,
    IN POWER_STATE          PowerState,
    IN PVOID                Context,
    IN PIO_STATUS_BLOCK     IoStatus
    )

{
    PDEVICE_OBJECT deviceObject = Context;
    PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
    NTSTATUS ntStatus = IoStatus->Status;

    // we should not be in the midst of handling a system-generated power irp
    USB_ASSERT( NULL == deviceExtension->PowerIrp );

    // We only need to set the event if we're powering up;
    // No caller waits on power down complete
    if ( (ULONG) PowerState.DeviceState < deviceExtension->PowerDownLevel ) {

        // Trigger Self-requested power irp completed event;
        //  The caller is waiting for completion
        KeSetEvent(&deviceExtension->SelfRequestedPowerIrpEvent, 1, FALSE);
    }

    USB_DecrementIoCount(deviceObject);

    USB_KdPrintCond( DBGLVL_HIGH, !NT_SUCCESS(ntStatus),("Exit USB_PoSelfRequestCompletion() FAILED, ntStatus = 0x%x\n", ntStatus ));

    return ntStatus;
}


BOOLEAN
USB_SetDevicePowerState(
    IN PDEVICE_OBJECT DeviceObject,
    IN DEVICE_POWER_STATE DeviceState
    )

{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension;
    BOOLEAN fRes = FALSE;

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    switch (DeviceState) {
    case PowerDeviceD3:

        //
        // Device will be going OFF,
                // TODO: add any needed device-dependent code to save state here.
                //  ( We have nothing to do in this sample )
        //

        USB_KdPrint( DBGLVL_MEDIUM,("USB_SetDevicePowerState() PowerDeviceD3 (OFF)\n"));

        deviceExtension->CurrentDevicePowerState = DeviceState;
        break;

    case PowerDeviceD1:
    case PowerDeviceD2:
        //
        // power states D1,D2 translate to USB suspend

        USB_KdPrint( DBGLVL_MEDIUM,("USB_SetDevicePowerState()  %s\n",
            USB_StringForDevState(DeviceState) ));

        deviceExtension->CurrentDevicePowerState =

⌨️ 快捷键说明

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