第一部分:
VOID
ExpTimerApcRoutine (
IN PKAPC Apc,
IN PKNORMAL_ROUTINE *NormalRoutine,
IN PVOID *NormalContext,
IN PVOID *SystemArgument1,
IN PVOID *SystemArgument2
)
/*++
Routine Description:
This function is the special APC routine that is called to remove
a timer from the current thread's active timer list.
Arguments:
Apc - Supplies a pointer to the APC object used to invoke this routine.
NormalRoutine - Supplies a pointer to a pointer to the normal routine
function that was specified when the APC was initialized.
NormalContext - Supplies a pointer to a pointer to an arbitrary data
structure that was specified when the APC was initialized.
SystemArgument1, SystemArgument2 - Supplies a set of two pointers to
two arguments that contain untyped data.
Return Value:
None.
--*/
{
PETHREAD ExThread;
PETIMER ExTimer;
KIRQL OldIrql1;
ULONG DerefCount;
UNREFERENCED_PARAMETER (NormalContext);
UNREFERENCED_PARAMETER (SystemArgument1);
UNREFERENCED_PARAMETER (SystemArgument2);
//
// Get address of executive timer object and the current thread object.
//
ExThread = PsGetCurrentThread();
ExTimer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);
//
// If the timer is still in the current thread's active timer list, then
// remove it if it is not a periodic timer and set APC associated FALSE.
// It is possible for the timer not to be in the current thread's active
// timer list since the APC could have been delivered, and then another
// thread could have set the timer again with another APC. This would
// have caused the timer to be removed from the current thread's active
// timer list.
//
// N. B. The spin locks for the timer and the active timer list must be
// acquired in the order: 1) timer lock, 2) thread list lock.
//
DerefCount = 1;
ExAcquireSpinLock(&ExTimer->Lock, &OldIrql1);
ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);
if ((ExTimer->ApcAssociated) && (&ExThread->Tcb == ExTimer->TimerApc.Thread)) {
if (ExTimer->Period == 0) {
RemoveEntryList(&ExTimer->ActiveTimerListEntry);
ExTimer->ApcAssociated = FALSE;
DerefCount++;
}
} else {
*NormalRoutine = (PKNORMAL_ROUTINE)NULL;
}
ExReleaseSpinLockFromDpcLevel(&ExThread->ActiveTimerListLock);
ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);
ObDereferenceObjectEx(ExTimer, DerefCount);
return;
}
1: kd> dv
Apc = 0x893b13b0
NormalRoutine = 0xba30ed48
NormalContext = 0xba30ed3c
SystemArgument1 = 0xba30ed40
SystemArgument2 = 0xba30ed44
OldIrql1 = 0x89 ''
DerefCount = 0x3d
1: kd> dt kapc 893b13b0
CSRSRV!KAPC
+0x000 Type : 0n18
+0x002 Size : 0n48
+0x004 Spare0 : 0x220
+0x008 Thread : 0x896d9da0 _KTHREAD
+0x00c ApcListEntry : _LIST_ENTRY [ 0x896d9ddc - 0x896d9ddc ]
+0x014 KernelRoutine : 0x80af2e9a void nt!ExpTimerApcRoutine+0
+0x018 RundownRoutine : (null)
+0x01c NormalRoutine : 0x7340a79a void +7340a79a
+0x020 NormalContext : (null)
+0x024 SystemArgument1 : 0x3218d5d4 Void
+0x028 SystemArgument2 : 0x01db94bc Void
+0x02c ApcStateIndex : 0 ''
+0x02d ApcMode : 1 ''
+0x02e Inserted : 0x1 ''
ExTimer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);
//
// Executive timer object structure definition.
//
typedef struct _ETIMER {
KTIMER KeTimer;
KAPC TimerApc;
KDPC TimerDpc;
LIST_ENTRY ActiveTimerListEntry;
KSPIN_LOCK Lock;
LONG Period;
BOOLEAN ApcAssociated;
BOOLEAN WakeTimer;
LIST_ENTRY WakeTimerListEntry;
} ETIMER, *PETIMER;
1: kd> dt _etimer 893b13b0-28
nt!_ETIMER
+0x000 KeTimer : _KTIMER
+0x028 TimerApc : _KAPC
+0x058 TimerDpc : _KDPC
+0x078 ActiveTimerListEntry : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
+0x080 Lock : 0
+0x084 Period : 0n0
+0x088 ApcAssociated : 0x1 ''
+0x089 WakeTimer : 0 ''
+0x08c WakeTimerListEntry : _LIST_ENTRY [ 0x0 - 0x5000000 ]
1: kd> dx -id 0,0,89601250 -r1 (*((ntkrnlmp!_KAPC *)0x893b13b0))
(*((ntkrnlmp!_KAPC *)0x893b13b0)) [Type: _KAPC]
[+0x000] Type : 18 [Type: short]
[+0x002] Size : 48 [Type: short]
[+0x004] Spare0 : 0x220 [Type: unsigned long]
[+0x008] Thread : 0x896d9da0 [Type: _KTHREAD *]
[+0x00c] ApcListEntry [Type: _LIST_ENTRY]
[+0x014] KernelRoutine : 0x80af2e9a [Type: void (*)(_KAPC *,void (**)(void *,void *,void *),void * *,void * *,void * *)]
[+0x018] RundownRoutine : 0x0 [Type: void (*)(_KAPC *)]
[+0x01c] NormalRoutine : 0x7340a79a [Type: void (*)(void *,void *,void *)]
[+0x020] NormalContext : 0x0 [Type: void *]
[+0x024] SystemArgument1 : 0x3218d5d4 [Type: void *]
[+0x028] SystemArgument2 : 0x1db94bc [Type: void *]
[+0x02c] ApcStateIndex : 0 [Type: char]
[+0x02d] ApcMode : 1 [Type: char]
[+0x02e] Inserted : 0x0 [Type: unsigned char]
1: kd> dx -id 0,0,89601250 -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x893b1400))
(*((ntkrnlmp!_LIST_ENTRY *)0x893b1400)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x896d9f8c [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x896d9f8c [Type: _LIST_ENTRY *]
0x896d9f8c-0x896d9da0=0x1ec
第二部分: ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);之后
ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);之前
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
+0x000 Tcb : _KTHREAD
+0x1c8 CreateTime : _LARGE_INTEGER 0x0edca5e1`45f8e6e0
+0x1c8 NestedFaultCount : 0y00
+0x1c8 ApcNeeded : 0y0
+0x1d0 ExitTime : _LARGE_INTEGER 0x896d9f70`896d9f70
+0x1d0 LpcReplyChain : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
+0x1d0 KeyedWaitChain : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
+0x1d8 ExitStatus : 0n0
+0x1d8 OfsChain : (null)
+0x1dc PostBlockList : _LIST_ENTRY [ 0x896d9f7c - 0x896d9f7c ]
+0x1e4 TerminationPort : 0xe15ae778 _TERMINATION_PORT
+0x1e4 ReaperLink : 0xe15ae778 _ETHREAD
+0x1e4 KeyedWaitValue : 0xe15ae778 Void
+0x1e8 ActiveTimerListLock : 0
+0x1ec ActiveTimerListHead : _LIST_ENTRY [ 0x893b1400 - 0x893b1400 ]
ExAcquireSpinLockAtDpcLevel(&ExThread->ActiveTimerListLock);之后
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
+0x000 Tcb : _KTHREAD
+0x1e8 ActiveTimerListLock : 0x896d9da1
第三部分:RemoveEntryList(&ExTimer->ActiveTimerListEntry);之后
RemoveEntryList(&ExTimer->ActiveTimerListEntry);之前
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
+0x000 Tcb : _KTHREAD
+0x1c8 CreateTime : _LARGE_INTEGER 0x0edca5e1`45f8e6e0
+0x1c8 NestedFaultCount : 0y00
+0x1c8 ApcNeeded : 0y0
+0x1d0 ExitTime : _LARGE_INTEGER 0x896d9f70`896d9f70
+0x1d0 LpcReplyChain : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
+0x1d0 KeyedWaitChain : _LIST_ENTRY [ 0x896d9f70 - 0x896d9f70 ]
+0x1d8 ExitStatus : 0n0
+0x1d8 OfsChain : (null)
+0x1dc PostBlockList : _LIST_ENTRY [ 0x896d9f7c - 0x896d9f7c ]
+0x1e4 TerminationPort : 0xe15ae778 _TERMINATION_PORT
+0x1e4 ReaperLink : 0xe15ae778 _ETHREAD
+0x1e4 KeyedWaitValue : 0xe15ae778 Void
+0x1e8 ActiveTimerListLock : 0
+0x1ec ActiveTimerListHead : _LIST_ENTRY [ 0x893b1400 - 0x893b1400 ]
1: kd> dx -id 0,0,89601250 -r1 (*((ntkrnlmp!_LIST_ENTRY *)0x893b1400))
(*((ntkrnlmp!_LIST_ENTRY *)0x893b1400)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x896d9f8c [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x896d9f8c [Type: _LIST_ENTRY *]
RemoveEntryList(&ExTimer->ActiveTimerListEntry);之后
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
+0x000 Tcb : _KTHREAD
+0x1e8 ActiveTimerListLock : 0x896d9da1
+0x1ec ActiveTimerListHead : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
1: kd> dx -id 0,0,89601250 -r1 (*((ntdll!_LIST_ENTRY *)0x896d9f8c))
(*((ntdll!_LIST_ENTRY *)0x896d9f8c)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x896d9f8c [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x896d9f8c [Type: _LIST_ENTRY *]
第四部分: ExReleaseSpinLockFromDpcLevel(&ExThread->ActiveTimerListLock);之后
1: kd> dt eTHREAD 896d9da0
ntdll!ETHREAD
+0x000 Tcb : _KTHREAD
+0x1e8 ActiveTimerListLock : 0
第五部分: ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);之后
1: kd> dt _etimer 893b13b0-28
nt!_ETIMER
+0x000 KeTimer : _KTIMER
+0x028 TimerApc : _KAPC
+0x058 TimerDpc : _KDPC
+0x078 ActiveTimerListEntry : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
+0x080 Lock : 0x896d9da1
+0x084 Period : 0n0
+0x088 ApcAssociated : 0 ''
+0x089 WakeTimer : 0 ''
+0x08c WakeTimerListEntry : _LIST_ENTRY [ 0x0 - 0x5000000 ]
ExReleaseSpinLock(&ExTimer->Lock, OldIrql1);之后
1: kd> dt _etimer 893b13b0-28
nt!_ETIMER
+0x000 KeTimer : _KTIMER
+0x028 TimerApc : _KAPC
+0x058 TimerDpc : _KDPC
+0x078 ActiveTimerListEntry : _LIST_ENTRY [ 0x896d9f8c - 0x896d9f8c ]
+0x080 Lock : 0
+0x084 Period : 0n0
+0x088 ApcAssociated : 0 ''
+0x089 WakeTimer : 0 ''
+0x08c WakeTimerListEntry : _LIST_ENTRY [ 0x0 - 0x5000000 ]