wzb_cncs
驱动牛犊
驱动牛犊
  • 注册日期2002-11-08
  • 最后登录2005-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:953回复:0

PAGEABLE CODE CALLED AT IRQL 2

楼主#
更多 发布于:2004-01-08 18:21
帮忙看一下:
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);

}
游客

返回顶部