« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
    Популярное
Свод событий ADO.NET

Сохранение запроса

Обзор ASP

ГОСТ 19.101-77 Единая система программной документации

Программируем под IIS на Visual C++

SSI в примерах

XML в Oracle - это очень просто

Глава 19. Печать и предварительный просмотр документов

Пять заблуждений связанных с .NET

Функция AccessResource




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 186
Пользователей: 0

Статьи:: Системы защиты :: Общая архитектура Windows NT :: Реализация уровневых драйверов



отправить ссылку другу версия для печати  Обсудить на форуме

Реализация уровневых драйверов

Стек драйверов обычно создается самими драйверами. Корректное создание стека зависит от правильной последовательности и момента загрузки каждого драйвера из стека. Первыми должны грузиться драйвера самого нижнего уровня и т.д.
При рассмотрении организации стека драйверов необходимо понимание трех моментов:

  • объединение драйверов в стек;
  • обработка запросов IRP стеком;
  • освобождение драйверов стека.


Объединение драйверов в стек

Для объединения драйверов в стек обычно используется функция loGetDeviceObject Pointer(). Функция вызывается драйвером вышележащего уровня для получения указателя на объект-устройство драйвера нижележащего уровня по его имени.
Функция имеет следующий прототип:

NTSTATUS loGetDeviceObjectPointer(
IN PUNICODE_STRING ObjectName,
IN ACCESS_MASK DesiredAccess,
OUT PFILE_OBJECT FileObject,
OUT PDEVICE_OBJECT DeviceObjct);

Где:
ObjectName - Имя требуемого Объекта-устройства;
DesiredAccess - Требуемый доступ к указанному Объекту-устройству;
FileObject - Указатель на Объект-файл, который будет использоваться для обращения к устройству;
DeviceObject - Указатель на Объект-устройство с именем ObjectName.
Функция IoGetDeviceObjectPointer() принимает имя Объекта-устройства, и возвращает указатель на Объект-устройство с этим именем. Функция работает, посылая запрос CREATE на названное устройство. Этот запрос будет неудачным, если никакого устройства по имени ObjectName не существует, или вызывающая программа не может предоставить доступ, указанный в параметре DesiredAccess. Если запрос CREATE успешен, создается Объект-файл, что увеличивает счетчик ссылок Объекта-устройства, с которым связан Объект-файл. Затем Диспетчер ввода/вывода искусственно увеличивает счетчик ссылок на Объект-файл на единицу, и посылает на устройство запрос CLOSE. В результате всего этого процесса, Объект-устройство (чей указатель возвращен в DeviceObject) не может быть удален, пока не обнулится счетчик ссылок соответствующего ему Объекта-файла. Таким образом, Объект-устройство нижнего уровня не может быть удален, в то время как драйвер вышележащего уровня имеет указатель на него.
Выделим из всего вышесказанного, что функция предусматривает в качестве выходного параметра указатель на Объект-файл специально для того, чтобы при выгрузке стека драйверов освободить устройство нижележащего уровня. Это должно быть сделано в функции Unload драйвера вышележащего уровня с помощью вызова функции ObDereferenceObject ( FileObject).
После получения указателя на объект-устройство драйвера нижележащего уровня, драйвер вышележащего уровня должен установить корректное значение полей Characteristics, StackSize, Flags и AlignmentRequirement своего объекта-устройства. Поля Characteristics, Flags и AlignmentRequirement объектов-устройств всех драйверов в стеке должны совпадать, а значение поля StackSize вышележащего устройства должно быть на 1 больше значения этого поля у нижележащего устройства.

Обработка запросов IRP стеком драйверов

Запрос ввода/вывода приходит в виде пакета IRP самому верхнему драйверу в стеке драйверов (драйверу верхнего уровня). При этом возможны следующие варианты обработки IRP:

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

Все варианты, кроме последнего, возможны при обработке пакета IRP драйвером любого уровня. Последний вариант - создание ассоциированных пакетов IRP - возможен только при обработке IRP драйвером верхнего уровня.
Самостоятельная обработка IRP драйвером. Если драйвер может завершить обработку пакетаIRP самостоятельно, он так и должен сделать. При этом обработка может быть завершена либо сразу при поступлении запроса ввода/вывода, либо после постановки запроса ввода/вывода в очередь.
Примером немедленного завершения обработки пакета IRP драйвером может служить случай обнаружения некорректного параметра в IRP.
Передача первоначального пакета IRP драйверу нижележащего уровня. Если драйвер не может самостоятельно обработать пакет IRP, он может передать его нижележащему драйверу. Для этого необходимо заполнить параметры в IRP в стеке размещения ввода/вывода, относящегося к нижележащему драйверу. Указатель на стек размещения ввода/вывода нижележащего драйвера возвращается функцией loGetNext IrpStackLocation(). После заполнения необходимых параметров IRP передается драйверу нижележащего уровня с помощью вызова функции IoCallDriver(). Прототип этой функции:

NTSTATUS loCallDriver (IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp) ;

Где:
DeviceObject - указатель на объект-устройство, принадлежащий драйверу нижележащего уровня в стеке драйверов, которому должен быть послан запрос;
IRP - указатель на IRP, который будет послан драйверу нижележащего уровня.
При вызове функции IoCallDriver() Диспетчер ввода/вывода напрямую вызывает соответствующую диспетчерскую функцию требуемого драйвера. Это означает, что loCallDriver() завершится только после завершения соответствующей диспетчерской функции.
Создание новых пакетов IRP для передачи драйверу нижележащего уровня. Вариантом передачиIRP драйверу нижележащего уровня является создание одного или нескольких новых пакетов IRP и передача этихIRP драйверу нижележащего уровня. Пакет IRP может быть создан драйвером различными способами, наиболее общим из которых является вызов функции IoAllocateIrp().

PIRP loAllocatelrp (IN CCHAR StackSize, IN BOOLEAN ChargeQuota);

Где: StackSize - Число Стеков размещения Ввода/вывода, требуемых в IRP;
ChargeQuota - Указывает, должна ли квота текущего процесса быть загружена.
Функция loAllocatelrp() возвращает частично инициализированный пакет IRP. По умолчанию, loAllocatelrp() предполагает, что вызванный драйвер не хочет иметь собственный Стек размещения Ввода/вывода. Драйвер, распределяющий IRP, может факультативно просить loAllocatelrp() создать IRP с достаточным количеством Стеков Размещения Ввода/вывода, которые он мог иметь один. В этом случае, драйвер должен вызвать IoSetNextIrpStackLocation() (макрокоманда в NTDDK.H), чтобы установить Стек Размещения. Драйвер может затем вызвать функцию loGetCurrentlrpStack Location().
Причина, по которой драйверу может потребоваться свой собственный Стек Размещения Ввода /вывода состоит в том, что драйвер может использовать стек для передачи информации к подпрограмме завершения. Подпрограмма Завершения (Completion Routine) обсуждается позже в этом разделе.
Как только IRP создан, драйвер может вызывать IoGetNextIrpStackLocation(), чтобы получить указатель на Стек размещения для драйвера нижележащего уровня в стеке драйверов. Затем драйвер заполняет параметры для Стека Ввода/вывода. Если для запроса требуется буфер данных, драйвер должен или установить MDL или SystemBuffer, как того требует используемый нижележащим драйвером способ передачи буферов в пакете IRP. IRP посылается нижележащему драйверу с помощью функции IoCallDriver(), как описано выше.
Создание новых ассоциированных пакетов IRP для передачи драйверу нижележащего уровня. Немного другой подход к созданию нового пакета IRP для передачи драйверу нижележащего уровня состоит в создании ассоциированного пакета IRP с помощью функции loMsakeAssociatedlrp()

PIRP loMakeAssociatedlrp (IN PIRP Masterlrp, IN CCHAR StackSize);

Где: StackSize - Число Стеков размещения Ввода/вывода, требуемых в IRP;
Masterlrp - Указатель на IRP, с которым должен быть связан создаваемый пакет IRP.
loMakeAssociatedlrp() позволяет создавать IRP, которые "связаны» с некоторым "главным" IRP. Драйвер, который вызывает loMakeAssociatedlrp()» должен вручную инициализировать поле Irp.IrpCount главного IRP счетчиком ассоциированных с ним IRP, которые созданы до вызова loMakeAssociatedlrp. Ассоциированные IRP являются особым видом пакетовIRP, при завершении которых значение поля IrpCount в главном IRP уменьшается. Когда значение поля IrpCount в главномIRP становится равным нулю, Диспетчер ввода/вывода автоматически завершает главныйIRP.
Ассоциированные пакеты IRP могут создаваться только драйвером высшего уровня. Драйвер высшего уровня, использующий ассоциированные пакеты IRP, может вернуть управление диспетчеру ввода/вывода после вызова IoCallDriver() для каждого из ассоциированных IRP и вызова IoMarklrpPending() для главного IRP. Если такой драйвер устанавливает процедуру завершения для созданного им ассоциированного IRP (с помощью вызова loSetCompletion Routine(), описанного ниже), Диспетчер ввода/вывода не завершит автоматически главный IRP. В этом случае процедура завершения должна напрямую завершить главный IRP посредством вызова IoCompleteRequest().

Получение драйвером вышележащего уровня уведомления о завершении обработки IRP драйвером нижележащего уровня

В некоторых случаях драйвер вышележащего уровня может захотеть получить уведомление о завершении обработки переданного им запроса ввода/вывода драйвером нижележащего уровня(CompletionNotification). Это может быть сделано с помощью вызова функции IoSetCompletionRoutine() перед передачей пакета IRP драйверу нижележащего уровня любым указанным выше способом.

VOID loSetCompletionRoutine(IN PIRP Irp,
IN PIO_COMPLETION_ROUTINE CompletionRoutine,
INPVOID Context,
IN BOOLEAN InvokeOnSuccess,
IN BOOLEAN InvokeOnError,
IN BOOLEAN InvokeOnCahcel);

Где: Irp - Указатель на IRP, при завершении которого вызывается точка входа CompletionRoutine;
CompletionRoutine - Указатель на точку входа драйвера, вызываемую при завершении IRP;
Context - определенное драйвером значение, которое нужно передать как третий параметр для точки входа CompletionRoutine;
InvokeOnSuccess, InvokeOnError, IwokeOnCancel - Параметры, которые, указывают должна ли точка входа CompletionRoutine быть вызвана при завершении IRP с указанным состоянием.
В качестве второго параметра в вызове loSetCompletionRoutine() передается адрес точки входа драйвера, которая должна быть вызвана при завершении указанного в первом параметре пакета IRP. Прототип функции - точки входа драйвера:

NTSTATUS CompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context) ;

Где: DeviceObject — Указатель на объект-устройство, которому предназначался закончившийся пакетIRP;
IRP - Указатель на закончившийся пакет IRP;
Context - Определенное драйвером значение контекста, переданное, когда была вызвана функция IoSetCompletionRoutine().
При вызове IoSetCompletionRoutine() указатель на функцию завершения сохраняется вIRP в следующем после текущего Стеке Размещения ввода/вывода (то есть в
Стеке Размещения ввода/вывода нижележащего драйвера). Из этого следуют два важных вывода:

  • Если драйвер установит функцию завершения для некоторого IRP и завершит этот IRP, функция завершения не будет вызвана.
  • Драйвер низшего уровня (либо монолитный драйвер) не может устанавливать функции завершения, так как, во-первых, это бессмысленно (см. предыдущий вывод), а во-вторых, это ошибка, так как следующего (за текущим) стека размещения ввода/вывода для таких драйверов не существует.

Функция завершения вызывается при том же уровне IRQL, при котором нижележащим драйвером была вызвана функция завершения обработки IRP - loComplete Request(). Это может быть любой уровень IRQL меньший либо равный IRQL_ DISPATCH_LEVEL.
Если драйвер вышележащего уровня создавал новые пакеты IRP для передачи драйверу нижележащего уровня, он обязан использовать функцию завершения для этих IRP, причем параметры InvokeOnSuccess, InvokeOnError, IwokeOnCancel должны быть установлены в TRUE. В этих случаях функция завершения должна освободить созданные драйвером IRP с помощью функции IoFreeIrp() и завершить первоначальный пакет IRP.
Требования к реализации функции завершения достаточно сложные. Эти требования можно найти в [Developing Windows NT Device Drivers, pages 481-485].








Вышел MySQL 5.1.30, первый стабильный рели....

MySQL

После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

Тестирование параллельных программ.

Тестирование

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


Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

Архитектура AMD64 (EM64T).

Архитектура AMD

Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

Остальные статьи:

Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия