Добавлен: 29.10.2018
Просмотров: 47995
Скачиваний: 190
1026
Глава 11. Изучение конкретных примеров: Windows 8
объекта драйвера) и ищет (по типу операции) в таблице переходов для драйверов со-
ответствующую точку входа в драйвер. Затем драйвер вызывается, и ему передается
объект устройства и IRP.
Рис. 11.21. Один уровень в стеке устройств
После того как драйвер завершил обработку представленного пакетом IRP запроса,
у него есть три варианта. Он может еще раз вызвать IoCallDriver, передав ему IRP и сле-
дующий объект устройства в стеке устройств. Он может объявить запрос ввода-вывода
завершенным и вернуться к его вызывающей стороне. Либо он может поставить IRP во
внутреннюю очередь и вернуться к его вызывающей стороне (объявив, что запрос вво-
да-вывода еще не завершен). В последнем случае получается операция асинхронного
ввода-вывода — по крайней мере, если все драйверы выше по стеку с этим соглашаются
и также возвращаются к своим вызывающим сторонам.
Пакеты запроса ввода-вывода
На рис. 11.22 показаны основные поля IRP. По существу, IRP — это массив (с динами-
чески изменяемым размером), содержащий поля, которые могут быть использованы
любым драйвером (для обрабатывающего запрос стека устройств). Эти стековые поля
позволяют драйверу указать процедуру, которую нужно вызвать при завершении за-
проса ввода-вывода. При завершении все уровни стека устройств проходятся в обрат-
ном порядке, при этом по очереди вызываются все процедуры завершения (для всех
драйверов). На каждом уровне драйвер может завершить запрос или принять решение,
что еще есть некая работа (которую нужно сделать), и оставить запрос незавершенным
(отложив на данный момент завершение ввода-вывода).
При выделении IRP диспетчер ввода-вывода должен знать, насколько глубок данный
конкретный стек устройств, чтобы выделить достаточно большой IRP. Он отслежи-
вает глубину стека в поле каждого объекта устройства (при формировании стека
устройств). Обратите внимание на то, что не существует формального определения,
какой следующий объект устройства в стеке. Эта информация содержится в закрытых
структурах данных, принадлежащих предыдущему в стеке драйверу. Фактически стек
может и не быть стеком вовсе. На каждом уровне драйвер может выделить новый IRP,
11.7. Ввод-вывод в Windows
1027
Рис. 11.22. Основные поля пакета IRP
продолжить использовать исходный IRP, послать операцию ввода-вывода в другой
стек устройства либо даже переключиться на системный рабочий процесс для про-
должения выполнения.
IRP содержит флаги, код операции для поиска по таблице переходов, указатели для
пользовательского буфера и буфера ядра, а также список MDL (Memory Descriptor
Lists), которые используются для описания представленных буферами физических
страниц (то есть для операций DMA). Имеются также поля для операций отмены
и завершения. Те поля в IRP, которые используются для постановки IRP в очередь
к устройствам, используются повторно после завершения операции ввода-вывода
(чтобы обеспечить память для управляющего объекта АРС, используемого для вызова
процедуры завершения диспетчера ввода-вывода в контексте исходного потока). Есть
также поле ссылки, используемое для связи всех незавершенных IRP с инициировав-
шим их потоком.
Стеки устройств
Драйвер в Windows может выполнять всю свою работу самостоятельно (как это делает
драйвер принтера, изображенный на рис. 11.23). В то же время драйверы также могут
формировать стек, а это значит, что запрос может пройти через целую последователь-
ность драйверов (каждый из которых делает часть работы). На рис. 11.23 показаны
также два формирующих стек драйвера. Стеки драйверов часто используются для того,
чтобы отделить управление шиной от работы по управлению устройством. Управление
шиной PCI очень сложное, поскольку она имеет множество режимов и шинных транз-
акций. Отделив эту часть от специфичной для устройства части, авторы драйверов
избавляются от необходимости изучать управление шиной. Они могут просто исполь-
зовать в своем стеке драйверов стандартный драйвер для шины. Аналогичным образом
драйверы для SCSI и USB имеют специфичную для устройств часть и общую часть,
причем часто используемые драйверы для общей части имеются в составе Windows.
1028
Глава 11. Изучение конкретных примеров: Windows 8
Рис. 11.23. Windows позволяет драйверам формировать стек (для работы с конкретным
экземпляром устройства). Соответствующие стеки драйверов представлены
объектами устройств
Еще один пример использования стеков драйверов — это вставка в стек драйверов-филь-
тров
(filter drivers). Мы уже рассматривали применение драйверов-фильтров файловых
систем, которые вставляются над файловой системой. Драйверы-фильтры используются
также для управления физическим оборудованием. Драйвер-фильтр выполняет некото-
рые преобразования над операциями (когда IRP перемещается вниз по стеку устройств),
а также при операции завершения (когда IRP проходит вверх через процедуры заверше-
ния, указанные каждым драйвером). Например, драйвер-фильтр может сжимать данные
на пути к диску или шифровать данные на пути к сети. Размещение здесь фильтра озна-
чает, что ни приложение, ни драйвер устройства не должны знать о нем — он работает
автоматически для всех данных, следующих в устройство (или приходящих из него).
Драйверы устройств режима ядра являются серьезной проблемой для надежности
и стабильности Windows. Большинство отказов ядра в Windows происходит из-за
ошибок в драйверах устройств. Поскольку драйверы устройств режима ядра совместно
используют одно и то же адресное пространство с уровнем ядра и исполнительным
уровнем, то ошибки в драйверах могут повредить системные структуры данных (или
сделать что-то худшее). Некоторые из этих ошибок возникают из-за потрясающе
большого количества существующих для Windows драйверов устройств либо из-за
разработки драйверов неопытными системными программистами. Ошибки возника-
11.8. Файловая система Windows NT
1029
ют и из-за большого количества подробностей, которые нужно знать для написания
корректного драйвера для Windows.
Модель ввода-вывода мощная и гибкая, но весь ввод-вывод является, по существу,
асинхронным (поэтому может возникать много состояний гонки). Windows 2000 впер-
вые добавила средства Plug-and-Play и управление электропитанием из систем Win9x
в системы на основе Windows NT. Это наложило на драйверы большое количество
требований по корректной обработке появляющихся и исчезающих устройств (в то
время, когда пакеты ввода-вывода находятся в середине обработки). Пользователи
персональных компьютеров часто подключают и отключают устройства, закрывают
крышку и кладут ноутбук в портфель и обычно не беспокоятся о том, горит ли ма-
ленький зеленый огонек активности устройства. Написание корректно работающих
в таких условиях драйверов устройств может быть очень сложной задачей, поэтому
для упрощения Windows Driver Model и была разработана Windows Driver Foundation.
О модели Windows Driver Model и более новой спецификации Windows Driver
Foundation существует множество книг (Kanetkar, 2008; Orwick and Smith, 2007; Reeves,
2010; Viscarola et al., 2007; Vostokov, 2009).
11.8. Файловая система Windows NT
Windows поддерживает несколько файловых систем, самыми важными из которых
являются FAT-16, FAT-32 и NTFS (NT File System). FAT-16 — это старая файловая
система операционной системы MS-DOS. Она использует 16-битные дисковые адреса,
что ограничивает размер дисковых разделов 2 Гбайт. В основном она применяется для
доступа к флоппи-дискам (для тех клиентов, которые их до сих пор используют). FAT-
32 использует 32-битные дисковые адреса и поддерживает дисковые разделы размером
до 2 Тбайт. FAT-32 не имеет никакой системы безопасности, и на сегодняшний день она
фактически используется только для переносных носителей (таких, как флеш-диски).
Файловая система NTFS была разработана специально для версии Windows NT. Начи-
ная с Windows XP ее по умолчанию устанавливает большинство производителей ком-
пьютеров, она существенно увеличивает безопасность и функциональность Windows.
NTFS использует 64-битные дисковые адреса и теоретически может поддерживать
дисковые разделы размером до 2
64
байт (однако некоторые соображения ограничивают
этот размер до более низких значений).
В этом разделе мы изучим файловую систему NTFS, так как это современная файловая
система со многими интересными функциональными возможностями и конструктив-
ными новшествами. Это большая и сложная файловая система, но объем книги не
позволяет описать все ее функциональные возможности, однако приведенный далее
материал должен дать вам довольно хорошее представление о ней.
11.8.1. Фундаментальные концепции
Имена файлов в NTFS ограничены 255 символами; размер полного маршрута ограни-
чен 32 767 символами. Имена файлов хранятся к кодировке Unicode, что позволяет
в тех странах, где не используется латинский алфавит (например, Греции, Японии,
Индии, России и Израиле), писать имена файлов на своем языке. Например, φιλε — это
допустимое имя файла. NTFS полностью поддерживает чувствительные к регистру
имена (так что
foo
отличается от
Foo
и
FOO
). Интерфейс прикладного программиро-
1030
Глава 11. Изучение конкретных примеров: Windows 8
вания Win32 не полностью поддерживает чувствительность к регистру имен файлов
и вовсе не поддерживает ее для имен каталогов. Поддержка чувствительности к реги-
стру имеется при работе подсистемы POSIX (для совместимости с UNIX). Win32 не
является чувствительным к регистру, но сохраняет регистр, так что имена файлов могут
иметь в своем составе буквы разных регистров. Несмотря на то что чувствительность
к регистру хорошо знакома пользователям UNIX, она очень неудобна для обычных
пользователей, которые обычно не делают таких различий. Например, почти весь со-
временный Интернет не имеет чувствительности к регистру.
Файл в NTFS — это не просто линейная последовательность байтов (как файлы в FAT-
32 и UNIX). Файл состоит из множества атрибутов, каждый из которых представлен
потоком байтов. Большинство файлов имеет несколько коротких потоков (таких, как
название файла и его 64-битный идентификатор объекта) плюс один длинный (неиме-
нованный) поток с данными. Однако файл может иметь также два или более длинных
потока данных. Каждый поток имеет имя, состоящее из имени файла, двоеточия и име-
ни потока (как, например,
foo:stream1
). Каждый поток имеет размер и может блокиро-
ваться независимо от всех остальных потоков. Идея множества потоков в NTFS не нова.
Файловая система компьютеров Apple Macintosh использует два потока на файл (ветвь
данных и ветвь ресурсов). Первоначально потоки в NTFS применялись для того, чтобы
файловый сервер NT мог обслуживать клиентов Macintosh. Множественность потоков
данных используется также для того, чтобы представлять метаданные файлов, такие
как контрольные картинки изображений в формате JPEG (которые есть в графическом
интерфейсе пользователя Windows). Однако, к сожалению, множественные потоки дан-
ных уязвимы, и они часто теряются при переносе в другие файловые системы или по
сети (и даже при резервном копировании и последующем восстановлении, поскольку
многие утилиты игнорируют их).
NTFS — это иерархическая файловая система, похожая на файловую систему UNIX.
Однако разделителем компонентов имени является знак «
\
», а не «
/
» (это атавизм,
унаследованный от требований совместимости с операционной системой СР/М в пе-
риод создания MS-DOS, поскольку в CP/M прямой слеш использовался для ключей
командной строки). В отличие от UNIX, здесь концепции текущего рабочего каталога,
жестких ссылок на текущий каталог (
.
) и родительский каталог (
..
) реализованы как
соглашения, а не как фундаментальная часть файловой системы. Жесткие ссылки под-
держиваются, но используются только для подсистемы POSIX, так же как и поддержка
проверки обхода каталогов (разрешение
‘x’
в UNIX).
Символические ссылки для NTFS поддерживаются. Создание символических ссылок
обычно разрешается только администраторам (во избежание проблем с безопасностью
типа спуфинга, которые появились в UNIX, когда в версии BSD 4.2 были введены
символические ссылки). Реализация символических ссылок использует функцио-
нальную возможность NTFS под названием «точка повторной обработки» (reparse
points), которая обсуждается далее в этом разделе. Кроме того, поддерживаются также
сжатие, шифрование, отказоустойчивость, журналирование и разреженные файлы. Это
функциональные возможности, и их реализацию мы скоро обсудим.
11.8.2. Реализация файловой системы NTFS
NTFS — это очень сложная файловая система, которая была разработана специально
для NT как альтернатива файловой системе HPFS, которая была разработана для OS/2.