zhoujiamurong
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2009-05-06
  • 粉丝4
  • 关注0
  • 积分1081分
  • 威望360点
  • 贡献值0点
  • 好评度215点
  • 原创分0分
  • 专家分0分
阅读:1614回复:1

完成例程的pUrb->UrbHeader.Status不为零

楼主#
更多 发布于:2008-08-07 10:34
我在Windows XP 使用 DDK2000 ,修改其中的Serial示例成为一个USB Modem,安装已经完成,默认管道PIPE0可以正常。
我在Pipe1(向硬件写数据),格式化了一个URB ,发送,在完成例程回来的时候pUrb->UrbHeader.Status一直就不为0,(硬件已经确认是好的,使用其他的驱动可以通讯),确认是我驱动的问题,大致的代码如下,请大大帮忙看看,两个星期都没有弄出来。



typedef struct _Smallbuffer
{
    PDEVICE_EXTENSION pdEx;
    PURB pUrb;
}Smallbuffer,*pSmallbuffer;

在PIPE1 的发送函数中:
//格式化urb
urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
if ( urb )
  {
    RtlZeroMemory(urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));

    UsbBuildInterruptOrBulkTransferRequest(urb,
         sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),PipeHandle.PipeHandle,
     TransferBuffer,0,BufferLength,TransferFlag |2,0);
   }

// 因为有两个指针要传给完成例程
pSmallBuffer = ExAllocatePool(NonPagedPool, sizeof(Smallbuffer));
  if ( !pSmallBuffer)
  {
    ExFreePool(pUrb);
    return STATUS_INSUFFICIENT_RESOURCES;
  }
  
  pSmallBuffer->pUrb = pUrb;
  pSmallBuffer->pdEx = pdEx;
  
   // Allocate the Irp
    //
  StackSize = pdEx->LowerDeviceObject->StackSize + 1;
  NewIrp = IoAllocateIrp((CCHAR)StackSize, FALSE);
  if ( !NewIrp )
  {
    ExFreePool(pUrb);
    ExFreePool(pSmallBuffer);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  // now can Abort pipe1(pipe20)
  pdEx2->CanAbortPipe20_4548 = TRUE;

    //
    // Set the Irp parameters
    //
  nextStack = IoGetNextIrpStackLocation(NewIrp);
  nextStack->Parameters.Others.Argument1 = pUrb;
  nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;

    //
    // Set the completion routine.
    //
  IoSetCompletionRoutine(NewIrp,IrpCompletionRoutinePipe1,
      pSmallBuffer,TRUE,TRUE,TRUE);

     //
    // pass the irp down usb stack
    //
  result = IofCallDriver(pdEx->LowerDeviceObject, NewIrp);
  
  pdEx2->HaveSendIrp4296 = TRUE;
  return result;

完成例程中
NTSTATUS IrpCompletionRoutinePipe1(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp, PVOID smallbuffer)
{
pSmallbuffer Buffer8 = smallbuffer;

  //
  // Init
  //
  pUrb = Buffer8->pUrb;
  pdEx = Buffer8->pdEx;

if(pUrb->UrbHeader.Status != 0)
{
////? 一直是0xC0010000 或者 0xC0007000
}

}
zhoujiamurong
驱动小牛
驱动小牛
  • 注册日期2006-03-20
  • 最后登录2009-05-06
  • 粉丝4
  • 关注0
  • 积分1081分
  • 威望360点
  • 贡献值0点
  • 好评度215点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-08-07 17:07
同时,当远程Modem拨号过来的时候,这边应该读到RING的字符串。

发现不仅Read IRP的完成例程一直没有被调用,而且Create时候的IRP 一直PENDING状态,无论多少电话来都是PENDING,直到关闭的时候,这个IRP才被Cancel.
应该是有字符来的时候,调用完成例程,读出字符,再发一个新的Read IRP,PENDING。

是否我的第一个Read IRP包就有问题,导致IRP一直PENDING
游客

返回顶部