阅读:1701回复:0
关于EZUSB的内核调用接口死锁问题!
关于EZUSB的内核调用接口死锁问题
我在EZUSB的驱动程序中加入了几个内核接口,他们都调用K_Ezusb_Read_Write与USBD通信。 我还编写了一个TCP/IP协议栈拦截的驱动程序 hook.vxd, 发送函数为MyIpSend,接收函数为MyIpReceive. MyIpSend调用EZUSB的内核接口加密数据,MyIpReceive调用EZUSB的内核接口解密数据。 当我运行FTP,开多个窗口PING时,EZUSB 会出现死锁现象。KeWaitForSingleObject等不到event!!!!! 为什么??? 请教各位!! 谢谢! 我的Email: hupg@21cn.com #include <wdm.h> #include "usbdi.h" #include "usbdlib.h" #include "sciusb.h" #include "ezusbkrnl.h" extern PDEVICE_DATA pDeviceData; extern KSPIN_LOCK SpinLock; NTSTATUS K_Ezusb_CallUSBD(IN PURB Urb) /* Arguments: fdo - pointer to the device object for this instance of an Ezusb Device Urb - pointer to Urb request block Return Value: STATUS_SUCCESS if successful, STATUS_UNSUCCESSFUL otherwise --*/ { NTSTATUS ntStatus, status = STATUS_SUCCESS; //PDEVICE_EXTENSION pdx; PIRP irp; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION nextStack; KEVENT event; KIRQL irql1, irql2 ; Ezusb_KdPrint (("enter Ezusb_CallUSBD\n")); KeInitializeEvent(&event,NotificationEvent,FALSE); //pdx = fdo->DeviceExtension; irql1=KeGetCurrentIrql(); Ezusb_KdPrint (("************** Current Irql %x\n", irql1)); // issue a synchronous request (see notes above) irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, pDeviceData->StackDeviceObject, NULL, 0, NULL, 0, TRUE, /* INTERNAL */ &event, &ioStatus); // Prepare for calling the USB driver stack nextStack = IoGetNextIrpStackLocation(irp); ASSERT(nextStack != NULL); // Set up the URB ptr to pass to the USB driver stack nextStack->Parameters.Others.Argument1 = Urb; Ezusb_KdPrint (("Calling USB Driver Stack\n")); // // Call the USB class driver to perform the operation. If the returned status // is PENDING, wait for the request to complete. // //IoSetCompletionRoutine( irp, (PIO_COMPLETION_ROUTINE)IrpCompletionRoutine, // (PVOID)&event, TRUE, TRUE, TRUE); ntStatus = IoCallDriver(pDeviceData->StackDeviceObject,irp); Ezusb_KdPrint (("return from IoCallDriver USBD %x\n", ntStatus)); if (ntStatus == STATUS_PENDING) { Ezusb_KdPrint (("Wait for single object\n")); // 等不到!!!!!!!!! status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); Ezusb_KdPrint (("Wait for single object, returned %x\n", status)); } else { ioStatus.Status = ntStatus; } Ezusb_KdPrint (("URB status = %x status = %x irp status %x\n", Urb->UrbHeader.Status, status, ioStatus.Status)); // // USBD maps the error code for us. USBD uses error codes in its URB // structure that are more insightful into USB behavior. In order to // match the NT Status codes, USBD maps its error codes into more general NT // error categories so higher level drivers can decipher the error codes // based on standard NT error code definitions. // ntStatus = ioStatus.Status; // // If the URB status was not USBD_STATUS_SUCCESS, we save a copy of the // URB status in the device extension. After a failure, another IOCTL, // IOCTL_EZUSB_GET_LAST_ERROR can be used to retrieve the URB status // for the most recently failed URB. Of course, this status gets // overwritten by subsequent failures, but it's better than nothing. // if (!(USBD_SUCCESS(Urb->UrbHeader.Status))) pDeviceData->LastFailedUrbStatus = Urb->UrbHeader.Status; // // if ioStatus.Status indicates an error (ie. the IRP failed) then return that. // If ioStatus.Status indicates success, it is still possible that what we were // trying to do failed. For example, if the IRP is cancelled, the status returned // by the I/O manager for the IRP will not indicate an error. In that case, we // should check the URB status. If it indicates anything other than // USBD_SUCCESS, then we should return STATUS_UNSUCCESSFUL. // if (NT_SUCCESS(ntStatus)) { if (!(USBD_SUCCESS(Urb->UrbHeader.Status))) ntStatus = STATUS_UNSUCCESSFUL; } Ezusb_KdPrint(("exit Ezusb_CallUSBD (%x)\n", ntStatus)); return ntStatus; } NTSTATUS K_Ezusb_Read_Write( PBULKTRANSFER BulkTransfer) /*++ Routine Description: Arguments: Return Value: NT status code STATUS_SUCCESS: Read was done successfully STATUS_INVALID_PARAMETER_3: The Endpoint Index does not specify an IN pipe STATUS_NO_MEMORY: Insufficient data memory was supplied to perform the READ This routine fills the status code into the Irp --*/ { //PDEVICE_EXTENSION pdx = fdo->DeviceExtension; NTSTATUS ntStatus; //PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation (Irp); PBULK_TRANSFER_CONTROL bulkControl =&BulkTransfer->BulkTransCtrl; ULONG bufferLength =BulkTransfer->dwTransLen ; PURB urb = NULL; ULONG urbSize = 0; ULONG transferFlags = 0; PUSBD_INTERFACE_INFORMATION interfaceInfo = NULL; PUSBD_PIPE_INFORMATION pipeInfo = NULL; USBD_PIPE_HANDLE pipeHandle = NULL; // KIRQL OldIrql; Ezusb_KdPrint(("enter Ezusb_Read_Write()\n")); // // verify that the selected pipe is valid, and get a handle to it. If anything // is wrong, return an error // interfaceInfo = pDeviceData->Interface;//pdx->Interface; if (!interfaceInfo) { Ezusb_KdPrint(("Ezusb_Read_Write() no interface info - Exiting\n")); return STATUS_UNSUCCESSFUL; } if (bulkControl->pipeNum > interfaceInfo->NumberOfPipes) { Ezusb_KdPrint(("Ezusb_Read_Write() invalid pipe - Exiting\n")); return STATUS_INVALID_PARAMETER; } pipeInfo = &(interfaceInfo->Pipes[bulkControl->pipeNum]); if (!((pipeInfo->PipeType == UsbdPipeTypeBulk) || (pipeInfo->PipeType == UsbdPipeTypeInterrupt))) { Ezusb_KdPrint(("Ezusb_Read_Write() invalid pipe - Exiting\n")); return STATUS_INVALID_PARAMETER; } pipeHandle = pipeInfo->PipeHandle; if (!pipeHandle) { Ezusb_KdPrint(("Ezusb_Read_Write() invalid pipe - Exiting\n")); return STATUS_UNSUCCESSFUL; } if (bufferLength > pipeInfo->MaximumTransferSize) { Ezusb_KdPrint(("Ezusb_Read_Write() invalid transfer size - Exiting\n")); return STATUS_INVALID_PARAMETER; } // // allocate and fill in the Usb request (URB) // urbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); urb = ExAllocatePool(NonPagedPool,urbSize); if (!urb) { Ezusb_KdPrint(("Ezusb_Read_Write() unable to alloc URB - Exiting\n")); return STATUS_NO_MEMORY; } transferFlags = USBD_SHORT_TRANSFER_OK; // // get direction info from the endpoint address // if (USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress)) transferFlags |= USBD_TRANSFER_DIRECTION_IN; UsbBuildInterruptOrBulkTransferRequest(urb, //ptr to urb (USHORT) urbSize, //size of urb pipeHandle, //usbd pipe handle BulkTransfer->pBuf,//NULL, //TransferBuffer NULL,//Irp->MdlAddress, //mdl bufferLength, //bufferlength transferFlags, //flags NULL); //link // // Call the USB Stack. // ntStatus = K_Ezusb_CallUSBD(urb); // // If the transfer was successful, report the length of the transfer to the // caller by setting IoStatus.Information // if (NT_SUCCESS(ntStatus)) { //Irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength; //Ezusb_KdPrint(("Successfully transfered 0x%x bytes\n",Irp->IoStatus.Information)); } // // free the URB // ExFreePool(urb); return ntStatus; } |
|
最新喜欢:linwn
|