阅读:2208回复:13
USB驱动中的电源管理
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; 这是我电源管理例程,但是对关机或待机等就会使系统崩溃.是不是要对某个东西进行处理,请各位楼主指出来如何处理,谢谢 |
|
沙发#
发布于: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; |
|
|
板凳#
发布于: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 |
|
地板#
发布于:2007-07-12 17:43
应该是:IoCopyCurrentIrpStackLocationToNext
|
|
|
地下室#
发布于: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);这个用过,那位大侠来顶一下咯 |
|
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);这个用过,那位大侠来顶一下咯 |
|
6楼#
发布于:2007-07-20 13:25
不能关机的这个问题曾经遇到过,应该是有IRP没完成,可以尝试取消它。另外一种方法是找一个好的程序参考一下它的电源管理部分。
|
|
|
7楼#
发布于:2007-07-20 13:58
楼主,我怎么知道有那些没有完成呢,再说,我没有做什么其它的啊
我这个例程就是USB2.0原理与工程开发的实际例子. |
|
8楼#
发布于:2007-09-28 16:06
你的irp完成了没有啊?
|
|
|
9楼#
发布于:2007-10-11 12:02
ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);
if (ntStatus == STATUS_PENDING) { IoMarkIrpPending(Irp); } return ntStatus; 我想问题在上面的代码中,你有IOCALLDRIVER(POCALLDRIVER)调用下层驱动,你的调用者的IRP有没有完成啊? |
|
驱动小牛
|
10楼#
发布于:2007-11-29 15:26
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; 这两行的意义是什么?为什么在IoGetCurrentIrpStackLocation (Irp)之前要做这个,这样不是有可能找到的IRP的位置不对么? |
驱动小牛
|
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); |
12楼#
发布于:2007-12-19 18:22
解决了么?也碰到了此问题...
|
|
|
13楼#
发布于:2008-06-25 16:01
没有解决,在xp中,没有问题,只是在windows2003中存在此问题,以上方法都试过啊.
|
|