论坛首页 开源情报交流区 阅读主题

[原创]Windows内核之鼠标处理

99 浏览 0 回复
#1 楼主 2026-06-01 21:08:58
前言:最近在研究Windows内核的一些技术,把毛德操老师的《Windows内核情景分析》上册看了一遍。又买了潘爱民老师的《Windows内核原理与实现》和潘爱民老师翻译的《深入解析Windows操作系统》第四版。这几本书也推荐给大家,都是绝版书,不过可以买二手的,看完了还可以垫显示器。
由于我只看完了上册,所以鼠标驱动部分就不介绍了,直接从这个函数开始,注意本文的代码都是ReactOS 0.3.3:1.鼠标事件VOID FASTCALL
MsqInsertSystemMessage(MSG* Msg)
   LARGE_INTEGER LargeTickCount;
   KIRQL OldIrql;
   ULONG Prev;

   IntLockSystemMessageQueue(OldIrql);

    * Bail out if the queue is full. FIXME: We should handle this case
    * more gracefully.

   if (SystemMessageQueueCount == SYSTEM_MESSAGE_QUEUE_SIZE)
      IntUnLockSystemMessageQueue(OldIrql);
      return;

   KeQueryTickCount(&LargeTickCount);
   Msg->time = MsqCalculateMessageTime(&LargeTickCount);

    * If we got WM_MOUSEMOVE and there are already messages in the
    * system message queue, check if the last message is mouse move
    * and if it is then just overwrite it.

   if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
      if (SystemMessageQueueTail == 0)
         Prev = SYSTEM_MESSAGE_QUEUE_SIZE - 1;
      else
         Prev = SystemMessageQueueTail - 1;
      if (SystemMessageQueue[Prev].message == WM_MOUSEMOVE)
         SystemMessageQueueTail = Prev;
         SystemMessageQueueCount--;

    * Actually insert the message into the system message queue.

   SystemMessageQueue[SystemMessageQueueTail] = *Msg;
   SystemMessageQueueTail =
      (SystemMessageQueueTail + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
   SystemMessageQueueCount++;

   IntUnLockSystemMessageQueue(OldIrql);

   KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);
}在鼠标的处理线程中首先读取鼠标的数据,然后调用上面的函数,这个函数最重要的部分就是将消息Msg写入消息队列SystemMessageQueue[SystemMessageQueueTail] = *Msg;同时叫醒正在睡眠的线程,这是通过KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);实现的,这一句会将正在等待HardwareMessageEvent事件的线程唤醒。
2.被叫醒的线程被叫醒的线程获得消息队列中 的消息后主要会判断当前的鼠标移动是不是在自己的窗口范围内,如果是就接收这个事件,那么这次鼠标移动的事件就被基本处理了,如果不是就将事件转发给当前正在鼠标之下的那个窗口处理。被叫醒的线程都是main函数中调用了GetMessage()函数的线程,这样就从系统中获得了一个msg,接下来介绍msg如何传递给窗口过程函数WndProc,这个是Windows用户程序的主要处理函数。
3.从用户空间回调过程函数WndProc在获得msg后,一般会调用DispatchMessage(&msg)函数,该函数负责回调过程函数WndProc。
3.从系统空间回调过程函数WndProc有时需要从系统空间调用用户空间函数,在系统空间中最终会调用KeUserModeCallback()函数,在这个函数中会伪造内核栈内容从而使得返回到用户态时会执行KiUserCallbackDispatcher()函数,在这个函数中会调用用户注册的WndProc函数,并在执行完后返回到内核中去。回到内核后退出KeUserModeCallback()函数。


[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。


#系统内核

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290846.htm

暂无回复,快来抢沙发吧!

请登录后参与讨论

立即登录 注册账号