Доступ к альтернативным представлениям реестра

64-битные версии Windows поддерживают два различных представления реестра для 32 и 64-битных приложений. По-умолчанию приложения работают со своим представлением. Также они могут выбирать желаемое представление с помощью флагов KEY_WOW64_32KEY и KEY_WOW64_64KEY. Применение этих флагов кажется очевидным и прямолинейным, однако это не совсем так.

Первая сложность – это возможность переключения выбранного представления на лету. Проблема заключается в том, что при переключении путь к ключу меняется по нетривиальному алгоритму. Например, можете ли вы сказать, на какой ключ будет указывать hChild после выполнения следующего кода?

HKEY hParent = NULL;
RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    "SOFTWARE",
    0,
    KEY_READ | KEY_WOW64_32KEY,
    &hParent);

HKEY hChild = NULL;
RegOpenKeyEx(
    hParent,
    "Microsoft",
    0,
    KEY_READ | KEY_WOW64_64KEY,
    &hChild);

Будет это «HKLM\SOFTWARE\Microsoft» или «HKLM\SOFTWARE\Wow6432Node\Microsoft»? Для предотвращения этой проблемы рекомендуется избегать переключения выбранного представления на лету. Комбинация флагов KEY_WOW64_XXKEY использованная для открытия или создания родительского ключа должна использоваться и для всех подчиненных ключей.

Вторая сложность – за выбор желаемого представления реестра отвечают разные компоненты в случае 32 и 64-битных приложений. В случае 32-битных приложений wow64.dll перехватывает вызовы функций NtCreateKey и NtOpenKey, добавляя необходимую функциональность. 64-битные приложения используют вспомогательные функции из advapi32.dll, которые вызываются 64-битными реализациями функций RegCreateKeyEx, RegOpenKeyEx и RegDeleteKeyEx. Иными словами если 64-битное приложение использует функции Native API напрямую оно должно быть готово к тому, что NtCreateKey и NtOpenKey ничего не знают о разных представлениях реестра.

comments powered by Disqus