|
阅读:2424回复:4
完成挂起的IRP时,蓝屏。 求助。
我要在应用层开buffer供内核使用。当采集数据时,应用层开辟足够的空间,然后传递给内核,驱动程序挂起该IRP。
当停止采集时,内核关闭挂起IRP(开始采集时的IRP)时,程序崩溃。 错误的原因是 IRQL LESS THAN OR EQUAL 给我的感觉是 挂起的IRP在分页内存中,我也粗略的检查了引入的buffer在崩溃1处,没有消除。 (如代码所示,经过各种测试,有3种情况会发生上述错误。) 代码如下 NTSTATUS
SfDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch( ioControlCode)
{
//...该IRP仅仅传递来了一个BUFFER,供内核输出。
case IOCTL_DRIVER_REF_BUFFER:
Irp->IoStatus.Status = STATUS_PENDING;
Irp->IoStatus.Information = 0;
IoMarkIrpPending(Irp);
IoSetCancelRoutine(Irp, OnCancelIrp);
deviceExtension->rbBufferIrp = Irp;
return STATUS_PENDING;
...
//buffer使用完成后,完成挂起的rbBufferIrp,其他问题不会处理rbBufferIrp
//应用程序也不会主动cancelIO
case IOCTL_DRIVER_DEREF_BUFFER:
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT); // 蓝屏,IRQL NOT LESS THAN OR EQUAL
break;
default:
//.....
break
}
//......
IoCompleteRequest(Irp,IO_NO_INCREMENT);
}
OnCancelIrp(PDEVICE_OBJECT DeviceObject, PIRP pirp)
{
PDEVICE_EXTENSION deviceExtension = ;
deviceExtension = (PDEVICE_EXTENSION)
DeviceObject->DeviceExtension;
IoReleaseCancelSpinLock(Irp->CancelIrql);
if( Irp==deviceExtension->UserMessageIrp)
{
deviceExtension->UserMessageIrp = NULL;
}
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
} |
|
|
沙发#
发布于:2012-01-13 09:16
这种错误通常是内存错误,比如你多次释放同一同存块,或者访问空指针。可以用!page 看一下这块内存是否存在
|
|
|
|
板凳#
发布于:2012-01-15 21:43
25.IoCompleteRequest(Irp,IO_NO_INCREMENT); // 蓝屏,IRQL NOT LESS THAN OR EQUAL
34.IoCompleteRequest(Irp,IO_NO_INCREMENT); 好象执行了2次 |
|
|
|
地板#
发布于:2012-01-17 23:01
NTSTATUS
SfDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) 返回了什么,采用异步方式只能返回STATUS_PENDING,即使你完成了IRP |
|
|
地下室#
发布于:2012-01-20 16:47
有可能是IRQL的问题哦, 看下蓝屏的dump里 CURRENT_IRQL 值为多少,在DISPATCH_LEVEL及以上是不允许使用PagedPool 内存的。
|
|