leo663366
驱动牛犊
驱动牛犊
  • 注册日期2010-10-21
  • 最后登录2011-01-03
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2106回复:0

驱动调驱动:KeWaitForSingleObject一直不返回

楼主#
更多 发布于:2010-12-28 19:25
本人实现文件系统过滤驱动来对usb驱动进行调用,硬件平台用的是68013,基于他的驱动程序进行了更改,由于文件系统的过滤驱动以并发的形式向下派发irp,我在usb驱动里面对irp进行串行化的处理,实现如下:在派发函数里面用事件来进行临界区的访问。
问题现象如下:在执行到以下代码的时候,程序在down在KeWaitForSingleObject,一直不返回。(代码在后面)
我的疑问是:当usb驱动位于顶层的时候,用户态以并发的形式来访问usb的时候,运行正常。我对这两种情况调试了一下,发现在用户态进行usb驱动的直接调用的时候,irql是passive_level,通过文件系统过滤驱动来调用usb驱动的时候,irql变成了apc_level,不知道这些有没有什么影响,忘高手指点小弟。

代码:
NTSTATUS
Ezusb_CallUSBD(
    IN PDEVICE_OBJECT fdo,
    IN PURB Urb
    )
{
   NTSTATUS ntStatus, status = STATUS_SUCCESS;
   PDEVICE_EXTENSION pdx;
   PIRP irp;
   KEVENT event;
   IO_STATUS_BLOCK ioStatus;
   PIO_STACK_LOCATION nextStack;

   Ezusb_KdPrint (("enter Ezusb_CallUSBD\n"));

   pdx = fdo->DeviceExtension;

   // issue a synchronous request (see notes above)
   KeInitializeEvent(&event, NotificationEvent, FALSE);

   irp = IoBuildDeviceIoControlRequest(
             IOCTL_INTERNAL_USB_SUBMIT_URB,
             pdx->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"));

    ntStatus = IoCallDriver(pdx->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));

    ntStatus = ioStatus.Status;

   if (!(USBD_SUCCESS(Urb->UrbHeader.Status)))
      pdx->LastFailedUrbStatus = Urb->UrbHeader.Status;

    if (NT_SUCCESS(ntStatus))
   {
      if (!(USBD_SUCCESS(Urb->UrbHeader.Status)))
         ntStatus = STATUS_UNSUCCESSFUL;
   }

   Ezusb_KdPrint(("exit Ezusb_CallUSBD (%x)\n", ntStatus));

   return ntStatus;
}
游客

返回顶部