如何访问/查询Windows定时器parsingpipe理信息?

这个问题受到SO问题的启发如何判断哪个进程在Windows中设置了高分辨率? , powercfg-energy如何检测请求的定时器分辨率? ,并仔细调查。

背景: Windows允许通过函数timeBeginPeriod / timeEndPeriod或底层的NtSetTimerResolution (由ntdll.dll导出)来修改系统计时器parsing。 任何进程都可以获取平台支持的定时器分辨率。 计时器分辨率是一个全局设置,Windows使用任何进程要求的最高分辨率。 这种定时器分辨率设置的全球性要求内部数据结构来跟踪哪个进程获得了哪个分辨率。 使用SetResolution = TRUE调用timeBeginPeriod或NtSetTimerResolution将在该数据结构中注册一个条目。 随后调用timeEndPeriod或NtSetTimerResolution并设置分辨率= FALSE将删除该条目。 当一个条目被移除并且获得的定时器分辨率是当前支持的最高分辨率时,系统计算出下一个最高的分辨率,并相应地设置定时器分辨率。 下一个最高分辨率可能小于或等于当前最高分辨率。 请参阅MSDN:计时器分辨率了解更多详情


上面提到的令人鼓舞的问题是询问一个API来访问这个pipe理数据结构,特别是关于哪个进程获得了哪个定时器分辨率,甚至哪个进程获得了当前的分辨率。

在这个问题上工作了一段时间,导致有理由相信,必须有一种方法来访问这些信息:

支持的分辨率数量取决于Windows和硬件平台的版本。 有些决议是典型的,有些则很奇怪,因为它们几乎不出现。 支持的分辨率列表可以通过调用timeBeginPeriod(uPeriod)随着uPeriod (通常范围从1到16)值的增加而获得

将定时器分辨率设置为XP / VISTA / 7上这些奇数分辨率之一,可能会导致分辨率自发地改变,但不一定会立即改变为特定平台上更常见的分辨率。 最初的想法导致这样的想法,这可能是另一个应用程序或驱动程序,只是不喜欢这个奇怪的决议。 因此,可疑的进程/驱动程序将改变计时器分辨率以更好地满足其要求。 但是,这只能朝着一个方向发展。 进程/驱动程序只能通过select更高的分辨率来修改计时器分辨率。 到现在为止还挺好。 但是现在,如果没有办法查询数据结构,系统应该停留在那个分辨率上。 禁止更改为较低的分辨率。

当奇数分辨率从列表中被取消时,例如通过调用timeEndPeriod,分辨率应该保持在不喜欢奇数分辨率的可疑进程/驱动程序设置的地方。

但事实并非如此! 分辨率返回到较低的分辨率。 程序/驱动程序必须已经知道奇数分辨率未注册的事实,并且也公布了其注册。 然而,更详细的调查表明,它不会得到asynchronous通知,有些延迟表明,可疑的进程/驱动程序可能经常监视实际的计时器分辨率数据结构。

问题:如何访问这个数据结构?

注意:它可能是内核本身。 但很难相信Windows本身会自发地改变“不喜欢”的定时器分辨率。

更新: 代码机 :关键的Windows内核数据结构目录: 内核variablesExpTimerResolutionListHead维护一个进程列表,调用NtSetTimerResolution()来更改计时器时间间隔。 ExpUpdateTimerResolution()使用此列表将时间分辨率更新为所有进程中所请求的最低值。

任何想法如何访问内核数据结构ExpTimerResolutionListHead除了使用LifeKD或其他方式进行内核模式debugging,如David Solomon和Mark Russinovich在“Windows Internals Part 1,6th Edition”中所述 ,Microsoft Press 2012?