阅读:1306回复:0
关于modem过滤驱动
小弟正在写一个modem驱动过滤程序。我们的设备包含modem功能,还有一个USB bulk接口,
我就是Windows的modem.sys和USBD之间加入一个过滤驱动程序来跟这个USB bulk接口通信,然后把modem.sys传送下来的数据(包括AT命令,发送到BULK接口(设备会把接收到的数据上传给modem功能块。), 然后自建URB从bulk接口把来自modem的数据传到上层。 小弟碰到了一个关于线程的问题(结束线程后产生了IRQL_NOT_LESS_OR_EQUAL) 小弟建立了一个线程来读取来自modem的数据,这个线程在IRP_MJ_OPEN处理例程里打开。例程代码如下: VOID ThreadProc(PDEVICE_EXTENSION pdx) { BOOLEAN kill = FALSE; NTSTATUS status; KTIMER timer; LARGE_INTEGER duetime = {0}; PIRP pIrp = NULL; PURB pUrb = NULL; PIO_STACK_LOCATION pStack=NULL; UCHAR *pDataBuf=NULL; PInternalURBEntry pInterIrp=NULL; 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,("InitializeInternalUSBReadQue:locating NO %d URB memory failed.\n",0)); //ExFreePool(pIrp); return ; } pDataBuf = ExAllocatePool(NonPagedPool,1024); 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")); 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); } //-----------end of freeing memory USBD_MODEM_KdPrint(DBGLVL_DEFAULT,("ThreadProc(): internal read thread will be killed.\n")); PsTerminateSystemThread(STATUS_SUCCESS); } 然后我通过设置事件pdx->evThreadKill来结束线程,我发现在这个函数执行结束后,出现了IRQL_NOT_LESS_OR_EQUAL错误,请高手赐教啊!谢谢先。 |
|