EX_RUNDOWN_REF RundownProtect;
typedef struct _EX_RUNDOWN_REF
{
union
{
ULONG Count;
PVOID Ptr;
};
} EX_RUNDOWN_REF, *PEX_RUNDOWN_REF;
这里结构都是基于Vista内核的。看的出来,所谓的EX_RUNDOWN_REF结构其实就是一个整数而已。关键是怎么使用的这个结构,想知道这一点得看一下ExAcquireRundownProtection()函数,这个函数是经常调用来给进程加保护的。我在WRK找到了这个函数的代码,如下
1 NTKERNELAPI
2 BOOLEAN
3 FORCEINLINE
4 FASTCALL
5 ExAcquireRundownProtection (
6 __inout PEX_RUNDOWN_REF RunRef
7 )
8 {
9 ULONG_PTR Value, NewValue;
10
11 Value = ReadForWriteAccess(&RunRef->Count) & ~EX_RUNDOWN_ACTIVE;
12 NewValue = Value + EX_RUNDOWN_COUNT_INC;
13 NewValue = (ULONG_PTR) InterlockedCompareExchangePointerAcquire (&RunRef->Ptr,
14 (PVOID) NewValue,
15 (PVOID) Value);
16 if (NewValue == Value) {
17 return TRUE;
18 } else {
19 return ExfAcquireRundownProtection (RunRef);
20 }
21 }
1 NTKERNELAPI
2 BOOLEAN
3 FASTCALL
4 ExfAcquireRundownProtection (
5 __inout PEX_RUNDOWN_REF RunRef
6 )
7 /*++
8
9 Routine Description:
10
11 Reference a rundown block preventing rundown occurring if it hasn't already started
12 This routine is NON-PAGED because it is being called on the paging path.
13
14 Arguments:
15
16 RunRef - Rundown block to be referenced
17
18 Return Value:
19
20 BOOLEAN - TRUE - rundown protection was acquired, FALSE - rundown is active or completed
21
22 --*/
23 {
24 ULONG_PTR Value, NewValue;
25
26 Value = RunRef->Count;
27 do {
28 //
29 // If rundown has started return with an error
30 //
31 if (Value & EX_RUNDOWN_ACTIVE) {
32 return FALSE;
33 }
34
35 //
36 // Rundown hasn't started yet so attempt to increment the unsage count.
37 //
38 NewValue = Value + EX_RUNDOWN_COUNT_INC;
39
40 NewValue = (ULONG_PTR) InterlockedCompareExchangePointer (&RunRef->Ptr,
41 (PVOID) NewValue,
42 (PVOID) Value);
43 if (NewValue == Value) {
44 return TRUE;
45 }
46 //
47 // somebody else changed the variable before we did. Either a protection call came and went or rundown was
48 // initiated. We just repeat the whole loop again.
49 //
50 Value = NewValue;
51 } while (TRUE);
52 }