第一部分:
//
 // 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]