Тонкости взаимодействия 32 и 64-битных программ
Aug 18, 2006 · CommentsWow64
Wow64 это сокращение от «Windows on Windows64». Так обозначается эмулятор 32-битного, x86-совместимого окружения, позволяющего запускать 32-битные приложения на 64-битных версиях Windows. Соответствующий раздел в MSDN (http://windowssdk.msdn.microsoft.com/en-us/library/ms775191.aspx) хорошо описывает отличия между окружением 32-битных и 64-битных приложений. Я же хотел бы рассказать о нескольких, очевидных и не очень, особенностях взаимодействия 32 и 64-битных приложений.
Wow64 перехватывает все переходы между 32-битным кодом приложения и ядром системы, что включает в себя как вызовы сервисов ядра, так и обратные вызовы 32-битного кода из ядра. Для этого 64-битные версии Windows включают в себя специальные версии 32-битных Ntdll.dll, User32.dll и Gdi32.dll, которые передают управление Wow64 вместо обычного системного вызова. В свою очередь Wow64 переключается в 64-битный режим, преобразует переданные 32-битные указатели в 64-битные и выполняет системный вызов. По окончанию вызова, Wow64 выполняет обратное преобразование возвращаемых значений. Также перехватываются исключения и обратные вызовы (callbacks). Таким образом, 32-битное приложение полностью изолируется от системы и других 64-битных приложений.Одним из следствий подобной изоляции является запрет на смешивания 32-битного и 64-битного кода в рамках одного процесса. 64-битный код может вызывать системные сервисы, минуя Wow64, что, в свою очередь, может нарушить целостность внутренних структур Wow64. С очевидными последствиями.
Наиболее неприятное следствие этого запрета – невозможность использования 32-битных in-process COM объектов 64-битными процессами. Это может стать серьезной проблемой при переносе 32-битного приложения в 64-битное окружение в случае, если исходные коды используемых in-process COM компонентов недоступны.
32-битные и 64-битные процессы по-прежнему могут использовать все существующие средства межпроцессного взаимодействия. Wow64 берет на себя все заботы по преобразованию указателей.
Как я уже писал ранее, Wow64 включает в себя файловый редиректор (file system redirector), который скрывает от 32-битных программ каталог «%windir%\System32», переправляя все запросы в «%windir%\SysWow64». В этом каталоге находятся 32-битные версии 64-разрядных компонентов из «%windir%\System32». Фактически «%windir%\SysWow64» это копия «%windir%\System32» 32-битной версии Windows.
Подобный дизайн обладает неожиданным побочным эффектом – несмотря на то, что система не накладывает ограничений на запуск 64-битных приложений из 32-битных, 32-битные приложения не имеют возможности напрямую запустить приложение установленное в «%windir%\System32». Так, например, открыв окно 32-битного «cmd.exe» нельзя так просто переключиться в 64-битный «cmd.exe». Конечно же, существует способы бороться с этой проблемой, однако все они опираются на использование специфичных для 64-битной системы механизмов, о существовании которых большинство 32-битных приложений не подозревает.
И последнее ограничение на сегодня - 64-битные версии Windows требуют, чтобы все драйвера в системе были 64-битными. На первый взгляд это не должно быть проблемой, однако это касается и драйверов принтеров, что автоматически затрагивает большинство программ PDF-генераторов. 32-битный драйвер виртуального принтера, который используется для генерации PDF, не работает на 64-битной системе. Точно также не работают старые версии эмуляторов различных устройств и некоторые программы для записи CD/DVD.
Резюме. 32-битные приложения на удивление хорошо интегрируются в 64-битную систему. Особенно если учесть, что 32 и 64-битный бинарный код не совместим даже на Amd64, не говоря уже об Itanium (IA-64). Тем не менее, обеспечение совместимости добавит (и уже добавило) головной боли разработчикам.