Защищенные подсистемы
Серверы Windows NT называются защищенными подсистемами, так как каждый из них – это отдельный процесс, память которого защищена от других процессов системой виртуальной памяти исполнительной системы NT. Каждая защищенная подсистема обеспечивает интерфейс прикладным программам (API) посредством DLLs клиентской стороны. Когда приложение или другой сервер вызывает некоторую процедуру API, соответствующая DLL упаковывает параметры функции API в сообщение и с помощью средства локального вызова процедур (Local Procedure Call, LPC) посылает его серверу, реализующему данную процедуру. Сервер же, выполнив вызов, посылает ответное сообщение вызывающей программе. Передача сообщений остается невидимой для прикладного программиста. Используя такую процедуру, вызывающая программа никогда не получает прямого доступа к адресному пространству подсистемы.
Надо отметить, что далеко не все функции API реализуются сервером, например, большая часть функций API Win32 оптимизирована в DLL клиентской стороны, и в действительности не обращается к подсистеме Win32.
Защищенные подсистемы подразделяются на подсистемы среды (environment subsystems) и неотъемлемые подсистемы (integral subsystems).
Подсистемы среды
Подсистема среды – это сервер пользовательского режима, реализующий API некоторой ОС. Самая важная подсистема среды в Windows NT – это подсистема среды Win32 (рассматриваемая ниже), которая предоставляет прикладным программам интерфейс API 32-разрядной Windows. В Windows NT также имеются подсистемы среды: POSIX, OS/2 и виртуальная DOS машина (virtual DOS machine, VDM), эмулирующая 16-разрядную Windows и MS-DOS.
Данные подсистемы предоставляют свои API, но используют для получения пользовательского ввода и отображения результатов подсистему Win32, то есть перенаправляют видеовывод своих приложений подсистеме Win32 для отображения.
Говоря о подсистемах окружения, необходимо отметить также следующее. Каждая прикладная программа (и даже более того – каждый модуль, будь то exe, dll, sys или что-то другое) может относиться только к какой-то одной подсистеме окружения, либо не относиться ни к одной из них. Эта информация прописывается в любом исполняемом модуле на этапе его компиляции и может быть получена через утилиту "Быстрый просмотр" (Quick View) в пункте "Subsystem" (варианты: The image does not require subsystem, Win32 GUI, Win32 Console,…).
Подсистема среды Win32
Подсистема среды Win32 делится на серверный процесс (csrss.exe – Client/Server Runtime Subsystem) и клиентские DLLs (user32.dll, gdi32.dll, kerneI32.dll), которые связаны с программой, использующей Win32 API. Win32. API разделен на три категории:
- Управление окнами (windowing) и передача сообщений (messaging). Эти интерфейсы оконных процедур и процедур сообщений включают, например, такие функции, как CreateWindow(), SendMessage(), и предоставляются прикладной программе через библиотеку user32.dll.
- Рисование (drawing). Например, функции BitBitQ и LineTo() являются Win32-функциями рисования и предоставляются библиотекой gdi32.dll.
- Базовые сервисы. Базовые сервисы включают весь ввод/вывод %т32, управление процессами и потоками, управление памятью, синхронизацию и предоставляются библиотекой kernel32.dll.
Когда Win32-приложение вызывает функцию API Win32, управление передается одной из клиентских DLLs подсистемы Win32. Эта DLL может:
- Выполнить функцию самостоятельно без обращения к системным сервисам ОС и вернуть управление вызывающей программе.
- Послать сообщение Win32-cepвepy для обработки запроса в том случае, если сервер должен участвовать в выполнении заданной функции. Так, функция CreateProcess(), экспортируемая библиотекой kernel32.dll, требует взаимодействия с Win32-cepBepOM, который, в свою очередь, вызывает функции "родного" API.
- Вовлечь "родной" интерфейс API для выполнения заданной функции. Последний вариант встречается наиболее часто. В версиях Windows NT ниже 4.0 функции окон (windowing) и рисования (drawing) были расположены в Win32-сервере (csrss.exe). Это означало, что, когда приложение использовало такие функции, посылались сообщения указанному серверу. В версии 4.0 эти функции были перенесены в компонент режима ядра, называемый win32k.sys. Теперь вместо того, чтобы посылать сообщение серверу, клиентская DLL обращается к этому компоненту ядра, уменьшая затраты на создание сообщений и переключение контекстов потоков различных процессов. Это увеличило производительность графического ввода/вывода. Библиотеки gdi32.dll и user32.dll стали вторым "родным" API, но оно менее загадочно, чем первое, так как хорошо документировано.