Драйвер VXDSRV
После такого краткого обзора сервиса, доступного виртуальным драйверам, перейдем к практике. Мы предлагаем вам познакомиться с разработанным нами виртуальным драйвером VXDSRV, предназначенным для запуска приложений Windows из командной строки виртуальной машины MS-DOS или из среды таких программ, как Norton Commander и Xtree, работающих в виртуальной машине MS-DOS.
Поясним подробнее, для чего же предназначен наш драйвер.
Запустите любое приложение Windows из командной строки виртуальной машины MS-DOS. Вы увидите беспомощное сообщение о том, что требуется наличие Microsoft Windows:
This program requires Microsoft Windows.
Но Microsoft Windows уже работает! Не лучше ли было бы, вместо того чтобы выдавать подобное сообщение, попытаться запустить приложение в системной виртуальной машине?
Именно это и делает наш драйвер. После его активизации вы никогда не увидите сообщения о невозможности запуска приложения из виртуальной машины MS-DOS. Драйвер, работающий вместе с DLL-библиотекой d2w.dll и обычным приложением Windows dos2win.exe (исходные тексты также будут описаны), передает приложению dos2win.exe параметры запускаемого приложения. Получив эти параметры, dos2win.exe обеспечивает запуск приложения с помощью функции LoadModule из программного интерфейса Windows.
Для того чтобы обнаружить попытку запуска программы MS-DOS или приложения Windows, мы перехватываем функцию 4B00h прерывания INT21h и анализируем передаваемый ей файл. Перехват выполняется при помощи сервиса VMM, поэтому свободное адресное пространство виртуальных машин MS-DOS не уменьшается (это было бы не так при использовании обычной резидентной программы MS-DOS).
После обнаружения попытки запуска, виртуальный драйвер анализирует заголовок соответствующего exe-файла, для того чтобы определить, что запускается - программа MS-DOS или приложение Windows.
Если запускается программа MS-DOS, виртуальный драйвер не вмешивается в процесс запуска, позволяя функции 4B00h прерывания INT 21h спокойно делать свое дело.
Если же пользователь сделал попытку запустить приложение Windows, виртуальный драйвер отменяет выполнение указанной выше функции прерывания INT 21h. Затем он сохраняет путь к запускаемому файлу, параметры и путь к текущему на момент запуска каталогу в буфере. Этот буфер расположен в фиксированном сегменте данных DLL-библиотеки d2w.dll.
Сохранив параметры в буфере, виртуальный драйвер вызывает функцию обратного вызова, которая находится в фиксированном сегменте кода той же DLL-библиотеки d2w.dll.
В свою очередь, функция обратного вызова записывает специальное сообщение в очередь сообщений главного окна приложения dos2win.exe, пользуясь для этого обычной функцией PostMessage.
Получив это сообщение, функция главного окна приложения dos2win.exe выполняет запуск приложения, параметры которого получены от виртуального драйвера.
Описанная схема не лишена недостатков. В частности, в составе системы разработки программного обеспечения Microsoft Visual C++ for Windows поставляются достаточно странные программы, для которых наш алгоритм не подходит. Эти программы являются, строго говоря, приложениями Windows, так как содержащие их exe-файлы имеют два заголовка - старый и новый. Однако их необходимо запускать из среды MS-DOS или из среды виртуальной машины MS-DOS - иначе они не работают.
Наш драйвер совершенно справедливо относит такие программы к приложениям Windows, так как он принимает решение на основе анализа заголовка exe-файла. Попытка запуска такого "приложения" функцией WinExec приводит к зацикливанию Windows. Другая функция, с помощью которой можно запустить приложение Windows, это LoadModule. Эта функция в данном случае просто ничего не делает.
В результате драйвер VXDSRV блокирует выполнение странных программ (что все же лучше, чем зацикливание Windows!).
Вам такое решение может не понравиться, что будет совершенно справедливо. Однако выход все-таки есть. Драйвер может считывать список имен нестандартных программ, и принимать решение о принадлежности программы, входящих в этот список, не на основе анализа заголовка exe-файла, а на основе данных, хранящихся в списке (вспомните драйвер setver.exe, который из благородных побуждений вводит программы MS-DOS в заблуждение относительно текущей версии MS-DOS).Реализацию этого способа мы оставляем вам в качестве упражнения.
Обратимся к исходному тексту виртуального драйвера (листинг 5.1).