Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
192
Добавлен:
20.02.2016
Размер:
86.02 Кб
Скачать

Лабораторная работа №4 Цель работы

Реализация драйвера-фильтра и управляющей программы.

Создание драйвера будет заключаться в модификации драйвера №3 (simple3) из л/р №1 и драйвера №5 (devioctl) из л/р №3 на основании информации, изложенной в лекции №9.

Создание прикладной программы будет заключаться в модификации диалоговой прикладной программы управления драйверами из л/р №2.

Драйвер №6

Имя проекта unifilt

Универсальный драйвер-фильтр.

Принцип реализации:

При загрузке драйвер должен создать эксклюзивное устройство GuiDevice, которое будет обрабатывать 2 кода управления – подключение фильтра к указанному устройству по его имени с возвращением в прикладную программу адреса объекта-устройства фильтра, и отключение фильтра по адресу объекта-устройства фильтра.

Устройство должно иметь расширение устройства (в IoCreateDevice() указывается размер структурыDeviceExtension). СтруктураDeviceExtensionопределяется разработчиком драйвера.

В нашем случае

typedef struct _DEVICE_EXTENSION

{

PDEVICE_OBJECT TargetDeviceObject;

PFILE_OBJECT FileObject;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

Функция DriverEntry

Особенности реализации функции DriverEntryследующие:

  • Для того, чтобы наш фильтр успешно обрабатывал все запросы к фильтруемому устройству, он должен иметь обработчики для всех возможных диспетчерских функций. Даже если фильтр не знает, что за запрос к нему пришел, он обязан передать этот запрос фильтруемому устройству с помощью вызова IoCallDriver(). Так как мы заранее не знаем, какой набор диспетчерских функций будет у фильтруемых устройств, мы должны установить все обработчики. Сделать это можно в цикле следующим образом (см. файл ntddk.hдля понимания того, как определены константыIRP_MJ_xxx):

for(i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)

{

DriverObject->MajorFunction[i] = FilterDrvDispatch;

}

  • Внутри функции DriverEntry мы создаем объект-устройство (GuiDevice) для взаимодействия с нашей управляющей прикладной программой. Это устройство должно обрабатывать только коды управления в/в для создания нового устройства-фильтра, и удаления существующего устройства-фильтра. Соответственно, каждое устройство-фильтр должно обрабатывать любой пришедший к нему запрос. Обработка всех запросов и дляGuiDevice, и для устройств-фильтров, производится внутри одной и той же диспетчерской функции драйвера FilterDrvDispatch. Встает вопрос: как нам отличить запросы, предназначенные фильтруемому устройству, от запросов, предназначенных устройствуGuiDevice? Для этого мы можем в глобальной переменнойpGuiDeviceхранить адрес управляющего устройства, а в диспетчерской функции сравнивать его с адресом устройства-получателя запроса:

NTSTATUS FilterDrvDispatch(PDEVICE_OBJECT pDevObj, PIRP irp)

{

NTSTATUS ntStatus;

if(pGuiDevice==pDevObj)

/* Это наше интерфейсное устройство (GUI) */

ntStatus = GuiDevDispatch(DeviceObject, Irp);

else

/* Это устройство-фильтр */

ntStatus = FilterDevDispatch(DeviceObject, Irp);

}

Подключение фильтра к устройству:

При получении запроса от прикладной программы на подключение фильтра к устройству запрос обрабатывается устройством GuiDeviceследующим образом:

  • Получаем указатель на объект-устройство, к которому нужно подключить фильтр, с помощью вызова IoGetDeviceObjectPointer()

  • Получаем тип объекта-устройства, к которому нужно подключить фильтр (поле DeviceTypeв структуреDEVICE_OBJECT)

  • С помощью вызова IoCreateDevice() создаем неэксклюзивный объект-устройство, которое будет фильтром. Тип устройства указываем тот же, что и для фильтруемого устройства.

  • Устанавливаем для устройства-фильтра метод передачи буфера таким же, что и у фильтруемого устройства (поле Flagsв структуреDEVICE_OBJECT). При этом важно не изменить значения других уже установленных флагов в этом поле.

  • В поле флагов объекта-устройства фильтра сбросить флаг DO_DEVICE_INITIALIZING. Это необходимо делать всегда, если мы создаем любой объект-устройство вне функции DriverEntry. Сброс флага осуществляется с помощью строкиFilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

  • Подключить объект-устройство фильтр к фильтруемому объекту-устройство с помощью вызова IoAttachDeviceToDeviceStack(). Указатель на объект-устройство, который вернет эта функция, необходимо сохранить в структуре DeviceExtension объекта-устройства фильтра.

  • Сохранить в структуре DeviceExtension объекта-устройства фильтра указатель на объект-файл, полученный ранее при вызове IoGetDeviceObjectPointer().

Соседние файлы в папке Лабы по драйверам