Вы используете «Wow6432Node» в своем коде? Немедленно прекратите!

May 7th, 2007

Я уже упоминал несколько раз, что 64-х разрядные версии Windows используют два раздельных представления реестра – одно для 32-х разрядных приложений, а другое для 64-х разрядных. Как-то, я даже писал о том, как это делается. Ключевых моментов там всего ничего:

  1. Разделён не весь реестр, а лишь некоторые из ключей;
  2. Физически 32-х разрядные ключи помещаются в ветки с именем «Wow6432Node»;
  3. Приложения могут выбирать представление реестра с которым они хотят работать с помощью флагов KEY_WOW64_32KEY и KEY_WOW64_64KEY (см. Accessing an Alternate Registry View).

Проблема, однако, заключается в том, что многие приложения имею тенденцию явно использовать «Wow6432Node», чтобы получить доступ к 32-х битным ключам реестра. Похоже, что всё происходит по такому сценарию:

  • Разработчики пробуют перевести приложение на 64-х битную платформу и натыкаются на проблему с реестром;
  • В процессе решения они узнают о разделении реестра и о том, что 32-х разрядные ключи расположены под «Wow6432Node»;
  • На коленке разрабатывается заплатка, которая, да, просто добавляет в путь «Wow6432Node», если программа выполняется под Wow64;
  • Ура! Всё работает, проблема решена, программисты идут пить пиво…

Что не тут так? «Wow6432Node» не документирована, как способ доступа к 32-х битному представлению реестра. Если поискать «Wow6432Node» на msdn.microoft.com, то в результате будет найдено довольно много статей упоминающих «Wow6432Node», однако все они либо описывают особенности организации реестра на 64-х разрядных версиях системы, либо описывают временные решения для проблем, возникающих с 32-х разрядными приложениями на 64-х битных системах. Поиск по KEY_WOW64_32KEY возвращает гораздо меньше статей, но первые же четыре ссылки ведут на статьи, описывающие рекомендованный способ работы реестром на 64-х разрядных OS.

Впрочем, я прекрасно понимаю, почему так происходит. Дизайн Wow64 – не самая прозрачная часть системы. Это скорее проэволюционировавший хак, чем хорошо продуманный компонент системы. В частности разделение реестра на два виртуальных представления – не самое очевидное архитектурное решения для разработчиков приложений. Тем не менее, код, использующий «Wow6432Node», – это очень плохое решение. По нескольким причинам:

  1. Структура реестра может поменяться с выходом следующей версией операционной системы либо даже с выходом нового сервис пака. Иными словами время жизни такого решения (фактически – заплатки) – пара лет;
  2. Как правило, используя подобную заплатку разработчики не понимают, что стоит за разделением реестра. В такой ситуации высока вероятность того, что в другие местах продукта имеется аналогичная или похожая проблема, связанная с особенностями 64-х разрядного реестра. В результате рождаются уродцы вроде принудительной синхронизации синхронизация 32-х и 64-х битных версий ключа (AKA закат солнца вручную). Частенько 32-х и 64-х разрядные компоненты приложения ведут себя по-разному;
  3. Такая заплатка создаёт иллюзию правильности – ведь работает же! Она имеет все шансы попасть в финальную версию продукта и разойтись по тысячам пользователей. Соответственно, распространение исправленной версии встанет в копеечку;
  4. Высокая стоимость исправления подобной заплатки может стать причиной того, что оно будет отложено до выхода следующей версии продукта, а пользователям будет рекомендовано не обновлять операционную систему. Фактически, повториться история с выходом Vista – относительно много приложений не будет совместимо со следующей версией системы. А на кого посыпятся все шишки? Именно!

В общем, вы всё еще используете «Wow6432Node» в своем коде? Немедленно прекратите!

, , ,

  1. Alexey.
    May 8th, 2007 at 00:04 | #1

    В общем, вы всё еще используете «Wow6432Node» в своем коде?
    Тогда мы идем к вам!
    :-)

    А если серьезно – непонятно – зачем вообще оставлять эту возможность хака и оттягивать конец(тм)?

  2. TarasCo
    May 8th, 2007 at 07:16 | #2

    Если продукт использует в своем составе как 32 битные, так и 64 битные модули ( например 64 битный драйвер + 32 битная консоль)? Могу предвидеть ответ – нужно все собирать в 64 битном виде, получить сертификат, логотип и еще кукую-нибудь дрянь :) . IMHO – хороший ключ. А то, что он не документирован – плохо.

  3. Andrey.
    May 8th, 2007 at 07:47 | #3

    А AppVerifier это ловит? Или всё ещё нет?

  4. Not a kernel guy
    May 8th, 2007 at 07:48 | #4

     

    Если продукт использует в своем составе как 32 битные, так и 64 битные модули ( например 64 битный драйвер + 32 битная консоль)? Могу предвидеть ответ – нужно все собирать в 64 битном виде, получить сертификат, логотип и еще кукую-нибудь дрянь :) . IMHO – хороший ключ. А то, что он не документирован – плохо.

    Для этого есть специальные флаги, о чём я в статье и написал:

    Приложения могут выбирать представление реестра с которым они хотят работать с помощью флагов KEY_WOW64_32KEY и KEY_WOW64_64KEY (см. Accessing an Alternate Registry View).

  5. Not a kernel guy
    May 8th, 2007 at 07:49 | #5

     

    А AppVerifier это ловит? Или всё ещё нет?

    Насколько я знаю – нет. Но есть надежда что будет.

  6. Not a kernel guy
    May 8th, 2007 at 07:54 | #6

     

    А если серьезно – непонятно – зачем вообще оставлять эту возможность хака и оттягивать конец(тм)?

    Скорее всего ответ будет “так получилось”. :-( В начале это была наименьшая из проблем. Теперь же Wow64 обслуживает 90% приложений и видимость Wow6432Node начинает мешать.

  1. No trackbacks yet.
Comments are closed.