_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]