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

📄 usbfx2lk_power.cpp

📁 VisualC++写的一个USB的驱动程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                   TRUE);
            
            //
            // Pass the system power irp down using PoCallDriver! 
            //  It is an error to use IoCallDriver here...Power irps 
            //  must be passed down with PoCallDriver, because it
            //  will do some additional work to ensure proper
            //  synchronization of power Irps
            //
            (VOID)PoCallDriver(devExt->DeviceToSendIrpsTo,
                               Irp);
            
            
            //
            // We've registered an IO completion routine so we're not 
            //  finished with this Irp...DON'T release our remove lock!
            //
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleSystemPowerIrp: Exiting!\n"));
            
            //
            // The IRP is marked pending so we MUST return STATUS_PENDING here.
            //
            return STATUS_PENDING;
            
            
       case IRP_MN_SET_POWER:


           OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, 
                       ("OsrHandleSystemPowerIrp: Setting System state to %s\n", 
                       OsrPrintSystemPowerState(powerState.SystemState)));
           //
           // mark the IRP pending 
           //
           IoMarkIrpPending(Irp);
           
           IoCopyCurrentIrpStackLocationToNext(Irp);
           
           //
           // Set our completion routine into the system power IRP
           //
           IoSetCompletionRoutine(Irp,
                                  SystemPowerIoCompletionRoutine,
                                  (PVOID)devExt,
                                  TRUE,
                                  TRUE,
                                  TRUE);
           
           //
           // Pass the irp down using PoCallDriver! It is an
           //  error to use IoCallDriver here...Power irps 
           //  must be passed down with PoCallDriver, since it
           //  will do some additional work to ensure proper
           //  synchronization of power Irps
           //
           (VOID)PoCallDriver(devExt->DeviceToSendIrpsTo,
                              Irp);        
           
           //
           // We've registered an IO completion routine so we're not 
           //  finished with this Irp...DON'T release our remove lock!
           //
           
           OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleSystemPowerIrp: Exiting!\n"));
           
           //
           // The IRP is marked pending so we 
           // MUST return STATUS_PENDING here.
           //
           return STATUS_PENDING;
               
        case IRP_MN_WAIT_WAKE:

            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, 
                        ("OsrHandleSystemPowerIrp: IRP_MN_WAIT_WAKE Received\n"));
                
            IoMarkIrpPending(Irp);

            IoCopyCurrentIrpStackLocationToNext(Irp);

            IoSetCompletionRoutine(
                            Irp,
                            (PIO_COMPLETION_ROUTINE)WaitWakeCompletionRoutine,
                            devExt, 
                            TRUE, 
                            TRUE, 
                            TRUE);

            PoStartNextPowerIrp(Irp);

            status = PoCallDriver(devExt->DeviceToSendIrpsTo, Irp);

            if(!NT_SUCCESS(status)) {

                OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_POWER_INFO,("Lower drivers failed the wait-wake Irp\n"));
            }

            status = STATUS_PENDING;

            //
            // push back the count HERE and NOT in completion routine
            // a pending Wait Wake Irp should not impede stopping the device
            //

            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);

            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleSystemPowerIrp: Exit.\n"));

            return STATUS_PENDING;

        case IRP_MN_BOGUS:

            //
            // Driver Verifier bogus minor function code
            //
            
            OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, 
                        ("OsrHandleSystemPowerIrp: Received IRP_MN_BOGUS: Just pass it along...\n"));

            //
            // Fall through...
            //

        case IRP_MN_POWER_SEQUENCE:

            // 
            // This device does not support wake or power sequence so 
            // we just send the request down to the bus
            //

            //
            // Fall through...
            //
        
        default:
        
            //
            // Unknown power code...
            //
            
            //
            // No matter what we always must call 
            //  PoStartNextPowerIrp...
            //
            //  We must also always make this call BEFORE calling
            //  IoSkipCurrentIrpStackLocation. Why? Because
            //  PoStartNextPowerIrp lets another power Irp of 
            //  the same kind that we're processing now through
            //  (System or Device). How does it know what kind
            //  of Irp we're handling? Why from the current
            //  stack location of course!
            //
            
            PoStartNextPowerIrp(Irp);
            
            IoSkipCurrentIrpStackLocation(Irp);
            
            //
            // Pass the irp down using PoCallDriver! It is an
            //  error to use IoCallDriver here...Power irps 
            //  must be passed down with PoCallDriver, since it
            //  will do some additional work to ensure proper
            //  synchronization of power Irps
            //
            status = PoCallDriver(devExt->DeviceToSendIrpsTo, Irp);
            
            //
            // We're done with this request
            //
            OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
            
            OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleSystemPowerIrp: Exiting!\n"));
            
            return status;

           
    }
    
    //
    // We never get here...
    //

    OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_POWER_INFO, 
        ("OsrHandleSystemPowerIrp: Should never reach the end! Breaking into the debugger if attached...\n"));

    //
    // Use KdBreakPoint instead of DbgBreakPoint so that 
    //  we only break in the checked build...
    //
    KdBreakPoint();

    return STATUS_UNSUCCESSFUL;


}


///////////////////////////////////////////////////////////////////////////////
//
// SystemPowerIoCompletionRoutine
//
//      Our I/O completion routine for system QUERY_POWER and SET_POWER IRPs.
//
//  INPUTS:
//
//      DeviceObject - Pointer to device object.
//      Irp          - Address of the system power IRP.
//      Context      - the device extension
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      NTSTATUS value signaling the I/O manager to continue processing IRP
//      stack locations or not.
//
//  IRQL:
//
//      This routine is called at IRQL <= DISPATCH_LEVEL
//
//  CONTEXT:
//
//      This routine is called in an arbitrary thread context
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SystemPowerIoCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PVOID Context) 
{
    PUSBFX2LK_EXT       devExt = (PUSBFX2LK_EXT) Context;
    PIO_STACK_LOCATION  ioStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS            status;
    POWER_STATE         powerState;
    SYSTEM_POWER_STATE  newSystemPowerState = ioStack->Parameters.Power.State.SystemState;
    UCHAR               minorFunction = ioStack->MinorFunction;


    UNREFERENCED_PARAMETER(DeviceObject);
    
    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("SystemPowerIoCompletionRoutine: Entered...\n"));

    // 
    // No need to propagate the pending flag here as
    // we already marked the IRP pending in the power
    // dispatch routine
    //

    // 
    // If the system power IRP failed for any reason, there is 
    // no reason to go on and request the device power IRP.
    // 
    status = Irp->IoStatus.Status;

    if(!NT_SUCCESS(status)) {


        //
        // Let the power manager know we are ready to handle
        // the next SystemPowerState power IRP.
        //            
        PoStartNextPowerIrp(Irp);

        //
        // We're done with this request. 
        //
        OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_POWER_INFO, 
            ("SystemPowerIoCompletionRoutine: System Power Irp failed with status 0x%8.8x (%s)!\n",
              status, OsrNtStatusToString(status)));
    
        //
        // Stop processing by returning STATUS_SUCCESS (
        //  it would be nice to return an error here,
        //  but completion routines must return either
        //  STATUS_SUCCESS or STATUS_MORE_PROCESSING_REQUIRED...
        //
        return STATUS_SUCCESS;

    }

    // 
    // Save the system power IRP in the device context to 
    // be completed after the device power IRP, that we request,
    // has been processed by the entire stack.
    //
    devExt->SystemPowerIrp = Irp;

    //
    // As the power policy owner we have to perform 
    // the system power state to device power state mappings.
    // We received default mappings from the bus driver by
    // catching the DEVICE_CAPABILITIES stucture in the PnP 
    // QUERY_CAPABILITIES request on its way up from the PDO.  
    // We use what the bus gave us here unmolested.  
    //
    powerState.DeviceState = 
        devExt->SystemToDevicePowerMappings[ioStack->Parameters.Power.State.SystemState];

    //
    // Now we request the device power IRP.
    //
    status = PoRequestPowerIrp(devExt->PhysicalDeviceObject, 
                             ioStack->MinorFunction,
                             powerState,
                             DevicePowerRequestCompletionRoutine, 
                             (PVOID)devExt, 
                             NULL);

    //
    // PoRequestPowerIrp returns STATUS_PENDING on success...
    //    
    if (status != STATUS_PENDING) {

        //
        // We're here either because there were insufficient
        //  resources available to allocate the power irp
        //  or the minor function supplied as parameter two
        //  was invalid. Nothing much we can do but return...
        //

        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_POWER_INFO, 
            ("SystemPowerIoCompletionRoutine: Unable to allocate device power Irp! Status 0x%8.8x (%s)\n",
                status, OsrNtStatusToString(status)));

        //
        // We need to allow the next power Irp to start...
        //
        PoStartNextPowerIrp(devExt->SystemPowerIrp);

        //
        // Fill in the Irp with the failure status...
        //
        devExt->SystemPowerIrp->IoStatus.Status = status;

        devExt->SystemPowerIrp = NULL;

        OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, ("SystemPowerIoCompletionRoutine: Exiting!\n"));

        //
        // We don't have an Irp to reclaim so just return
        // success to continue completion processing...
        //
        return STATUS_SUCCESS;

    }

    OsrTracePrint(TRACE_LEVEL_INFORMATION,OSRDBG_POWER_INFO, ("SystemPowerIoCompletionRoutine: Exiting!\n"));

    if(minorFunction == IRP_MN_SET_POWER) {
        devExt->SystemPowerState = newSystemPowerState;
    }

    // 
    // We complete the system power IRP in the power completion routine.  The
    // power completion routine, not to be confused with an I/O completion routine,
    // is called when the device power IRP, requested above, has been processed by
    // every device in the stack and completed.  We return 
    // STATUS_MORE_PROCESSING_REQUIRED here to let the I/O manager know we aren't 
    // done with the system power IRP.
    // 
    return STATUS_MORE_PROCESSING_REQUIRED;

}



///////////////////////////////////////////////////////////////////////////////
//
// OsrHandleDevicePowerIrp
//
//      Entry point to handle DEVICE power IRPs
//
//  INPUTS:
//
//      DeviceObject - Pointer to our device object.
//      Irp          - Address of the device power IRP.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_PENDING if we are going to handle the IRP,
//       otherwise the NTSTATUS value of the driver below us
//
//  IRQL:
//
//      This routine is called at IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      This routine is called in an arbitrary thread context
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OsrHandleDevicePowerIrp(PDEVICE_OBJECT DeviceObject,PIRP Irp) {

    PUSBFX2LK_EXT       devExt  = (PUSBFX2LK_EXT)DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION  ioStack = IoGetCurrentIrpStackLocation(Irp);
    POWER_STATE         powerState;
    NTSTATUS            status;

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_POWER_INFO, ("OsrHandleDevicePowerIrp: Entered...\n"));

⌨️ 快捷键说明

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