news 2026/7/7 19:46:53

RawInputThread定义了aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange事件RequestDeviceChange->KeSetEvent

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RawInputThread定义了aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange事件RequestDeviceChange->KeSetEvent

win32k!RawInputThread线程定义了aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange和aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange事件和RequestDeviceChange函数调用了KeSetEvent函数设置了信号!!!


第一部分:对于键盘来说:
VOID RawInputThread(
PRIT_INIT pInitData)
{

/*
* Create an event for signalling mouse/kbd attach/detach and device-change
* notifications such as QueryRemove, RemoveCancelled etc.
*/
aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange =
apObjects[ID_HIDCHANGE]=
CreateKernelEvent(SynchronizationEvent, FALSE);

aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange =
CreateKernelEvent(SynchronizationEvent, FALSE);

/*
* Create an event for desktop threads to pass mouse input to RIT
*/
apObjects[ID_MOUSE] = CreateKernelEvent(SynchronizationEvent, FALSE);
gpkeMouseData = apObjects[ID_MOUSE];


if (Status == ID_MOUSE) {
/*
* A desktop thread got some Mouse input for us. Process it.
*/
ProcessQueuedMouseEvents();

} else if (Status == ID_HIDCHANGE) {
TAGMSG0(DBGTAG_PNP | RIP_THERESMORE, "RIT wakes for HID Change");
EnterCrit();
ProcessDeviceChanges(DEVICE_TYPE_KEYBOARD);
LeaveCrit();
}


第二部分:对于鼠标来说:
VOID xxxDesktopThread(
PTERMINAL pTerm)
{

/*
* Reference the mouse input event. The system terminal doesn't
* wait for any mouse input.
*/
if (!(pTerm->dwTERMF_Flags & TERMF_NOIO)) {
pfnHidChangeRoutine = (MSGWAITCALLBACK)ProcessDeviceChanges;//pfnHidChangeRoutine
idMouseInput = nEvents++;
UserAssert(aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange);
apRITEvents[idMouseInput] = aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange;
}

参考:
VOID RawInputThread(
PRIT_INIT pInitData)
{

aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange =
CreateKernelEvent(SynchronizationEvent, FALSE);
参考:

/*
* Wait for any message sent or posted to this queue, while calling
* ProcessDeviceChanges whenever the mouse change event (pkeHidChange)
* is set.
*/
result = xxxMsgWaitForMultipleObjects(nEvents,
apRITEvents,
pfnHidChangeRoutine,//pfnHidChangeRoutine
NULL);

DWORD xxxMsgWaitForMultipleObjects(
DWORD nCount,
PVOID *apObjects,
MSGWAITCALLBACK pfnNonMsg, //pfnHidChangeRoutine
PKWAIT_BLOCK WaitBlockArray)
{


if (Status == STATUS_WAIT_0 && pfnNonMsg != NULL) {
/*
* Call pfnNonMsg for the first event
*/
pfnNonMsg(DEVICE_TYPE_MOUSE); //pfnHidChangeRoutine


第三部分:

F:\srv03rtm>grep "pkeHidChange" -nr F:\srv03rtm\windows\core\ntuser |grep -v "inary"
F:\srv03rtm\windows\core\ntuser/kernel/desktop.c:450: UserAssert(aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange);
F:\srv03rtm\windows\core\ntuser/kernel/desktop.c:451: apRITEvents[idMouseInput] = aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange;
F:\srv03rtm\windows\core\ntuser/kernel/desktop.c:585: * ProcessDeviceChanges whenever the mouse change event (pkeHidChange)
F:\srv03rtm\windows\core\ntuser/kernel/ghost.c:908: * ProcessDeviceChanges whenever the mouse change event (pkeHidChange)
F:\srv03rtm\windows\core\ntuser/kernel/globals.c:571:PKEVENT gpkeHidChange;
F:\srv03rtm\windows\core\ntuser/kernel/globals.h:419:extern PKEVENT gpkeHidChange;
F:\srv03rtm\windows\core\ntuser/kernel/init.c:205: if (aDeviceTemplate[i].pkeHidChange) {
F:\srv03rtm\windows\core\ntuser/kernel/init.c:206: FreeKernelEvent(&aDeviceTemplate[i].pkeHidChange);
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:630:* If the latter, then wake the PnP thread via pkeHidChangeCompleted so that it
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:670: * thread with the pkeHidChangeCompleted so that it will free it
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:687: KeSetEvent(pDeviceInfo->pkeHidChangeCompleted, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:713: if (pDeviceInfo->pkeHidChangeCompleted != NULL) {
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:715: FreeKernelEvent(&pDeviceInfo->pkeHidChangeCompleted);
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6027: aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange =
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6030: aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange =
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6034: gpkeHidChange =
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6036: aDeviceTemplate[DEVICE_TYPE_HID].pkeHidChange = CreateKernelEvent(SynchronizationEvent, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6045: if (aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange == NULL ||
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6049: || gpkeHidChange == NULL
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6458: KeSetEvent(aDeviceTemplate[DEVICE_TYPE_MOUSE].pkeHidChange, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6459: KeSetEvent(aDeviceTemplate[DEVICE_TYPE_KEYBOARD].pkeHidChange, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:34: NULL // pkeHidChange
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:50: NULL // pkeHidChange
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:67: NULL, // pkeHidChange,
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:656: pDeviceInfo->pkeHidChangeCompleted = CreateKernelEvent(SynchronizationEvent, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:657: if (pDeviceInfo->pkeHidChangeCompleted == NULL) {
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:659: "failed to create pkeHidChangeCompleted");
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:725: if (pDeviceInfo->pkeHidChangeCompleted) {
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:726: FreeKernelEvent(&pDeviceInfo->pkeHidChangeCompleted);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2409: KeSetEvent(pDeviceInfo->pkeHidChangeCompleted, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2509:* Flag the Device for the specified actions, then set its pkeHidChange to
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2523: UserAssert(pDevTpl->pkeHidChange != NULL);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2592: KeSetEvent(pDevTpl->pkeHidChange, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2594: KeWaitForSingleObject(pDeviceInfo->pkeHidChangeCompleted, WrUserRequest, KernelMode, FALSE, NULL);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2617: KeSetEvent(pDevTpl->pkeHidChange, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/userk.h:1970: PKEVENT pkeHidChangeCompleted; // wake RequestDeviceChange()
F:\srv03rtm\windows\core\ntuser/kernel/userk.h:2252: PKEVENT pkeHidChange; // event to signal changes to this sort of device

F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2592: KeSetEvent(pDevTpl->pkeHidChange, EVENT_INCREMENT, FALSE);
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2617: KeSetEvent(pDevTpl->pkeHidChange, EVENT_INCREMENT, FALSE);


第四部分:

F:\srv03rtm>grep "xxxRegisterForDeviceClassNotifications" -nr F:\srv03rtm\windows\core\ntuser |grep -v "inary"
F:\srv03rtm\windows\core\ntuser/kernel/ntinput.c:6198: xxxRegisterForDeviceClassNotifications();
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:937:xxxRegisterForDeviceClassNotifications(
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:948: TAGMSG0(DBGTAG_PNP, "enter xxxRegisterForDeviceClassNotifications()");
F:\srv03rtm\windows\core\ntuser/kernel/pnp.c:2706: xxxRegisterForDeviceClassNotifications();
F:\srv03rtm\windows\core\ntuser/kernel/userk.h:4946:NTSTATUS xxxRegisterForDeviceClassNotifications();

VOID RawInputThread(
PRIT_INIT pInitData)
{


/*
* Register for Plug and Play devices.
* If any PnP devices are already attached, these will be opened and
* we will start reading them at this time.
*/
xxxRegisterForDeviceClassNotifications();


NTSTATUS
xxxRegisterForDeviceClassNotifications(
VOID)
{


for (DeviceType = 0; DeviceType <= DEVICE_TYPE_MAX; DeviceType++) {
if (!OpenMultiplePortDevice(DeviceType) && (gpWin32kDriverObject != NULL)) {
/*

OpenMultiplePortDevice(DWORD DeviceType)
{


pDeviceInfo = CreateDeviceInfo(DeviceType, &DeviceName, GDIF_NOTPNP);
if (pDeviceInfo) {
return TRUE;
}


for (*pwchNameIndex = L'0'; *pwchNameIndex <= L'9'; (*pwchNameIndex)++) {
CreateDeviceInfo(DeviceType, &DeviceName, GDIF_NOTPNP);
}
}

return FALSE;
}

PDEVICEINFO CreateDeviceInfo(DWORD DeviceType, PUNICODE_STRING pustrName, BYTE bFlags)
{


/*
* Create this device's HidChangeCompletion event. When the RIT completes
* a synchronous ProcessDeviceChanges() it signals the HidChangeCompletion
* event to wake the requesting RequestDeviceChange() which is blocking on
* the event.
* Each device has it's own HidChangeCompletion event,
* since multiple PnP notification may arrive for several different
* devices simultaneously. (see #331320 IanJa)
*/
pDeviceInfo->pkeHidChangeCompleted = CreateKernelEvent(SynchronizationEvent, FALSE);
if (pDeviceInfo->pkeHidChangeCompleted == NULL) {
RIPMSGF0(RIP_WARNING,
"failed to create pkeHidChangeCompleted");
goto CreateFailed;
}


/*
* Tell the RIT there is a new device so that it can open it and start
* reading from it. This is non-blocking (no GDIAF_PNPWAITING bit set)
*/
RequestDeviceChange(pDeviceInfo, GDIAF_ARRIVED, TRUE);
LeaveDeviceInfoListCrit();

VOID RequestDeviceChange(
PDEVICEINFO pDeviceInfo,
USHORT usAction,
BOOL fInDeviceInfoListCrit)
{


if (usAction & GDIAF_PNPWAITING) {

CheckDeviceInfoListCritIn();
KeSetEvent(pDevTpl->pkeHidChange, EVENT_INCREMENT, FALSE);
LeaveDeviceInfoListCrit();
KeWaitForSingleObject(pDeviceInfo->pkeHidChangeCompleted, WrUserRequest, KernelMode, FALSE, NULL);

} else {
KeSetEvent(pDevTpl->pkeHidChange, EVENT_INCREMENT, FALSE);
}
}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 19:07:35

day25 异常处理

Python的异常处理机制为程序提供了强大的容错能力 (fault tolerance)。当程序在运行时遇到意外情况&#xff08;即异常&#xff09;&#xff0c;它不会直接崩溃&#xff0c;而是可以被设计成优雅地处理这些错误&#xff0c;并可能继续执行后续逻辑&#xff08;如果设计允许&…

作者头像 李华
网站建设 2026/7/7 2:39:08

10 个自考开题演讲稿工具,AI 工具推荐优化写作效率

10 个自考开题演讲稿工具&#xff0c;AI 工具推荐优化写作效率 论文写作的重压&#xff0c;你真的扛得住吗&#xff1f; 对于自考学生来说&#xff0c;撰写开题演讲稿、文献综述乃至整篇毕业论文&#xff0c;往往是一场与时间赛跑的持久战。在有限的时间内&#xff0c;既要完成…

作者头像 李华
网站建设 2026/7/7 5:17:56

2006-2024年《中国城乡建设统计年鉴》Excel+pdf版

资源介绍 今日数据&#xff1a;《中国城乡建设统计年鉴-2006-2024》 一、数据介绍 (本年鉴【出版年份】【数据年份】&#xff09; 《中国城乡建设统计年鉴》是一部全面反映我国城乡市政公用设施建设与发展状况&#xff0c;中国城乡建设全貌的统计年鉴。 此年鉴的统计范围&a…

作者头像 李华
网站建设 2026/7/7 2:06:54

板凳----------(枯藤 )vs2026+win10(第五章-2)

致谢&#xff1a; VS2026配置x86/x64调用32位和64位汇编语言动态库环境 参考 https://blog.csdn.net/chenyijun/article/details/148952640 Lrvine64.obj 外部库可以在这里下载 链接: https://pan.baidu.com/s/1ljbseUDxpBcG_rrnhAiMEA 提取码: skbd;------------------------…

作者头像 李华
网站建设 2026/7/7 2:47:34

车载系统开发:DeepSeek 辅助编写 ADAS 功能需求文档与测试用例

车载ADAS功能开发&#xff1a;需求文档与测试用例编写指南引言随着汽车智能化水平的不断提升&#xff0c;高级驾驶辅助系统已成为现代车辆不可或缺的核心组成部分。ADAS通过融合传感器、控制器和执行器&#xff0c;为驾驶员提供预警、辅助控制甚至部分自动化功能&#xff0c;显…

作者头像 李华
网站建设 2026/7/7 4:31:53

数据库设计全景指南:从核心原则到现代分布式实践

数据库设计全景指南:从核心原则到现代分布式实践 数据库设计是任何成功软件系统的基石。一个优秀的数据库设计不仅保证数据的准确性与完整性,也直接影响系统性能、可扩展性和维护成本。本指南提供一份全面、详尽的数据库设计详解,涵盖核心原则、设计流程、九大核心策略、现…

作者头像 李华