hex.pp.ua

Native приложения. Первые шаги

С чего начать программирование native приложений для Windows




Native приложения — это программы, предназначенные для выполнения на операционных системах Windows семейства NT (NT/2000/XP/2003/Vista/7), способные запускаться на раннем этапе загрузки Windows, до окна входа в систему и даже до запуска каких-либо подсистем Windows. Синий экран при загрузке Windows XP, в котором, например, происходит проверка диска и есть тот самый режим. Native приложения используют только Native API, они могут использовать только функции, экспортируемые из библиотеки ntdll.dll. Для них недоступны функции WinAPI.

Native приложения запускаются на экране, который возникает до появления окна входа в систему. Примером native приложения является приложение chkdsk, которое запускается перед входом в Windows, если предварительно была запущена проверка системного раздела на ошибки и отложена до перезагрузки. Приложение работает, выводя сообщения экран, а затем происходит обычный запуск Windows.

Преимущества использования этого режима: большая часть компонентов Windows ещё не запущена, отсутствуют многие ограничения. Этот режим, например, используется в приложениях, которые хотят что-то сделать с системным разделом Windows, но не могут, пока запущена операционная система: дефрагментаторы, конверторы файловой системы, и тому подобные утилиты.

Моя программа Native shell запускается до экрана входа в систему и предоставляет интерфейс командной строки с возможностью перемещаться по файловой системе Windows, копировать и удалять файлы, просматривать некоторую информацию об операционной системе и запускать другие процессы, способные выполняться в native-режиме, такие как autochk.exe и autoconv.exe. Доступны исходные коды программы на языке Си.

Загрузочные экраны native режима разных версий Windows:

Синий экран Windows XPСиний экран Windows XP. ерый экран Windows Server 2003 Серый экран Windows Server 2003
Чёрный экран Windows Vista Чёрный экран Windows Vista  Чёрный экран Windows 7 Чёрный экран Windows 7

Что нужно знать:

Native приложения компилируются с помощью WDK - Windows Driver Kit (также известный, как DDK). Есть возможность делать их и в какой-то другой среде разработки, но в WDK проще всего.

Native приложения используют Native API. Оно частично документировано в MSDN для использования при написании драйверов. Но документированы не все функции. Информацию по остальным нужно брать из неофициальных источников. Например, на сайте http://undocumented.ntinternals.net/

Функции в ntdll.dll имеют префиксы Zw и Nt, а также некоторые другие. Видно, что у Zw и Nt функции дублируются названия. На самом деле это одни и те же функции. Если искать в сети пример использования какой-либо функции, стоит поискать сначала с одним префиксом, потом с другим, иначе можно что-то упустить. Почему у них разные префиксы - отдельная история, для программирования native приложений существенной роли не играет.

Для программирования нужны прототипы функций Native API, но в заголовочных файлах WDK присутствуют не все определения. Нужно использовать альтернативные заголовочные файлы, содержащие в том числе и определения недокументированных функций и типов данных. Например, можно воспользоваться заголовочными файлами Native Development Kit (NDK), которые доступны здесь.

Программировать на чистом Native API неудобно. Не обойтись без библиотеки, в которой уже реализованы некоторые рутинные действия. Существует библиотека с открытым кодом - ZenWINX, можно пользоваться ей. Ещё на страничке NDK анонсирована некая библиотека NDL, но на сайте её нет.

Чтобы native приложение запустилось при запуске Windows, надо положить его в каталог system32, а в ключ реестра HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute прописать его имя файла, и аргументы, если они есть. Ключ имеет тип MULTI_SZ, может содержать несколько строк. Первой строкой там идёт Autocheck Autochk *. После неё можно прописывать свою программу. Программа, прописанная в этом ключе, имеет свойство запускаться даже в безопасном режиме Windows (safe mode), так что нужно быть осторожным. Ошибка в программе - и система не запустится. Но можно внутри приложения отслеживать факт запуска в safe mode и обрабатывать этот режим отдельно, например сделать завершение программы, если она обнаружила себя запущенной в safe mode. Кроме того, несмотря на то, что программа запускается и может выполнять какие-то действия, в этом режиме не работает вывод на консоль. Невозможно взаимодействие с пользователем. Это следует учитывать.

При необходимости, native-приложение можно запустить и не перезагружая компьютер. Для этого следует воспользоваться утилитой nrun.exe. Но загрузочный экран от этого не появится, и вам следует придумать, как ещё взаимодействовать с вашим приложением, если нужна интерактивность. В исходном коде nrun можно посмотреть, как реализован запуск native-процессов с использованием недокументированных функций Native API.

У native приложений точка входа не main и не wmain, а NtProcessStartup. В PE-заголовке EXE-файла есть специальное поле, означающее подсистему, в которой выполняется приложение. У native приложений в это поле установлено специальное значение, означающее, что EXE не требует подсистемы. У обычных приложений ставится значение, соответствующее подсистемам "Windows GUI" или "Windows console". Native приложения не запускаются в обычном режиме работы Windows. При попытке запустить программу Windows выдаёт сообщение "Приложение нельзя запустить в режиме Win32".

Вывод кириллицы на экран по-умолчанию в этом режиме не поддерживается. Есть способ обойти это ограничение, впрочем, способ сложный и пока работает только на Windows XP.

Приложение нельзя запустить в режиме Win32
Приложение нельзя запустить в режиме Win32

Заготовка проекта Native приложения

Я создал заготовку проекта Native приложения — набор файлов, который можно использовать в качестве базы для разработки собственного Native приложения. Заготовка содержит файл native.c, содержащий точку входа в приложение. Остальные файлы - это файлы библиотеки ZenWINX, которые модифицированы так, что используют определения функций из NDK, а не из своего файла с определениями. Это позволяет использовать как функции самой библиотеки, так и функции Native API, которые разработчики ZenWINX забыли включить в собственный заголовочный файл. Фактически, NDK - более полный каталог Native API функций, чем файл, поставляемый с ZenWINX. Компилировать заготовку нужно утилитой build из состава WinDDK (я использую версию WinDDK 1.1.6001.000). Следует подключать заголовочные файлы NDK, прописав пути к каталогу с ними.

Возможно также разрабатывать и собирать Native-приложения прямо в Visual Studio, без использования компилятора WDK. О том, как это сделать, написано в статье Сборка Native API-приложения в Visual Studio 2010.

Программы режима Native API


При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт. По поводу рекламы обращайтесь на почту [email protected]