📄 usbfx2lk_power.cpp
字号:
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 + -