hupeng
驱动牛犊
驱动牛犊
  • 注册日期2001-05-09
  • 最后登录2018-05-28
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望117点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1701回复:0

关于EZUSB的内核调用接口死锁问题!

楼主#
更多 发布于:2001-10-16 20:32
关于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;
  
}


最新喜欢:

linwnlinwn
hp
游客

返回顶部