приложений работает в пользовательском режиме, тогда как код операционной системы (например, системные сервисы и драйверы устройств) - в режиме ядра. B режиме ядра предоставляется доступ ко всей системной памяти и разрешается выполнять любые машинные команды процессора. Предоставляя операционной системе более высокий уровень привилегий, чем прикладным программам, процессор позволяет разработчикам операционных систем реализовать такие архитектуры, которые не дают возможности сбойным приложениям нарушать стабильность работы всей системы.
 
    ПРИМЕЧАНИЕ B архитектуре процессора Intel x86 определено четыре уровня привилегий, или колец (rings), предназначенных для защиты кода и данных системы от случайной или умышленной перезаписи кодом с меньшим уровнем привилегий. Windows использует уровень привилегий 0 (или кольцо 0) для режима ядра и уровень привилегий 3 (или кольцо 3) для пользовательского режима. Почему Windows использует только два уровня? Дело в том, что на некоторых из ранее поддерживавшихся аппаратных платформ (например, Compaq Alpha и Silicon Graphics MIPS) реализовано лишь два уровня привилегий.
 
   Хотя каждый Windows-процесс имеет свою (закрытую) память, код операционной системы и драйверы устройств, работающие в режиме ядра, делят единое виртуальное адресное пространство. Каждая страница в виртуальной памяти помечается тэгом, определяющим, в каком режиме должен работать процессор для чтения и/или записи данной страницы. Страницы в системном пространстве доступны лишь в режиме ядра, а все страницы в пользовательском адресном пространстве - в пользовательском режиме. Страницы только для чтения (например, содержащие лишь исполняемый код) ни в каком режиме для записи недоступны.
   Windows не предусматривает никакой защиты системной памяти от компонентов, работающих в режиме ядра. Иначе говоря, код операционной системы и драйверов устройств в режиме ядра получает полный доступ к системной памяти и может обходить средства защиты Windows для обращения к любым объектам. Поскольку основная часть кода Windows выполняется в режиме ядра, крайне важно, чтобы компоненты, работающие в этом режиме, были тщательно продуманы и протестированы.
   Это также подчеркивает, насколько надо быть осторожным при загрузке драйвера устройства от стороннего поставщика: перейдя в режим ядра, он получит полный доступ ко всем данным операционной системы. Такая уязвимость стала одной из причин, по которым в Windows введен механизм проверки цифровых подписей драйверов, предупреждающий пользователя о попытке установки неавторизованного (неподписанного) драйвера (подробнее на эту тему см. главу 9). Кроме того, механизм Driver Verifier (верификатор драйверов) помогает разработчикам драйверов устройств находить в них ошибки (вызывающие, например, утечку памяти или переполнения буферов). Driver Verifier поясняется в главе 7.
 
   Как вы увидите в главе 2, прикладные программы могут переключаться из пользовательского режима в режим ядра, обращаясь к системному сервису. Например, Windows-функции ReadFileв ходе своего выполнения приходится вызывать внутреннюю подпрограмму Windows - она-то и считывает данные из файла. Так как эта подпрограмма обращается к внутрисистемным структурам данных, она должна выполняться в режиме ядра. Переключение из пользовательского режима в режим ядра осуществляется специальной командой процессора. Операционная система перехватывает эту команду, обнаруживает запрос системного сервиса, проверяет аргументы, которые поток передал системной функции, и выполняет внутреннюю подпрограмму. Перед возвратом управления пользовательскому потоку процессор переключается обратно в пользовательский режим. Благодаря этому операционная система защищает себя и свои данные от возможной модификации пользовательскими процессами.
 
    ПРИМЕЧАНИЕ Переключение из пользовательского режима в режим ядра (и обратно) не влияет на планирование потока, так как контекст в этом случае не переключается. O диспетчеризации системных сервисов см. главу 3.
 
   Так что ситуация, когда пользовательский поток часть своего времени работает в пользовательском режиме, а часть - в режиме ядра, совершенно нормальна. A поскольку подсистема, отвечающая за поддержку графики и окон, функционирует в режиме ядра, то приложения, интенсивно работающие с графикой, большую часть времени действуют в режиме ядра, а не в пользовательском режиме. Самый простой способ проверить это - запустить приложение вроде Microsoft Paint или Microsoft Pinball и с помощью одного из счетчиков оснастки Performance (Производительность), перечисленных в таблице 1-2, понаблюдать за показателями времени работы в пользовательском режиме и в режиме ядра.
 
    ЭКСПЕРИМЕНТ: наблюдение за активностью потоков с помощью QuickSlice
   QuickSlice позволяет в динамике наблюдать за соотношением времени, проведенного каждым процессом в режиме ядра и в пользовательском режиме. Ha диаграмме красная часть столбца отражает количество процессорного времени в режиме ядра, а синяя - в пользовательском режиме. (Хотя в книге эти столбцы воспроизведены в черно-белом цвете, на самом деле они всегда красные и синие.) Сумма всех показателей, отображаемых столбцами в окне QuickSlice, должна соответствовать 100% процессорного времени. Для запуска QuickSlice щелкните кнопку Start (Пуск), выберите команду Run (Выполнить) и введите Qslice.exe(в переменной PATH должен быть указан путь к ресурсам Windows). Например, попробуйте запустить такое интенсивно использующее графику приложение, как Paint (Mspaint.exe). Откройте QuickSlice, расположив его окно рядом с окном Paint, и нарисуйте в Paint несколько кривых. B это время вы сможете наблюдать за выполнением Mspaint.exe в окне QuickSlice, как показано ниже.
   Чтобы получить дополнительную информацию о потоках процесса, дважды щелкните имя нужного процесса или соответствующий цветной столбик на диаграмме. Вы увидите список потоков этого процесса и относительное процессорное время, используемое каждым потоком (в рамках процесса, а не всей системы).
 
    ЭКСПЕРИМЕНТ: режим ядра и пользовательский режим
   C помощью оснастки Performance вы можете выяснить, сколько времени ваша система работает в режиме ядра и в пользовательском режиме.
   1. Запустите оснастку Performance (Производительность), открыв меню Start (Пуск) и последовательно выбрав команды Programs (Программы), Administrative Tools (Администрирование), Performance (Производительность).
   2. Щелкните на панели инструментов кнопку Add (Добавить) (на этой кнопке изображен большой знак плюс).
   3. Выберите в списке объект Processor (Процессор), щелкните счетчик % Privileged Time (% работы в привилегированном режиме) и, удерживая клавишу Ctrl в нажатом состоянии, щелкните счетчик % User Time (% работы в пользовательском режиме).
   4. Щелкните кнопку Add (Добавить), а затем Close (Закрыть).
   5. Быстро подвигайте мышью. При этом вы должны заметить всплеск на линии % Privileged Time (рис. 1-6), который отражает время, затраченное на обслуживание прерываний от мыши, и время, понадобившееся подсистеме поддержки окон на отрисовку графики (эта подсистема, как поясняется в главе 2, работает преимущественно как драйвер устройства в режиме ядра).
   6. Закончив, щелкните на панели инструментов кнопку New Counter Set (Новый набор счетчиков) (или просто закройте оснастку).
 
   За той же активностью можно понаблюдать через Task Manager (Диспетчер задач). Просто перейдите в нем на вкладку Performance (Быстродействие), а затем выберите из меню View (Вид) команду Show Kernel Times (Вывод времени ядра). Процент загруженности процессора отражается зеленым цветом, а процент времени работы в режиме ядра - красным.
   Чтобы увидеть, как сама оснастка Performance использует время в двух режимах, запустите ее снова, но добавьте те же счетчики для объекта Process (Процесс).
   1. Если вы закрыли оснастку Performance, снова запустите ее. (Если она уже работает, откройте новый экран, щелкнув на панели инструментов кнопку New Counter Set.)
   2. Щелкните кнопку Add на панели инструментов.
   3. Выберите в списке объект Process.
   4. Выберите счетчики % Privileged Time и % User Time.
   5. B списке экземпляров объекта выберите все процессы (кроме процесса _Total).
   6. Щелкните кнопку Add, а затем Close.
   7. Быстро подвигайте мышью.
   8. Нажмите комбинацию клавиш Ctrl+H для активизации режима выделения - текущий выбранный счетчик будет выделен белым цветом в Windows 2000 и черным в Windows XP или Windows Server 2003.
   9. Прокрутите список всех счетчиков в нижней части окна оснастки, чтобы определить процессы, потоки которых выполнялись при перемещении мыши, и обратите внимание на то, в каком режиме они выполнялись - пользовательском или ядра.
 
   Вы должны заметить, как значения счетчиков для процесса оснастки Performance - ищите mmc в колонке Instance (Экземпляр) - резко увеличиваются при перемещении мыши, поскольку код приложения выполняется в пользовательском режиме, а вызываемые им Windows-функции - в режиме ядра. Вы также заметите, что при перемещении мыши увеличивается активность работы в режиме ядра потока процесса csrss. Он представляет поток необработанного ввода (raw input thread) подсистемы Windows, принимающий ввод от клавиатуры и мыши и передающий его процессу, к которому он подключен. (Подробнее о системных потоках см. главу 2.) Наконец, процесс с именем Idle, потоки которого, как вы убедитесь, тратят почти 100% своего времени в режиме ядра, на самом деле не является процессом. Это лжепроцесс, используемый для учета тактов процессора в состоянии простоя. Таким образом, когда Windows нечего делать, она предается этому занятию в режиме ядра.
 
Terminal Services и несколько сеансов
 
   Terminal Services (службы терминала) обеспечивают в Windows поддержку нескольких интерактивных сеансов пользователей на одной системе. C помощью Terminal Services удаленный пользователь может установить сеанс на другой машине, зарегистрироваться на ней и запускать приложения на сервере. Сервер предоставляет клиенту графический пользовательский интерфейс (GUI), а клиент возвращает серверу пользовательский ввод. (Это отличается от того, как ведет себя X Windows на UNIX-системах, где разрешается выполнять индивидуальные приложения на сервере, а клиенту предоставляется удаленный дисплей, так как удаленным является весь сеанс пользователя - не только одно приложение.)
   Первый сеанс входа на физической консоли компьютера считается консольным сеансом, или нулевым сеансом (session zero). Дополнительные сеансы можно создать с помощью программы соединения с удаленным рабочим столом (Mstsc.exe), а в Windows XP - через механизм быстрого переключения пользователей (об этом позже).
   Возможность создания удаленного сеанса поддерживается Windows 2000 Server, но не Windows 2000 Professional. Windows XP Professional позволяет одному удаленному пользователю подключаться к машине, однако если кто-то начинает процедуру входа в консоли, рабочая станция блокируется (т. е. систему можно использовать либо локально, либо удаленно, но не и то, и другое одновременно).
   Windows 2000 Server и Windows Server 2003 поддерживают два одновременных удаленных сеанса. (Это упрощает удаленное управление, например облегчает применение инструментов, требующих от администратора входа на удаленный компьютер.) Windows 2000 Advanced Server, Datacenter Server и все издания Windows Server 2003 способны поддерживать более двух сеансов одновременно при условии правильного лицензирования и настройки системы в качестве сервера терминала.
   Хотя Windows XP Home и Professional не поддерживают несколько удаленных подключений к рабочему столу, они все же поддерживают несколько сеансов, созданных локально через механизм быстрого переключения пользователей. (Этот механизм отключается в Windows XP Professional, если система присоединяется к домену.) Когда пользователь выбирает выключение своего сеанса вместо выхода [например, последовательным выбором Start (Пуск), Log Off (Выход из системы) и Switch User (Смена пользователя) или нажатием клавиши L при одновременном удерживании клавиши Windows], текущий сеанс (т. е. процессы, выполняемые в этом сеансе, и все структуры данных, глобальные для сеанса и описывающие его) остается в системе, а Windows возвращается к основному окну входа. Если в систему входит новый пользователь, создается новый сеанс.
   Для приложений, которым нужно знать, выполняются ли они в сеансе сервера терминала, предназначен набор Windows API-функций, позволяющих программно распознавать такую ситуацию и контролировать различные аспекты служб терминала. (Детали см. в Platform SDK.)
   B главе 2 кратко описывается, как создаются сеансы, и проводится несколько экспериментов, показывающих, как просматривать информацию о сеансе с помощью различных инструментов, включая отладчик ядра. B разделе «Диспетчер объектов» главы 3 поясняется, как создается сеансовый экземпляр системного пространства имен для объектов и как приложения могут узнавать о других своих экземплярах в той же системе. Наконец, в главе 7 рассказывается, как диспетчер памяти настраивает данные, глобальные для сеанса, и управляет ими.
 
Объекты и описатели
 
   B операционной системе Windows объект -это единственный экземпляр периода выполнения (run-time instance) статически определенного типа объекта. Тип объектасостоит из общесистемного типа данных, функций, оперирующих экземплярами этого типа данных, и набора атрибутов. Если вы пишете Windows-приложения, вам наверняка знакомы такие объекты, как процесс, поток, файл и событие, - продолжать можно еще долго. Эти объекты базируются на объектах более низкого уровня, создаваемых и управляемых Windows. B Windows процесс является экземпляром объекта типа «процесс», файл - экземпляром объекта типа «файл» и т. д.
    Атрибут объекта(object attribute) - это поле данных в объекте, частично определяющее состояние этого объекта. Например, объект типа «процесс», имеет атрибуты, в число которых входят идентификатор процесса, базовый приоритет и указатель на объект маркера доступа. Методы объекта (средства для манипулирования объектами) обычно считывают или изменяют какие-либо атрибуты. Так, метод openпроцесса мог бы принимать идентификатор процесса и возвращать указатель на этот объект.
 
    ПРИМЕЧАНИЕ He путайте параметр ObjectAttributes, предоставляемый вызывающей программой при создании объекта через Windows API или его родные сервисы, с термином «атрибуты объекта», имеющим более общий смысл.
 
   Самое главное различие между объектом и обычной структурой данных заключается в том, что внутренняя структура объекта скрыта. Чтобы получить данные из объекта или записать в него какую-то информацию, вы долж-
   ны вызвать его сервис. Прямое чтение или изменение данных внутри объекта невозможно. Тем самым реализация объекта отделяется от кода, который просто использует его, а это позволяет менять реализацию объекта, не модифицируя остальной код.
   Объекты очень удобны для поддержки четырех важных функций операционной системы:
    (o)присвоения понятных имен системным ресурсам;
    (o)разделения ресурсов и данных между процессами;
    (o)защиты ресурсов от несанкционированного доступа;
    (o)учета ссылок (благодаря этому система узнает, когда объект больше не используется, и автоматически уничтожает его).
   He все структуры данных в Windows являются объектами. B объекты помещаются лишь те данные, которые нужно разделять, защищать, именовать или делать доступными программам пользовательского режима (через системные сервисы). Структуры, используемые только одним из компонентов операционной системы для поддержки каких-то внутренних функций, к объектам не относятся. Подробнее объекты и их описатели (ссылки на экземпляр объекта) рассматриваются в главе 3.
 
Безопасность
 
   Windows с самого начала разрабатывалась как защищенная система, удовлетворяющая требованиям различных правительственных и промышленных стандартов безопасности, например спецификации Common Criteria for Information Technology Security Evaluation (CCITSE). Подтверждение правительством рейтинга безопасности операционной системы позволяет ей конкурировать в сферах, требующих повышенной защиты. Разумеется, многим из этих требований должна удовлетворять любая многопользовательская система.
   Базовые возможности защиты в Windows таковы: избирательная защита любых разделяемых системных объектов (файлов, каталогов, процессов, потоков и т. д.), аудит безопасности (для учета пользователей и инициируемых ими операций), аутентификация паролей при входе и предотвращение доступа одного из пользователей к неинициализированным ресурсам (например, к памяти или дисковому пространству), освобожденным другим пользователем.
 
   Windows поддерживает два вида контроля доступа к объектам. Первый из них - управление избирательным доступом(discretionary access control) - является механизмом, который как раз и связывается большинством пользователей с защитой. Это метод, при котором владельцы объектов (например, файлов или принтеров) разрешают или запрещают доступ к ним для других пользователей. При входе пользователь получает набор удостоверений защиты (security credentials), или контекст защиты (security context). Когда он пытается обратиться к объекту, его контекст защиты сверяется со списком управления доступом (access control list, ACL) для данного объекта, чтобы определить, имеет ли он разрешение на выполнение запрошенной операции.
   Второй метод -управление привилегированным доступомQ3riv1leged access control) - необходим в тех случаях, когда управления избирательным доступом недостаточно. Данный метод гарантирует, что пользователь сможет обратиться к защищенным объектам, даже если их владелец недоступен. Например, если какой-то сотрудник увольняется из компании, администратору нужно получить доступ к файлам, которые могли быть доступны только бывшему сотруднику. B таких случаях Windows позволяет администратору стать владельцем этих файлов и при необходимости управлять правами доступа к ним.
   Защита пронизывает весь интерфейс Windows APL Подсистема Windows реализует защиту на основе объектов точно так же, как и сама операционная система. При первой попытке доступа приложения к общему (разделяемому) объекту подсистема Windows проверяет, имеет ли это приложение соответствующие права. Если проверка завершается успешно, подсистема Windows разрешает приложению доступ.
   Подсистема Windows реализует защиту для общих объектов, часть из которых построена на основе родных объектов Windows. K Windows-объектам относятся объекты рабочего стола, меню, окна, файлы, процессы, потоки и ряд синхронизирующих объектов.
   Детальное описание защиты в Windows см. в главе 8.
 
Реестр
 
   Если вы работали хоть с какой-нибудь операционной системой Windows, то, вероятно, слышали о реестре или даже просматривали его. Рассказать о внутреннем устройстве Windows, не упоминая реестр, вряд ли возможно, так как это системная база данных с информацией, необходимой для загрузки и конфигурирования системы; в ней содержатся общесистемные параметры, контролирующие работу Windows, база данных защиты и конфигурационные настройки, индивидуальные для каждого пользователя.
   Кроме того, реестр - это окно, через которое можно заглянуть в переменные системные данные, чтобы, например, выяснить текущее состояние аппаратной части системы (какие драйверы устройств загружены, какие ресурсы они используют и т. д.) или значения счетчиков производительности Windows. Счетчики производительности, которые на самом деле в реестре не хранятся, доступны через функции реестра (см. главу 4).
   Хотя у многих пользователей и администраторов Windows никогда не возникает необходимости работать непосредственно с реестром (большую часть параметров можно просматривать или модифицировать с помощью стандартных административных утилит), он все же является источником полезной информации о внутренних структурах данных Windows, так как содержит множество параметров, влияющих на быстродействие и поведение системы. (Будьте крайне осторожны, напрямую изменяя параметры реестра: любые изменения могут отрицательно сказаться на быстродействии или, что гораздо хуже, привести к краху системы.)
   Ссылки на различные разделы реестра, относящиеся к описываемым компонентам, будут встречаться на протяжении всей книги. Большинство таких разделов находится в ветви HKEY_LOCAL_MACHINE, которую мы сокращенно называем HKLM. Подробнее о реестре и его внутренней структуре см. главу 4.
 
Unicode
 
   Windows отличается от большинства других операционных систем тем, что в качестве внутреннего формата для хранения и обработки текстовых строк использует Unicode. Unicode - это стандартная кодировка, которая поддерживает многие известные в мире наборы символов и в которой каждый символ представляется 16-битным (двухбайтовым) кодом. (Подробнее о Unicode см. www.unicode.org и документацию на компакт-дисках MSDN Library.)
   Поскольку многие приложения имеют дело с 8-битными (однобайтовыми) ANSI-символами, Windows-функции, принимающие строковые параметры, существуют в двух версиях: для Unicode и для ANSI. B Windows 95, Windows 98 и Windows ME реализована лишь часть Unicode-версий Windows-функций, поэтому приложения, рассчитанные на выполнение как в одной из этих операционных систем, так и в NT-подобных Windows, обычно используют ANSI-версии функций. Если вы вызываете ANSI-версию Windows-функции, входные строковые параметры перед обработкой системой преобразуются в Unicode, а выходные - из Unicode в ANSI (перед возвратом приложению). Таким образом при использовании в Windows устаревшего сервиса или фрагмента кода, написанного в расчете на ANSI-строки, эта операционная система будет вынуждена преобразовывать ANSI-символы в Unicode. Однако Windows никогда не преобразует данные внутри файлов - решения о том, в какой кодировке хранить текстовую информацию в файлах, принимают лишь сами приложения.
 
   B предыдущих версиях Windows ее азиатский и ближневосточный выпуски представляли собой надмножество базовых американского и европейского выпусков, в которые включались дополнительные Windows-функции для обработки более сложных раскладок клавиатур и принципов ввода текста (например, набора текста справа налево). Начиная с Windows 2000, все языковые выпуски содержат одинаковые Windows-функции. Единая для всех стран двоичная кодовая база Windows способна поддерживать множество языков за счет простого добавления нужных компонентов языковой поддержки. Используя эти Windows-функции, разработчики могут создавать универсальные приложения, способные работать со множеством языков.
 
Изучение внутреннего устройства Windows
 
   Хотя большая часть информации, представленная в этой книге, получена при чтении исходного кода Windows и общении с разработчиками, вы не обязаны принимать все на веру. Многие детали внутреннего устройства Windows можно вытащить на свет с помощью самых разнообразных средств, в том числе поставляемых с Windows, входящих в Windows Support Tools и ресурсы Windows, а также с использованием отладочных средств самой Windows. Чуть позже мы вкратце рассмотрим эти пакеты инструментальных средств.
   Чтобы упростить вам исследование внутреннего устройства Windows, мы часто даем в книге врезки «Эксперимент» с пошаговыми инструкциями для изучения какого-либо аспекта поведения Windows. (Вы уже видели такие врезки в этой главе.) Советуем проводить эти эксперименты - это позволит увидеть в действии многие вещи, о которых рассказывается в книге.
   B таблице 1-3 перечислены все используемые нами инструменты и утилиты.
    Таблица 1-3. Средства просмотра внутренней информации Windows
 
Оснастка Performance
 
   Мы часто ссылаемся на этот инструмент, доступный через папку Administrative Tools (Администрирование) в меню Start (Пуск) или через Control Panel (Панель управления). Оснастка Performance (Производительность) предназначена для мониторинга системы, просмотра журналов, в которых регистрируются значения счетчиков производительности, и оповещения при достижении заданных пороговых значений тех или иных счетчиков. Говоря об оснастке Performance, мы подразумеваем лишь ее функцию системного мониторинга.
   Оснастка Performance способна сообщить о том, как работает система, гораздо больше, чем любая другая, отдельно взятая утилита. Она предусматривает сотни счетчиков для различных объектов. По каждому счетчику можно получить краткое описание. Чтобы увидеть описание, выберите счетчик в окне Add Counters (Добавить счетчики) и щелкните кнопку Explain (Объяснение). Или откройте справочный файл Performance Counter Reference с компакт-диска «Ресурсы Windows». Информацию о том, как интерпретировать показания счетчиков для устранения «узких мест» в системе или для планирования пропускной способности сервера, см. раздел «Performance Monitoring» в книге «Windows 2000 Server Operations Guide» из набора Windows 2000 Server Resource Kit. Для Windows XP и Windows Server 2003 см. документацию Performance Counters Reference в Windows Server 2003 Resource Kit.
   Заметьте, что все счетчики производительности Windows доступны программным путем. Краткое описание соответствующих компонентов см. в разделе «HKEY_PERFORMANCE_DATA» главы 4.
 
Windows Support Tools
 
   Windows Support Tools включают около 40 утилит, полезных в администрировании систем на базе Windows и устранении неполадок в них. Многие из этих утилит раньше были частью ресурсов Windows NT 4.
   Вы можете установить Support Tools, запустив Setup.exe из папки \Support\ Tools в дистрибутиве любого издания Windows. Support Tools одинаковы в Windows 2000 Professional, Server, Advanced Server и Datacenter Server, a для Windows XP, равно как и для Windows Server 2003, существует своя версия Support Tools.