Добавлен: 29.10.2018
Просмотров: 48025
Скачиваний: 190
946
Глава 11. Изучение конкретных примеров: Windows 8
реестра в пространство имен NT. Обращение к объекту устройства тома дает доступ
к самому тому, но объект устройства также предоставляет неявное монтирование тома
в пространство имен NT. К файлам тома можно обращаться путем присоединения
имени файла на томе в конец имени объекта устройства (для этого тома).
Постоянные имена также могут использоваться для представления объектов синхро-
низации и совместно используемой памяти (чтобы их можно было совместно исполь-
зовать процессам без постоянного их воссоздания при запуске и останове процессов).
Объектам устройств (и часто — объектам драйверов) даются постоянные имена, что
придает им некоторые свойства сохраняемости специальных i-узлов, содержащихся
в каталоге
/dev
систем UNIX.
Мы опишем многие другие функциональные возможности собственных интерфейсов
прикладного программирования NT в следующем разделе, где обсуждается интерфейс
прикладного программирования Win32, который предоставляет оболочки для систем-
ных вызовов NT.
11.2.2. Интерфейс прикладного
программирования Win32
Вызовы функций Win32 называются интерфейсом прикладного программирования
Win32
(Win32 API). Эти интерфейсы раскрыты и полностью документированы. Они
реализованы как библиотечные процедуры, которые заключают в оболочку собствен-
ные системные вызовы NT (используемые для выполнения задачи), либо (в некоторых
случаях) выполняют эту задачу прямо в пользовательском режиме. Несмотря на то
что собственные интерфейсы прикладного программирования NT не опубликованы,
большая часть предоставляемой ими функциональности доступна через Win32 API.
При выходе новых версий Windows уже существующие вызовы Win32 API меняются
редко (хотя в API добавляется много новых функций).
В табл. 11.5 показаны различные низкоуровневые вызовы Win32 API и собственные
вызовы NT API, для которых они служат оболочками. Примечательно то, насколько
неинтересным выглядит это соответствие. Большинство низкоуровневых функций
Win32 имеет эквиваленты в NT, что неудивительно, поскольку Win32 разрабатывался
с учетом NT. Во многих случаях уровень Win32 должен манипулировать параметрами
Win32 для отображения их в NT. Например, при канонизации маршрутов и установ-
лении соответствия маршрутам NT (в том числе специальным именам устройств
MS-DOS вроде
LPT:
). Win32 API при создании процессов и потоков должен также
уведомить процесс подсистемы Win32 (csrss.exe) о том, что у него появились новые
процессы и потоки (за которыми он должен наблюдать), — мы опишем это в разделе
«Процессы и потоки в Windows».
В некоторых случаях вызовы Win32 принимают маршруты, а соответствующие вызовы
NT — описатели. Поэтому процедуры-оболочки должны открыть файлы, вызвать NT,
а в конце — закрыть описатель. Процедуры-оболочки также транслируют Win32 API
из ANSI в Unicode. Показанные в табл. 11.5 функции Win32 (которые используют
в качестве параметров строки) фактически являются двумя интерфейсами приклад-
ного программирования (например, CreateProcessW и CreateProcessA). Переданные
второму API строки перед вызовом NT API должны быть транслированы в Unicode,
поскольку NT работает только с Unicode.
11.2. Программирование в Windows
947
Таблица 11.5. Примеры вызовов Win32 API и тех вызовов NT API, для которых они
являются оболочками
Вызов Win32
Собственный вызов NT API
CreateProcess
NtCreateProcess
CreateThread
NtCreateThread
SuspendThread
NtSuspendThread
CreateSemaphore
NtCreateSemaphore
ReadFile
NtReadFile
DeleteFile
NtSetInformationFile
CreateFileMapping
NtCreateSection
VirtualAlloc
NtAllocateVirtualMemory
MapViewOfFile
NtMapViewOfSection
DuplicateHandle
NtDuplicateObject
CloseHandle
NtClose
Поскольку в новых версиях Windows происходит мало изменений в существующих
интерфейсах Win32, то, теоретически, все двоичные программы, которые правильно
работали в предыдущих версиях, должны правильно работать и в новых версиях. На
практике же с новыми версиями возникает много проблем совместимости. Система
Windows настолько сложна, что несколько, казалось бы, незначительных изменений
могут вызвать сбои приложений. Очень часто в этом виноваты и сами приложения,
поскольку они часто делают явные проверки версии операционной системы или
страдают от собственных скрытых ошибок, которые проявляются при работе в новой
версии системы. Тем не менее компания Microsoft с каждой версией предпринимает
определенные усилия для того, чтобы протестировать широкий спектр приложений
(для поиска несовместимостей) и либо откорректировать их, либо дать специфичные
для приложения обходные пути его использования.
Windows поддерживает две специальные среды выполнения, которые называются
Windows-on-Windows (WOW). WOW32 используется на 32-битных системах x86
для выполнения 16-битных приложений Windows 3.x (при этом производится ото-
бражение системных вызовов и параметров 16-битной «вселенной» на 32-битную).
Аналогичным образом WOW64 позволяет 32-битным приложениям Windows работать
на системах x64.
Философия интерфейсов прикладного программирования Windows сильно отличает-
ся от философии UNIX. В системах UNIX функции операционной системы просты,
имеют мало параметров и существует мало таких мест, где одну и ту же операцию
можно выполнить несколькими способами. Win32 предоставляет очень подробные
интерфейсы с множеством параметров (часто есть три-четыре способа выполнения
одного и того же), причем используется гибрид функций низкого и высокого уровней
(вроде CreateFile и CopyFile).
Это означает, что Win32 предоставляет очень богатый набор интерфейсов, который,
однако, является очень сложным из-за плохого разбиения на уровни этой системы, где
в одном API смешаны функции высокого и низкого уровней. Для нашего изучения
948
Глава 11. Изучение конкретных примеров: Windows 8
операционных систем существенны только те функции низкого уровня Win32 API,
которые являются оболочками собственного NT API, поэтому именно на них мы и со-
средоточимся.
Win32 имеет вызовы для создания и управления процессами и потоками. Существует
также много вызовов, которые относятся к межпроцессному обмену (такие, как со-
здание, уничтожение и использование мьютексов, семафоров, событий, портов обмена
и прочих объектов IPC).
Несмотря на то что большая часть системы управления памятью для программистов
невидима, одна ее функциональная возможность вполне очевидна — это способность
процесса отобразить файл на область своей виртуальной памяти. Это позволяет
потокам процесса читать и писать части файла при помощи указателей (без необхо-
димости выполнения явных операций чтения и записи для передачи данных между
диском и памятью). При использовании таких отображенных в память файлов система
управления памятью сама выполняет ввод-вывод по мере необходимости (подкачка
по требованию).
Windows реализует отображение файлов в память при помощи трех совершенно раз-
ных средств. Во-первых, она обеспечивает интерфейсы, которые позволяют процессам
управлять своим виртуальным адресным пространством (в том числе можно резер-
вировать диапазоны адресов для последующего использования). Во-вторых, Win32
поддерживает абстракцию под названием отображение файлов (file mapping), которая
используется для представления адресуемых объектов в виде файлов (отображенный
файл на уровне NT называется сегментом). Чаще всего отображенные файлы создаются
для ссылки на файлы при помощи описателя файла, но они также могут создаваться
для ссылки на частные страницы, выделенные в системном файле подкачки.
Третий способ преобразует «представление» отображений файлов в адресное про-
странство процесса. Win32 позволяет создать представление только для текущего
процесса, но лежащее в его основе средство NT имеет более общий характер, что позво-
ляет создавать представления для любого процесса (для которого у вас есть описатель
с достаточными правами). Отделение создания отображения файла от самой операции
отображения файла на адресное пространство — это совсем другой подход (в отличие
от используемой в UNIX функции mmap).
В Windows отображения файлов — это объекты режима ядра, представленные описате-
лем. Подобно большинству описателей, отображения файлов могут быть дублированы
в другие процессы. Каждый из этих процессов может отобразить отображение файла
в свое адресное пространство (так, как считает нужным). Это полезно для совместного
использования частной памяти разными процессами (без необходимости создавать
для этого файлы). На уровне NT отображения файлов (сегменты) могут быть сделаны
постоянными в пространстве имен NT, после чего к ним можно обращаться по имени.
Для многих программ очень важным является файловый ввод-вывод. В основном пред-
ставлении Win32 файл является просто линейной последовательностью байтов. Win32
предоставляет более 60 вызовов для создания и уничтожения файлов и каталогов,
открытия и закрытия файлов, чтения и записи в них, запроса и установки атрибутов
файлов, блокировки диапазона байтов, а также многих других основных операций по
организации файловой системы и обращению к файлам.
Есть также и различные расширенные средства для управления данными в файлах.
Кроме основного потока данных, хранящихся в файловой системе NTFS, файлы
11.2. Программирование в Windows
949
могут иметь дополнительные потоки. Файлы (и даже целые тома) могут быть зашиф-
рованы. Файлы могут быть сжаты, они могут быть представлены в виде разреженного
потока байтов (когда отсутствующие области данных не занимают места на диске).
Тома файловой системы могут быть организованы в массивы RAID разного уровня.
Модификацию файлов или деревьев каталогов можно обнаружить через механизм
уведомления или при чтении журнала (journal), который NTFS поддерживает для
каждого тома.
Каждый том файловой системы неявно смонтирован в пространстве имен NT (в соот-
ветствии с данным ему именем, так что файл
\foo\bar
может быть назван, например,
\Device\HarddiskVolume\foo\bar
). Для каждого тома NTFS внутренним образом поддер-
живаются точки монтирования (называемые в Windows точками повторной обработки)
и символические ссылки — все это делается для облегчения организации томов.
Модель ввода-вывода низкого уровня в Windows принципиально асинхронная.
После начала операции ввода-вывода системный вызов может сделать возврат и по-
зволить потоку, который инициировал ввод-вывод, продолжить работу параллельно
с операцией ввода-вывода. Windows поддерживает для потоков отмену, а также не-
которые другие механизмы для синхронизации с операциями ввода-вывода. Windows
также позволяет программам указать при открытии файла, что ввод-вывод должен
быть синхронным. Многие библиотечные функции (библиотеки C и многие вызовы
Win32) также задают синхронный ввод-вывод для совместимости или упрощения
модели программирования. В этих случаях исполнительная система будет явно
синхронизироваться с завершением ввода-вывода (перед возвращением в пользова-
тельский режим).
Еще одна область, для которой в Win32 есть вызовы, — это безопасность. Каждый по-
ток ассоциируется с объектом режима ядра, называемым маркером (token), который
предоставляет информацию об идентификаторе и привилегиях потока. Каждый объ-
ект может иметь ACL (Access Control List — список управления доступом), который
очень подробно указывает, какие пользователи могут к объекту обращаться и какие
операции они могут с ним выполнять. Такой подход обеспечивает тонкую настройку
безопасности, при которой конкретным пользователям может быть предоставлен
конкретный доступ к любому объекту. Модель безопасности способна к расширению,
что позволяет приложениям добавлять новые правила безопасности (такие, как огра-
ничение часов доступа).
Пространство имен Win32 отличается от собственного пространства имен NT (которое
было описано в предыдущем разделе). Интерфейсам Win32 API видна только часть
пространства имен NT (хотя доступ к полному пространству имен NT можно полу-
чить через специальные строки-префиксы, например «
\\.
»). В Win32 доступ к файлам
производится через буквы дисков. Каталог
\DosDevices
в NT содержит целый набор
символических ссылок (с букв дисков на фактические объекты устройств). Напри-
мер,
\DosDevices\C:
может быть ссылкой на
\Device\HarddiskVolume1
. В этом каталоге
содержатся ссылки и для других устройств Win32, таких как
COM1:
,
LPT1:
и
NUL:
(последовательный порт, порт принтера и очень важное «нуль-устройство»).
\Dos\
Devices
— это фактически символическая ссылка на
\??
, которая была сделана для ее
эффективности. Другой каталог NT —
\BaseNamedObjects
— используется для хране-
ния различных именованных объектов режима ядра, доступ к которым производится
через Win32 API. Сюда входят объекты синхронизации вроде семафоров, совместно
используемая память, таймеры, коммуникационные порты и имена устройств.
950
Глава 11. Изучение конкретных примеров: Windows 8
В дополнение к описанным нами системным интерфейсам низкого уровня Win32
API поддерживает также многие функции для работы с графическим интерфейсом
пользователя (в том числе все вызовы для управления графическим интерфейсом
системы). Имеются вызовы для создания, уничтожения и использования окон, меню,
панелей инструментов, строк состояния, полос прокрутки, диалоговых окон, значков
(и множества других имеющихся на экране элементов), а также управления ими. Есть
вызовы для рисования геометрических фигур, их закраски, управления палитрами ис-
пользуемых цветов, работы со шрифтами, размещения значков на экране. И наконец,
есть вызовы для работы с клавиатурой, мышью и другими устройствами ввода, а также
для аудио, печати и прочих устройств вывода.
Операции графического интерфейса пользователя работают напрямую с драйвером
win32k.sys (при помощи специальных интерфейсов для доступа к этим функциям ре-
жима ядра из библиотек пользовательского режима). Поскольку эти вызовы не влекут
за собой выполнения базовых системных вызовов в исполнительном модуле NTOS, мы
больше не будем о них говорить.
11.2.3. Реестр Windows
Корень пространства имен NT поддерживается в ядре. Система хранения (тома фай-
ловой системы) связана с пространством имен NT. Поскольку пространство имен NT
собирается при каждой загрузке системы, как система узнает об особенностях кон-
фигурации? Ответ состоит в том, что Windows подключает к пространству имен NT
файловую систему особого типа (оптимизированную для небольших файлов). Эта фай-
ловая система называется реестром (registry). Реестр организован в отдельные тома,
называемые разделами (hives). Каждый раздел хранится в отдельном файле (в каталоге
C:\Windows\system32\config\
загрузочного тома)
1
. Когда Windows загружается, раздел
SYSTEM грузится в память той же самой программой загрузки, которая загружает
ядро и прочие файлы загрузки (такие, как загрузочные драйверы) с загрузочного тома.
Windows содержит в разделе SYSTEM большое количество важной информации, в том
числе какие драйверы с какими устройствами использовать, какое программное обеспе-
чение первоначально запускать, а также множество других параметров, управляющих
работой системы. Эта информация используется даже самой программой загрузки
(для определения загрузочных драйверов, которые нужны сразу же после загрузки).
В число таких драйверов входят драйверы файловых систем и драйверы дисков для
того тома, на котором содержится сама операционная система.
Другие конфигурационные разделы используются после загрузки системы для описа-
ния информации об инсталлированном в системе программном обеспечении, пользо-
вателях, а также об инсталлированных в системе классах объектов COM (Component
Object-Model) режима пользователя. Регистрационная информация о локальных
пользователях хранится в разделе SAM (Security Access Manager). Информация
о сетевых пользователях поддерживается службой lsass в разделе SECURITY, причем
она согласовывается с серверами сетевого каталога, чтобы пользователи могли иметь
единые имя учетной записи и пароль по всей Сети. Список используемых в Windows
разделов показан в табл. 11.6.
1
Имя каталога может отличаться, если используется другое имя каталога для операционной
системы и/или она установлена на другой логический диск. — Примеч. ред.