原文连接:
http://bbs.pediy.com/showthread.php?t=173763
NT 5.1 内核引入的Run-down Protection
XP以后的windows内核,引用了一种新的同步技术,微软叫它: Run-down Protection。这种同步技术至今还很神密,连很多搞内核和驱动很有经验的朋友,和他们讨论起来的时候,了解的人也不多。所以今天我写篇短文简单介绍一下。
我们知道对象的删除在并行系统中是一个问题,如果一个对象一个执行流在使用对象,而另一个执行流却在删除对象,就会出现问题。解决这个问题的一个办法就是引用计数。我们今天介绍的 Run-down Protection 其实也就是引用计数,不过它还做了一些额外的工作。
Drivers can use run-down protection to safely access objects in shared system memory that are created and deleted by another kernel-mode driver.
这句话是微软MSDN里的介绍。简单点说,就是为了保护对象的安全的删除。现在XP中,主要用它来保护内核中进程对象和线程对象的删除。
我这里主要介绍它的四个例程 ExfInitializeRundownProtection,ExfAcquireRundownProtection, ExfReleaseRundownProtection,ExfWaitForRundownProtectionRelease
指出一下,在内核导出时,为这几个函数使用了别名, Exf的前缀换成了Ex。 例如 ExfInitializeRundownProtection 变成了 ExInitializeRundownProtection。
下面我一一介绍。 先说一下功能,顺便说一下原理。
typedef struct _EX_RUNDOWN_REF { #define EX_RUNDOWN_ACTIVE 0x1 #define EX_RUNDOWN_COUNT_SHIFT 0x1 #define EX_RUNDOWN_COUNT_INC (1<<EX_RUNDOWN_COUNT_SHIFT) union { ULONG_PTR Count; PVOID Ptr; }; } EX_RUNDOWN_REF, *PEX_RUNDOWN_REF; NTKERNELAPI VOID FASTCALL ExfReInitializeRundownProtection ( __out PEX_RUNDOWN_REF RunRef )。
NTKERNELAPI BOOLEAN FASTCALL ExfAcquireRundownProtection ( __inout PEX_RUNDOWN_REF RunRef )
NTKERNELAPI VOID FASTCALL ExfReleaseRundownProtection ( __inout PEX_RUNDOWN_REF RunRef )
NTKERNELAPI VOID FASTCALL ExfWaitForRundownProtectionRelease ( __inout PEX_RUNDOWN_REF RunRef )
也许有人会疑惑,那个KEVENT,在哪个地方保存?EX_RUNDOWN_REF 里并没有相应的数据结构。答案在这里。
EX_RUNDOWN_WAIT_BLOCK WaitBlock;
在这里, WaitBlock要取代原来的引用计数。所以你可以看到EX_RUNDOWN_REF里Count和Ptr共用内存空间。在ExfWaitForRundownProtectionRelease调用前Count被用来计数,ExfWaitForRundownProtectionRelease调用之后,Ptr指向了WaitBlock,接管计数,并且提供KEVENT等待计数归0。*转载请注明来自看雪论坛@PEdiy.com