当前位置: 代码迷 >> 驱动开发 >> 请问USB过滤驱动怎么写端点
  详细解决方案

请问USB过滤驱动怎么写端点

热度:158   发布时间:2016-04-28 10:04:48.0
请教USB过滤驱动如何写端点
本人驱动菜鸟一枚!平时写上位机较多,遇到一个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
  相关解决方案