|
我在做一个HID USB设备的minidriver,USB设备总是循环的发送相同的数据,在以中断传输方式读取数据的时候,我不知道该采用怎么样的方式:
1. 根据Walter Oney,HID USB设备的hidMinidriverRegistration.DevicesArePolled应该设为FALSE,这样的话,HID Classdriver将会保持ping-pong IRPs,也就是会保持两个IRP来读取数据,是不是应该采用系统列队将IRP存入,然后再逐个处理?
2. 将IRP发往USB总线驱动时,需要创建URB,那么是不是需要创建新的IRP呢?
我几种方法都试过,就是数据读不上来,我给出没有使用系统列队的代码,请各位指点,这个驱动装上去后一切显示正常,就是读取数据不对,而且如果使用IRP TRACE来跟踪IRP,会发现似乎下面的函数一直在向底层驱动发送IRP_MJ_CREAT。请各位大侠指点。
在处理IOCTL_HID_READ_REPORT时调用下面函数:
#pragma LOCKEDCODE
NTSTATUS
ReadReport(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
................
//initialize some variable
//create the URB
urb=ExAllocatePool(NonPagedPool,sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
urbFlags =USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
UsbBuildInterruptOrBulkTransferRequest(
urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
pipehandle_In, //pipehandle
&deviceExtension->indata,
NULL,
1,
urbFlags,//USBD_TRANSFER_DIRECTION_IN
NULL);
//Create an NerIrp
nextDeviceObject=GET_NEXT_DEVICE_OBJECT(DeviceObject);
NewIrp=IoAllocateIrp(nextDeviceObject->StackSize,FALSE);
//set the paramaters of the next stack
nextStack=IoGetNextIrpStackLocation(Irp);
nextStack->MajorFunction=IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.Others.Argument1=urb;
nextStack->Parameters.DeviceIoControl.IoControlCode=IOCTL_INTERNAL_USB_SUBMIT_URB;
deviceExtension->ParentIrp=Irp;
deviceExtension->urb=urb;
IoMarkIrpPending(Irp);
//set up completion routine
IoSetCompletionRoutine(NewIrp,
(PIO_COMPLETION_ROUTINE)ReadWriteCompletion,
deviceExtension,
TRUE,
TRUE,
TRUE);
//send NewIrp down
ntstatus=IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject),NewIrp);
return ntstatus
}
#pragma LOCKEDCODE
NTSTATUS
ReadWriteCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
............
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
IoFreeIrp(Irp); //释放创建的IRP
ExFreePool(deviceExtension->urb); //释放URB
RtlCopyMemory(deviceExtension->ParentIrp->UserBuffer,&deviceExtension->indata,0x01);
deviceExtension->ParentIrp->IoStatus.Information=1;
deviceExtension->ParentIrp->IoStatus.Status=ntstatus;
IoCompleteRequest(deviceExtension->ParentIrp,IO_NO_INCREMENT);
return STATUS_MORE_PROCESSING_REQUIRED;
}
|
|