阅读:2224回复: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 内存的。
|
|