📄 testdispatch.c
字号:
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 + -