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);
}
}