summerfruit
驱动牛犊
驱动牛犊
  • 注册日期2004-06-12
  • 最后登录2013-12-07
  • 粉丝0
  • 关注0
  • 积分395分
  • 威望67点
  • 贡献值0点
  • 好评度36点
  • 原创分0分
  • 专家分0分
阅读:1227回复:0

看看我的线程相关的代码有什么问题

楼主#
更多 发布于:2007-03-29 13:20
  我建立一个线程,代码如下:
PVOID mainevents[] = {
        (PVOID) &pdx->evThreadKill,
        //(PVOID) &timer,
        (PVOID) &pdx->evInterIrpComplete
        };

    //------prepare internal IRP for reading data from modem.
    
    pUrb = ExAllocatePool(NonPagedPool,sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
    if (pUrb==NULL)
    {
        USBD_MODEM_KdPrint(DBGLVL_MEDIUM,("ThreadProc:locating NO %d URB memory failed.\n",0));
        //ExFreePool(pIrp);
        return ;
    }

    pDataBuf = ExAllocatePool(NonPagedPool,1024);
    if (pDataBuf == NULL)
    {
        USBD_MODEM_KdPrint(DBGLVL_HIGH,("ThreadProc()--Error,no memory resource for internal read IRP.\n"));
        ExFreePool(pUrb);
        return;
    }

    UsbBuildInterruptOrBulkTransferRequest(pUrb,sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                                        pdx->hBulkInPipe,
                                        pDataBuf,NULL,1024,
                                        USBD_TRANSFER_DIRECTION_IN|USBD_SHORT_TRANSFER_OK,
                                        NULL);

    pInterIrp = ExAllocatePool(NonPagedPool,sizeof(InternalURBEntry));
    //pInterIrp->Irp = pIrp;
    pInterIrp->Urb = pUrb;
    pInterIrp->pDataBuf = pDataBuf;
    pInterIrp->pvDX = pdx;
    //------end of preparing internal IRP for reading data from modem.
    
    KeInitializeTimerEx(&timer, SynchronizationTimer);
    //KeSetEvent(&pdx->evInterIrpComplete, 0, FALSE);
    //KeClearEvent(&pdx->evInterIrpComplete);

    ASSERT(3 <= THREAD_WAIT_OBJECTS);
    //C_ASSERT(arraysize(pollevents) <= THREAD_WAIT_OBJECTS);

    while (!kill)
    {                        // until told to quit
        if (pIrp!=NULL)
            IoFreeIrp(pIrp);
        
        pIrp = IoAllocateIrp((pdx->LowerDevice->StackSize),FALSE);
        if (pIrp==NULL)
        {
            break ;
        }
        //pStack = IoGetNextIrpStackLocation(pIrp);

        // Now set up the parameters for that driver...
        //pStack->DeviceObject = pdx->DeviceObject;
        //IoSetNextIrpStackLocation(pIrp);
            
        //PIRP Irp = GetCurrentIrp(&pdx->dqReadWrite);
        IoSetCompletionRoutine(pIrp,
                                    (PIO_COMPLETION_ROUTINE) OnInternalIrpComplete,
                                    pInterIrp,
                                    TRUE,        // InvokeOnSuccess
                                    TRUE,        // InvokeOnError
                                    TRUE);       // InvokeOnCancel

        pStack = IoGetNextIrpStackLocation(pIrp);

        // Now set up the parameters for that driver...
        pStack->MajorFunction                            = IRP_MJ_INTERNAL_DEVICE_CONTROL;
        pStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
        pStack->Parameters.Others.Argument1              = pUrb;

        pInterIrp->Irp = pIrp;
        // Starting the timer with a zero due time will cause us to perform the
        // first poll immediately. Thereafter, polls occur at the POLLING_INTERVAL
        // interval (measured in milliseconds).
        KeSetTimerEx(&timer, duetime, POLLING_INTERVAL, NULL);
        KeClearEvent(&pdx->evInterIrpComplete);
        
        USBD_MODEM_KdPrint(DBGLVL_DEFAULT,("-----Now IoCallDriver Called------------.\n"));
        
        lPendingIRPCountIncrement(pdx);
        IoCallDriver(pdx->LowerDevice,pIrp);

        /*status = KeWaitForMultipleObjects(3,
            mainevents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);*/
        status = KeWaitForMultipleObjects(2,
            mainevents, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);

        if (!NT_SUCCESS(status))
        {                    // error in wait
            USBD_MODEM_KdPrint(DBGLVL_HIGH,("POLLING - KeWaitForMultipleObjects failed - %X\n", status));
            break;
        }                    
        if (status == STATUS_WAIT_0)// kill event was set
        {
            USBD_MODEM_KdPrint(DBGLVL_HIGH,("Thread kill event is set.\n"));
            IoCancelIrp(pIrp);
            break;                
        }
        //
        /*if (status == STATUS_WAIT_0+1)
        {
            USBD_MODEM_KdPrint(DBGLVL_HIGH,("timer is out.\n"));
            IoCancelIrp(pIrp);
            KeSetTimerEx(&timer, duetime, POLLING_INTERVAL, NULL);
            continue;
        }*/
        USBD_MODEM_KdPrint(DBGLVL_HIGH,("next read internal URB will be sent.\n"));
    }

    KeWaitForSingleObject(&pdx->evInterIrpComplete,Executive,KernelMode,FALSE,NULL);
    
    //-----------free memory
    if (pInterIrp)
    {
        USBD_MODEM_KdPrint(DBGLVL_DEFAULT,("ThreadProc():pInterIrp will be freed,because thread will be stopped.\n"));
        ExFreePool(pInterIrp);
    }
    if (pUrb)
    {
        USBD_MODEM_KdPrint(DBGLVL_DEFAULT,("ThreadProc():pUrb will be freed, because thread will be stopped.\n"));
        ExFreePool(pUrb);
    }
    if (pIrp)
    {
        USBD_MODEM_KdPrint(DBGLVL_DEFAULT,("ThreadProc():pIrp will be freed, because thread will be stopped.\n"));
        //ExFreePool(pIrp);
        IoFreeIrp(pIrp);
    }
    //-----------end of freeing memory
    USBD_MODEM_KdPrint(DBGLVL_DEFAULT,("ThreadProc(): internal read thread will be killed.\n"));
    
    PsTerminateSystemThread(STATUS_SUCCESS);


IRP完成历程的代码如下:
USBD_MODEM_KdPrint(DBGLVL_MINIMUM,("OnInternalIrpComplete:Enter.\n"));
    if (pInterURBIrp == NULL)
    {
        return STATUS_INVALID_PARAMETER;
    }

    //if (Irp->PendingReturned)
    //    IoMarkIrpPending(Irp);

    //Cancel this irp and release all associated resources.
    if ((status == STATUS_CANCELLED) || (Irp->Cancel == TRUE))
    {
        USBD_MODEM_KdPrint(DBGLVL_MINIMUM,("OnInternalIrpComplete:IRP canceled.\n"));
        lPendingIRPCountDecrement(pdx);
        KeSetEvent(&pdx->evInterIrpComplete, 0, FALSE);
        //return STATUS_CANCELLED;
        return STATUS_MORE_PROCESSING_REQUIRED;
    }
    //get received data length.
    。。。。。。。。收到数据之后的处理,这里省略
    
    KeSetEvent(&pdx->evInterIrpComplete, 0, FALSE);
    USBD_MODEM_KdPrint(DBGLVL_MINIMUM,("OnInternalIRPComplete:Exit.\n"));
    return STATUS_MORE_PROCESSING_REQUIRED;
    
    //return CompleteRequest(Irp, STATUS_SUCCESS, ulRxDataLen);
    
    //return STATUS_SUCCESS;


现在的问题当我Kesetevent(evkill)事件,来结束线程之后,出现了IRQL_NOT_LESS_OR_...错误。

上面的代码有什么问题吗?谢谢
调试过程中发现IoFreeIrp(pIrp);已经执行完毕。

请大家赐教啊
MSN:connectjhp@hotmail.com
EMAIL:huaping.jiang@gmail.com
游客

返回顶部