Мегаобучалка Главная | О нас | Обратная связь


Инициализация драйвера



2019-07-03 358 Обсуждений (0)
Инициализация драйвера 0.00 из 5.00 0 оценок




Начнём с процедуры, вызываемой при инициализации драйвера — DriverEntry. Она определяется следующим образом:

 

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)


Тип NTSATUS, соответствующий возвращаемому значению, определяет тип ошибки. Многие функции драйвера возвращают значение этого типа. Если работа проходит успешно, результат принимает значение STATUS_SUCCESS.

В данной процедуре необходимо сообщить системе остальные процедуры обработки пакетов IRP:

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

 

DriverObject->MajorFunction[IRP_MJ_CREATE] = RamDskCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamDskCreateClose; DriverObject->MajorFunction[IRP_MJ_READ] = RamDskReadWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = RamDskReadWrite; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamDskIOCtl; DriverObject->MajorFunction[IRP_MJ_PNP] = RamDskDispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = RamDskDispatchPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = RamDskDispatchSystemControl; DriverObject->DriverExtension->AddDevice = RamDskAddDevice;  DriverObject->DriverUnload = RamDskUnload;

 

Массив MajorFunction устанавливает соответствие между кодом типа запроса IRP_MJ_NNN и диспетчерской функцией, которая его обрабатывает. Наш драйвер обрабатывает запросы на открытие и закрытие устройства (RamDskCreateClose), чтение и запись (RamDskReadWrite), расширенные запросы обработки IOCTL(RamDskIOCtl), запросы Plug and Play (RamDskDispatchPnp), функции управления питанием (RamDskDispatchPower), запросы от подсистемы инструментария Windows (RamDskDispatchSystemControl).

Сам объект функционального устройства, который будет отвечать за наше устройство, создается далее, когда система вызовет процедуру RamDskAddDevice. Но для его создания необходимо узнать путь реестра с параметрами драйвера, а также необходим признак, что устройство добавлено. Данные параметры будем хранить в структуре расширения драйвера. Поля и размер структуры выбираются разработчиком, для хранения нужных ему данных. Объявим структуру расширения драйвера следующим образом:

 

typedef struct _RAMDSK_DRIVER_EXTENSION  { UNICODE_STRING RegistryPath;   ULONG DeviceInitialized;  } RAMDSK_DRIVER_EXTENSION, *PRAMDSK_DRIVER_EXTENSION;

 

В процедуре DriverEntry мы создаем экземпляр структуры и инициализируем ее поля: копируем путь реестра RegistryPath, который передается в параметрах процедуры, и сбрасываем признак DeviceInitialized того, что устройство добавлено.

 

status = IoAllocateDriverObjectExtension(DriverObject, RAMDSK_DRIVER_EXTENSION_KEY, sizeof(RAMDSK_DRIVER_EXTENSION), &driverExtension); // Сохраним путь реестра driverExtension->RegistryPath.Length = RegistryPath->Length; driverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength +   sizeof(UNICODE_NULL); driverExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,   driverExtension->RegistryPath.MaximumLength, RAMDSK_TAG_GENERAL); RtlCopyUnicodeString( &(driverExtension->RegistryPath), RegistryPath); driverExtension->DeviceInitialized = FALSE;


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

Проверим, может быть уже создан объект устройство, а процедура RamDskAddDevice вызывается повторно. Для этого проанализируем признак DeviceInitialized расширения драйвера:

 

// Может присутствоать только одно устройство, если повторно вызывается запрос

// AddDevice для следующего устройства, отклоним запрос

if ( driverExtension->DeviceInitialized == TRUE )

{

DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR, ("Device exists\n") );

return STATUS_DEVICE_ALREADY_ATTACHED;

}

 

Если процедура RamDskAddDevice вызвана в первый раз, создаем объект устройство с типом дисковый накопитель (FILE_DEVICE_DISK) и инициализируем расширение устройства DEVICE_EXTENSION:

 

status = IoCreateDevice(

    DriverObject,

    sizeof(DEVICE_EXTENSION),

    &uniDeviceName,

    FILE_DEVICE_DISK ,

    (FILE_DEVICE_SECURE_OPEN),

    FALSE,

    &functionDeviceObject);


Если создание прошло успешно, мы читаем параметры диска из реестра и устанавливаем начальное состояние устройства остановлено (STOPPED) в расширении устройства, а также устанавливаем флаги сигнализирующие о том, что мы используем прямой метод передачи данных (DO_DIRECT_IO) и процедуры драйвера находятся в страничной памяти(DO_POWER_PAGABLE):

 

RamDskQueryDiskRegParameters(&driverExtension->RegistryPath,&devExt->DiskRegInfo);

devExt->DevState = STOPPED; // состояние остановлен

// Установим флаги

functionDeviceObject->Flags |= DO_POWER_PAGABLE;

functionDeviceObject->Flags |= DO_DIRECT_IO;

// Резервируем память под образ диска

devExt->DiskImage =

ExAllocatePoolWithTag ( NonPagedPool,

devExt->DiskRegInfo.DiskSize,

RAMDSK_TAG_DISK ) ;

 

Последней операцией мы резервируем память в нестраничном пуле под образ диска(размер образа devExt->DiskRegInfo.DiskSize байт).

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

 

RamDskFormatDisk( functionDeviceObject );

 

Создаем символическую ссылку, которая ассоциирует с нашим драйвером указанную в параметрах букву диска и имеет формат «\DosDevices\X:», где «Х» - буква диска.


RtlInitUnicodeString( &uniWin32Name, DOS_DEVICE_NAME );

devExt->SymbolicLink.MaximumLength = DOS_DEVNAME_LENGTH;

devExt->SymbolicLink.Length = uniWin32Name.Length;

RtlCopyUnicodeString( &(devExt->SymbolicLink), &uniWin32Name );

RtlAppendUnicodeStringToString(&(devExt->SymbolicLink),&(devExt->DiskRegInfo.DriveLetter));

// Создаем символьную ссылку в пространстве имен Win32

status = IoCreateSymbolicLink( &devExt->SymbolicLink, &uniDeviceName );

 

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

 

devExt->Flags |= FLAG_LINK_CREATED;

devExt->LowerDeviceObject = // подключение к стеку устройств

IoAttachDeviceToDeviceStack( functionDeviceObject, PhysicalDeviceObject );

// Сбросим флаг DO_DEVICE_INITIALIZING

functionDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

// устройство добавлено успешно

driverExtension->DeviceInitialized = TRUE;

 

Последней операцией устанавливается признак DeviceInitialized расширения драйвера, что устройство добавлено.



2019-07-03 358 Обсуждений (0)
Инициализация драйвера 0.00 из 5.00 0 оценок









Обсуждение в статье: Инициализация драйвера

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас...
Почему люди поддаются рекламе?: Только не надо искать ответы в качестве или количестве рекламы...
Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (358)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.005 сек.)