我正在尝试编写一个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
}
};
2条答案
按热度按时间a1o7rhls1#
我使用Hyper V虚拟机作为调试机器,这就是它不工作的原因。当我用另一台电脑时,短信就被发送了。
如果你想模仿鼠标或鼠标移动,这是我的建议:
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