Windows 3.x жив?

Функция CreateProcess может по праву считаться одной из самых больших и сложных функций Win32 API. Помимо собственно создания адресного пространства, загрузки кода и запуска первого потока она делает ещё много неочевидных, но необходимых вещей. Например, она умеет запускать 16-ти битные приложения на 64-х битной системе. Позвольте, скажете вы, но разве поддержка 16-ти битных DOS, Windows и OS/2 приложений не была полностью убрана из 64-х битных версий системы?

Это действительно так, однако здесь есть одна тонкость. Старые версии InstallShield, да и других инсталляторов, создавали инсталляции, включающие в себя 16-ти битный загрузчик (setup.exe). Из-за этого заметное количество 32-х битных приложений отказывалось устанавливаться на 64-х битной системе. Для решения этой проблемы в CreateProcess была добавлена возможность распознавать такие исполняемые файлы и на лету подменять их на аналогичные по функциональности 32-х битные.

Работает это так: если NtCreateUserProcess возвращает ошибку STATUS_INVALID_IMAGE_WIN_16, то CreateProcess пытается сопоставить загружаемый модуль со списком из “HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\NtVdm64”. Если файл совпадает с описанием из списка, то вместо него будет загружен 32-х битный модуль с идентичной функциональностью. При поиске используется информация о версии модуля, а именно: ProductName , ProductVersion и InternalName. При этом, как видно из примера ниже, работают маски ‘*’:

[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows
 NT\\CurrentVersion\\NtVdm64\\INSTALLSHIELD5]
"ProductVersion"="5*"
"ProductName"="InstallShield*"
"InternalName"="*"
"CommandLine"="-isw64\\"%m\\" %c"
"MappedExeName"="C:\\\\Windows\\\\SysWOW64\\\\InstallShield\\\\setup.exe"

Значение “CommandLine” задает параметры командной строки, которые будут переданы в 32-х битный модуль. “%m” заменяется именем оригинального 16-ти битного файла. “%c” заменяется командной строкой, переданной 16-ти битному исполняемому файлу.

Список поддерживаемых 16-ти битных программ можно расширять (раз уж он храниться в реестре). Хотя вряд ли это кому понадобиться.

Статья на MSDN: Application Installation

comments powered by Disqus