当前位置: 首页 > news >正文

_DISPATCHER_HEADER结构中的WaitListHead和_KWAIT_BLOCK的关系


第一部分:

//
// Wait block
//
// begin_ntddk begin_wdm begin_nthal begin_ntifs begin_ntosp

typedef struct _KWAIT_BLOCK {
    LIST_ENTRY WaitListEntry;
    struct _KTHREAD *RESTRICTED_POINTER Thread;
    PVOID Object;
    struct _KWAIT_BLOCK *RESTRICTED_POINTER NextWaitBlock;
    USHORT WaitKey;
    USHORT WaitType;
} KWAIT_BLOCK, *PKWAIT_BLOCK, *RESTRICTED_POINTER PRKWAIT_BLOCK;

        WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
                                      KWAIT_BLOCK,
                                      WaitListEntry);

第二部分:等待块0x8976d648对应的线程0x8976d5a8第一个等待,等待块0x89124e40对应的线程0x89124da0第二个等待。
1: kd> dt kevent  8984ed18
CSRSRV!KEVENT
   +0x000 Header           : _DISPATCHER_HEADER
1: kd> dx -id 0,0,89838358 -r1 (*((CSRSRV!_DISPATCHER_HEADER *)0x8984ed18))
(*((CSRSRV!_DISPATCHER_HEADER *)0x8984ed18))                 [Type: _DISPATCHER_HEADER]
    [+0x000] Type             : 0x1 [Type: unsigned char]
    [+0x001] Absolute         : 0x0 [Type: unsigned char]
    [+0x002] Size             : 0x4 [Type: unsigned char]
    [+0x003] Inserted         : 0x0 [Type: unsigned char]
    [+0x003] DebugActive      : 0x0 [Type: unsigned char]
    [+0x000] Lock             : 262145 [Type: long]
    [+0x004] SignalState      : 0 [Type: long]
    [+0x008] WaitListHead     [Type: _LIST_ENTRY]
1: kd> dx -id 0,0,89838358 -r1 (*((CSRSRV!_LIST_ENTRY *)0x8984ed20))
(*((CSRSRV!_LIST_ENTRY *)0x8984ed20))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x8976d648 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x89124e40 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_LIST_ENTRY *)0x8976d648)
((CSRSRV!_LIST_ENTRY *)0x8976d648)                 : 0x8976d648 [Type: _LIST_ENTRY *]
    [+0x000] Flink            : 0x89124e40 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x8984ed20 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_LIST_ENTRY *)0x89124e40)
((CSRSRV!_LIST_ENTRY *)0x89124e40)                 : 0x89124e40 [Type: _LIST_ENTRY *]
    [+0x000] Flink            : 0x8984ed20 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x8976d648 [Type: _LIST_ENTRY *]


第三部分:
1: kd> dt KWAIT_BLOCK 0x8976d648                            //Flink            : 0x8976d648
CSRSRV!KWAIT_BLOCK
   +0x000 WaitListEntry    : _LIST_ENTRY [ 0x89124e40 - 0x8984ed20 ]
   +0x008 Thread           : 0x8976d5a8 _KTHREAD
   +0x00c Object           : 0x8984ed18 Void
   +0x010 NextWaitBlock    : 0x8976d648 _KWAIT_BLOCK
   +0x014 WaitKey          : 0
   +0x016 WaitType         : 1
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_KTHREAD *)0x8976d5a8)
((CSRSRV!_KTHREAD *)0x8976d5a8)                 : 0x8976d5a8 [Type: _KTHREAD *]
    [+0x000] Header           [Type: _DISPATCHER_HEADER]
    [+0x010] MutantListHead   [Type: _LIST_ENTRY]
    [+0x018] InitialStack     : 0xba247000 [Type: void *]
    [+0x01c] StackLimit       : 0xba244000 [Type: void *]
    [+0x020] KernelStack      : 0xba246c5c [Type: void *]
    [+0x024] ThreadLock       : 0x0 [Type: unsigned long]
    [+0x028] ContextSwitches  : 0x1 [Type: unsigned long]
    [+0x02c] State            : 0x5 [Type: unsigned char]
    [+0x02d] NpxState         : 0xa [Type: unsigned char]
    [+0x02e] WaitIrql         : 0x0 [Type: unsigned char]
    [+0x02f] WaitMode         : 1 [Type: char]
    [+0x030] Teb              : 0x7ff98000 [Type: void *]
    [+0x034] ApcState         [Type: _KAPC_STATE]
    [+0x04c] ApcQueueLock     : 0x0 [Type: unsigned long]
    [+0x050] WaitStatus       : 0 [Type: long]
    [+0x054] WaitBlockList    : 0x8976d648 [Type: _KWAIT_BLOCK *]
   
1: kd> dt KWAIT_BLOCK  0x89124e40
CSRSRV!KWAIT_BLOCK
   +0x000 WaitListEntry    : _LIST_ENTRY [ 0x8984ed20 - 0x8976d648 ]
   +0x008 Thread           : 0x89124da0 _KTHREAD
   +0x00c Object           : 0x8984ed18 Void
   +0x010 NextWaitBlock    : 0x89124e40 _KWAIT_BLOCK
   +0x014 WaitKey          : 0
   +0x016 WaitType         : 1
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_KTHREAD *)0x89124da0)
((CSRSRV!_KTHREAD *)0x89124da0)                 : 0x89124da0 [Type: _KTHREAD *]
    [+0x000] Header           [Type: _DISPATCHER_HEADER]
    [+0x010] MutantListHead   [Type: _LIST_ENTRY]
    [+0x018] InitialStack     : 0xba2b7000 [Type: void *]
    [+0x01c] StackLimit       : 0xba2b3000 [Type: void *]
    [+0x020] KernelStack      : 0xba2b681c [Type: void *]
    [+0x024] ThreadLock       : 0x0 [Type: unsigned long]
    [+0x028] ContextSwitches  : 0x4 [Type: unsigned long]
    [+0x02c] State            : 0x5 [Type: unsigned char]
    [+0x02d] NpxState         : 0xa [Type: unsigned char]
    [+0x02e] WaitIrql         : 0x0 [Type: unsigned char]
    [+0x02f] WaitMode         : 1 [Type: char]
    [+0x030] Teb              : 0x7ff9a000 [Type: void *]
    [+0x034] ApcState         [Type: _KAPC_STATE]
    [+0x04c] ApcQueueLock     : 0x0 [Type: unsigned long]
    [+0x050] WaitStatus       : 0 [Type: long]
    [+0x054] WaitBlockList    : 0x89124e40 [Type: _KWAIT_BLOCK *]
   

第四部分:

LONG
KeSetEvent (
    IN PRKEVENT Event,
    IN KPRIORITY Increment,
    IN BOOLEAN Wait
    )

{

    KIRQL OldIrql;
    LONG OldState;
    PRKTHREAD Thread;

    ASSERT_EVENT(Event);
    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

    //
    // Collect call data.
    //

#if defined(_COLLECT_SET_EVENT_CALLDATA_)

    RECORD_CALL_DATA(&KiSetEventCallData);

#endif

    //
    // Raise IRQL to dispatcher level and lock dispatcher database.
    //

    KiLockDispatcherDatabase(&OldIrql);

    //
    // Capture the old state and set the new state to signaled.
    //
    // If the old state is not-signaled and the wait list is not empty,
    // then satisfy as many waits as possible.
    //

    OldState = Event->Header.SignalState;
    Event->Header.SignalState = 1;
    if ((OldState == 0) &&
        (IsListEmpty(&Event->Header.WaitListHead) == FALSE)) {

        if (Event->Header.Type == EventNotificationObject) {
            KiWaitTestWithoutSideEffects(Event, Increment);


第五部分:

FORCEINLINE
VOID
KiWaitTestWithoutSideEffects (
    IN PVOID Object,
    IN KPRIORITY Increment
    )
{

    PKEVENT Event = Object;
    PLIST_ENTRY ListHead;
    PRKTHREAD Thread;
    PRKWAIT_BLOCK WaitBlock;
    PLIST_ENTRY WaitEntry;

    //
    // Empty the entire list of waiters since the specified object has
    // no side effects when a wait is satisfied.
    //

    ListHead = &Event->Header.WaitListHead;

    ASSERT(IsListEmpty(&Event->Header.WaitListHead) == FALSE);

    WaitEntry = ListHead->Flink;
    do {

        //
        // Get the address of the wait block and the thread doing the wait.
        //

        WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
        Thread = WaitBlock->Thread;

        //
        // If the wait type is wait any, then unwait the thread with the
        // wait key status. Otherwise, unwait the thread with a kernel APC
        // status.
        //

        if (WaitBlock->WaitType == WaitAny) {
            KiUnwaitThread(Thread, (NTSTATUS)WaitBlock->WaitKey, Increment);

        } else {
            KiUnwaitThread(Thread, STATUS_KERNEL_APC, Increment);
        }

        WaitEntry = ListHead->Flink;//激活第一个线程后,第一个等待块会脱链!!
    } while (WaitEntry != ListHead);

    return;
}

第六部分:

例子1:只有一个等待线程
1: kd> g
Breakpoint 22 hit
nt!KeSetEvent:
80a34206 55              push    ebp
0: kd> dv
          Event = 0xf78ce2f8
      Increment = 0n0
           Wait = 0x00 ''
       OldState = 0n8
        OldIrql = 0xf7 ''
0: kd> dx -r1 ((ntkrnlmp!_KEVENT *)0xf78ce2f8)
((ntkrnlmp!_KEVENT *)0xf78ce2f8)                 : 0xf78ce2f8 [Type: _KEVENT *]
    [+0x000] Header           [Type: _DISPATCHER_HEADER]
0: kd> dx -r1 (*((ntkrnlmp!_DISPATCHER_HEADER *)0xf78ce2f8))
(*((ntkrnlmp!_DISPATCHER_HEADER *)0xf78ce2f8))                 [Type: _DISPATCHER_HEADER]
    [+0x000] Type             : 0x0 [Type: unsigned char]
    [+0x001] Absolute         : 0x0 [Type: unsigned char]
    [+0x002] Size             : 0x4 [Type: unsigned char]
    [+0x003] Inserted         : 0x0 [Type: unsigned char]
    [+0x003] DebugActive      : 0x0 [Type: unsigned char]
    [+0x000] Lock             : 262144 [Type: long]
    [+0x004] SignalState      : 0 [Type: long]
    [+0x008] WaitListHead     [Type: _LIST_ENTRY]
0: kd> dx -r1 (*((ntkrnlmp!_LIST_ENTRY *)0xf78ce300))
(*((ntkrnlmp!_LIST_ENTRY *)0xf78ce300))                 [Type: _LIST_ENTRY]
    [+0x000] Flink            : 0x8999e6c0 [Type: _LIST_ENTRY *]
    [+0x004] Blink            : 0x8999e6c0 [Type: _LIST_ENTRY *]

0: kd> g
Breakpoint 33 hit
nt!KiUnwaitThread:
80a402c6 55              push    ebp

0: kd> g
Breakpoint 32 hit
nt!KiReadyThread:
80a42c6c 8b4144          mov     eax,dword ptr [ecx+44h]
 


http://www.mrgr.cn/news/95779.html

相关文章:

  • Linux的SPI子系统的原理和结构详解【SPI控制器(spi_master)、SPI总线(device-driver-match匹配机制)、SPI设备、SPI万能驱动`spidev.c`】
  • Unity 实现一个简易可拓展性的对话系统
  • 深度解读DeepSeek:开源周(Open Source Week)技术解读
  • 从零开始的LeetCode刷题日记:128. 最长连续序列
  • Spring Boot 整合 Nacos 注册中心终极指南
  • CentOS 7 更换 yum 源(阿里云)+ 扩展 epel 源
  • Jackson实现JSON数据的合并
  • vivo 湖仓架构的性能提升之旅
  • AI本地部署之dify
  • Redis 服务搭建
  • DeepSeek面试——模型架构和主要创新点
  • 《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型
  • springboot使用netty做TCP客户端
  • python面试高频考点(深度学习大模型方向)
  • 鸿蒙进行视频上传,使用 request.uploadFile方法
  • 大模型应用(Java)2025/3/24
  • LeetCode热题100JS(69/100)第十三天|34|33|153|4|20
  • 2025-3-24 leetcode刷题情况(动态规划——01背包)
  • 【HTML5游戏开发教程】零基础入门合成大西瓜游戏实战 | JS物理引擎+Canvas动画+完整源码详解
  • stm32-IIC