Как восстановить все элементы ключа реестра?(время последней записи, тип, значение, имя ...) Это правильный метод? - PullRequest
0 голосов
/ 26 апреля 2019

Я бы хотел восстановить все элементы ключа реестра. методы окон API RegOpenEX и RegEnumKeyEx. Но я не уверен, что это правильный способ сделать это. Вот пример моего кода, поэтому должны ли эти два метода использоваться для получения этой информации?

HKEY RegHkey;
Long RC=0;
DWORD a=0;
DWORD TMP=255;
FILETIME filetime;
LPWSTR lpName=nullptr;
LPWSTR lpClass=nullptr;
DWORD cchClasss=0;

RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\",0,KEY_READ,&RegHkey);

while(RC != ERROR_NO_MORE_ITEMS)
{
  RC=RegEnumKeyEx(RegHkey, a, lpName, &TMP, nullptr, lpClass, &cchClass, &filetime);
   if(RC==ERROR_SUCCESS)
   {
      std::cout<<"type= "<<cchClass<<std::endl;
     //etc...

   }
   a++;
}

если RC == ERROR_SUCCESS Я хотел бы получить тип, значение и last_write_time .... Это правильный метод?

1 Ответ

1 голос
/ 27 апреля 2019

К сожалению, в этом коде почти все не так.

LPWSTR lpName=nullptr;
LPWSTR lpClass=nullptr;

Всякий раз, когда документация для параметра функции говорит что-то вроде " Указатель на буфер ", вы должны предоставить буфер, который вы выделили.

// The {} brackets zero-initialize the buffers.
wchar_t szName[255]{};
wchar_t szClass[255]{};
DWORD TMP=255;
DWORD cchClasss=0;

Установка cchClass на ноль неверна. Вы должны сообщить функции, насколько велики ваши буферы (сколько символов, включая «\ 0», она может хранить там). Переменная TMP не имеет значащего имени, cchName будет более согласованным:

// No need to hardcode the array size.
DWORD cchName  = ARRAYSIZE(szName);
DWORD cchClass = ARRAYSIZE(szClass);
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\",0,KEY_READ,&RegHkey);

Отсутствует проверка на успешность функции. Открытие раздела реестра может завершиться неудачей по целому ряду причин, e. г. недостаточно прав:

DWORD res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\",0,KEY_READ,&RegHkey);
if(res == ERROR_SUCCESS)
{
    // do something with the registry key
} 
while(RC != ERROR_NO_MORE_ITEMS)

У вас есть бесконечный цикл, когда RegEnumKeyEx дает сбой по другим причинам, кроме завершения перечисления. Правильное условие будет RC == ERROR_SUCCESS.

  RC=RegEnumKeyEx(RegHkey, a, lpName, &TMP, nullptr, lpClass, &cchClass, &filetime);

Дочерние ключи реестра SOFTWARE\Microsoft\Windows\CurrentVersion\Run\ являются значениями, поэтому вместо них следует использовать RegEnumValueW().

Убедитесь, что вы также позвонили RegCloseKey(), как только вы закончите с ключом реестра.

...