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

📄 pwr.c

📁 usbhostDriver, 设计USB的目标就是使不同厂家所生产的设备可以在一个开放的体系下广泛的使用。该规范改进了便携商务或家用电脑的现有体系结构
💻 C
📖 第 1 页 / 共 3 页
字号:

/*********************************************************************

Routine Description:

  This is the completion routine for the system power irps of minor
  function types IRP_MN_QUERY_POWER and IRP_MN_SET_POWER.
  This completion routine sends the corresponding device power irp and
  returns STATUS_MORE_PROCESSING_REQUIRED. The system irp is passed as a
  context to the device power irp completion routine and is completed in
  the device power irp completion routine.

Arguments:

  DeviceObject - pointer to device object
  Irp - I/O request packet
  DeviceExtension - pointer to device extension

Return Value:

  NT status value

--*/
NTSTATUS SysPoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN DEVICE_EXTENSION * DeviceExtension) {
  NTSTATUS           ntS;
  PIO_STACK_LOCATION irpStack;

  //
  // initialize variables
  //
  ntS = Irp->IoStatus.Status;
  irpStack = IoGetCurrentIrpStackLocation(Irp);
  DPRINT(("SysPoCompletionRoutine - begins\n"));
  //
  // lower drivers failed this Irp
  //
  if(!NT_SUCCESS(ntS)) {
    PoStartNextPowerIrp(Irp);
    DPRINT(("SysPoCompletionRoutine::"));
    DevIoDecrement(DeviceExtension);
    return STATUS_SUCCESS;
  }
  //
  // ..otherwise update the cached system power state (IRP_MN_SET_POWER)
  //
  if(irpStack->MinorFunction == IRP_MN_SET_POWER) {
    DeviceExtension->SysPower = irpStack->Parameters.Power.State.SystemState;
  }
  //
  // queue device irp and return STATUS_MORE_PROCESSING_REQUIRED
  //
  SendDeviceIrp(DeviceObject, Irp);
  DPRINT(("SysPoCompletionRoutine - ends\n"));
  return STATUS_MORE_PROCESSING_REQUIRED;
}

/*********************************************************************
*
* Routine Description:
*
*  This routine services irps of minor type IRP_MN_SET_POWER
*  for the system power state
*
* Arguments:
*  DeviceObject - pointer to device object
*  Irp - I/O request packet sent by the power manager
*
* Return Value:
*  NT status value:
*/
NTSTATUS HandleSystemSetPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) {
  NTSTATUS           ntS;
  DEVICE_EXTENSION *  deviceExtension;
  SYSTEM_POWER_STATE systemState;
  PIO_STACK_LOCATION irpStack;
  
  DPRINT(("HandleSystemSetPower - begins\n"));
  //
  // initialize variables
  //
  deviceExtension = (DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
  irpStack = IoGetCurrentIrpStackLocation(Irp);
  systemState = irpStack->Parameters.Power.State.SystemState;
  DPRINT(("Set request for system power state S%X\n"
          "Current system power state S%X\n",
          systemState - 1,
          deviceExtension->SysPower - 1));
  IoCopyCurrentIrpStackLocationToNext(Irp);
  IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
                         deviceExtension, TRUE, TRUE, TRUE);
  ntS = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
  DPRINT(("HandleSystemSetPower - ends\n"));
  return STATUS_PENDING;
}

/*********************************************************************
*
*       HandleSystemQueryPower
*
* Routine Description:
*
*  This routine handles the irp with minor function of type IRP_MN_QUERY_POWER
*  for the system power states.
*
* Arguments:
*
*  DeviceObject - pointer to device object
*  Irp - I/O request packet sent by the power manager.
*
* Return Value:
*
*  NT status value
*/
NTSTATUS HandleSystemQueryPower(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) {
  NTSTATUS           ntS;
  DEVICE_EXTENSION *  deviceExtension;
  SYSTEM_POWER_STATE systemState;
  PIO_STACK_LOCATION irpStack;
  
  DPRINT(("HandleSystemQueryPower - begins\n"));
  //
  // initialize variables
  //
  deviceExtension = (DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
  irpStack = IoGetCurrentIrpStackLocation(Irp);
  systemState = irpStack->Parameters.Power.State.SystemState;
  DPRINT(("Query for system power state S%X\n"
         "Current system power state S%X\n",
          systemState - 1,
          deviceExtension->SysPower - 1));
  //
  // Fail a query for a power state incompatible with waking up the system
  //
  if((deviceExtension->WaitWakeEnable) &&
     (systemState > deviceExtension->DeviceCapabilities.SystemWake)) {
    DPRINT(("Query for an incompatible system power state\n"));
    PoStartNextPowerIrp(Irp);
    Irp->IoStatus.Status = ntS = STATUS_INVALID_DEVICE_STATE;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DPRINT(("HandleSystemQueryPower::"));
    DevIoDecrement(deviceExtension);
    return ntS;
  }

  //
  // if querying for a lower S-state, issue a wait-wake
  //

  if((systemState > deviceExtension->SysPower) &&
     (deviceExtension->WaitWakeEnable)) {
    IssueWaitWake(deviceExtension);
  }
  IoCopyCurrentIrpStackLocationToNext(Irp);
  IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
          deviceExtension, TRUE, TRUE, TRUE);
  ntS = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
  DPRINT(("HandleSystemQueryPower - ends\n"));
  return STATUS_PENDING;
}

/*++
 
Routine Description:

    This is the IoSet completion routine for the wait wake irp.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
NTSTATUS WaitWakeCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN DEVICE_EXTENSION * DeviceExtension) {
  DPRINT(("WaitWakeCompletionRoutine - begins\n"));
  if(Irp->PendingReturned) {
    IoMarkIrpPending(Irp);
  }
  //
  // Nullify the WaitWakeIrp pointer-the Irp is released 
  // as part of the completion process. If it's already NULL, 
  // avoid race with the CancelWaitWake routine.
  //
  if (InterlockedExchangePointer(&DeviceExtension->WaitWakeIrp, NULL)) {
    PoStartNextPowerIrp(Irp);
    return STATUS_SUCCESS;
  }
  //
  // CancelWaitWake has run. 
  // If FlagWWCancel != 0, complete the Irp.
  // If FlagWWCancel == 0, CancelWaitWake completes it.
  //
  if(InterlockedExchange(&DeviceExtension->FlagWWCancel, 1)) {
    PoStartNextPowerIrp(Irp);
    return STATUS_CANCELLED;
  }
  DPRINT(("WaitWakeCompletionRoutine - ends\n"));
  return STATUS_MORE_PROCESSING_REQUIRED;
}

/*********************************************************************
 
Routine Description:

    This routine processes queue of pending irps.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
NTSTATUS SetDeviceFunctional(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,IN DEVICE_EXTENSION * DeviceExtension) {
  KIRQL              oldIrql;
  NTSTATUS           ntS;
  POWER_STATE        newState;
  PIO_STACK_LOCATION irpStack;
  DEVICE_POWER_STATE newDevState,
                     oldDevState;
  //
  // initialize variables
  //
  ntS = Irp->IoStatus.Status;
  irpStack = IoGetCurrentIrpStackLocation(Irp);
  newState = irpStack->Parameters.Power.State;
  newDevState = newState.DeviceState;
  oldDevState = DeviceExtension->DevPower;
  DPRINT(("SetDeviceFunctional - begins\n"));
  //
  // update the cached state
  //
  DeviceExtension->DevPower = newDevState;
  //
  // restore appropriate amount of state to our h/w
  // this driver does not implement partial context
  // save/restore.
  //
  PoSetPowerState(DeviceObject, DevicePowerState, newState);
  if(PowerDeviceD0 == newDevState) {
  //
  // empty existing queue of all pending irps.
  //
    KeAcquireSpinLock(&DeviceExtension->DevStateLock, &oldIrql);

    DeviceExtension->QueueState = AllowRequests;
  
    KeReleaseSpinLock(&DeviceExtension->DevStateLock, oldIrql);

    ProcessQueuedRequests(DeviceExtension);
  }
  PoStartNextPowerIrp(Irp);
  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = 0;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
  DPRINT(("SetDeviceFunctional::"));
  DevIoDecrement(DeviceExtension);
  DPRINT(("SetDeviceFunctional - ends\n"));
  return STATUS_SUCCESS;
}

/*********************************************************************
* 
* Routine Description:

    completion routine for the device power UP irp with minor function
    IRP_MN_SET_POWER.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    DeviceExtension - pointer to device extension

Return Value:

    NT status value

--*/
NTSTATUS FinishDevPoUpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN DEVICE_EXTENSION * DeviceExtension ) {
  NTSTATUS           ntS;
  //
  // initialize variables
  //
  ntS = Irp->IoStatus.Status;
  DPRINT(("FinishDevPoUpIrp - begins\n"));
  if(Irp->PendingReturned) {
    IoMarkIrpPending(Irp);
  }
  if(!NT_SUCCESS(ntS)) {
    PoStartNextPowerIrp(Irp);
    DPRINT(("FinishDevPoUpIrp::"));
    DevIoDecrement(DeviceExtension);
    return STATUS_SUCCESS;
  }
  SetDeviceFunctional(DeviceObject, Irp, DeviceExtension);
  DPRINT(("FinishDevPoUpIrp - ends\n"));
  return STATUS_MORE_PROCESSING_REQUIRED;
}


/*********************************************************************
*
*       HandleDeviceSetPower
*
* Routine Description:

  This routine services irps of minor type IRP_MN_SET_POWER
  for the device power state

Arguments:

  DeviceObject - pointer to device object
  Irp - I/O request packet sent by the power manager

Return Value:

  NT status value

--*/
NTSTATUS HandleDeviceSetPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) {
  KIRQL              oldIrql;
  NTSTATUS           ntS;
  POWER_STATE        newState;    
  PIO_STACK_LOCATION irpStack;
  DEVICE_EXTENSION *  deviceExtension;
  DEVICE_POWER_STATE newDevState,
                     oldDevState;

  DPRINT(("HandleDeviceSetPower - begins\n"));
  //
  // initialize variables
  //
  deviceExtension = (DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
  irpStack = IoGetCurrentIrpStackLocation(Irp);
  oldDevState = deviceExtension->DevPower;
  newState = irpStack->Parameters.Power.State;
  newDevState = newState.DeviceState;
  DPRINT(("Set request for device power state D%X\n"
         "Current device power state D%X\n",
          newDevState - 1,
          deviceExtension->DevPower - 1));
  if(newDevState < oldDevState) {
    //
    // adding power
    //
    DPRINT(("Adding power to the device\n"));
    //
    // send the power IRP to the next driver in the stack
    //
    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine(Irp, FinishDevPoUpIrp,deviceExtension, TRUE, TRUE, TRUE);
    ntS = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
  } else {
    //
    // newDevState >= oldDevState 
    //
    // hold I/O if transition from D0 -> DX (X = 1, 2, 3)
    // if transition from D1 or D2 to deeper sleep states, 
    // I/O queue is already on hold.
    //
    if(PowerDeviceD0 == oldDevState && newDevState > oldDevState) {
      //
      // D0 -> DX transition
      //
      DPRINT(("Removing power from the device\n"));
      ntS = HoldIoRequests(DeviceObject, Irp);
      if(!NT_SUCCESS(ntS)) {

⌨️ 快捷键说明

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