oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
阅读:2208回复:13

USB驱动中的电源管理

楼主#
更多 发布于:2007-07-11 11:00
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION IrpStack, NextStack;
    PDEVICE_EXTENSION pdx;

    pdx = fdo->DeviceExtension;
 
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IrpStack = IoGetCurrentIrpStackLocation (Irp);

    switch (IrpStack->MinorFunction) {
        case IRP_MN_SET_POWER:   //设置系统或设备电源状态
            switch (IrpStack->Parameters.Power.Type) {
                case SystemPowerState:
                    break;
                case DevicePowerState:
                    switch (IrpStack->Parameters.Power.State.DeviceState) {
                        case PowerDeviceD3:
                            break;
                        case PowerDeviceD2:
                            break;
                        case PowerDeviceD1:
                            break;
                        case PowerDeviceD0:
                            break;
                    }
                break;
             }
         break;  
         case IRP_MN_QUERY_POWER: //查询能否更改系统或设备电源状态
             switch (IrpStack->Parameters.Power.Type) {
            case SystemPowerState:
                break;
            case DevicePowerState:
                switch (IrpStack->Parameters.Power.State.DeviceState) {
                    case PowerDeviceD2:                    
                        break;
                    case PowerDeviceD1:
                         break;
                    case PowerDeviceD3:
                         break;
                }
               break;
             }
         break;
         default:
             ;
    }
    NextStack = IoGetNextIrpStackLocation(Irp);
    RtlCopyMemory(NextStack, IrpStack, sizeof(IO_STACK_LOCATION));

    ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);

   if (ntStatus == STATUS_PENDING) {
       IoMarkIrpPending(Irp);
   }
   return ntStatus;

这是我电源管理例程,但是对关机或待机等就会使系统崩溃.是不是要对某个东西进行处理,请各位楼主指出来如何处理,谢谢
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
沙发#
发布于:2007-07-11 12:01
下面几行有点问题:
    NextStack = IoGetNextIrpStackLocation(Irp);
    RtlCopyMemory(NextStack, IrpStack, sizeof(IO_STACK_LOCATION));

    ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);

   if (ntStatus == STATUS_PENDING) {
       IoMarkIrpPending(Irp);
  }
  return status;


改一下:
IoCopyCurrentIrpStackLocation(Irp);
// 不要用RtlCopyMemory

ntStatus = PoCallDriver(pdx->StackDeviceObject, Irp);
 // Vista 下面可以用IoCallDriver, 但2000/XP/2003下面必须用 PoCallDriver

return status;
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-07-11 15:25
    //RtlCopyMemory(NextStack, IrpStack, sizeof(IO_STACK_LOCATION));
    IoCopyCurrentIrpStackLocation(Irp);


    //ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);
    ntStatus = PoCallDriver(pdx->StackDeviceObject, Irp);

编译说error C4013: 'IoCopyCurrentIrpStackLocation' undefined; assuming extern returning int
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
地板#
发布于:2007-07-12 17:43
应该是:IoCopyCurrentIrpStackLocationToNext
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-07-19 14:18
/********************************************************************************************
电源管理例程Start
********************************************************************************************/
NTSTATUS Ezusb_PowerIrp(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION IrpStack, NextStack;
    PDEVICE_EXTENSION pdx;

    pdx = fdo->DeviceExtension;
 
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IrpStack = IoGetCurrentIrpStackLocation (Irp);

    switch (IrpStack->MinorFunction) {
        case IRP_MN_SET_POWER:   //设置系统或设备电源状态
            switch (IrpStack->Parameters.Power.Type) {
                case SystemPowerState:
                    break;
                case DevicePowerState:
                    switch (IrpStack->Parameters.Power.State.DeviceState) {
                        case PowerDeviceD3:
                            break;
                        case PowerDeviceD2:
                            break;
                        case PowerDeviceD1:
                            break;
                        case PowerDeviceD0:
                            break;
                    }
                break;
             }
         break;  
         case IRP_MN_QUERY_POWER: //查询能否更改系统或设备电源状态
             switch (IrpStack->Parameters.Power.Type) {
            case SystemPowerState:
                break;
            case DevicePowerState:
                switch (IrpStack->Parameters.Power.State.DeviceState) {
                    case PowerDeviceD2:                    
                        break;
                    case PowerDeviceD1:
                         break;
                    case PowerDeviceD3:
                         break;
                }
               break;
             }
         break;
         default:
             ;
    }
    /*NextStack = IoGetNextIrpStackLocation(Irp);
    RtlCopyMemory(NextStack, IrpStack, sizeof(IO_STACK_LOCATION));
    */
    //IoCopyCurrentIrpStackLocationToNext(Irp);


    //ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    ntStatus = PoCallDriver(pdx->StackDeviceObject, Irp);


   if (ntStatus == STATUS_PENDING) {
       IoMarkIrpPending(Irp);
   }
   return ntStatus;
}
/********************************************************************************************
电源管理例程End
********************************************************************************************/

现在的问题是使用这个例程后,WINDOWS关机的最后一步关不掉电源,死在那里了,郁闷
IoCopyCurrentIrpStackLocationToNext(Irp);这个用过,那位大侠来顶一下咯
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-07-19 15:24
/********************************************************************************************
电源管理例程Start
********************************************************************************************/
NTSTATUS Ezusb_PowerIrp(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION IrpStack, NextStack;
    PDEVICE_EXTENSION pdx;

    pdx = fdo->DeviceExtension;

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IrpStack = IoGetCurrentIrpStackLocation (Irp);

    switch (IrpStack->MinorFunction) {
        case IRP_MN_SET_POWER:  //设置系统或设备电源状态
            switch (IrpStack->Parameters.Power.Type) {
                case SystemPowerState:
                    break;
                case DevicePowerState:
                    switch (IrpStack->Parameters.Power.State.DeviceState) {
                        case PowerDeviceD3:
                            break;
                        case PowerDeviceD2:
                            break;
                        case PowerDeviceD1:
                            break;
                        case PowerDeviceD0:
                            break;
                    }
                break;
             }
        break;  
        case IRP_MN_QUERY_POWER: //查询能否更改系统或设备电源状态
            switch (IrpStack->Parameters.Power.Type) {
            case SystemPowerState:
                break;
            case DevicePowerState:
                switch (IrpStack->Parameters.Power.State.DeviceState) {
                    case PowerDeviceD2:                    
                        break;
                    case PowerDeviceD1:
                        break;
                    case PowerDeviceD3:
                        break;
                }
              break;
             }
        break;
        default:
             ;
    }
    /*NextStack = IoGetNextIrpStackLocation(Irp);
    RtlCopyMemory(NextStack, IrpStack, sizeof(IO_STACK_LOCATION));
    */
    //IoCopyCurrentIrpStackLocationToNext(Irp);


    //ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    ntStatus = PoCallDriver(pdx->StackDeviceObject, Irp);


  if (ntStatus == STATUS_PENDING) {
       IoMarkIrpPending(Irp);
  }
  return ntStatus;
}
/********************************************************************************************
电源管理例程End
********************************************************************************************/

现在的问题是使用这个例程后,WINDOWS关机的最后一步关不掉电源,死在那里了,郁闷
IoCopyCurrentIrpStackLocationToNext(Irp);这个用过,那位大侠来顶一下咯
lejianz
驱动中牛
驱动中牛
  • 注册日期2003-03-05
  • 最后登录2023-11-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望145点
  • 贡献值0点
  • 好评度116点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2007-07-20 13:25
不能关机的这个问题曾经遇到过,应该是有IRP没完成,可以尝试取消它。另外一种方法是找一个好的程序参考一下它的电源管理部分。
一起交流,共同提高!
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-07-20 13:58
楼主,我怎么知道有那些没有完成呢,再说,我没有做什么其它的啊
我这个例程就是USB2.0原理与工程开发的实际例子.
chenliang03
驱动牛犊
驱动牛犊
  • 注册日期2007-08-27
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分110分
  • 威望12点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-09-28 16:06
你的irp完成了没有啊?
to be or not to be
maoxiaojun
驱动牛犊
驱动牛犊
  • 注册日期2007-09-04
  • 最后登录2009-04-07
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望42点
  • 贡献值0点
  • 好评度39点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-10-11 12:02
ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);

  if (ntStatus == STATUS_PENDING) {
       IoMarkIrpPending(Irp);
  }
  return ntStatus;
我想问题在上面的代码中,你有IOCALLDRIVER(POCALLDRIVER)调用下层驱动,你的调用者的IRP有没有完成啊?
zhoujiamurong
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2009-05-06
  • 粉丝4
  • 关注0
  • 积分1081分
  • 威望360点
  • 贡献值0点
  • 好评度215点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-11-29 15:26
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
这两行的意义是什么?为什么在IoGetCurrentIrpStackLocation (Irp)之前要做这个,这样不是有可能找到的IRP的位置不对么?
zhoujiamurong
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2009-05-06
  • 粉丝4
  • 关注0
  • 积分1081分
  • 威望360点
  • 贡献值0点
  • 好评度215点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-11-29 15:46
下面的
    NextStack = IoGetNextIrpStackLocation(Irp);
    RtlCopyMemory(NextStack, IrpStack, sizeof(IO_STACK_LOCATION));
    上面两句不知道不用IoCopyCurrentIrpStackLocationToNext(Irp);有什么意思
    ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);

改成
    PoStartNextPowerIrp( Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return PoCallDriver( pdx->StackDeviceObject, Irp);
ubuntu_amateur
驱动牛犊
驱动牛犊
  • 注册日期2006-08-04
  • 最后登录2008-12-04
  • 粉丝0
  • 关注0
  • 积分970分
  • 威望98点
  • 贡献值0点
  • 好评度97点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-12-19 18:22
解决了么?也碰到了此问题...
there is a will,there is a way
oushengfen
驱动牛犊
驱动牛犊
  • 注册日期2007-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分747分
  • 威望124点
  • 贡献值1点
  • 好评度82点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2008-06-25 16:01
没有解决,在xp中,没有问题,只是在windows2003中存在此问题,以上方法都试过啊.
游客

返回顶部