windows HID提交HID_XFER_PACKET以模拟屏蔽

bt1cpqcv  于 2023-10-22  发布在  Windows
关注(0)|答案(2)|浏览(84)

我正在尝试编写一个Kubernetes驱动程序来模拟Kubernetes。
当驱动程序接收到IOCTL_HID_READ_REPORT时,它会将请求重定向到队列:

switch (IoControlCode)
{
case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
    KdPrint(("GET DEVICE DESCRIPTOR\n"));
    _Analysis_assume_(deviceContext->HidDescriptor.bLength != 0);
    status = RequestCopyFromBuffer(Request, &deviceContext->HidDescriptor, deviceContext->HidDescriptor.bLength);
    break;

case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
    KdPrint(("GET DEVICE ATTRIBUTES\n"));
    status = RequestCopyFromBuffer(Request, &queueContext->DeviceContext->HidDeviceAttributes, sizeof(HID_DEVICE_ATTRIBUTES));
    break;

case IOCTL_HID_GET_REPORT_DESCRIPTOR:
    KdPrint(("GET REPORT DESCRIPTOR\n"));
    status = RequestCopyFromBuffer(Request, deviceContext->ReportDescriptor, deviceContext->HidDescriptor.DescriptorList[0].wReportLength);
    break;

case IOCTL_HID_READ_REPORT:
   WdfRequestForwardToIoQueue(Request, QueueContext->DeviceContext->ManualQueue); // <= HERE
    break;}

使用计时器,项目会定期出队,键盘输入报告会在请求中复制

void EvtTimerFunc(_In_  WDFTIMER Timer)
{
    NTSTATUS                status;
    WDFQUEUE                queue;
    PMANUAL_QUEUE_CONTEXT   queueContext;
    WDFREQUEST              request;

    KdPrint(("EvtTimerFunc\n"));

    queue = (WDFQUEUE)WdfTimerGetParentObject(Timer);
    queueContext = GetManualQueueContext(queue);

    //
    // see if we have a request in manual queue
    //
    status = WdfIoQueueRetrieveNextRequest(queueContext->Queue, &request);

    if (NT_SUCCESS(status))
    {
        KdPrint(("Handling"));

        HID_XFER_PACKET hidXferPacket;

        BYTE keycodes[6] = {0};
        keycodes[0] = 0x04;

        HID_KEYBOARD_INPUT_REPORT report;
        report.ReportId = REPORT_ID_KEYBOARD_INPUT;
        report.Modifiers = 0;
        report._reserved = 0;
        memcpy(&report.KeyCodes, &keycodes, 6);

        hidXferPacket.reportBuffer = (UCHAR*)&report;
        hidXferPacket.reportBufferLen = sizeof(HID_KEYBOARD_INPUT_REPORT);
        hidXferPacket.reportId = REPORT_ID_KEYBOARD_INPUT;

        RequestCopyFromBuffer(request, hidXferPacket.reportBuffer, sizeof(HID_KEYBOARD_INPUT_REPORT));
        
        WdfRequestComplete(request, status);
    }
}

虽然一切都正常工作,但没有发出任何错误。我错过了什么?!
描述符:

HID_REPORT_DESCRIPTOR g_reportDescriptor[] = {
    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
    0x09, 0x02,        // USAGE (Mouse)
    0xA1, 0x01,        // COLLECTION (Application)
    0x85,                  REPORT_ID_MOUSE_INPUT,
    0x09, 0x01,            // USAGE_PAGE (Pointer)
    0xA1, 0x00,            // COLLECTION (Physical)
    0x05, 0x09,                // USAGE_PAGE (Buttons)
    0x19, 0x01,                // USAGE_MINIMUM (1)
    0x29, 0x03,                // USAGE_MAXIMUM (3)
    0x15, 0x00,                // LOGICAL_MINIMUM (0)
    0x25, 0x01,                // LOGICAL_MAXIMUM (1)
    0x95, 0x03,                // REPORT_COUNT (3)
    0x75, 0x01,                // REPORT_SIZE (1)
    0x81, 0x02,                // INPUT (Data, Variable, Absolute)
    0x95, 0x01,                // REPORT_COUNT (1)
    0x75, 0x05,                // REPORT_SIZE (5)
    0x81, 0x01,                // INPUT (Constant)
    0x05, 0x01,                // USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                // USAGE (X)
    0x09, 0x31,                // USAGE (Y)
    0x15, 0x81,                // LOGICAL_MINIMUM (-127)
    0x25, 0x7F,                // LOGICAL_MAXIMUM (127)
    0x75, 0x08,                // REPORT_SIZE (8)
    0x95, 0x02,                // REPORT_COUNT (2)
    0x81, 0x06,                // Input (Data, Variable, Relative)
    0xC0,                  // END_COLLECTION
    0xC0,              // END_COLLECTION

    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
    0x09, 0x00,        // USAGE (Undefined)
    0xa1, 0x01,        // COLLECTION (Application)
    0x85,                  REPORT_ID_MOUSE_OUTPUT,
    0x09, 0x00,            // USAGE (Undefined)
    0x15, 0x00,            // LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,      // LOGICAL_MAXIMUM (255)
    0x95, 0x03,            // REPORT_COUNT (3)
    0x75, 0x08,            // REPORT_SIZE (8)
    0x91, 0x02,            // OUTPUT (Data, Variable, Absolute)
    0xc0,              // END_COLLECTION

    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,        // USAGE (Keyboard)
    0xA1, 0x01,        // COLLECTION (Application)
    0x85,                  REPORT_ID_KEYBOARD_INPUT,
    0x05, 0x07,            // USAGE_PAGE (Keyboard Key Codes)
    0x19, 0xE0,            // USAGE_MINIMUM (224)
    0x29, 0xE7,            // USAGE_MAXIMUM (231)
    0x15, 0x00,            // LOGICAL_MINIMUM (0)
    0x25, 0x01,            // LOGICAL_MAXIMUM (1)
    0x75, 0x01,            // REPORT_SIZE (1)
    0x95, 0x08,            // REPORT_COUNT (8)
    0x81, 0x02,            // INPUT (Data, Variable, Absolute)
    0x95, 0x01,            // REPORT_COUNT (1)
    0x75, 0x08,            // REPORT_SIZE (8)
    0x81, 0x01,            // INPUT (Constant)
    0x19, 0x00,            // USAGE_MINIMUM (0)
    0x29, 0x65,            // USAGE_MAXIMUM (101)
    0x15, 0x00,            // LOGICAL_MINIMUM (0)
    0x25, 0x65,            // LOGICAL_MAXIMUM (101)
    0x95, 0x06,            // REPORT_COUNT (6)
    0x75, 0x08,            // REPORT_SIZE (8)
    0x81, 0x00,            // INPUT (Data, Array, Absolute)
    0x05, 0x08,            // USAGE_PAGE (LEDs)
    0x19, 0x01,            // USAGE_MINIMUM (Num Lock)
    0x29, 0x05,            // USAGE_MAXIMUM (Kana)
    0x95, 0x05,            // REPORT_COUNT (5)
    0x75, 0x01,            // REPORT_SIZE (1)
    0x91, 0x02,            // OUTPUT (Data, Variable, Absolute)
    0x95, 0x01,            // REPORT_COUNT (1)
    0x75, 0x03,            // REPORT_SIZE (3)
    0x91, 0x01,            // OUTPUT (Constant)
    0xC0,              // END_COLLECTION

    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
    0x09, 0x00,        // USAGE (Undefined)
    0xa1, 0x01,        // COLLECTION (Application)
    0x85,                  REPORT_ID_KEYBOARD_OUTPUT,
    0x09, 0x00,            // USAGE (Undefined)
    0x15, 0x00,            // LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,      // LOGICAL_MAXIMUM (255)
    0x95, 0x08,            // REPORT_COUNT (8)
    0x75, 0x08,            // REPORT_SIZE (8)
    0x91, 0x02,            // OUTPUT (Data, Variable, Absolute)
    0xc0               // END_COLLECTION
};

HID_DESCRIPTOR g_hidDescriptor = {
    0x09,        // length of HID descriptor
    0x21,        // descriptor type == HID 0x21
    0x0100,      // hid spec release
    0x00,        // country code == Not Specified
    0x01,        // number of HID class descriptors
    {            // DescriptorList[0]
        0x22,                             // report descriptor type 0x22
        sizeof(g_reportDescriptor)        // total length of report descriptor
    }
};
a1o7rhls

a1o7rhls1#

我使用Hyper V虚拟机作为调试机器,这就是它不工作的原因。当我用另一台电脑时,短信就被发送了。
如果你想模仿鼠标或鼠标移动,这是我的建议:

mum43rcc

mum43rcc2#

您如何连接到Hyper V调试机?
在我的情况下,它也发生在Hyper V虚拟机上,在物理机或VMware虚拟机上也可以,但是......我意识到,只有当我通过RDP连接到它时才会发生,当我通过控制台连接到它时,它在Hyper V虚拟机上按预期工作。所以,我只是把我的情况记录在那里:
据我所知,鼠标/键盘RDP驱动程序工作在RDP会话上,可以生成事件,但只有它们可以。因此,可以通过以下几种选择来解决这个问题:
1.使用UMFD/KMFD lowefilters驱动程序(例如,它可以基于HID Minidriver Sample (UMDF version 2)只有当您断开RDP会话(和rdp驱动程序消失)与sleep 5 | tscon.exe 2 /dest:console命令,执行作为管理员从powershell控制台(使可用的GUI没有RDP,并通过驱动程序控制它)

P/S也描述了类似的情况,并回答了我在ms question

相关问题