ExpTimerApcRoutine函数分析之作用是ActiveTimerListHead里面移除定时器_etimer

第一部分:

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 ]