本人驱动菜鸟一枚!平时写上位机较多,遇到一个USB写端点的问题,没解决,哭求各位大大的热心赐教:
目的:接到APP的WriteFile命令,然后把数据转发到USB设备端点2中,端点2采用中断传输,64个字节。
来源:USB设备过滤驱动,参考了微软的WDK源代码:08WDK\src\general\toaster\filter\claslower
修改:针对这个源代码,增加IRP_MJ_WRITE的响应,
case IRP_MJ_WRITE:即当得到符合长度的数据就往设备里面写,这个写函数如下:
WriteLen = irpStack->Parameters.Write.Length;
DebugPrint(("Write : %d\n", WriteLen));
if (irpStack->Parameters.Write.Length >= sizeof(VK_SENDKEY)) {
status = FilterWriteRequest(DeviceObject, Irp, Irp->AssociatedIrp.SystemBuffer, WriteLen);
if (NT_SUCCESS(status))
Irp->IoStatus.Information = WriteLen;
}
else {
status = STATUS_INVALID_PARAMETER;
}
break;
NTSTATUS FilterWriteRequest(PDEVICE_OBJECT RequestDevice, PIRP Irp, PUCHAR WriteBuffer, ULONG WriteLen)
{
PDEVICE_OBJECT pDeviceObject;
PCOMMON_DEVICE_DATA commonData;
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PIRP pNewIrp;
IO_STATUS_BLOCK NewIoStatus;
KEVENT NewEvent;
NTSTATUS NewNtStatus = STATUS_UNSUCCESSFUL;
ULONG IoControlCode;
URB urb;
UCHAR byData[64] = {0x03, 0x07};
PIO_STACK_LOCATION pStack;
// 遍历并找到第一个符合的设备
pDeviceObject = RequestDevice->DriverObject->DeviceObject;
while (pDeviceObject != NULL) {
commonData = (PCOMMON_DEVICE_DATA)pDeviceObject->DeviceExtension;
DebugPrint(("FilterWriteRequest+2: %p %x\n", pDeviceObject, commonData->Type));
if (commonData->Type == DEVICE_TYPE_FIDO) {
UsbBuildInterruptOrBulkTransferRequest(
&urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
(USBD_PIPE_HANDLE)0x02,
byData,
NULL,
sizeof(byData),
0,
NULL
);
IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
KeInitializeEvent(&NewEvent, NotificationEvent, FALSE);
pNewIrp = IoBuildDeviceIoControlRequest(
IoControlCode,
pDeviceObject,
NULL,
0,
NULL,
0,
TRUE, // internal ( use IRP_MJ_INTERNAL_DEVICE_CONTROL )
&NewEvent,
&NewIoStatus
);
if (pNewIrp != NULL) {
pStack = IoGetNextIrpStackLocation(pNewIrp);
pStack->Parameters.Others.Argument1 = (PVOID)&urb;
NewNtStatus = IoCallDriver(pDeviceObject, pNewIrp);
DebugPrint(("FilterWriteRequest+3: %x\n", NewNtStatus));
if (NewNtStatus == STATUS_PENDING) {
DebugPrint(("FilterWriteRequest+4: Wait for single object\n"));
NewNtStatus = KeWaitForSingleObject(
&NewEvent,
Suspended,
KernelMode,
FALSE,
NULL);
DebugPrint(("CycleResetDevice+5: Wait forsingle object, returned %x\n", NewNtStatus));
} else {
NewIoStatus.Status = NewNtStatus;
}
NewNtStatus = NewIoStatus.Status;
}
else {
NewNtStatus = STATUS_INSUFFICIENT_RESOURCES;
}
ntStatus = NewNtStatus;
break;
}
// 换成下一个设备,继续遍历
pDeviceObject = pDeviceObject->NextDevice;
}
return ntStatus;
}
问题就在这里:调用UsbBuildInterruptOrBulkTransferRequest这个函数时,第三个参数,端点2的句柄不知如何获取,如果直接写0x02来代表端点2,是失败的额。请问这里需要怎么修改?
------解决思路----------------------
USBD_PIPE_HANDLE 必须从USB的Host Controller驱动(HCD)获得。不是USB的Endpoint Number。
你在写什么设备类型的过滤驱动程序?过滤驱动程序挂在什么地方了?
一般来说,只有USB设备本身的Function驱动才可以获取对应设备的USBD_PIPE_HANDLE 。
------解决思路----------------------
PipeHandle [in]
Specifies the handle for this pipe returned by the HCD when a configuration was selected.
UsbBuildInterruptOrBulkTransferRequest routine
如何在 USB 批量终结点中打开和关闭静态流
最佳实践:使用 URB