阅读:1774回复:2
求助关于完成挂起的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); // 1: [backcolor=#ff0000][color=#000000]蓝屏,IRQL NOT LESS THAN OR EQUAL [/color][/backcolor] 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); // 2: [backcolor=#ff0000]强制结束进程时,调用此处也蓝屏。同1是一样的错误[/backcolor] if( Irp==deviceExtension->UserMessageIrp) { deviceExtension->UserMessageIrp = NULL; } Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp,IO_NO_INCREMENT); //3: 注释2,[backcolor=#ff0000]强制结束进程时,调用此处也蓝屏。同1是一样的错误[/backcolor] } |
|
沙发#
发布于:2012-01-17 23:18
// 1:请求到来要么完成IRP 要么悬挂IRP STATUS_CANCELLED实在异步取消时才能设置
if(irp == device->CurrentIrp) { KIRQL oldirql = irp -> CancelIrql; IoReleaseCancelSpinLock(irp->CancelIrql); KeLowerIrql(oldirql); }else { IoReleaseCancelSpinLock(irp->CancelIrql); } |
|
板凳#
发布于:2012-01-18 20:33
2 3 先要以取消的方式完成IRP 之后再释放自旋锁
|
|