Я пытаюсь зарегистрировать счетчик производительности, и часть этого процесса включает добавление некоторых текстовых описаний к определенному разделу реестра. Для английского языка этот ключ - HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Perflib \ 009, который также известен как HKEY_PERFORMANCE_TEXT. Там есть пара значений (Counter, Help), которые имеют данные REG_MULTI_SZ, и мне нужно изменить их для достижения моей цели.
Официальный способ сделать это - использовать инструмент под названием lodctr вместе с файлами .h и .ini . Существует также функция для выполнения этой программы , но, насколько я понимаю, это всего лишь простая оболочка для вызова программы lodctr. Перспектива сохранения, распространения и хранения синхронизированных трех отдельных файлов была немного обременительной, поэтому ранее я писал для этого код, и он прекрасно работал в Windows XP (и, возможно, в Vista, хотя я точно не помню).
Сейчас я пытаюсь использовать тот же код в Windows 7, и он не работает. Проблема в том, что всякий раз, когда я пытаюсь установить значения реестра, происходит сбой с ERROR_BADKEY; даже regedit не может изменить значения, так что это не проблема с моим кодом. Я запустил Process Monitor и заметил, что на уровне драйвера не было никаких действий, поэтому кажется, что этот доступ должен быть заблокирован в коде пользовательского режима (например, advapi32.dll или где-либо еще). Я понимаю, почему Microsoft пытается запретить людям делать это, поскольку это очень легко испортить, и это приведет к повреждению всей коллекции счетчиков производительности на компьютере.
Я собираюсь отладить lodctr и посмотреть, что за волшебство чисто из любопытства, но мне интересно, сталкивался ли кто-нибудь с этим раньше? Есть ли альтернативы, кроме утилиты lodctr? Возможно, вызов API реестра NT напрямую? Я действительно предпочел бы избежать хлопот метода lodctr, если это возможно.
Минимальный пример для воспроизведения вопроса:
HKEY hKey = NULL;
LONG nResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009"), 0, KEY_ALL_ACCESS, &hKey);
if(ERROR_SUCCESS == nResult)
{
LPCTSTR lpData = _T("bar");
DWORD cbData = (_tcsclen(lpData) + 1) * sizeof(TCHAR);
nResult = RegSetValueEx(hKey, _T("foo"), 0, REG_SZ, (const BYTE*)lpData, cbData);
// here nResult == ERROR_BADKEY
RegCloseKey(hKey);
hKey = NULL;
}
РЕДАКТ. 1:
Я потратил около часа или около того, пытаясь отладить официальные API, и не мог понять это, поэтому я попробовал еще немного Google. Через некоторое время я наткнулся на эту статью базы знаний , которая объясняет поведение RegSetValueEx. Поскольку в нем упоминалось изменение системных файлов, я подумал, что, возможно, именно эти данные реестра поддерживаются сопоставленным файлом. Затем я наткнулся на другую статью базы знаний , в которой упоминаются Perfc009.dat и Perfh009.dat в папке system32. Открыл их в шестнадцатеричном редакторе и, конечно же, это необработанные данные REG_MULTI_SZ, которые я пытаюсь изменить. Теперь, когда я знаю, что, может быть, я смогу еще раз взглянуть и разобраться, хотя сейчас мне это надоело.