Dealing with Localized Performance Monitor Counters Part 2/2
In the last post we talked about using the PdhAddEnglishCounter function to add English-localized performance counters to a query set, but were stuck on how enumerate through all of the counters on a specific object.
I disassembled PDH.dll and found that PdhAddEnglishCounter uses an internal function, PdhTranslateLocaleCounterA, to do the needful. It would be nice if that function were public and documented. :|
I kept digging and traced this function down several layers deep, and found it's getting data from the registry. (That's a clue.) Digging deeper into that I found some references online to a very old (2006) Windows 2003 KB article, Q287159 Using PDH APIs Correctly in a Localized Language.
This content is no longer available from Microsoft, and inconveniently the internet archive is currently offline due to a DDOS attack. I was able to find the article here: Microsoft KB Archive/287159 - BetaArchive Wiki.
That KB/Q gives the keys for decoding the localized perfmon counters. On all systems, and I confirmed this on my de-de German system, the English language ID to Object/Counter mapping is stored in the registry in this key.
Path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009
Name: Counter
Type: REG_MULTI_SZ
The format is index string followed by name string, and then index string followed by name string terminated by another NULL character at the end.
So, to build my secret perfmon decoder ring, I can get this key and parse it into a hashtable. Then I can grab the index value for a given object or counter, and then pass that to the PdhLookupPerfNameByIndex() API. Magic!
Comments