2

This question is inspired by SO questions How to tell which process set the high timer resolution in Windows?, How does powercfg -energy detect the requested timer resolution?, and careful investigations.

Background: Windows allows to modify the system timer resolution by means of the functions timeBeginPeriod / timeEndPeriod or the underlying NtSetTimerResolution (exported by ntdll.dll). Any process is allowed to acquire timer resolutions supported by the platform. The timer resolution is a global setting, Windows uses the highest resolution requested by any process. The global nature of this timer resolution setting requires an internal data structure to keep track of which process has acquired which resolution. A call to timeBeginPeriod or NtSetTimerResolution with SetResolution=TRUE will register an entry in that data structure. A subsequent call to timeEndPeriod or NtSetTimerResolution with SetResolution=FALSE will remove that entry. When an entry is removed and the acquired timer resolution was the currently highest resolution supported, the system works out what the next highest registered resolution is and sets the timer resolution accordingly. The next highest resolution may be less or equal to the currently highest resolution. See MSDN: Timer Resolution for more details.


The inspiring questions mentioned above are asking about an API to access this management data structure, particularly about which processes acquired which timer resolutions or even only which process has acquired the current resolution.

Working on this matter for some time has resulted in reasons to believe that there must be a way to access this information:

The number of supported resolution depends on the version of Windows and the hardware platform. Some resolutions are typical, others seem odd since they hardly appear. A list of supported resolution can be obtained by calling timeBeginPeriod(uPeriod) with increasing values of uPeriod (typically ranging from 1 to 16).

Setting the timer resolution to one of these odd resolutions on XP / VISTA / 7 may cause the resolution to change spontaneously but not necessarily immediately to something more common on specific platforms. First thoughts led to the idea that this could be another application or a driver which just dislikes this particular odd resolution. Consequently, the suspicious process/driver would change the timer resolution to better suit its requirements. However, this can only go in one direction; the process/driver could only modify the timer resolution by choosing a higher resolution. So far so good. But now the system should be stuck at that resolution if there was not way to query the data structure. A change to a lower resolution would be prohibited.

When the odd resolution is taken off the list, e.g. by a call to timeEndPeriod, the resolution shall stay where it has been set to by the suspicious process/driver which disliked the odd resolution.

But that's not the case! The resolution returns to a lower resolution. The process/driver must have gotten knowledge of the fact that the odd resolution was unregistered and it released its registration as well. However, more detailed investigation showes that it would not get asynchronously informed, some delay indicates that the suspicious process/driver perhaps monitored the actual timer resolution data structure frequently.

Question: How can this data structure be accessed?

Note: It may well be that it was the kernel itself. But it's hard to believe that Windows itself spontaneously changes "disliked" timer resolutions on its own.

Update: Code Machine: Catalog of key Windows kernel data structures: The kernel variable ExpTimerResolutionListHead maintains a list of processes that have called NtSetTimerResolution() to change the timer interval. This list is used by ExpUpdateTimerResolution() to update the time resolution to the lowest requested value amongst all the processes.

Any idea how to access the kernel data structure ExpTimerResolutionListHead other than using LifeKD or other ways for kernel mode debugging as described in "Windows Internals Part 1, 6th Edition" by David Solomon and Mark Russinovich, Microsoft Press 2012?

Community
  • 1
  • 1
Arno
  • 4,994
  • 3
  • 39
  • 63
  • powercfg -energy also shows the call stack of the call which set process' highest timer resolution. I assume this call stack works also retroactively - for calls that were done before running powercfg -energy. So perhaps kernel has even information for these callstacks too. I only wonder why...? And mainly in this context - where could this information be located? Is it also in the same kernel data structure? – Roland Pihlakas Jun 29 '14 at 13:29

0 Answers0