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