news 2026/5/13 17:25:02

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/5/13 17:25:02

10 个专科生论文降重工具,AI 写作推荐与查重率优化

10 个专科生论文降重工具&#xff0c;AI 写作推荐与查重率优化 论文战场上的无声战役 对于专科生而言&#xff0c;期末论文不仅是对知识的检验&#xff0c;更是一场与时间、压力和自我怀疑的较量。在论文写作过程中&#xff0c;许多人常常陷入“写不出来”“写不好”的困境&…

作者头像 李华
网站建设 2026/5/11 22:11:52

9 个 MBA 毕业答辩 PPT 工具推荐,AI 格式优化神器

9 个 MBA 毕业答辩 PPT 工具推荐&#xff0c;AI 格式优化神器 论文写作的“三座大山”&#xff1a;时间、重复率与效率 对于MBA学生而言&#xff0c;毕业答辩不仅是学术生涯的重要节点&#xff0c;更是对综合能力的一次全面检验。然而&#xff0c;从选题到撰写&#xff0c;再到…

作者头像 李华
网站建设 2026/5/9 1:29:19

如何在大数据数仓中搭建数据集市

一、什么是数据集市&#xff1f;数据集市是面向特定业务需求&#xff08;如销售、财务、市场等&#xff09;的小型数据仓库&#xff0c;通常从企业级数据仓库中抽取、转换并聚合相关数据&#xff0c;形成易于理解、查询性能优良的数据结构。与全局数据仓库相比&#xff0c;数据…

作者头像 李华
网站建设 2026/5/11 3:11:33

HuggingFace Dataset集成Qwen-Image生成样本数据

HuggingFace Dataset集成Qwen-Image生成样本数据 在当今AIGC&#xff08;人工智能生成内容&#xff09;迅猛发展的背景下&#xff0c;文生图技术正从实验室走向真实应用场景。无论是电商广告配图、影视概念设计&#xff0c;还是数字艺术创作&#xff0c;高质量图像的自动化生成…

作者头像 李华
网站建设 2026/5/9 1:35:02

Fail2Ban 实战终极速查表

一、核心基础操作&#xff08;必记&#xff09;1. 服务管理启动服务&#xff1a;sudo systemctl start fail2ban停止服务&#xff1a;sudo systemctl stop fail2ban重启服务&#xff1a;sudo systemctl restart fail2ban查看状态&#xff08;验证服务是否运行&#xff09;&…

作者头像 李华
网站建设 2026/5/9 1:29:43

权限系统设计与RBAC实现

目录权限系统设计与RBAC实现引言1. 权限系统基础1.1 权限系统的重要性1.2 权限系统的基本元素2. RBAC模型详解2.1 RBAC模型概述2.2 RBAC的核心组件2.2.1 基础RBAC模型2.2.2 层级RBAC模型2.3 RBAC的数学表示3. 高级RBAC特性3.1 角色继承与层级3.2 约束条件3.3 动态约束与会话管理…

作者头像 李华