"2.Внутреннее устройство Windows (гл. 5-7)" - читать интересную книгу автора (Руссинович Марк, Соломон Дэвид)

М.Руссинович, Д.Соломон
2.Внутреннее устройство Microsoft Windows (главы 5-7)

Г Л A B A 5 Запуск и завершение работы системы


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


Процесс загрузки

Описание процесса загрузки мы начнем с рассмотрения установки Windows, а затем исследуем выполнение загрузочных файлов. Поскольку драйверы устройств играют ключевую роль в процессе загрузки, будет уделено внимание и тому, как они контролируют собственную загрузку и инициализацию. Далее мы поясним, как инициализируются компоненты исполнительной системы и как ядро запускает пользовательскую часть Windows, активизируя процессы Session Manager (Smss.exe) и Winlogon, а также подсистему Windows. Попутно вы узнаете, что происходит внутри системы на момент вывода тех или иных текстовых сообщений, появляющихся на экране в процессе загрузки.

Ранние стадии процесса загрузки на платформах x86 и x64 сильно отличаются от таковых на платформе IA64. B следующих разделах описываются стадии, специфичные для x86 и x64, а потом поясняются стадии, специфичные доя IA64.


Что предшествует загрузке на платформах x86 и x64

Процесс загрузки Windows начинается не при включении компьютера или нажатии кнопки Reset, а еще при установке этой системы на компьютер. Ha одном из этапов работы программы установки Windows (Windows Setup) происходит подготовка основного жесткого диска системы: на нем размещается код, в дальнейшем участвующий в процессах загрузки. Прежде чем рассказывать, что делает этот код, мы покажем, как и в какой области жесткого диска он размещается.

Стандарт разбиения физических жестких дисков на тома существует в системах типа x86 со времен первых версий MS-DOS. Операционные системы Microsoft разбивают жесткие диски на дискретные области, называемые разделами (partitions). После форматирования с использованием файловых систем (типа FAT и NTFS) разделы образуют тома. Ha жестком диске может быть до четырех главных разделов (primary partitions). Поскольку это ограничило бы количество томов на одном диске, данная схема предусматривает особый тип раздела – дополнительный (extended partition), что дает до четырех дополнительных разделов в главном разделе. Дополнительные разделы могут содержать другие дополнительные разделы, те в свою очередь – третьи дополнительные разделы и т. д. Так что диск можно разбить практически на бесконечное число томов. Пример разбиения жесткого диска на разделы показан на рис. 5-1, а компоненты, участвующие в процессе загрузки, перечислены в таблице 5-1. (Подробнее о разбиении жестких дисков в Windows см. главу 10.)

Единицей адресации физических дисков является сектор. Типичный размер сектора жесткого диска на IBM-совместимом PC – 512 байтов. Такие утилиты, как Fdisk в MS-DOS или программа Windows Setup, позволяющие создавать на жестком диске тома, записывают в первый сектор жесткого диска специальные данные, создавая таким образом главную загрузочную запись (MBR) диска (детали см. в главе 10). Размер MBR фиксирован. Она состоит из набора машинных команд (загрузочный код) и таблицы разделов с четырьмя записями, которые определяют расположение главных разделов на диске. Первый код, выполняемый при загрузке IBM-совместимого компьютера, называется BIOS, – он хранится в ПЗУ компьютера. BIOS выбирает загрузочное устройство, считывает его MBR в память и передает управление ее загрузочному коду.

MBR начинает со сканирования таблицы разделов в поисках раздела, помеченного особым флагом. Этот флаг сигнализирует, что данный раздел является загрузочным. Как только MBR обнаружит хотя бы один такой флаг, она считывает в память код из первого сектора раздела, помеченного флагом, и передает ему управление. Такой раздел называется загрузочным, как и его первый сектор, а том, определенный для загрузочного раздела, – системным.

Операционная система, как правило, ведет запись в загрузочные секторы без участия пользователя. Например, Windows Setup при записи MBR одновременно создает в первом загрузочном разделе жесткого диска свой загрузочный сектор. Перед этим программа установки проверяет, является ли он сейчас загрузочным сектором MS-DOS. Если да, Windows Setup сначала копирует содержимое загрузочного сектора в файл Bootsect.dos, помещая его в корневой каталог раздела.

Перед записью в загрузочный сектор Windows Setup проверяет совместимость текущей файловой системы этого раздела с Windows. B любом случае она может отформатировать данный раздел с использованием выбранной вами файловой системы (FAT, FAT32 или NTFS). Если раздел уже отформатирован, вы можете пропустить этот этап. После того как загрузочный раздел отформатирован, Setup копирует на него файлы Windows, в том числе два стартовых файла, Ntldr и Ntdetect.com.

Еще одна задача программы установки – создание файла загрузочного меню, Boot.ini, в корневом каталоге системного тома. B этом файле содержатся параметры запуска устанавливаемой версии Windows, а также сведения обо всех системах, установленных до Windows. Если файл Bootsect.dos содержит загрузочный сектор MS-DOS, в Boot.ini добавляется запись, позволяющая загружать MS-DOS. Ниже приведен пример файла Boot.ini с поддержкой двухвариантной загрузки для компьютера, на котором перед установкой Windows XP была установлена MS-DOS.


[boot loader] timeout=30

default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(1)

\WINDOWS="Microsoft Windows XP Professional " /fastdetect C:\="Microsoft Windows"


Заметьте, что в этом примере путь к каталогу Windows задан по специальному синтаксису, отвечающему соглашению по именованию Advanced RISC Computing (ARC). B Windows используется три вида такого синтаксиса. Первый, синтаксис multiO, показан в примере; он указывает Windows загружать системные файлы через функции прерывания INT 13, предоставляемые BIOS. Таким образом, синтаксис multiO применяется, когда у диска, на котором находится загрузочный том, есть контроллер с поддержкой прерывания INT 13. Синтаксис multi() имеет следующий формат:


multi(W)disk(X)rdisk(Y)partition(Z)


где W- номер дискового контроллера (также называемый порядковым номером), обычно равный 0, X – всегда 0 в синтаксисе multi(), а Y указывает физический жесткий диск, подключенный к контроллеру W. Для АТА-контроллеров значение Y1 как правило, укладывается в диапазон от 0 до 3, для SCSI-контроллеров – 0-15. Z сообщает номер раздела на физическом диске, соответствующего загрузочному тому. Первому разделу присваивается значение 1.

ARC-синтаксис scsi0 сообщает Windows, что для доступа к файлам на загрузочном томе нужно задействовать сервисы дискового ввода-вывода, предоставляемые Ntbootdd.sys (о нем чуть позже). Синтаксис scsi0 выглядит так:


scsi(W)disk(X)rdisk(Y)partition(Z)


Здесь W - номер контроллера, X – физический жесткий диск, подключенный к этому контроллеру (обычно равен 0-15). Y указывает SCSI LUN-номер (logical unit number) диска, содержащего загрузочный том, и, как правило, равен 0. Наконец, Z – это раздел, соответствующий загрузочному тому с нумерацией, начинающейся от 1.

Наконец, в Windows применяется третий вид синтаксиса – signature(). Он указывает Windows найти диск с сигнатурой, соответствующей первому значению в скобках, независимо от номера контроллера, сопоставленного с этим диском, и использовать Ntbootdd.sys для доступа к загрузочному тому. Сигнатура диска (disk signature) – это глобально уникальный идентификатор (GUID), извлекаемый Windows Setup из информации в MBR и записываемый на диск. Синтаксис signature() выглядит так:

signature(V)disk(X)rdisk(Y)partition(Z)


где V- 32-битная сигнатура диска в шестнадцатеричной форме, идентифицирующая диск, X – физический жесткий диск со специфической сигнатурой, который может быть подключен к любому контроллеру в системе, Y – всегда 0, a Z – номер раздела, на котором находится загрузочный том. Windows использует синтаксис signatureO, если:

(o) размер загрузочного тома больше 7,8 Гб, а BIOS-функции расширенного прерывания INT 13 (которые применяются для доступа к частям диска за пределами 7,8 Гб) не могут обращаться ко всему тому;

(o) BIOS не поддерживает расширенное прерывание INT 13.


Загрузочный сектор и Ntldr на платформах x86 и x64

Перед тем как произвести запись в загрузочный сектор, программа установки должна выяснить формат раздела, поскольку от него зависит содержимое загрузочного сектора. Если это раздел FAT, Windows записывает в загрузочный сектор код, поддерживающий файловую систему FAT Если раздел отформатирован под NTFS, в загрузочный сектор записывается код, соответствующий NTFS. Задача кода загрузочного сектора – предоставлять Windows информацию о структуре и формате тома и считывать из его корневого каталога файл Ntldr. После считывания Ntldr в память код загрузочного сектора передает управление в точку входа Ntldr. Если код загрузочного сектора не может найти Ntldr в корневом каталоге тома, он выводит сообщение об ошибке: «BOOT: Couldn't find NTLDRP» (в FAT) или «NTLDR is missing» (в NTFS).

Ntldr начинает свою работу, когда система функционирует в реальном режиме (real mode) x86. B реальном режиме трансляция между виртуальными и физическими адресами не осуществляется, поэтому программы, использующие какие-либо адреса памяти, интерпретируют их как физические. B этом режиме доступен лишь первый мегабайт физической памяти компьютера; в нем выполняются простые программы MS-DOS. Однако первое, что делает Ntldr, – переключает систему в защищенный режим (protected mode). Ha этой стадии трансляция между виртуальными адресами и физическими по-прежнему отсутствует, но становится доступным полный объем памяти. Переключив систему в защищенный режим, Ntldr может работать со всей физической памятью. После того как он создает таблицы страниц, число которых достаточно для доступа к нижним 16 Мб памяти с подкачкой, Ntldr включает поддержку подкачки страниц. Защищенный режим с подкачкой страниц является нормальным режимом работы Windows.

C этого момента Ntldr может работать в полнофункциональном режиме. Ho при доступе к IDE-дискам и дисплею Ntldr все еще зависит от функций загрузочного кода, которые на непродолжительное время отключают подкачку страниц и возвращают процессор в режим, позволяющий выполнять сервисы BIOS. Если диск, содержащий загрузочный или системный том, является SCSI-устройством и недоступен через BIOS, Ntldr загружает файл Ntbootdd.sys и использует его функции доступа к диску вместо аналогичных функций загрузочного кода. Ntbootdd.sys – это экземпляр минипорт-драйвера SCSI, применяемый Windows для полноценного доступа к загрузочному диску. (O дисковых драйверах см. главу 10.) Затем Ntldr с помощью встроенного кода файловой системы считывает из корневого каталога файл Boot.ini. B отличие от кода загрузочного сектора код Ntldr способен читать и подкаталоги.

Далее Ntldr очищает экран. Если в корневом каталоге системного тома присутствует допустимый файл Hiberfil.sys, Ntldr считывает его содержимое в память и передает управление коду в ядре, восстанавливающему спящую (hibernated) систему. Этот код отвечает за перезапуск драйверов, которые были активны на момент выключения системы. Hiberfil.sys считается допустимым, только если при последнем выключении компьютер был переведен в спящий режим. (O спящем режиме см. раздел «Диспетчер электропитания» главы 11.)

Если в файле Boot.ini имеется более одной записи о доступных для загрузки операционных системах, Ntldr выводит загрузочное меню. (Если в файле Boot.ini только одна запись, Ntldr пропускает загрузочное меню и сразу выводит стартовый индикатор прогресса загрузки.) Информация из Boot.ini адресует Ntldr к разделу, в котором находится системный каталог Windows (обычно \Windows). Этим разделом может быть как загрузочный, так и другой главный раздел.

Если запись Boot.ini ссылается на MS-DOS, Ntldr считывает в память содержимое файла Bootsect.dos, переключается обратно в 1б-разрядный реальный режим и вызывает из Bootsect.dos код MBR. B результате код из Bootsect.dos выполняется аналогично коду, считанному MBR с диска. Код из Bootsect.dos инициирует процесс загрузки, специфичный для MS-DOS. Так же происходит загрузка Microsoft Windows Me, Windows 98 или Windows 95, если они установлены вместе с Windows.

Записи Boot.ini могут включать ряд необязательных параметров, интерпретируемых Ntldr и другими компонентами в процессе загрузки. Полный список этих параметров приводится в таблице 5-2. Утилита Bootcfg.exe, впервые появившаяся в Windows XP, предоставляет удобный интерфейс для задания ряда параметров. Любые параметры, включаемые в Boot.ini, сохраняются в параметре реестра HKLM\System\CurrentControlSet\Control\System-StartOptions.


Таблица 5-2. Паоаметры в Boot.ini

Если до истечения периода ожидания, указанного в Boot.ini, пользователь не выбрал ни одной команды загрузочного меню, Ntldr выбирает вариант по умолчанию, который соответствует самой верхней записи в Boot.ini и содержит путь, совпадающий с путем в строке «default=». После выбора одного из вариантов Ntldr загружает и запускает Ntdetect.com, 1б-разрядную программу реального режима, которая получает от BIOS сведения о базовых устройствах и конфигурации компьютера:

(o) время и дату, хранящиеся в энергонезависимой памяти CMOS;

(o) типы шин в системе (например, ISA, PCI, EISA, MCA) и идентификаторы устройств, подключенных к этим шинам;

(o) число, емкость и тип дисков, присутствующих в системе;

(o) тип подключенной мыши

(o) число и тип параллельных портов, сконфигурированных в системе;

(o) типы видеоадаптеров, присутствующих в системе.


Эти сведения, записываемые во внутренние структуры данных, на более поздних этапах загрузки будут сохранены в разделе реестра HKLM\HARDWARE\DESCRIPTION.

Далее Ntldr в Windows 2000 очищает экран и выводит индикатор прогресса загрузки с надписью «Starting Windows» (Запуск Windows). Индикатор остается на нулевой отметке до начала загрузки драйверов устройств (см. п. 5 в следующем списке). Под индикатором появляется сообщение: «For troubleshooting and advanced startup options for Windows 2000, press F8» («Для выбора особых вариантов загрузки Windows 2000 нажмите F8»). При нажатии клавиши F8 выводится дополнительное загрузочное меню, предлагающее выбрать особые варианты загрузки – последнюю удачную конфигурацию, безопасный или отладочный режим и т. д. B Windows XP и Windows Server 2003 Ntldr выводит экран-заставку вместо индикатора прогресса загрузки.

Если Ntldr выполняется в х64-системе и в загрузочном меню выбран элемент, указывающий на запуск ядра для x64, то Ntldr переключает процессор в режим, в котором «родной» размер слова составляет 64 бита. Затем Ntldr начинает загружать необходимые для инициализации ядра файлы. Загрузочным является том, соответствующий разделу, на котором находится системный каталог (обычно \Windows) загружаемой системы. Ниже описываются операции, выполняемые Ntldr.

1. Загружает соответствующие образы ядра и HAL (по умолчанию – Ntoskrnl.exe и Hal.dll). Если Ntldr не удается загрузить какой-либо из этих файлов, он выводит сообщение «Windows could not start because the following file was missing or corrupt» («He удается запустить Windows из-за испорченного или отсутствующего файла»), за которым следует имя файла.

2. Для поиска драйверов устройств, которые нужно загрузить, считывает в память содержимое куста реестра SYSTEM, \Windows\System32\Config\ System. Куст – это файл, содержащий поддерево реестра. Подробнее о реестре см. главу 4.

3. Сканирует загруженный в память куст реестра SYSTEM и находит все загрузочные драйверы устройств (это драйверы, обязательные для запуска системы). Они отмечены в реестре флагом SERVICEBOOTSTART (0). Каждому драйверу устройства в реестре соответствует подраздел HKLM\ SYSTEM\CurrentControlSet\Services. Например, драйверу диспетчера логических дисков (Logical Disk Manager) в разделе Services соответствует подраздел Dmio, показанный на рис. 5-2. (Подробное описание содержимого Services см. в разделе «Сервисы» главы 4.)

4. Вносит в список загрузочных драйверов устройств драйвер файловой системы, отвечающий за реализацию кода для конкретного типа раздела (FAT, FAT32 или NTFS), на котором находится системный каталог. Ntldr должен загрузить этот драйвер именно сейчас, иначе ядро будет требовать от драйверов их же загрузки, и получится замкнутый круг.

5. Загружает драйверы, обязательные для запуска системы. Ход загрузки отражается индикатором «Starting Windows». Полоска на индикаторе продвигается вперед по мере загрузки драйверов (число загрузочных драйверов считается равным 80, поэтому после успешной загрузки каждого драйвера полоска продвигается на 1,25%). Если в Boot.ini указан параметр /SOS, то вместо индикатора Ntldr выводит имя файла каждого загрузочного драйвера. Учтите, что на этом этапе драйверы лишь загружаются, а их инициализация происходит позже.

6. Подготавливает регистры процессора для выполнения Ntoskrnl.exe.

Ha этом участие Ntldr в процессе загрузки заканчивается. Для инициализации системы Ntldr вызывает главную функцию из Ntoskrnl.exe.


Процесс загрузки на платформе IA64

Файлы, участвующие в процессе загрузки на платформе IA64 перечислены в таблице 5-3. Системы IA64 соответствуют спецификации Extensible Firmware Interface (EFI), определенной Intel. B EFI-совместимой системе имеется микрокод, который запускает стартовый загрузчик (загрузочный код), записываемый Windows Setup в системную NVRAM (nonvolatile RAM). Загрузочный код считывает содержимое IАб4-эквивалента Boot.ini, который также хранится в NVRAM. Средства Microsoft EFI можно запускать в консоли EFI, а Bootcfg.exe (утилита, поставляемая с Windows) позволяет модифицировать параметры и варианты загрузки из NVRAM.


Далее происходит распознавание оборудования, в ходе которого стартовый загрузчик использует интерфейсы EFI для определения числа и типов следующих устройств:

(o) сетевых адаптеров;

(o) видеоадаптеров;

(o) клавиатур;

(o) дисковых контроллеров; (o) накопителей.


Так же, как и Ntldr в системах x86 и x64, стартовый загрузчик выводит меню с вариантами загрузки. Как только пользователь выбирает один из вариантов, загрузчик переходит в подкаталог в разделе EFI System, соответствующий выбранному варианту, и загружает несколько других файлов, необходимых для продолжения загрузки: Fpswa.efi и Ia641dr.efi. Спецификация EFI требует, чтобы в системе был раздел, обозначенный как EFI System; он форматируется под файловую систему FAT и может быть размером от 100 Мб до 1 Гб (или до 1% от общего размера диска). Для каждой установленной Windows-системы выделяется свой подкаталог в разделе EFI System (в каталоге EFI\Microsoft). Первой системе назначается подкаталог Winnt50, второй – Winnt50.1 и т. д. Ia641dr.efi отвечает за загрузку Ntoskrnl.exe, Hal.dll и драйверов, применяемых на этапе загрузки. Далее процесс загрузки идет так же, как и на платформе x86 или x64.


Инициализация ядра и компонентов исполнительной системы

Вызывая Ntoskrnl.exe, Ntldr передает структуру данных с копией строки из Boot.ini (представляющей выбранный вариант загрузки), с указателем на таблицы памяти (сгенерированные Ntldr для описания физической памяти в данной системе), с указателем на загруженные в память копии кустов реестра HARDWARE и SYSTEM и с указателем на список загруженных драйверов.

Ntoskrnl начинает первую из двух фаз процесса инициализации (они нумеруются от 0). Большинство компонентов исполнительной системы имеет инициализирующую функцию, которая принимает параметр, определяющий текущую фазу.

B фазе 0 прерывания отключены. Предназначение этой фазы в том, чтобы сформировать рудиментарные структуры, необходимые для вызова сервисов в фазе 1. Главная функция Ntoskrnl вызывает KiSystemStartup, которая в свою очередь вызывает HalInitializeProcessor и KiInitializeKernel для каждого процессора. Работая на стартовом процессоре, KiInitializeKernel выполняет общесистемную инициализацию ядра, в том числе всех внутренних структур данных, разделяемых всеми процессорами. Затем каждый экземпляр KiInitializeKernel вызывает функцию ExpInitializeExecutive, отвечающую за управление фазой 0.

ExpInitializeExecutive начинает с вызова HAL-функции HalInitSystem, позволяющей HAL взять управление инициализацией системы на себя. Одной из задач HalInitSystem является подготовка системного контроллера прерываний каждого процессора к обработке прерываний и конфигурирование таймера, используемого для учета распределяемого процессорного времени (подробнее на эту тему см. раздел «Учет квантов времени» главы 6).

Лишь на стартовом процессоре ExpInitializeExecutive не просто вызывает HalInitSystem, но и выполняетдругие операции по инициализации. Когда HalInitSystem возвращает управление, функция ExpInitializeExecutive, выполняемая на стартовом процессоре, обрабатывает параметр /BURNMEMORY файла Boot.ini (если таковой указан и действителен для данного варианта загрузки). B соответствии с этим параметром ExpInitializeExecutive исключает указанный объем памяти.

Далее ExpInitializeExecutive вызывает процедуры инициализации для диспетчера памяти, диспетчера объектов, монитора состояния защиты, диспетчера процессов и диспетчера Plug and Play. Эти компоненты выполняют следующие инициализирующие операции.


1. Диспетчер памяти формирует таблицы страниц и внутренние структуры данных, необходимые для предоставления базовых сервисов, связанных с памятью. Кроме того, он создает и резервирует пространство для кэша файловой системы, а также выделяет области для пулов подкачиваемой и неподкачиваемой памяти. Другие компоненты исполнительной системы, ядро и драйверы устройств пользуются этими пулами, выделяя память под собственные структуры данных.

2. При инициализации диспетчера объектов определяются объекты, необходимые для создания его пространства имен, чтобы другие компоненты могли помещать в него свои объекты. Также создается таблица описателей для поддержки учета ресурсов.

3. Монитор состояния защиты инициализирует объект типа «маркер доступа» и использует его для создания и подготовки первого маркера по учетной записи локальной системы, назначаемого начальному процессу (об учетной записи локальной системы см. главу 8).

4. Диспетчер процессов производит большую часть своей инициализации в фазе 0, определяя типы объектов «процесс» и «поток» и создавая списки для отслеживания активных процессов и потоков. Он также создает объект «процесс» для начального процесса и присваивает ему имя Idle. Наконец, диспетчер процессов создает процесс System и системный поток для выполнения процедуры PhaselInitialization. Этот поток не запускается сразу после создания, поскольку прерывания пока запрещены.

5. Далее наступает фаза 0 в инициализации диспетчера Plug and Play, в ходе которой просто инициализируется ресурс исполнительной системы, используемый для синхронизации ресурсов шин.


Когда на каждом процессоре управление возвращается к функции KiInitializeKernel, она передает его циклу Idle. B результате системный поток, созданный, как было описано в п. 4 предыдущего списка, начинает фазу 1. Дополнительные процессоры ждут начала своей инициализации до п. 5 фазы 1 (см. список ниже). B фазе 1 выполняются следующие операции. (Ha экране заставке, выводимом при загрузке Windows 2000, отображается индикатор прогресса, поэтому в списке упоминаются операции, связанные с обновлением этого индикатора.)

1. Для подготовки системы к приему прерываний от устройств и для разрешения прерываний вызывается HalInitSystem.

2. Вызывается загрузочный видеодрайвер (\Windows\System32\Bootvid.dll), который выводит экран-заставку, показываемую в процессе запуска Windows. (B Windows XP и Windows Server 2003 этот драйвер отображает ту картинку, которую Ntldr ранее вывел на экран.)

3. Инициализируется диспетчер электропитания.

4. Инициализируются системные часы (вызовом HalQueryRealTimeClock), текущее значение которых сохраняется как время загрузки системы.

5. B многопроцессорной системе инициализируются остальные процессоры и начинается выполнение команд.

6. Индикатор прогресса загрузки устанавливается на отметку 5%.

7. Диспетчер объектов создает корневой каталог пространства имен (\), каталог \ObjectTypes и каталог сопоставлений DOS-имен устройств (\?? в Windows 2000 или \Global?? в Windows XP и Windows Server 2003), а также символьную ссылку в каталоге сопоставлений DOS-имен устройств.

8. Вызывается исполнительная система для создания своих типов объектов, включая семафор, мьютекс, событие и таймер.

9. Ядро инициализирует структуры данных планировщика (диспетчера) и таблицу диспетчеризации системных сервисов.

10.Монитор состояния защиты создает в пространстве имен диспетчера объектов каталог \Security и инициализирует структуры данных аудита (если аудит системы разрешен).

11.Индикатор прогресса загрузки устанавливается на отметку 10%.

12.Для создания объекта «раздел» и системных рабочих потоков вызывается диспетчер памяти (см. главу 7).

13.Ha системное адресное пространство проецируются таблицы NLS (National Language Support).

14.Ha системное адресное пространство проецируется Ntdll.dll.

15.Диспетчер кэша инициализирует структуры данных кэша файловой системы и создает свои рабочие потоки.

1б.Диспетчер конфигурации создает в пространстве имен объект «раздел реестра» \Registry и копирует переданные Ntldr начальные данные в кусты реестра HARDWARE и SYSTEM.

17.Инициализируются структуры данных драйвера файловой системы.

18.Диспетчер Plug and Play вызывает PnP BIOS.

19. Индикатор прогресса загрузки устанавливается на отметку 20%.

20.Подсистема LPC инициализирует объект типа «порт LPC».

21. Если система запущена с протоколированием загрузки (/BOOTLOG), инициализируется файл протокола загрузки.

22.Индикатор прогресса загрузки устанавливается на отметку 25%.

23. Наступает момент инициализации диспетчера ввода-вывода. Согласно показаниям индикатора, эта стадия запуска системы занимает 50% времени. После успешной загрузки каждого драйвера диспетчер ввода-вывода продвигает полоску на индикаторе на 2% (если загружается более 25 драйверов, индикатор останавливается на отметке 75%).


Диспетчер ввода-вывода прежде всего инициализирует различные внутренние структуры и создает типы объектов «устройство» и «драйвер». Затем он вызывает диспетчер Plug and Play, диспетчер электропитания и HAL, чтобы начать динамическое перечисление и инициализацию устройств. (Подробнее этот сложный процесс, специфичный для конкретной подсистемы ввода-вывода, рассматривается в главе 9.) Далее инициализируется подсистема WMI Windows Management Instrumentation), которая пpeдocтaвляeт WMI-пoддepжкy дpaйвepaм устройств. (Подробнее о WMI см. раздел «Windows Management Instrumentation" главы 4.) После этого вызываются все загрузочные драйверы, которые осуществляют свою инициализацию. Также загружаются и инициализируются драйверы, необходимые для запуска системы (см. главу 9). Наконец, в пространстве имен диспетчера объектов создаются имена устройств MS-DOS в виде символьных ссылок.


24.Индикатор прогресса загрузки устанавливается на отметку 75%.

25.Если система загружается в безопасном режиме, этот факт отмечается в реестре.

26.Включается подкачка страниц для кода режима ядра (в Ntkrnl и драйверах), если она явно не запрещена в реестре.

27.Индикатор прогресса загрузки устанавливается на отметку 80%.

28.Вызывается диспетчер электропитания для инициализации своих структур данных.

29.Индикатор прогресса загрузки устанавливается на отметку 85%.

З0.Вызывается монитор состояния защиты для создания потока Command Server, взаимодействующего с LSASS (см. раздел «Компоненты системы защиты» главы 8).

31.Индикатор прогресса загрузки устанавливается на отметку 90%.

32.Ha завершающем этапе создается процесс Smss диспетчера сеансов (базовые сведения об Smss см. в главе 2). Smss отвечает за создание среды пользовательского режима, которая предоставляет визуальный интерфейс Windows. Об инициализации Smss см. следующий раздел.

ЗЗ.Индикатор прогресса загрузки устанавливается на отметку 100%.


Перед завершением инициализации компонентов исполнительной системы и ядра поток инициализации фазы 1 в течение пяти секунд ждет освобождения описателя процесса Smss. Если этот процесс завершается до истечения пяти секунд, происходит крах системы с кодом SESSION5_INITIALIZATION_FAILED.

По истечении пяти секунд запуск диспетчера сеансов считается успешным, и вызывается функция потока обнуления страниц диспетчера памяти (см. главу 7).


Smss, Csrss и Winlogon

Smss похож на любой другой процесс пользовательского режима, но имеет два существенных отличия. Во-первых, Windows считает его доверяемой (trusted) частью системы. Во-вторых, Smss является встроенным (native) приложением. Как доверяемый компонент Smss может выполнять операции, доступные лишь немногим процессам, например создавать маркеры защиты. A как встроенное приложение Smss использует не Windows API, а базовые API-функции исполнительной системы, в совокупности называемые Windows Native API. Smss не обращается к Windows API, поскольку при его запуске подсистема Windows еще не функционирует. Запуск подсистемы Windows и является одной из его первых задач.

Затем Smss вызывает диспетчер конфигурации, который завершает инициализацию реестра, заполняя все его разделы. Диспетчер конфигурации запрограммирован так, что ему известно местонахождение всех кустов реестра на диске, кроме содержащих пользовательские параметры. Пути ко всем загружаемым им кустам реестра записываются в раздел HKLM\SYSTEM\CurrentControlSet\Control\Hivelist.


Основной поток Smss выполняет следующие инициализирующие операции.

1. Создает объект «порт LPC» (\SmApiPort) и два потока, ожидающие клиентские запросы (например, на загрузку новой подсистемы или на создание сеанса).

2. Определяет символьные ссылки на имена устройств MS-DOS (вроде COM1 и LPT1).

3. Если установлены Terminal Services, создает в пространстве имен диспетчера объектов каталог \Sessions (для нескольких сеансов).

4. Запускает программы, указанные в HKLM\SYSTEM\CurrentControlSet\Con-trol\Session Manager\BootExecute. Как правило, в нем содержится одна команда на зaпycк Autochk (версия Chkdsk, работающая на этапе загрузки).

5. Выполняет отложенные действия по переименованию и удалению файлов, указанные в разделах HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations и HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations2.

6. Открывает известные DLL и создает для них объекты «раздел» в каталоге \Knowndlls пространства имен диспетчера объектов. Список DLL, считаемых известными, находится в разделе HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\Control\Session Manager\KnownDLLs, а путь к каталогу, где расположены эти DLL, хранится в параметре Dlldirectory этого раздела. Об использовании разделов Known DLLs при загрузке DLL см. главу 6.

7. Создает дополнительные страничные файлы. Их конфигурация хранится в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ Session Manager\Memory Management\PagingFiles.

8. Инициализирует реестр. Диспетчер конфигурации заполняет реестр, загружая кусты HKLM\SAM, HKLM\SECURITY и HKLM\SOFTWARE. Хотя информация о местонахождении файлов кустов содержится в разделе HKLM\ SYSTEM\CurrentControlSet\Control\Hivelist, диспетчер конфигурации ищет эти файлы в каталоге \Windows\System32\Config.

9. Создает системные переменные окружения, определенные в HKLM\System\CurrentControlSet\Session Manager\Environment.

10.Загружает часть подсистемы Windows, работающую в режиме ядра (Win32k.sys). Smss определяет местонахождение Win32k.sys и других загружаемых им компонентов по путям, хранящимся в HKLM\SYSTEM\CurrentControlSet\Control\Session Manager. Инициализирующий код в Win32k.sys использует видеодрайвер для переключения экрана в разрешение, определенное в профиле по умолчанию. Таким образом, в этот момент видеоадаптер переключается с VGA-режима, используемого загрузочным видеодрайвером, в выбранное для данной системы разрешение.

11. Запускает процессы подсистем, в том числе Csrss. (Как говорилось в главе 2, подсистемы POSIX и OS/2 в Windows 2000 запускаются по требованию.)

12.3апускает процесс Winlogon. Этапы запуска Winlogon кратко описываются ниже.

1З. Создает порты LPC для сообщений об отладочных событиях (DbgSsApiPort и DbgUiApiPort) и потоки, прослушивающие эти порты.


Отложенные действия по переименованию файлов

Тот факт, что исполняемые образы и DLL при использовании проецируются в память, делает невозможным обновление базовых системных файлов по окончании загрузки Windows. API-функция MoveFileEx позволяет указать, что перемещение файла должно быть отложено до следующей загрузки. Пакеты обновлений и критические исправления, которым нужно обновлять уже используемые файлы, проецируемые в память, устанавливают заменяющие файлы во временные каталоги и вызывают функцию MoveFileEx именно так, как говорилось чуть выше. B этом случае MoveFileEx просто записывает команды в параметры PendingFileRenameOperatiom и PendingFileRenameOperatiom2 в разделе реестра HKLM\SYSTEM\CurrentControlSet\Control\Session Manager. Эти параметры имеют тип MULTI_SZ, и каждая операция указывается парами имен файлов: первое имя – источник, а второе – приемник. B операциях удаления вместо приемника задается пустая строка. Чтобы просмотреть зарегистрированные отложенные команды переименования и удаления, используйте утилиту Pendmoves с сайта www.sysinternate.com.

После выполнения вышеперечисленных операций основной поток Smss переходит к бесконечному ожиданию описателей процессов Csrss и Winlogon. Поскольку от этих процессов зависит функционирование Windows, в случае их неожиданного завершения Smss вызывает крах системы. (B Windows XP и выше, если Csrss по какой-то причине завершается, крах системы вызывается ядром, а не Smss.)

Далее Winlogon продолжает инициализацию, выполняя такие операции, как создание начального объекта WindowStation и объектов рабочего стола. Если в HKLM\Software\Microsoft\Windows NT\Current Version\WinLogon\ GinaDLL указана какая-нибудь DLL, Winlogon использует ее в качестве GINA; в ином случае применяется GINA по умолчанию от Microsoft, Msgina (\Windows\System32\Msgina.dll), которая отображает стандартное диалоговое окно входа в Windows. Затем Winlogori создает процесс SCM (диспетчера управления сервисами) (\Windows\System32\Services.exe), который загружает все сервисы и драйверы устройств, помеченные для автоматического запуска, а также запускает процесс LSASS (подсистемы локальной аутентификации) (\Windows\System32\Lsass.exe). Подробнее о запуске Winlogon и LSASS см. раздел «Инициализация Winlogon» главы 8.

После того как SCM инициализирует автоматически запускаемые сервисы и драйверы устройств, а пользователь успешно зарегистрируется в системе, загрузка считается успешно завершенной. Параметры в разделе HKLM\ SYSTEM\Select\LastKnownGood обновляются в соответствии со значениями параметров последней удачной конфигурации (\CurrentControlSet).


ПРИМЕЧАНИЕ Если на неинтерактивном сервере не бывает интерактивного входа, раздел LastKnownGood, отражающий набор управления (control set), который позволил выполнить успешную загрузку, не обновляется.


Вы можете заменить определение успешной загрузки. Для этого установите HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ReportBootOk в 0, напишите свою программу, проверяющую успешность загрузки, и укажите путь к ней в HKLM\System\CurrentControlSet\Control\BootVerificationProgram. Такая программа должна вызывать API-функцию NotifyBootConfigStatus, если загрузка прошла успешно.

Запустив SCM, Winlogon ждет уведомления об интерактивном входе от GINA. Получив такое уведомление и проверив вход (об этом процессе см. в главе 8), Winlogon загружает куст реестра из профиля зарегистрировавшегося пользователя и отображает его на HKCU. Затем он настраивает переменные окружения для данного пользователя, хранящиеся в HKCU\Environment, и направляет уведомления о входе компонентам, зарегистрированным в HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify.

Затем Winlogon сообщает GINA запустить оболочку. B ответ на этот запрос Msgina запускает исполняемый файл (или исполняемые файлы), указанный в параметре HKLM\Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Userinit (несколько исполняемых файлов перечисляются через запятые), который по умолчанию указывает на \Windows\System32\Userinit.exe. Userinit.exe выполняет следующие операции.


1. Обрабатывает пользовательские сценарии, указанные в HKCU\Software\ Policies\Microsoft\Windows\System\Scripts, и машинные сценарии входа, заданные в HKLM\Software\Policies\Microsoft\Windows\System\Scripts.

(Так как машинные сценарии выполняются после пользовательских, они могут переопределять пользовательские настройки.)

2. Если политика группы задает какую-либо квоту в профиле пользователя, Userinit.exe запускает \Windows\System32\Proquota.exe для ее применения.

3. Запускает оболочку (или оболочки), указанную в HKCU\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell. Если этого параметра нет, Userinit.exe запускает оболочку (или оболочки), определенные в HKLM\Software\Microsoft\Windows\CurrentVersion\Winlogon\Shell (по умолчанию – Explorer.exe).


Далее Winlogon уведомляет зарегистрированные провайдеры сетей о входе пользователя. Провайдер сети Microsoft, маршрутизатор многосетевого доступа (Multiple Provider Router, MPR) (\Windows\System32\Mpr.dll), восстанавливает постоянные подключения к сетевому диску и принтерам, установленные пользователем; эти сопоставления хранятся в HCU\Network и HKCU\ Printers соответственно. Ha рис. 5-3 показано дерево процессов, которое отображается в Process Explorer при входе до завершения Userinit.


Автоматически запускаемые образы

Помимо параметров Userinit и Shell в разделе Winlogon, существует много других разделов в реестре и каталогов, проверяемых и обрабатываемых системными компонентами для автоматического запуска процессов при загрузке и входе. Утилита Msconfig (в Windows XP и Windows Server 2003 это \Windows\System32\Msconfig.exe) показывает образы, сконфигурированные в нескольких местах. Ho утилита Autoruns от Sysinternals (wwwsysinternals.com), представленная на рис. 5-4, анализирует больше разделов реестра и каталогов, чем Msconfig, и выводит больше информации об образах, настроенных на автоматический запуск. По умолчанию Autoruns показывает только те места, где задается автоматический запуск хотя бы одного образа, но команда Include Empty Locations в меню View заставляет Autoruns отображать все проверяемые ею разделы реестра и каталоги. B меню View можно настроить Autoruns на отображение сведений о других типах автоматически запускаемых образов, например служб Windows и надстроек Explorer.


ЭКСПЕРИМЕНТ: утилита Autoruns

Многие пользователи даже не представляют, сколько программ выполняется в процессе их входа. OEM (original equipment manufacturers) часто конфигурируют свои системы с помощью дополнительных утилит, которые выполняются в фоновом режиме и обычно не видны. Чтобы увидеть, какие программы настроены на автоматический запуск на вашем компьютере, запустите утилиту Autoruns; ее можно скачать с сайта wwwsysinternals.com. Сравните полученный в Autoruns список с тем, что показывается Msconfig (доступной в Windows XP и Windows Server 2003), и обратите внимание на различия. Потом попробуйте разобраться в предназначении каждой программы.


Анализ проблем при загрузке и запуске системы

B этом разделе представлены подходы к решению проблем, возможных в процессе запуска Windows из-за повреждения жесткого диска и файлов, отсутствия каких-либо файлов и ошибок в сторонних драйверах. Сначала мы опишем три режима восстановления Windows при возникновении проблем с загрузкой: последняя удачная конфигурация, безопасный режим и консоль восстановления (Recovery Console). Затем мы расскажем о наиболее распространенных проблемах при загрузке, об их причинах и способах устранения.


Последняя удачная конфигурация

Последняя удачная конфигурация (last known good, LKG) – полезный механизм для возврата системы, рухнувшей в процессе загрузки, в загружаемое состояние. Поскольку параметры системной конфигурации хранятся в HKLM\System\CurrentControlSet\Control, конфигурация драйверов и сервисов – в HKLM\System\CurrentControlSet\Services, изменения этих частей реестра могут привести к тому, что система станет незагружаемой. Например, если вы установили драйвер устройства с ошибкой, из-за которой происходит крах системы при загрузке, то можете нажать клавишу F8 в момент загрузки и выбрать из меню последнюю удачную конфигурацию. Система отмечает набор управления, использовавшийся при загрузке как неудачный, устанавливая параметр Failed в HKLM\System\Select и заменяя значение параметра HKLM\System\Select\Current на значение параметра HKLM\System\ Select\LastKnownGood. Она также обновляет символьную ссылку HKLM\Sys-tem\CurrentControlSet так, чтобы она указывала на набор управления Last-KnownGood. Поскольку для нового драйвера нет подраздела в разделе Services набора управления LastKnownGood, система успешно загрузится.


Безопасный режим

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

Нажав клавишу F8 в начале загрузки Windows 2000, вы открываете дополнительное загрузочное меню, в котором присутствуют три варианта загрузки в безопасном режиме: Safe Mode (Безопасный режим), Safe Mode With Networking (Безопасный режим с загрузкой сетевых драйверов) и Safe Mode With Command Prompt (Безопасный режим с поддержкой командной строки). Стандартный безопасный режим подразумевает использование минимума необходимых для успешной загрузки драйверов. B безопасном режиме с сетевой поддержкой дополнительно загружаются сетевые драйверы и сервисы. Наконец, единственное отличие безопасного режима с поддержкой командной строки от стандартного заключается в том, что Windows вместо обычной оболочки Windows Explorer, позволяющей работать в GUI-режиме, запускает оболочку командной строки (Cmd.exe).

B Windows предусмотрен и четвертый безопасный режим – Directory Services Restore (Восстановление службы каталогов), который применяется для загрузки системы с отключенной службой каталогов Active Directory и без открытия ее базы данных. Это позволяет администратору исправить поврежденную базу данных или восстановить ее с резервной копии. B этом режиме загружается весь набор драйверов и сервисов, кроме Active Directory. B тех случаях, в которых вам не удается войти в систему из-за повреждения базы данных Active Directory, этот режим дает возможность устранить неполадки.


Загрузка драйверов в безопасном режиме

Как Windows определяет набор драйверов для загрузки в стандартном безопасном режиме и безопасном режиме с сетевой поддержкой? Ответ следует искать в содержимом раздела реестра HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot. B нем присутствуют подразделы Minimal и Network. Каждый подраздел в свою очередь содержит подразделы с именами драйверов, сервисов или их групп. Так, подраздел vga.sys определяет драйвер видеоадаптера VGA, который поддерживает базовый набор графических сервисов стандартного видеоадаптера для IBM-совместимого компьютера. Этот драйвер используется системой в безопасном режиме вместо драйверов, которые позволяют задействовать все преимущества куда более совершенных видеоадаптеров, но способны помешать успешной загрузке системы. Каждому подразделу в разделе SafeBoot соответствует параметр по умолчанию, описывающий, что именно идентифицирует данный подраздел. Например, в подразделе vga.sys параметр по умолчанию – Driver.

Параметром по умолчанию для подраздела файловой системы является Driver Group. При создании сценария установки для драйвера устройства разработчик может указать, что он относится к какой-либо группе драйверов. Группы драйверов, определенные в системе, перечисляются в параметре List раздела реестра HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder. Разработчик приписывает драйвер к той или иной группе, чтобы указать Windows, на каком этапе загрузки следует запускать данный драйвер. Главное предназначение раздела ServiceGroupOrder – определение порядка загрузки групп драйверов. Некоторые группы драйверов нужно загружать до или после других. Параметр Group в подразделе реестра со сведениями о конфигурации драйвера, сопоставляет его с определенной группой. Подразделы со сведениями о конфигурации драйверов и сервисов находятся в разделе HKLM\SYSTEM\CurrentControlSet\Services. Взглянув на его содержимое, вы найдете раздел VgaSave для драйвера видеоадаптера VGA, который принадлежит к группе Video Save. Любой драйвер файловой системы, необходимый Windows для обращения к системному диску, находится в группе Boot File System. Если файловой системой такого диска является NTFS, то в группу входит драйвер NTFS; в ином случае в группу входит драйвер Fastfat (поддерживающий диски FAT12, FATl6 и FAT32). Другие драйверы файловой системы входят в группу File System, которая также включена в конфигурации Safe Mode и Safe Mode With Networking.

При загрузке в безопасном режиме Ntldr передает ядру (Ntoskrnl.exe) вместе с другими параметрами, указанными в Boot.ini для текущего варианта загрузки, параметр командной строки /SAFEBOOT:, добавляя к нему одну или несколько строк в зависимости от выбранного типа безопасного режима. Для стандартного безопасного режима Ntldr добавляет MINIMAL, для Safe Mode With Networking – NETWORK, для Safe Mode With Command Prompt – MINIMAL(ALTERNATESHELL), a для Directory Services Restore – DSREPAIR.

Ядро Windows сканирует параметры загрузки в поисках спецификаторов безопасного режима и устанавливает значение внутренней переменной InitSafeBootMode в соответствии с результатом поиска. Значение этой переменной также записывается в раздел HKLM\SYSTEM\CurrentControlSet\Cont-rol\SafeBoot\Option\OptionValue, что позволяет компонентам пользовательского режима (например, SCM) определять режим загрузки системы. Кроме того, при выборе Safe Mode With Command Prompt, ядро присваивает значение 1 параметру UseAlternateShell в разделе реестра HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Option. Кроме того, ядро записывает параметры, переданные Ntldr, в раздел HKLM\SYSTEM\CurrentControlSet\Control\SystemStartOptions.


Когда диспетчер ввода-вывода загружает драйверы устройств, указанные в разделе HKLM\SYSTEM\CurrentControlSet\Services, он выполняет функцию IopLoadDriver. A когда диспетчер Plug and Play обнаруживает новое устройство и хочет динамически загрузить драйвер для этого устройства, он вызывает функцию IopCallDriverAddDevice. Обе эти функции перед загрузкой драйвера обращаются к функции IopSafeBootDriverLoad. Последняя проверяет значение переменной InitSafeBootMode и определяет, можно ли загрузить данный драйвер. Так, если система загружается в стандартном безопасном режиме, IopSafeBootDriverLoad ищет группу этого драйвера (если таковая есть) в подразделе Minimal. Найдя ее, IopSafeBootDriverLoad уведомляет вызвавшую функцию о том, что этот драйвер можно загрузить. B ином случае IopSafeBootDriverLoad ищет в том же подразделе имя драйвера. Если оно есть в списке, драйвер может быть загружен. Если IopSafeBootDriverLoad не находит в списке группу или имя данного драйвера, его загрузка запрещается. При загрузке системы в безопасном режиме с сетевой поддержкой IopSafeBootDriverLoad ведет поиск в подразделе Network, а в случае загрузки системы в нормальном режиме IopSafeBootDriverLoad разрешает загрузку всех драйверов.

Однако Ntldr загружает все драйверы, у которых в соответствующих разделах реестра значение Start равно 0, что указывает на необходимость их загрузки при запуске системы. Поскольку Ntldr не проверяет раздел SafeBoot (считая, что любой драйвер с нулевым значением параметра Start необходим для успешного старта системы), он загружает все загрузочные драйверы, которые впоследствии запускаются Ntoskrnl.


Программное обеспечение с поддержкой безопасного режима

SCM (Services.exe), проводя инициализацию при загрузке, проверяет параметр OptionValue в разделе реестра HKLM\SYSTEM\CurrentControlSet\Cont-rol\SafeBoot\Option, чтобы выяснить, загружается ли система в безопасном режиме. Если да, SCM зеркально воспроизводит действия IopSafeBootDriverLoad. Он обрабатывает все сервисы, перечисленные в HKLM\SYSTEM\CurrentControlSet\Services, но загружает лишь отмеченные в соответствующем подразделе реестра для загрузки в безопасном режиме. Подробнее об инициализации SCM см. раздел «Сервисы» главы 4.

Userinit (\Windows\System32\Userinit.exe) – другой компонент пользовательского режима, которому нужно знать, загружается ли система в безопасном режиме. Userinit, инициализирующий среду для пользователя при его входе в систему, проверяет значение HKLM\SYSTEM\CurrentControlSet\Cont-rol\SafeBoot\UseAlternateValue. Если это значение установлено, в качестве пользовательской оболочки он запускает не Explorer.exe, а программу, указанную в HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\AlternateShell. Когда вы устанавливаете Windows на компьютер, параметру AlternateShell присваивается значение Cmd.exe, и командная строка Windows становится оболочкой по умолчанию для безопасного режима с командной строкой. Ho, даже если текущей оболочкой является командная строка, из нее можно запустить Windows Explorer, введя команду Explorer.exe. Аналогичным образом из командной строки можно запустить любую GUI-программу.

A как приложения узнают о загрузке системы в безопасном режиме? Вызовом Windows-функции GetSystemMetrics (SM_CLEANBOOT). Пакетные сценарии, выполняющие некоторые действия при загрузке системы в безопасном режиме, проверяют наличие переменной окружения SAFEBOOT_OPTION, так как система определяет ее только при загрузке в безопасном режиме.


Ведение протокола при загрузке в безопасном режиме

Если вы загружаете систему в безопасном режиме, Ntldr передает ядру Windows вместе с параметрами, устанавливающими безопасный режим, и параметр /BOOTLOG. При инициализации ядро проверяет наличие параметра /BOOTLOG независимо от того, задан ли безопасный режим. Если ядро обнаруживает соответствующую строку, оно протоколирует все свои действия при загрузке каждого драйвера. Так, если функция IopSafeBootDriverLoad запрещает загрузку какого-либо драйвера, диспетчер ввода-вывода вызывает функцию IopBootLog, регистрируя, что данный драйвер не загружен. Аналогичным образом после успешной загрузки драйвера, входящего в конфигурацию безопасного режима, IopLoadDriver вызывает IopBootLog для внесения записи о загрузке этого драйвера. Изучив файлы протокола загрузки, можно выяснить, какие драйверы являются частью данной конфигурации.

Поскольку ядро избегает изменения данных на диске до запуска Chkdsk, который происходит на более позднем этапе загрузки, IopBootLog не может просто сбрасывать записи в файл. Вместо этого она записывает их в раздел реестра HKLM\SYSTEM\CurrentControlSet\BootLog. Диспетчер сеансов (Smss), первый загружаемый компонент пользовательского режима, запускает Chkdsk для проверки целостности системного диска, а потом завершает инициализацию реестра, вызывая NtInitializeRegistry. Этот вызов указывает ядру, что уже можно безопасно открыть на диске файл протокола, что и делается вызовом IopCopyBootLogRegistryToFile. Эта функция создает в системном каталоге Windows (по умолчанию – \Windows) файл Ntbtlog.txt и копирует в него содержимое раздела реестра BootLog. IopCopyBootLogRegistryToFile также устанавливает флаг, сигнализирующий IopBootLog о возможности записи непосредственно в файл протокола. Ниже показан фрагмент образца такого файла.


Service Pack 1 3 30 2004 14:05:21.500

Loaded driver \WIND0WS\system32\ntoskrnl.exe

Loaded driver \WIND0WS\system32\hal.dll

Loaded driver \WIND0WS\system32\KDC0M.DLL

Loaded driver \WIND0WS\system32\B00TVID.dll

Loaded driver ACPI.sys

Loaded driver \WIND0WS\System32\DRIVERS\WMILIB.SYS

Loaded driver pci.sys

Loaded driver isapnp.sys

Loaded driver intelide.sys

Loaded driver \WIND0WS\System32\DRIVERS\PCIIDEX.SYS

Loaded driver MountMgr.sys

Loaded driver ftdisk.sys

Loaded driver dmload.sys

Loaded driver dmio.sys Microsoft (R)Windows 2000 (R)Version 5.0 (Build 2195) 2 11 2000 10:53:27.500

Loaded driver \WINNT \System32 \ntoskrnl.exe

Loaded driver \WINNT \System32 \hal.dll

Loaded driver \WINNT \System32 \B00TVID.DLL

Loaded driver ACPI.sys

Loaded driver \WINNT \System32 \DRIVERS \WMILIB.SYS

Loaded driver pci.sys

Loaded driver isapnp.sys

Loaded driver compbatt.sys

Loaded driver \WINNT \System32 \DRIVERS \BATTC.SYS

Loaded driver intelide.sys

Loaded driver \WINNT \System32 \DRIVERS \PCIIDEX.SYS

Loaded driver pcmcia.sys

Loaded driver ftdisk.sys

Loaded driver Diskperf.sys

Loaded driver dmload.sys

Loaded driver dmio.sys

Did not load driver \SystemRoot\System32\Drivers\lbrtfdc.SYS Did not load driver \SystemRoot\System32\Drivers\Sfloppy.SYS Did not load driver \SystemRoot\System32\Drivers\i2omgmt.SYS Did not load driver Media Control Devices Did not load driver Communications Port Did not load driver Audio Codecs


Консоль восстановления

B безопасном режиме обычно удается восстановить систему, ставшую незагружаемой в нормальном режиме из-за неправильной работы какого-либо драйвера устройства. Однако в некоторых ситуациях это не помогает: система все равно не загружается. Так, если сбойный драйвер входит в группу Safe, загрузиться в безопасном режиме не удастся. Другая ситуация, когда загрузка в безопасном режиме не помогает, – сбои в загрузочном драйвере стороннего поставщика, например в драйвере антивирусного сканера, поскольку загрузочные драйверы стартуют независимо от режима загрузки системы. Аналогичная ситуация возникает при повреждении файлов системных модулей или драйверов, входящих в конфигурацию безопасного режима, а также главной загрузочной записи (MBR) системного диска. Эти проблемы можно решить с помощью Recovery Console (Консоль восстановления). Консоль восстановления позволяет загрузить компактную оболочку командной строки с дистрибутивного компакт-диска Windows (или ранее подготовленных загрузочных дискет) и восстановить систему без загрузки компьютера с жесткого диска.

При загрузке системы с дистрибутивного компакт-диска Windows появляется экран, на котором можно выбрать между установкой Windows и восстановлением существующей системы. При выборе второго варианта предлагается вставить дистрибутивный компакт-диск Windows (если он не вставлен в CD-привод). Далее вы должны выбрать один из двух вариантов восстановления: запустить консоль восстановления или начать процесс аварийного восстановления. Если при появлении экрана Setup Welcome (Вас приветствует программа установки) вы нажмете клавишу F10, это меню выводиться не будет, а сразу запустится консоль восстановления.

После запуска консоль восстановления сканирует жесткие диски и формирует список систем Windows NT и Windows на данном компьютере (если они есть). Выбрав нужную систему, вы должны ввести пароль, соответствующий учетной записи администратора для данной системы. Если регистрация прошла успешно, система предоставляет вам командную оболочку, аналогичную среде MS-DOS. Гибкий набор команд позволяет выполнять простые операции с файлами (вроде копирования, переименования и удаления), включать и отключать службы и драйверы и даже восстанавливать MBR и загрузочные записи. Однако консоль восстановления обеспечивает доступ лишь к корневому каталогу, к каталогу, в котором установлена система и в котором вы сейчас зарегистрировались, и к каталогам на сменных дисках, например на компакт-дисках или 3,5-дюймовых дискетах (если это разрешено локальной политикой безопасности, чьи параметры хранятся в кусте SECURITY реестра текущей системы). Эти ограничения диктуются требованиями защиты данных, право на доступ к которым может отсутствовать у администратора одной из систем. Вы можете переопределить эти ограничения, используя редактор локальной политики безопасности (secpol.msc) для настройки параметров Recovery Console (Консоль восстановления) в папке Security Options (Параметры безопасности) в Local Policies (Локальные политики) при нормальной загрузке системы.

Для поддержки таких команд файлового ввода-вывода, как Cd, Rename или Move, консоль восстановления использует встроенный интерфейс системных вызовов Windows. Команды Enable и Disable, позволяющие изменять режимы запуска драйверов устройств и сервисов (служб), работают иначе. Например, когда вы командуете консоли восстановления отключить какой-либо драйвер, она обращается к разделу реестра Services и присваивает параметру Start в подразделе для соответствующего драйвера значение SERVICE_DISABLED. B результате при следующей загрузке системы данный драйвер загружаться не будет. Консоль также загружает куст реестра SYSTEM (\Windows\System32\Config\System) для текущей системы, где в разделе HKLM\SYSTEM\CurrentControlSet\Services хранится нужная информация.


Когда вы загружаете систему с дистрибутивного компакт-диска Windows или загрузочных дискет, к моменту появления экрана, предлагающего выбор между установкой или восстановлением Windows, происходит загрузка с компакт-диска стартовой копии ядра Windows и всех драйверов поддержки (например, драйверов NTFS, FAT, SCSI и видеоадаптера). Ha компьютерах с процессорами типа x86 загрузка с компакт-диска управляется файлом Txtsetup.sif из каталога i386. B нем содержится список файлов, подлежащих загрузке, с указанием их местонахождения на компакт-диске. Как и при загрузке Windows с жесткого диска, первой запускаемой программой пользовательского режима является диспетчер сеансов (Smss.exe), расположенный в каталоге I386\System32. Диспетчер сеансов, используемый программой установки Windows, отличается от стандартного в уже установленной системе. Эта версия диспетчера сеансов предоставляет меню, позволяющие установить или восстановить Windows, а также выбрать тип восстановления. B процессе установки Windows этот компонент также помогает выбрать раздел для установки системы и копирует файлы на жесткий диск.

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

Консоль восстановления, приняв от вас пароль для входа в выбранную систему, должна проверить его, даже несмотря на то что подсистема защиты Windows сейчас не функционирует. Таким образом, проверка пароля возлагается исключительно на консоль восстановления. Для этого консоль прежде всего загружает с жесткого диска (через Setupdd.sys) куст реестра диспетчера учетных записей безопасности (Security Accounts Manager, SAM) данной системы, где хранится информация о паролях. Куст SAM находится в каталоге \Windows\System32\Config\Sam. После загрузки этого куста консоль восстановления находит в реестре системный ключ для расшифровки копии SAM в памяти. Шифрование куста SAM введено, начиная с Windows NT 4 Service Pack 3, для защиты от попыток взлома из MS-DOS.

Далее консоль восстановления (Spcmdcon.sys) отыскивает в SAM пароль для учетной записи Administrator (Администратор). Ha заключительном этапе проверки консоль хэширует пароль по алгоритму MD5, а затем сравнивает полученный хэш с зашифрованным хэшем из SAM. Если они совпадают, консоль восстановления считает, что вы успешно вошли в систему, в ином случае консоль восстановления отказывает вам в доступе.


Решение распространенных проблем загрузки

B этом разделе описываются проблемы, которые могут возникнуть в процессе загрузки, их симптомы, причины и подходы к решению.


Повреждение MBR

(o) Симптомы Система с поврежденной главной загрузочной записью (Master Boot Record, MBR) пройдет тест самодиагностики при включении, выполняемый BIOS (power-on self test, POST), выведет на экран информацию о версии BIOS или модели компьютера, затем экран станет черным, и компьютер зависнет. B зависимости от типа повреждения MBR вы можете увидеть одно из следующих сообщений: «Invalid Partition Table» (недопустимая таблица разделов), «Error Loading Operating System» (ошибка при загрузке операционной системы) или «Missing Operating System» (операционная система не найдена).

(o) Причина MBR может быть повреждена из-за ошибок жесткого диска, в результате ошибки одного из драйверов в процессе работы Windows или из-за деструктивной деятельности какого-либо вируса.

(o) Решение Загрузите консоль восстановления и запустите команду fixmbr. Эта команда заменяет исполняемый код в MBR K сожалению, она не исправит таблицу разделов. Единственный способ это сделать – восстановить поврежденную таблицу разделов из резервной копии или использовать сторонний инструмент для устранения повреждений на диске.


Повреждение загрузочного сектора

(o) Симптомы Повреждение загрузочного сектора выглядит как повреждение MBR, когда система зависает с черным экраном после прохождения BIOS POST, либо на черном экране появляется сообщение: «А disk read error occurred» (ошибка чтения с диска), «NTLDR is missing» (NTLDR не найден) или «NTLDR is compressed» (NTLDR заархивирован).

(o) Причина Загрузочная запись может быть повреждена из-за ошибок жесткого диска, в результате ошибки одного из драйверов в процессе работы Windows или из-за деструктивной деятельности какого-либо вируса.

(o) Решение Загрузите консоль восстановления и запустите команду fixboot. Эта команда перепишет загрузочный сектор указанного вами тома. Вы должны выполнить такую команду применительно к системному и загрузочному томам, если они разные.


Неправильная конфигурация Boot.ini

(o) Симптом После BIOS POST вы видите сообщение, которое начинается как «Windows could not start because of a computer disk hardware configuration problem» (Windows не удалось запустить из-за проблемы с конфигурацией дискового устройства), «Could not read from selected boot disk» (не удалось считать данные с выбранного загрузочного диска) или «Check boot path and disk hardware» (проверьте путь к загрузочному диску и дисковое устройство).

(o) Причина Файл Boot.ini удален, поврежден или больше не ссылается на загрузочный том из-за добавления раздела, которое привело к изменению ARC-имени тома (Advanced RISC Computing).

(o) Решение Загрузите консоль восстановления и запустите команду bootcfg /rebuild. Эта команда заставит консоль восстановления просканировать каждый том в поисках установленных систем Windows. Обнаружив первую из них, она спросит, следует ли добавить ее в Boot.ini как вариант загрузки и под каким названием отображать ее в загрузочном меню.


Повреждение системных файлов

(o) Симптомы Повреждение системных файлов (в том числе драйверов и DLL) может проявляться по-разному. Один из вариантов – сообщение на черном экране после прохождения BIOS POST, в котором говорится «Windows could not start because the following file is missing or corrupt» ^Win-dows не удалось запустить из-за отсутствия или повреждения следующего файла). Далее выводится имя файла и запрос на его переустановку. Еще один вариант – синий экран в результате краха при загрузке с текстом «STOP: 0xC0000135 {Unable to Locate Component}».

(o) Причины Том, на котором находится системный файл, поврежден, один или несколько системных файлов удалены либо повреждены.

(o) Решение Загрузите консоль восстановления и запустите команду chkdsk. Эта команда попытается устранить повреждение тома. Если Chkdsk не сообщит о каких-либо проблемах, возьмите резервную копию нужного системного файла. Одно из мест, где можно найти такие копии, – каталог \Windows\System32\DllCache, в котором Windows хранит копии многих системных файлов для использования Windows File Protection (см. врезку «Windows File Protection» далее в этом разделе). Если вам не удалось найти копию файла в этом каталоге, поищите ее на другом компьютере в сети. Заметьте, что резервная копия файла должна быть от того же пакета обновлений или критического исправления, что и заменяемый файл.


B некоторых случаях может быть удалено или повреждено много системных файлов, поэтому процесс восстановления потребует неоднократных перезагрузок, пока вы поочередно не замените все файлы. Если вы считаете, что повреждения системных файлов слишком обширны, подумайте о восстановлении системы с резервного образа, который генерируется, например, Automated System Recovery (ASR). Запустив Windows Backup (Архивация данных) [эта программа находится в папке System (Служебные) в группе Accessories (Стандартные) меню Start (Пуск)], вы можете сгенерировать резервный ASR-образ, который включает все файлы на системном и загрузочном томах, плюс дискету, на которой сохраняется информация о дисках и томах в системе. Чтобы восстановить систему из ASR, загрузите компьютер с дистрибутива Windows и нажмите F2, когда появится соответствующий запрос.

Если у вас нет резервной копии, остается последнее средство – запуск программы установки Windows в режиме исправления: загрузите компьютер с дистрибутива Windows и следуйте указаниям мастера. Мастер спросит вас, хотите ли вы исправить существующую систему или установить новую. Как только вы выберете первый вариант, Setup переустановит все системные файлы, сохранив данные ваших приложений и параметры реестра.


Windows FiIe Protection

Помимо своих основных задач, Winlogon также поддерживает функциональность защиты файлов Windows (Windows File Protection, WFP). WFP, которая реализована в виде двух DLL (\Windows\System32\Sfc.dll и \Windows\System32\Sfc_os.dll), отслеживает несколько каталогов на предмет изменения ключевых драйверов, исполняемых файлов и DLL, в том числе большинство подкаталогов в \Windows. При этом она использует версию ReadDirectoryChangesWRJisL Native API. Когда WFP обнаруживает изменение в одном из системных файлов, список которых «зашит» в \Windows\System32\Sfcfiles.dll (с помощью утилиты Strings от wwwsysinternals.com вы можете получить этот список), она проверяет, подписан ли данный файл цифровой подписью Microsoft (об этом процессе см. раздел «Установка драйверов» главы 9). Если подписан, WFP разрешает изменение и копирует файл в свой резервный каталог. По умолчанию это \Windows\System32\DllCache, но его можно переопределить, изменив параметр реестра HKLM\Software\Microsoft\Win-dows NT\CurrentVersion\Winlogon\SFCDllCacheDir. Критические исправления и пакеты обновлений всегда устанавливают системные файлы, подписанные Microsoft.

Если в результате модификации появляется файл, не подписанный Microsoft, WFP заменяет его резервной версией из подкаталога DLL-Cache. Если Winlogon не удается найти резервную версию в этом подкаталоге, он проверяет сетевой путь установки или дистрибутив (в этом случае предлагается вставить компакт-диск).


Повреждение куста System

(o) Симптомы Если куст реестра System (сведения об этом кусте см. в разделе «Реестр» главы 4) отсутствует или поврежден, NTLDR выводит на черном экране после BIOS POST сообщение «Windows could not start because the following file is missing or corrupt: \WINDOWS\SYSTEM32\CONFIG\SYSTEM» (Windows не удалось запустить из-за отсутствия или повреждения следующего файла: \WINDOWS\SYSTEM32\CONFIG\SYSTEM).

(o) Причины Куст реестра System, который содержит конфигурационную информацию, необходимую для загрузки системы, поврежден или удален.

(o) Решение Загрузите консоль восстановления и запустите команду cbkdsk применительно к загрузочному тому, чтобы исправить любые возможные его повреждения. Если это не решило проблему, возьмите резервную копию куста System. Если вы делали резервные ASR-копии системы или использовали утилиту Windows Backup для создания резервных копий состояния системы (это один из вариантов, предлагаемых в ее UI), то скопируйте кусты реестра из самой последней резервной копии, которые хранятся в каталоге \Windows\Repair, в частности скопируйте файл System в \Windows\System32\Config.


Если вы используете Windows XP и средство System Restore (Восстановление системы) включено (о System Restore см. в главе 12), то можете получить резервные копии кустов реестра, в том числе System, из самой последней точки восстановления. Однако не исключено, что консоль восстановления не позволит вам обратиться к каталогу, где хранятся точки восстановления, – \System Volume Information. Версия консоли восстановления из Windows XP Service Pack 1 разрешает доступ к этому каталогу, а более старые версии – нет (если только это не разрешено локальной политикой безопасности). Чтобы обойти это ограничение, используйте Local Security Policy Editor (Редактор локальной политики безопасности) для изменения параметров консоли восстановления, как уже пояснялось ранее. Вы также можете применить сторонние утилиты для доступа к другим каталогам. Получив доступ к каталогу точек восстановления, выполните следующие операции, чтобы получить файлы кустов реестра.


1. Перейдите в каталоге \System Volume Information на загрузочном томе в подкаталог, имя которого начинается с «_restore».

2. Найдите подкаталог RP с самым большим числом (например, RP173).

3. Скопируйте файл с именем _REGISTRY_MACHINE_SYSTEM в файл \Windows\System32\Config\System.

4. Перезагрузите систему.


Другой вариант – попробовать исправить повреждение с помощью утилиты Microsoft ChkReg. Она пытается делать это автоматически и запускается с дискет, подготовленных в программе установки Windows XP Setup.

Если у вас нет резервных копий, нет доступа к точкам восстановления и утилита ChkReg не помогла, используйте копию куста System из \Windows \Repair как последнее средство. Windows Setup делает копию куста System по окончании установки, поэтому вы потеряете все изменения в конфигурации системы и драйверов устройств, произошедшие с того момента.


Крах или зависание после вывода экрана-заставки

(o) Симптомы K этой категории относятся проблемы, которые возникают после отображения экрана-заставки Windows, вывода рабочего стола или входа в систему. Они могут проявляться как крах с отображением синего экрана или зависание, при котором замораживается вся система (либо сохраняется возможность перемещать по экрану курсор мыши, но система ни на что не реагирует).

(o) Причины Эти проблемы почти всегда являются следствием ошибки в драйвере устройства, но иногда могут быть результатом повреждения куста реестра, отличного от System.

(o) Решение Вы можете попытаться устранить такую проблему. Первое, что стоит попробовать, – последнюю удачную конфигурацию (last known good, LKG), о которой уже рассказывалось в этой главе и в разделе «Сервисы» главы 4. Она состоит из набора управления реестром (registry control set), с помощью которого в последний раз удалось успешно загрузить систему. Поскольку этот набор включает базовую системную конфигурацию и регистрационную базу данных драйверов устройств и сервисов, он не отражает самые последние изменения в составе драйверов устройств или сервисов, что часто помогает обойти источник проблемы. Для доступа к последней удачной конфигурации нажмите клавишу F8 на самой ранней стадии процесса загрузки и в появившемся загрузочном меню выберите этот вариант.


Как уже говорилось в этой главе, когда вы загружаете LKG, система сохраняет набор управления, от которого вы тем самым отказываетесь, и помечает его как неудачный. Если LKG позволит сделать систему загружаемой, вы сможете экспортировать содержимое текущего и неудачного наборов управления в .reg-файлы и, сравнив их, определить, что стало причиной неудачной загрузки системы. Для этого используйте поддержку экспорта в Regedit, доступную в меню FiIe (Файл) [или Registry (Реестр), если вы работаете с Windows 2000].

1. Запустите Regedit и выберите HKLM\System\CurrentControlSet.

2. Выберите Export (Экспорт) из меню FiIe (Файл) и сохраните содержимое в файл с именем good.reg.

3. Откройте HKLM\System\Select, посмотрите значение параметра Failed и выберите подраздел HKLM\System\ControlXXX, где XXX – значение параметра Failed.

4. Экспортируйте содержимое этого набора управления в файл bad.reg.

5. Используйте Wordpad для глобальной замены всех вхождений «CurrentControlSet» в good.reg на «ControlSet».

6. C помощью Wordpad замените все вхождения «ControlXXX» (вместо XXX должно быть значение параметра Failed) в bad.reg на «ControlSet».

7. Запустите Windiff из Support Tools и сравните два файла.


Различия между неудачным и удачным наборами управления могут быть весьма значительными, поэтому вы должны сосредоточиться на изменениях в подразделе Control, а также в подразделах Parameters каждого драйвера и сервиса, зарегистрированного в подразделе Services. Различия в подразделах Enum разделов для драйверов в ветви Services набора управления игнорируйте.

Если проблема вызвана драйвером или сервисом, который присутствовал в системе до последней успешной загрузки, LKG не сделает систему загружаемой. LKG не поможет и в том случае, если изменившийся проблематичный параметр конфигурации находится вне набора управления или если он был изменен до последней успешной загрузки. B таких случаях следующий шаг – попробовать загрузиться в безопасном режиме (о нем уже рассказывалось в этом разделе). Если система успешно загружается в безопасном режиме и вам известно, какой драйвер привел к провалу нормальной загрузки, вы можете отключить его через диспетчер устройств, доступный с вкладки Hardware (Оборудование) апплета System (Система). Для этого укажите проблемный драйвер и выберите Disable (Отключить) из меню Action (Действие). Если вы используете Windows XP или Windows Server 2003, недавно обновили драйвер и считаете, что в обновленной версии есть какая-то ошибка, то можете выбрать откат драйвера к его предыдущей версии, что также делается в диспетчере устройств. Чтобы восстановить предыдущую версию драйвера, дважды щелкните нужный драйвер для открытия его окна свойств и нажмите кнопку Roll Back Driver (Откатить) на вкладке Drivers (Драйвер).

B Windows XP при включенном System Restore предлагается вариант отката состояния всей системы к предыдущей точке (определенной средством System Restore), когда LKG ничего не дала. Безопасный режим распознает наличие точек восстановления и, если они есть, спрашивает, что вы хотите – войти в систему и вручную выполнить диагностику и исправление или запустить мастер восстановления системы. Попытка сделать систему загружаемой с помощью System Restore – хороший вариант, когда вы знаете причину проблемы и хотите автоматически ее устранить или когда причина вам не известна, но вы не желаете тратить время на ее поиск.

Если System Restore вас не устраивает или если вам нужно определить причину краха при нормальной загрузке, когда в безопасном режиме система успешно загружается, то попробуйте вести журнал в ходе неудачной загрузки. Для этого выберите соответствующий вариант в загрузочном меню, которое открывается нажатием клавиши F8 на самой ранней стадии загрузки. Какуже говорилось в этой главе, диспетчер сеансов (\Windows\System32\ Smss.exe) сохраняет журнал загрузки в \Windows\ntbtlog.txt; в нем отмечаются как загруженные, так и незагруженные системой драйверы устройств, поэтому вы получите такой журнал, только если крах или зависание происходит после инициализации диспетчера сеансов. После перезагрузки в безопасный режим система добавит в существующий журнал загрузки новые записи. Отделите части журнала, относящиеся к неудачной попытке загрузки и к загрузке в безопасный режим, и сохраните их в разных файлах. Удалите строки с текстом «Did not load driver», а затем сравните эти файлы с помощью утилиты наподобие Windiff. Поочередно отключайте драйверы, загружавшиеся при нормальной загрузке, но не в безопасном режиме, пока система вновь не будет загружаться в нормальном режиме. (После чего вновь включите драйверы, не связанные с проблемой.)

Если вам не удается получить журнал при нормальной загрузке (например, из-за того, что крах системы происходит до инициализации диспетчера сеансов), если система рушится и при загрузке в безопасном режиме или если при сравнении двух частей журнала не обнаруживается значимых различий, то остается лишь прибегнуть к утилите Driver Verifier в сочетании с анализом аварийного дампа. (Более подробные сведения по этой тематике см. в главе 14.)


Завершение работы системы

Если в систему кто-то вошел и некий процесс инициирует завершение работы системы, вызывая Windows-функцию ExitWindowsEx, Csrss получает сообщение о необходимости завершения системы. Тогда Csrss в интересах инициатора завершения системы посылает скрытому окну, которое принадлежит Winlogon, Windows-сообщение с требованием завершить работу системы. Winlogon, олицетворяющий зарегистрированного в данный момент пользователя (чей контекст защиты может совпадать, а может и не совпадать с контекстом защиты пользователя процесса, инициировавшего завершение работы), вызывает ExitWindowsEx с набором специальных внутренних флагов. B результате Csrss получает еще одно сообщение с запросом на завершение системы.

Ha этот раз Csrss видит, что запрос поступил от Winlogon, и перебирает все процессы в сеансе интерактивного пользователя (а не того, кто инициировал завершение системы). Вызвав SetProcessShutdownParameters, процесс может указать уровень завершения (shutdown level), который сообщает системе, когда этому процессу нужно завершиться по отношению к другим процессам. Допустимые уровни укладываются в диапазон 0-1023 (по умолчанию – 640). Explorer, например, устанавливает свой уровень в 2, a Task Manager – в 1.Для каждого процесса, владеющего окном верхнего уровня, Csrss посылает сообщения WM_QUERYENDSESSION всем его потокам с циклом выборки Windows-сообщений. Если поток возвращает TRUE, процесс завершения работы системы продолжается. Тогда Csrss посылает потоку сообщение WM_ENDSESSION с требованием завершить свою работу. Csrss ждет завершения потока в течение времени, указанного в HKCU\Control Panel\ Desktop\HungAppTimeout (по умолчанию – 5000 мс).

Если в течение указанного времени поток не завершается, Csrss открывает диалоговое окно, показанное на рис. 5-5. (Вывод этого окна можно отключить, присвоив параметру HKCU\Control Panel\Desktop\AutoEndTasks значение, равное 1.) Диалоговое окно уведомляет пользователя о том, что корректное завершение данной программы невозможно, и предлагает принудительно завершить процесс или отменить завершение работы системы (тайм-аут для этого диалогового окна не предусмотрен, а значит, на этом этапе запрос на завершение может ждать бесконечно долго).

Рис. 5-5. Диалоговое окно для принудительного закрытия программы

Если поток успевает завершиться до истечения указанного времени, Csrss посылает пары сообщений WM_QUERYENDSESSION, WM_ENDSESSION другим потокам процесса с окнами верхнего уровня. Как только все его потоки завершаются, Csrss завершает выполнение этого процесса и переходит к следующему процессу в интерактивном сеансе.


ЭКСПЕРИМЕНТ: проверка HungAppTimeout

Вы можете проверить, как используется параметр реестра HungAppTimeout, запустив Notepad, введя в него какой-нибудь текст и выйдя из системы. По истечении времени, заданного в HungAppTimeout, Csrss.exe откроет диалоговое окно с запросом о том, хотите ли вы закрыть процесс Notepad, который еще не завершился. Notepad ждет, когда вы сообщите ему, надо ли сохранить введенный вами текст. Если вы нажмете Cancel в этом диалоговом окне, Csrss.exe отменит завершение работы системы.

Обнаружив консольное приложение, Csrss вызывает обработчик консоли, посылая событие CTRLLOGOFFEVENT (при завершении работы системы только процессы сервисов получают события CTRL_SHUTDOWN_ EVENT). Если обработчик возвращает FALSE, Csrss уничтожает процесс. Если обработчик возвращает TRUE или не отвечает в течение времени, указанного в HKCU\Control Panel\Desktop\WaitToKillAppTimeout (по умолчанию – 20000 мс), Csrss выводит диалоговое окно, показанное на рис. 5-5.

Далее Winlogon вызывает функцию ExitWindowsEx, чтобы Csrss завершил любые СОМ-процессы, являющиеся частью сеанса интерактивного пользователя.

K этому моменту выполнение всех процессов в сеансе уже завершено. Winlogon снова вызывает функцию ExitWindowsEx, на этот раз в контексте системного процесса, и та посылает Csrss сообщение. Csrss просматривает все процессы, принадлежащие контексту системы и рассылает сообщения WM_QUERYENDSESSION/WM_ENDSESSION всем GUI-потокам. Ho консольным приложениям с зарегистрированными обработчиками Csrss посылает не CTRL_LOGOFF_EVENT, a CTRL_SHUTDOWN_EVENT. Заметьте, что SCM является консольной программой, которой регистрируется свой обработчик. Получив запрос на завершение, SCM рассылает соответствующие сообщения всем сервисам, которые зарегистрированы на уведомление о завершении работы. Подробнее о завершении работы сервисов (в том числе о таймауте для SCM) см. раздел «Сервисы» главы 4.

Хотя при завершении системных процессов действуют те же таймауты, что и для пользовательских процессов, Csrss не выводит никаких диалоговых окон и не завершает их принудительно. (Значения таймаутов завершения системных процессов берутся из профиля пользователя по умолчанию.) Смысл этих таймаутов только в том, чтобы системные процессы корректно завершились до выключения системы. Ho многие системные процессы вроде Smss, Winlogon, SCM и LSASS на самом деле еще выполняются при выключении системы.

Как только Csrss заканчивает рассылку уведомлений системным процессам о завершении работы, Winlogon вызывает функцию исполнительной системы NtShutdownSystem. Она в свою очередь вызывает функцию NtSet-SystemPowerState, управляющую завершением драйверов и остальных компонентов исполнительной системы (диспетчеров Plug and Play, электропитания, ввода-вывода, конфигурации и памяти).

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


Резюме

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