⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testdispatch.c

📁 USB2.0原理与工程开发光盘(第二版)
💻 C
📖 第 1 页 / 共 2 页
字号:
   ULONG                      packetSize = 0;
   PUSBD_INTERFACE_INFORMATION interfaceInfo = NULL;
   PUSBD_PIPE_INFORMATION     pipeInfo = NULL;
   USBD_PIPE_HANDLE           pipeHandle = NULL;
   PISO_STREAM_OBJECT         streamObject;
   ULONG                      i;
   
   interfaceInfo = pdx->Interface;

   if (!interfaceInfo)
   {
      return STATUS_UNSUCCESSFUL;
   }
   
   if (isoControl->PipeNum > interfaceInfo->NumberOfPipes)
   {
      return STATUS_INVALID_PARAMETER;
   }

   pipeInfo = &(interfaceInfo->Pipes[isoControl->PipeNum]);

   if (!(pipeInfo->PipeType == UsbdPipeTypeIsochronous))
   {
      return STATUS_INVALID_PARAMETER;
   }

   pipeHandle = pipeInfo->PipeHandle;

   if (!pipeHandle)
   {
      return STATUS_UNSUCCESSFUL;
   }
 
   if (isoControl->PacketCount % (isoControl->FramesPerBuffer * isoControl->BufferCount))
   {
      return STATUS_INVALID_PARAMETER;
   }
   
   packetSize = isoControl->PacketSize;

   if (bufferLength < (isoControl->PacketCount * (packetSize + sizeof(USBD_ISO_PACKET_DESCRIPTOR))))
   {
      return STATUS_UNSUCCESSFUL;
   }

   streamObject = ExAllocatePool(NonPagedPool, sizeof(ISO_STREAM_OBJECT));

   if (!streamObject)
   {
      return STATUS_NO_MEMORY;
   }
   
   streamObject->FramesPerBuffer = isoControl->FramesPerBuffer;
   
   streamObject->BufferCount = isoControl->BufferCount;

   streamObject->DeviceObject = fdo;
   streamObject->PipeInfo = pipeInfo;
   streamObject->PacketSize = packetSize;
   streamObject->NumPackets = isoControl->PacketCount;
   streamObject->TransferBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
   streamObject->TransferBufferLength = streamObject->PacketSize * streamObject->NumPackets;
   streamObject->IsoDescriptorBuffer = (PUCHAR) streamObject->TransferBuffer + streamObject->TransferBufferLength;
   
   streamObject->TransferObject = ExAllocatePool(NonPagedPool,
                            sizeof(ISO_TRANSFER_OBJECT) * streamObject->BufferCount);

   if (!streamObject->TransferObject)
   {
      return STATUS_NO_MEMORY;
   }

   for (i=0; i < streamObject->BufferCount; i++)
   {
      InitTransferObject(streamObject,i);
   }

   for (i=0; i < streamObject->BufferCount; i++)
   {
      IoCallDriver(pdx->LowerDeviceObject,
                  streamObject->TransferObject[i].Irp);
   }
  
   for (i=0; i < streamObject->BufferCount; i++)
   {
      KeWaitForSingleObject(
                    &streamObject->TransferObject[i].Done,
                    Suspended,
                    KernelMode,
                    FALSE,
                    NULL);
   }
 
   ExFreePool(streamObject->TransferObject);
   ExFreePool(streamObject);

   return STATUS_SUCCESS;
}

NTSTATUS InitTransferObject(IN OUT PISO_STREAM_OBJECT streamObject,IN ULONG index)
{
   PISO_TRANSFER_OBJECT transferObject = &streamObject->TransferObject[index];
   PUSBD_PIPE_INFORMATION pipeInfo = streamObject->PipeInfo;
   USHORT urbSize = 0;
   CCHAR stackSize;
   PIO_STACK_LOCATION nextStack = NULL;
   PURB urb = NULL;
   PIRP irp = NULL;
   PDEVICE_EXTENSION pdx =
      (PDEVICE_EXTENSION) streamObject->DeviceObject->DeviceExtension;
   ULONG i;

 
   urbSize = (USHORT)GET_ISO_URB_SIZE(streamObject->FramesPerBuffer);

   urb = ExAllocatePool(NonPagedPool, urbSize);
   RtlZeroMemory(urb,urbSize);

   urb->UrbHeader.Length = urbSize;
   urb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
   urb->UrbIsochronousTransfer.PipeHandle = pipeInfo->PipeHandle;
   urb->UrbIsochronousTransfer.TransferFlags =
      USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress) ? USBD_TRANSFER_DIRECTION_IN : 0;
   urb->UrbIsochronousTransfer.TransferFlags |=
      USBD_START_ISO_TRANSFER_ASAP;
   urb->UrbIsochronousTransfer.TransferFlags |=
      USBD_SHORT_TRANSFER_OK;
   urb->UrbIsochronousTransfer.TransferBufferLength =
      streamObject->PacketSize * streamObject->FramesPerBuffer;
   urb->UrbIsochronousTransfer.TransferBuffer =
      ((PUCHAR) streamObject->TransferBuffer) +  (index * streamObject->PacketSize * streamObject->FramesPerBuffer);

   urb->UrbIsochronousTransfer.NumberOfPackets = streamObject->FramesPerBuffer;

 
   for (i=0; i<streamObject->FramesPerBuffer; i++)
   {
      urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i * streamObject->PacketSize;
      urb->UrbIsochronousTransfer.IsoPacket[i].Length = streamObject->PacketSize;
   }

   stackSize = (CCHAR) (pdx->LowerDeviceObject->StackSize + 1);

   irp = IoAllocateIrp(stackSize, FALSE);
   IoInitializeIrp(irp, irp->Size, stackSize);

   nextStack = IoGetNextIrpStackLocation(irp);

   nextStack->Parameters.Others.Argument1 = urb;
   nextStack->Parameters.DeviceIoControl.IoControlCode = 
      IOCTL_INTERNAL_USB_SUBMIT_URB;                    
   nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;

   IoSetCompletionRoutine(irp,
                          IsoTransferComplete,
                          transferObject,
                          TRUE,
                          TRUE,
                          TRUE);

   transferObject->Frame = index * streamObject->FramesPerBuffer;
   transferObject->Urb = urb;
   transferObject->Irp = irp;
   transferObject->StreamObject = streamObject;
   KeInitializeEvent(&transferObject->Done, NotificationEvent, FALSE);

   return STATUS_SUCCESS;
}

NTSTATUS IsoTransferComplete(IN PDEVICE_OBJECT bunkfdo,IN PIRP Irp,IN PVOID Context)
{
   NTSTATUS ntStatus,status;
   PISO_TRANSFER_OBJECT transferObject = (PISO_TRANSFER_OBJECT) Context;
   PISO_STREAM_OBJECT streamObject = transferObject->StreamObject;
   PDEVICE_OBJECT fdo = streamObject->DeviceObject;
   PDEVICE_EXTENSION          pdx = fdo->DeviceExtension;
   PIO_STACK_LOCATION nextStack;
   PURB urb = transferObject->Urb;
   USHORT urbSize = 0;
   ULONG i;

   RtlCopyMemory((PUCHAR) streamObject->IsoDescriptorBuffer + (transferObject->Frame * sizeof(USBD_ISO_PACKET_DESCRIPTOR)),
                 urb->UrbIsochronousTransfer.IsoPacket,
                 (streamObject->FramesPerBuffer * sizeof(USBD_ISO_PACKET_DESCRIPTOR)));

   transferObject->Frame += (streamObject->FramesPerBuffer * streamObject->BufferCount);

   if (transferObject->Frame < streamObject->NumPackets)
   {   
      urbSize = (USHORT)GET_ISO_URB_SIZE(streamObject->FramesPerBuffer);
      RtlZeroMemory(urb,urbSize);

      urb->UrbHeader.Length = urbSize;
      urb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
      urb->UrbIsochronousTransfer.PipeHandle = streamObject->PipeInfo->PipeHandle;
      urb->UrbIsochronousTransfer.TransferFlags =
         USB_ENDPOINT_DIRECTION_IN(streamObject->PipeInfo->EndpointAddress) ? USBD_TRANSFER_DIRECTION_IN : 0;
      urb->UrbIsochronousTransfer.TransferFlags |=
         USBD_START_ISO_TRANSFER_ASAP;
      urb->UrbIsochronousTransfer.TransferFlags |=
         USBD_SHORT_TRANSFER_OK;
      urb->UrbIsochronousTransfer.TransferBufferLength =
         streamObject->PacketSize * streamObject->FramesPerBuffer;
      urb->UrbIsochronousTransfer.TransferBuffer =
         ((PUCHAR) streamObject->TransferBuffer) +  (transferObject->Frame * streamObject->PacketSize);
      urb->UrbIsochronousTransfer.NumberOfPackets = streamObject->FramesPerBuffer;

      for (i=0; i<streamObject->FramesPerBuffer; i++)
      {
         urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i * streamObject->PacketSize;
         urb->UrbIsochronousTransfer.IsoPacket[i].Length = streamObject->PacketSize;
      }
    
      IoInitializeIrp(Irp,
                     IoSizeOfIrp((pdx->LowerDeviceObject->StackSize + 1)),
                     (CCHAR)(pdx->LowerDeviceObject->StackSize + 1));

      nextStack = IoGetNextIrpStackLocation(Irp);

      nextStack->Parameters.Others.Argument1 = transferObject->Urb;
      nextStack->Parameters.DeviceIoControl.IoControlCode = 
         IOCTL_INTERNAL_USB_SUBMIT_URB;                    
      nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;

      IoSetCompletionRoutine(Irp,
             IsoTransferComplete,
             transferObject,
             TRUE,
             TRUE,
             TRUE);
    
      status = IoCallDriver(pdx->LowerDeviceObject,Irp);
      ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
   }
   else
   {

      IoFreeIrp(Irp);
      ExFreePool(urb);

      KeSetEvent(&transferObject->Done,1,FALSE);

      ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
   }

   return ntStatus;
}

NTSTATUS UsbResetPipe(IN PDEVICE_OBJECT fdo,ULONG PipeNum)
{
   NTSTATUS ntStatus;
   PDEVICE_EXTENSION             pdx = fdo->DeviceExtension;
   PUSBD_INTERFACE_INFORMATION   interfaceInfo = NULL;
   USBD_PIPE_HANDLE              pipeHandle = NULL;
   PURB urb;
   USBD_VERSION_INFORMATION VersionInformation;
  
   interfaceInfo = pdx->Interface;

   if (!interfaceInfo)
   {
      return STATUS_UNSUCCESSFUL;
   }
   
   if (PipeNum > interfaceInfo->NumberOfPipes)
   {
      return STATUS_INVALID_PARAMETER;
   }

   pipeHandle = interfaceInfo->Pipes[PipeNum].PipeHandle;

   urb = ExAllocatePool(NonPagedPool,
                      sizeof(struct _URB_PIPE_REQUEST));

   if (urb)
   {
      urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
      urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
      urb->UrbPipeRequest.PipeHandle = pipeHandle;
     
      USBD_GetUSBDIVersion(&VersionInformation);
      if (VersionInformation.USBDI_Version < 0x101) 
      {
         urb->UrbHeader.Length -= sizeof(ULONG);
      }

      ntStatus = UsbCallUSBDI(fdo, urb);

      ExFreePool(urb);
   }
   else
   {
      ntStatus = STATUS_INSUFFICIENT_RESOURCES;
   }

   return ntStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -