阅读:978回复:0
PAGEABLE CODE CALLED AT IRQL 2
帮忙看一下:
1)当队列中只有一个IRP时,在等中断来处理,但此时如果应用程序取消这个IRP时,调用取消例程时,总会出现PAGEABLE CODE CALLED AT IRQL 2?这个问题调试了很久,不能得到解决,望各位高人出手小助,不胜感激! 源代码如下: VOID StigCancelFromReadQueue(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { ///////////////////////////////////////////////////////////////// KIRQL oldIrql; PIRP irpToComplete = NULL; PLIST_ENTRY thisEntry; PLIST_ENTRY listHead; PIRP pendingIrp; PQSPAN_DEVICE_EXTENSION devExt; devExt = DeviceObject->DeviceExtension; #if DBG //DbgPrint(\"StigCancelFromReadQueue... Passed IRP = 0x%0x\\n\", Irp); #endif PAGED_CODE(); oldIrql = Irp->CancelIrql; //KeAcquireSpinLockAtDpcLevel(&devExt->StigReadLock); //IoReleaseCancelSpinLock( KeGetCurrentIrql()); // // Remove the IRP from the queue // listHead = &devExt->ReadQueue; for(thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = thisEntry->Flink) { pendingIrp = CONTAINING_RECORD(thisEntry, IRP, Tail.Overlay.ListEntry); // // Found it! // if(pendingIrp->Cancel) { RemoveEntryList(thisEntry); irpToComplete = pendingIrp; break; } } #if DBG //DbgPrint(\"StigFindQueuedRequest: pendingIrp 0x%0x\\n\", pendingIrp); #endif if(irpToComplete) { #if DBG //DbgPrint(\"StigFindQueuedRequest: canceling irp= 0x%0x\\n\", irpToComplete); #endif // // Put the packet on the free queue // irpToComplete->IoStatus.Status = STATUS_CANCELLED; irpToComplete->IoStatus.Information = 0; IoCompleteRequest(irpToComplete, IO_NO_INCREMENT); StigRequestDecrement(devExt); } #if DBG //DbgPrint(\"StigCancelFromReadQueue: Leaving\\n\"); #endif return; ///////////////////////////////////////////////////////////////// } NTSTATUS StigRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PQSPAN_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; //KIRQL oldIrql; NTSTATUS code = STATUS_SUCCESS; //BOOLEAN listWasEmpty; PIO_STACK_LOCATION ioStack; //ULONG temp; PAGED_CODE(); //_asm{INT 3H; //} #if DBG DbgPrint(\"StigRead: entered\\n\"); #endif // // See what sort of state we\'re in // #if DBG DbgPrint(\"StigRead: devExt->State = 0x%0x\\n\", devExt->State ); #endif if (devExt->State < STATE_ALL_BELOW_FAIL) { code = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; Irp->IoStatus.Status = code; IoCompleteRequest (Irp, IO_NO_INCREMENT); return code; } StigRequestIncrement(devExt); #if DBG DbgPrint(\"StigRead: CurrentIrp = 0x%0x\\n\", Irp); #endif // // Validate the IRP we\'ve received // ioStack = IoGetCurrentIrpStackLocation(Irp); // // If the length of the requested transfer is either zero or too long, // we immediately compelte the IRP with an error status. // if (ioStack->Parameters.Read.Length == 0) { Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return(STATUS_INVALID_USER_BUFFER); } if (Irp->Cancel) { // // Can\'t complete a request with a valid cancel routine! // Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return(STATUS_CANCELLED); } IoMarkIrpPending(Irp); IoSetCancelRoutine(Irp, StigCancelFromReadQueue); // // We\'re done // //KeReleaseSpinLock(&devExt->StigReadLock, oldIrql); ExInterlockedInsertTailList( &devExt->ReadQueue, &Irp->Tail.Overlay.ListEntry, &devExt->StigReadLock); #if DBG DbgPrint(\"StigRead: exiting\\n\"); #endif return(STATUS_PENDING); } |
|