39773

Написание драйверов для Windows NT 4.0

Реферат

Информатика, кибернетика и программирование

Поддерживающие пакетный вводвывод с повторно используемыми I O request pckets IRPs запросы вводавывода. 3 показан стандартный цикл работы драйвера заключающийся в обработке запроса на прерывание IRP. Disptch NTSTTUS PDRIVER_DISPTCH IN PDEVICE_OBJECT DeviceObject IN PIRP Irp ; Каждый драйвер должен иметь по крайней мере одну процедуру Disptch. StrtIo или Queuemngement VOID PDRIVER_STRTIO IN PDEVICE_OBJECT DeviceObject...

Русский

2013-10-08

442.5 KB

8 чел.

Написание драйверов для Windows NT 4.0.

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

Прежде чем перейти непосредственно к теме статьи, хотелось бы сказать несколько слов о роли драйверов в операционной системе. Вспомним первые персоналки и MS DOS, бывшую в то время практически единственным выбором для настольного ПК. Несмотря на всю ее простоту, драйвера, конечно, присутствовали и в ней. Практически все дело ограничивалось накопителями – дисководами, CD-ROM приводами, винчестерами, да элементарнейшими драйверами клавиатуры и дисплея. Для каждой программы, требующей большего, чем перечисленный набор, требовалось создавать собственный драйвер. Представьте себе, что вам требуется воспроизвести звук на имеющейся в компьютере звуковой карте. Если вы знаете ее модель и у вас есть хорошая документация, вы, потратив немало времени, напишете программу, которая сделает все желаемое. А если необходимо поддерживать две модели? Три? Двадцать? И это при учете того, что новая звуковая карта появляется не реже раза в полтора-два месяца? Естественный выход – возложить написание кода, специфичного для аппаратуры, на ее создателя. Да и фирма-производитель, наняв высококвалифицированных специалистов, справится с задачей намного эффективнее и быстрее. Во всех современных операционных системах так и поступают. Существуют требования, например, к драйверу звуковой карты, и пользователь устанавливает тот  вариант, который соответствует его «железу». А программа-проигрыватель через вызовы системных функций указывает, что именно она хотела бы воспроизвести, не заботясь об особенностях аппаратуры.

Система ввода-вывода в Windows NT.

Теперь перейдем собственно в Windows NT. Прежде всего следует заметить, что фирма Microsoft выпускает пакет DDK (Driver Development Kit), предназначенный именно для создания системных драйверов. Он содержит необходимые для разработки программы и библиотеки, а также документацию и примеры. В дальнейшем я буду неоднократно на него ссылаться.

В Windows NT драйвера бывают следующих типов:

  •  Kernel mode drivers. Основной тип драйвера. Если вы не знаете, какой тип драйвера вам нужен – вам сюда.
  •  Graphics drivers. Драйвера видеокарт. Как правило, создаются одновременно с самой видеокартой. Очень сложны в написании, так как должны учитывать множество противоречивых требований и поддерживать множество стандартов. Скорее всего, вам не потребуется создавать ничего подобного.
  •  Multimedia drivers. Драйверы для :
    •  Аудиоустройств – считывание, воспроизведение и компрессия аудиоданных.
    •  устройств работы с видео – захват и компрессия видеоданных.
    •  позиционных устройств – джойстики, световые перья, планшеты и пр.
  •  Network drivers – работа с сетью и сетевыми протоколами на всех уровнях.
  •  Virtual DOS Drivers – драйверы для виртуальных машин MS-DOS. Постепенно переходят в раздел рудиментарных.

Я остановлюсь на Kernel mode drivers, как на представляющих наибольший интерес для программиста. Прежде всего необходимо представить окружение драйвера, среду, в которой он работает (рис.1).

Рисунок 1. Главные компоненты операционной системы Windows NT.

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

Существует три типа драйверов ядра, каждый тип имеет четко определенные структуру и функциональность.

  •  Device drivers, такие как драйвер клавиатуры или дисковый драйвер, напрямую общающийся с дисковым контроллером. Эти драйвера также называются драйверами низкого уровня, т. к. они находятся в самом низу цепочки драйверов Windows NT.
  •  Intermediate drivers, такие как драйвер виртуального или зеркального диска. Они используют драйверы устройств для обращения к аппаратуре.
  •  File system drivers (FSDs). Драйверы файловых систем, таких как FAT, NTFS, CDFS, для доступа к аппаратуре используют Intermediate drivers и Device drivers.

Драйвера Windows NT должны удовлетворять следующим требованиям:

  •  Переносимы с одной платформы на другую.
  •  Конфигурируемые программно.
  •  Всегда прерываемые.
  •  Поддерживающие мультипроцессорные платформы.
  •  Объектно-ориентированные.
  •  Поддерживающие пакетный ввод-вывод с повторно используемыми I/O request packets (IRPs, запросы ввода-вывода).
  •  Поддерживающими асинхронный ввод-вывод.

Каждая операционная система имеет модель ввода-вывода для управления потоками данных к и от периферийных устройств. Модель ввода-вывода Windows NT имеет следующие особенности:

  •  Менеджер ввода-вывода NT представляет интерфейс для всех kernel-mode драйверов, включая драйвера физических устройств, драйвера логических устройств и драйвера файловых систем.
  •  Операции ввода-вывода послойные. Это значит, что вызов, сделанный пользователем, проходит через несколько слоев, генерируя несколько пакетных запросов ввода-вывода и обращаясь к необходимым драйверам (см. рис.2).
  •  Менеджер ввода-вывода определяет множество стандартных процедур, которые должны быть реализованы разработчиком драйвера.
  •  Подобно NT в целом, драйвера имеют объектную архитектуру. Драйвера, их устройства и системное оборудование представлены как объекты Windows NT.

Рисунок 2.

Стандартные процедуры.

Любой драйвер должен реализовывать основное множество процедур и, возможно, еще несколько дополнительных подмножеств в зависимости от разновидности драйвера. На рис. 3 показан стандартный цикл работы драйвера, заключающийся в обработке запроса на прерывание (IRP). Для получения дополнительной информации читайте документацию к Windows NT Driver Development Kit.

–  Каждый драйвер должен иметь следующие процедуры:

  •  DriverEntry

   NTSTATUS  

   (*PDRIVER_INITIALIZE) (  

       IN PDRIVER_OBJECT DriverObject,

       IN PUNICODE_STRING RegistryPath

       );

 Каждый драйвер должен иметь инициализационную процедуру, которую менеджер ввода-вывода вызывает автоматически, если эта процедура называется DriverEntry.

 

  •  Dispatch

   NTSTATUS  

   (*PDRIVER_DISPATCH) (  

       IN PDEVICE_OBJECT DeviceObject,

       IN PIRP Irp

       );

Каждый драйвер должен иметь по крайней мере одну процедуру Dispatch.

  •  StartIo (или Queue-management)

   VOID  

   (*PDRIVER_STARTIO) (  

       IN PDEVICE_OBJECT DeviceObject,

       IN PIRP Irp

       );

Если драйвер устройства не может завершить все возможные запросы ввода-вывода в его Dispatch процедуре, он должен иметь либо процедуру StartIo,  либо заводить одну или более внутренних очередей и управлять собственным механизмом отложеных запросов на прерывание.

– В зависимости от уровня, занимаемого драйвером в стеке обработки запроса на прерывание, драйвер может обладать следующими процедурами:

  •  Reinitialize

   VOID  

   (*PDRIVER_REINITIALIZE) (  

       IN PDRIVER_OBJECT DriverObject,

       IN PVOID Context,

       IN ULONG Count

       );

 

В добавок к процедуре DriverEntry драйвер может иметь процедуру Reinitialize, вызываемую один или несколько раз в процессе загрузки системы после того, как DriverEntry вернет управление.

  •  InterruptService (ISR)

   BOOLEAN  

   (*PKSERVICE_ROUTINE) (

       IN PKINTERRUPT Interrupt,

       IN PVOID ServiceContext // usually points to device object

       );

 

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

Рисунок 3. Стандартные процедуры драйвера.

 

  •  DpcForIsr или CustomDpc

   VOID  

   (*PIO_DPC_ROUTINE) (  

       IN PKDPC Dpc,

       IN PDEVICE_OBJECT DeviceObject,

       IN PIRP Irp,

       IN PVOID Context

       );

 

   VOID

   (*PKDEFERRED_ROUTINE) (

       IN PKDPC Dpc,

       IN PVOID DeferredContext,

       IN PVOID SystemArgument1,

       IN PVOID SystemArgument2

       );

 Любой драйвер, имеющий ISR должен иметь DpcForIsr или CustomDpc.

  •  SynchCritSection

   BOOLEAN  

   (*PKSYNCHRONIZE_ROUTINE) (  

       IN PVOID SynchronizeContext

       );

 

Любой низкоуровневый драйвер устройства, данные которого или регистры сопряженного устройства могут изменятся в его ISR и других процедурах драйвера, должен иметь одну или более процедур SynchCritSection.

  •  AdapterControl и/или ControllerControl

   IO_ALLOCATION_ACTION  

   (*PDRIVER_CONTROL) (  

       IN PDEVICE_OBJECT DeviceObject,

       IN PIRP Irp,

       IN PVOID MapRegisterBase,

       IN PVOID Context

       );

 

Любой драйвер устройства использующий DMA, должен иметь процедуру AdapterControl. Любой драйвер устройства, который должен синхронизировать операции с физическим контроллером для нескольких устройств или каналов устройства, должен иметь ControllerControl.

  •  Cancel

   VOID  

   (*PDRIVER_CANCEL) (  

       IN PDEVICE_OBJECT DeviceObject,

       IN PIRP Irp

       );

 

Клавиатура, мышь, последовательный, параллельный, звуковой драйверы и драйвер файловой системы имеют процедуру Cancel. Любой драйвер, обрабатывающий запрос в течении длительного промежутка времени (в течении которого пользователь может отменить операцию), должен иметь процедуру Cancel. Обычно эту процедуру имеет высший драйвер в стеке обработки запроса.

  •  IoCompletion

   NTSTATUS  

   (*PIO_COMPLETION_ROUTINE) (  

       IN PDEVICE_OBJECT DeviceObject,

       IN PIRP Irp,

       IN PVOID Context

       );

 

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

  •  IoTimer и/или CustomTimerDpc

   VOID  

   (*PIO_TIMER_ROUTINE) (  

       IN PDEVICE_OBJECT DeviceObject,

       IN PVOID Context

       );

 

   VOID

   (*PKDEFERRED_ROUTINE) (

       IN PKDPC Dpc,

       IN PVOID DeferredContext,

       IN PVOID SystemArgument1,        // reserved for system use

       IN PVOID SystemArgument2            // reserved for system use

       );

 

Для отслеживания времени, занимаемого процедурой ввода-вывода, или для некоторой другой цели, определяемой разработчиком, любой драйвер должен иметь процедуры IoTimer и/или CustomTimerDpc. IoTimer вызывается раз в секунду когда драйвер включает таймер. CustomTimerDpc может быть вызвана в более мелкий или переменный интервал.

  •  Unload

   VOID  

   (*PDRIVER_UNLOAD) (  

       IN PDRIVER_OBJECT DriverObject

       );

 

Драйвер должен иметь процедуру Unload если он может быть выгружен во время работы системы.
Сервисные системные вызовы.
Для осуществления обращений в микроядру, работы с реестром, памятью, объектами, синхронизацией и пр. существует набор функций, называющихся функциями поддержки ядра. Я приведу только самые необходимые. Для дополнительной информации обращайтесь к Microsoft Windows NT DDK.
  •  IoCreateDevice
Создает новый объект устройства и инициализирует его для использования драйвером. Объект устройства представляет собой физическое, виртуальное или логическое устройство, которое необходимо драйверу для поддержки динамического управления этим устройством.

NTSTATUS 
IoCreateDevice(
 
IN PDRIVER_OBJECT  DriverObject, Указатель на объект драйвера
 
IN ULONG  DeviceExtensionSize, размер блока пользовательской информации в байтах
 
IN PUNICODE_STRING  DeviceName,  имя устройства (иногда опускается)
 
IN DEVICE_TYPE  DeviceType, тип устройства (последованельное, диск, мышь и т.д.)
 
IN ULONG  DeviceCharacteristics, параметры устройства (вынимаемое и пр.)
 
IN BOOLEAN  Exclusive, параллельность доступа к устройству
 
OUT PDEVICE_OBJECT  *DeviceObject указатель на объект создаваемого устройства  );

  •  IoCreateSymbolicLink
Создает символическую ссылку между устройством и видимым пользователем именем.

NTSTATUS
IoCreateSymbolicLink(
 
IN PUNICODE_STRING  SymbolicLinkName, символическое имя, видимое пользователю
 
IN PUNICODE_STRING  DeviceName имя устройства в пространстве имен ядра Windows  );

  •  IoCompleteRequest
Объявляет менеджеру ввода-вывода, что обработка текущего запроса ввода-вывода закончена.

VOID 
IoCompleteRequest(
 
IN PIRP  Irp, указатель на запрос ввода-вывода
 
IN CCHAR  PriorityBoost повышение приоритета драйвера для обработки запроса. Зависит     от обрабатываемого устройства. IO_NO_INCREMENT при      ошибке или очень быстрой обработке запроса
 );

Пример: драйвер виртуального диска
Закончив обзор драйверов ядра Windows NT, перейдем к конкретному примеру – драйверу виртуального диска, снабжая текст программы необходимыми описаниями.
Драйвер создает виртуальный диск, отформатированный по умолчанию как FAT. Выбор этого типа драйвера обусловлен следующим:
  •  Простота реализации. Не требуется кода для работы с оборудованием.
  •  Легкость демонстрации. Пример, не требуя специфичных устройств, может быть продемонстрирован практически на любой машине.
  •  Малый объем исходного текста, позволяющий изучить основные принципы работы, не вдаваясь в подробности.
В целях экономии места и концентрации на основной теме я опущу незначительные, но необходимые детали – инициализацию и освобождение памяти, получение параметров из реестра, обработку ошибок, – заменив  их комментариями, вкратце описывающими процесс.
Начнем с рассмотрения функции DriverEntry – точки входа в драйвер, служащей для инициализации программы. С нее начинается выполнение драйвера. Функция устанавливает, какие системные вызовы она будет обрабатывать и создает собственно виртуальный диск.

NTSTATUS

  •  DriverEntry(
    IN OUT PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING      RegistryPath
    )

Аргументы:
   DriverObject – указатель на объект, представляющий этот драйвер.
   RegistryPath – указатель на строку, задающую точку входа в реестре, отведенную для этого драйвера. Через реестр может осуществляться конфигурирование драйвера.
Возвращаемое значение:
   STATUS_SUCCESS если драйвер нормально инициализировался, иначе код ошибки

{

   NTSTATUS        ntStatus;

   UNICODE_STRING  paramPath;

   static  WCHAR   SubKeyString[] = L"\\Parameters";

… Считывание параметров из реестра

…Инициализация объекта драйвера и его точек входа. Соответствующим элементам массива DriverObject->MajorFunction присваиваются адреса поддерживаемых функций.

   DriverObject->MajorFunction[IRP_MJ_CREATE] = RamDiskCreateClose;

   DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamDiskCreateClose;

   DriverObject->MajorFunction[IRP_MJ_READ] = RamDiskReadWrite;

   DriverObject->MajorFunction[IRP_MJ_WRITE] = RamDiskReadWrite;

   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamDiskDeviceControl;

   ntStatus = RamDiskInitializeDisk(DriverObject, &paramPath);

   return ntStatus;

}

  •  NTSTATUS
    RamDiskInitializeDisk(
    IN PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING  ParamPath
    )
RamDiskInitializeDisk  вызывается во время инициализации функцией DriverEntry().
Создает и инициализирует объект устройства для диска. Память для образа выделяется в несвопируемой области. RamDiskFormatFat вызывается для создания файловой системы FAT.
Два параметра могут быть заданы при помощи реестра:
  •  DiskSize определяет размер виртуального диска в байтах. Если система не может выделить достаточно памяти, возвращается STATUS_INSUFFICIENT_RESOURCES. По умолчанию – 1 МБ.
  •  DriveLetter используется для указания имени диска. Строка должна быть буквой или буквой с двоеточием.

Аргументы:
   DriverObject – указатель на объект, представляющий этот драйвер.
   ParamPath – указатель на подключ Parameters реестра.
Возвращаемое значение:
   STATUS_SUCCESS если драйвер нормально инициализировался, иначе код ошибки

{

   STRING              ntNameString;       Имя устройства NT "\Device\RamDisk"

   UNICODE_STRING      ntUnicodeString;    Unicode версия ntNameString

   UNICODE_STRING      Win32PathString;    Имя Win32 "\DosDevices\Z:"

   

   PDEVICE_OBJECT      deviceObject = NULL;    указатель на объект устройства

   PRAMDISK_EXTENSION  diskExtension = NULL;   указатель на специфические данные устройства

   

   NTSTATUS            ntStatus;

   ULONG               defaultDiskSize = DEFAULT_DISK_SIZE;

   ULONG               diskSize = DEFAULT_DISK_SIZE;

   UNICODE_STRING      driveLetterString;

   WCHAR               driveLetterBuffer[sizeof(WCHAR) * 10];

… Инициализация и считывание параметров конфигурации из реестра

   

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

   ntStatus = IoCreateDevice(

       DriverObject,                    Наш драйвер устройства

       sizeof( RAMDISK_EXTENSION ),     Размер дополнительной информации

       &ntUnicodeString,                Имя устройства "\Device\RamDisk"

       FILE_DEVICE_VIRTUAL_DISK,        Тип устройства

       0,                               Свойства устройства

       FALSE,                           Особое устройство. Драйвер обрабатывает только одного клиента

       &deviceObject );                 Возвращает указатель на объект устройства

   

… Размещение и обнуление образа диска, установление данных boot сектора, корневого каталога и пр.
   … Форматирование файловой системы FAT

   RamDiskFormatFat(diskExtension, ParamPath);

… Создание символической связи между именем устройства "\Device\RamDisk" и именем Win32 "\DosDevices\Z:"

   ntStatus = IoCreateSymbolicLink(

                       &diskExtension->Win32NameString, &ntUnicodeString );

RamDiskInitializeDiskExit:

   return ntStatus;

}

  •  Функция RamDiskFormatFat не представляет интереса. Она размечает выделенный образ диска в соответствии со стандартом файловой системы Fat.
  •  NTSTATUS
    RamDiskCreateClose(
       IN PDEVICE_OBJECT DeviceObject,
       IN PIRP Irp
       )
Функция вызывается системой ввода-вывода каждый раз, когда RamDisk открывается или закрывается. Реализация ничего не выполняет, просто корректно закрывая запрос.
Аргументы:
   DeviceObject – указатель на объект представляемого устройства
   Irp – указатель на запрос ввода-вывода для этого вызова
Возвращаемое значение:
   STATUS_INVALID_PARAMETER если параметры заданы неверно, иначе STATUS_SUCCESS.

{

   Irp->IoStatus.Status = STATUS_SUCCESS;

   Irp->IoStatus.Information = 0;

   

   IoCompleteRequest( Irp, IO_NO_INCREMENT );

   

   return STATUS_SUCCESS;

}

  •  NTSTATUS
    RamDiskDeviceControl(
       IN PDEVICE_OBJECT DeviceObject,
       IN PIRP Irp
       )
Функция реализует ioctl функции
Аргументы:
   DeviceObject – указатель на объект устройства
   Irp – указатель на запрос ввода-вывода
Возвращаемое значение:
STATUS_SUCCESS если поддерживаемый запрос, иначе STATUS_INVALID_DEVICE_REQUEST.

{

   PRAMDISK_EXTENSION  diskExtension;

   PIO_STACK_LOCATION  irpSp;

   NTSTATUS            ntStatus;

Инициализация
По умолчанию – неверный запрос

   Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;

Определяет, какая функция требуется

   switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )

   {

   

   case IOCTL_DISK_GET_MEDIA_TYPES:

   case IOCTL_DISK_GET_DRIVE_GEOMETRY:

… Возвращает параметры диска, так называемую геометрию

       {

           PDISK_GEOMETRY outputBuffer;

           outputBuffer = ( PDISK_GEOMETRY ) Irp->AssociatedIrp.SystemBuffer;

           outputBuffer->MediaType = RemovableMedia;

           outputBuffer->Cylinders = RtlConvertUlongToLargeInteger(

               diskExtension->NumberOfCylinders );

           outputBuffer->TracksPerCylinder = diskExtension->TracksPerCylinder;

           outputBuffer->SectorsPerTrack = diskExtension->SectorsPerTrack;

           outputBuffer->BytesPerSector = diskExtension->BytesPerSector;

           Irp->IoStatus.Status = STATUS_SUCCESS;

           Irp->IoStatus.Information = sizeof( DISK_GEOMETRY );

       }

       break;

   case IOCTL_DISK_GET_PARTITION_INFO:

 … Возвращает информацию о разделе

       {

           PPARTITION_INFORMATION outputBuffer;

           PBOOT_SECTOR    bootSector = (PBOOT_SECTOR) diskExtension->DiskImage;

       

           outputBuffer = ( PPARTITION_INFORMATION )Irp->AssociatedIrp.SystemBuffer;

       

           outputBuffer->PartitionType =

               (bootSector->bsFileSystemType[4] == '6') ?

                   PARTITION_FAT_16 : PARTITION_FAT_12;

       

           outputBuffer->BootIndicator = FALSE;

           outputBuffer->RecognizedPartition = TRUE;

           outputBuffer->RewritePartition = FALSE;

           outputBuffer->StartingOffset = RtlConvertUlongToLargeInteger(0);

           outputBuffer->PartitionLength = RtlConvertUlongToLargeInteger(diskExtension->DiskLength);

    outputBuffer->HiddenSectors =  1L;

       

           Irp->IoStatus.Status = STATUS_SUCCESS;

           Irp->IoStatus.Information = sizeof( PARTITION_INFORMATION );

       }

       break;

   case IOCTL_DISK_VERIFY:

       {

 Выполняет проверку носителя. Операция идентична чтению

           PVERIFY_INFORMATION verifyInformation;

           verifyInformation = Irp->AssociatedIrp.SystemBuffer;

           irpSp->Parameters.Read.ByteOffset.LowPart =

               verifyInformation->StartingOffset.LowPart;

           irpSp->Parameters.Read.ByteOffset.HighPart =

               verifyInformation->StartingOffset.HighPart;

           irpSp->Parameters.Read.Length = verifyInformation->Length;

           ntStatus = RamDiskReadWrite( DeviceObject, Irp );

       }

       return ntStatus;

   default:

 Нераспознанная функция. Ошибка

       break;

   }

Закончить операцию ввода-вывода.

   ntStatus = Irp->IoStatus.Status;

   IoCompleteRequest( Irp, IO_NO_INCREMENT );

   return ntStatus;

}

  •  NTSTATUS
    RamDiskReadWrite(
       IN PDEVICE_OBJECT DeviceObject,
       IN PIRP Irp
       )
Эта процедура вызывается для чтения и записи данных.
Аргументы:
   DeviceObject – указатель объект драйвера
   Irp – указатель на запрос ввода-вывода
Возвращаемое значение:
   STATUS_INVALID_PARAMETER если параметр неверен, иначе STATUS_SUCCESS.

{

   PRAMDISK_EXTENSION  diskExtension;

   PIO_STACK_LOCATION  irpSp;

   PUCHAR              CurrentAddress;

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

  

… Получить указатель на данные пользователя в системном контексте

   CurrentAddress = MmGetSystemAddressForMdl( Irp->MdlAddress );

   Irp->IoStatus.Information = irpSp->Parameters.Read.Length;

   switch (irpSp->MajorFunction)

   {

   case IRP_MJ_READ:

Чтение

       RtlMoveMemory(

           CurrentAddress,

           diskExtension->DiskImage + irpSp->Parameters.Read.ByteOffset.LowPart,

           irpSp->Parameters.Read.Length);

       break;

   case IRP_MJ_DEVICE_CONTROL:

       … Проверка. Всегда все в порядке

       break;

   case IRP_MJ_WRITE:

Запись

       RtlMoveMemory(

           diskExtension->DiskImage + irpSp->Parameters.Read.ByteOffset.LowPart,

           CurrentAddress, irpSp->Parameters.Read.Length);

       break;

   default:

… Что-то не поддерживаемое

       Irp->IoStatus.Information = 0;

       break;

   }

   Irp->IoStatus.Status = STATUS_SUCCESS;

   IoCompleteRequest( Irp, IO_NO_INCREMENT );

   return STATUS_SUCCESS;

}

  •  VOID
    RamDiskUnloadDriver(
       IN PDRIVER_OBJECT DriverObject
       )
Эта процедура вызывается системой для выгрузки драйвера. Требуется освободить все занятые ресурсы
Аргументы:
   DriverObject – указатель на объект драйвера

{

… Освобождает всю выделенную для драйвера память.
Удаление объекта устройства. Символическая связь рвется автоматически

       IoDeleteDevice( deviceObject );

}


Защищенная подсистема

(серверы)

Подсистема защиты

одсистема OS/2

Подсистема

POSIX

Подсистема

Win32

Режим пользователя

Режим ядра

LAN

Системные процессы

Менеджер ввода-вывода

Менеджер конфигурации

Менеджер памяти.

Поддержка выполнения

Вызов удаленных процедур

Менеджер объектов

Монитор защиты

Ядро

HAL (уровень абстракции аппаратуры)

Аппаратура

Пользовательский вызов

Драйвер файловой системы

Драйвер дискового устройства

Накопитель


 

А также другие работы, которые могут Вас заинтересовать

36693. Администрирование Web-сервера Apache. Виртуальный хостинг на основе имен 43.5 KB
  Пусть необходимо создать виртуальные хосты с именами www.ваша_фамилия1.ua и www.ваша_фамилия2.ua. Сначала необходимо создать на локальном сервере DNS запись, указывающую, что адресу 127.0.0.1 соответствуют несколько имен. Для этого откройте файл /etc/hosts и допишите в строку
36694. Данило Галицький 90.16 KB
  Метою цього завдання є опис практичного застосування ресурсів мережі Інтернет при вивченні історії та особисто персони Данила Галицького. В даному випадку переді мною постало завдання отримання інформація для роботи з моєю презентацією. Її темою було Данило Галицький
36695. Администрирование СУБД MySQL. Работа с таблицами системной базы данных mysql 62 KB
  Откройте их с помощью команд [ltF3] и [ltF4] и зайдите в систему под именем любого пользователя например user. В лабораторной работе создаваемые пользователи обозначаются user1 и user2. То есть вам необходимо подставить вместо user1 и user2 имена ivnov1 и ivnov2. Выполните команду для добавления пользователя user1 и задания ему привилегий: insert into user Host User Pssword Select_priv vlues ‘loclhost’ ’user1’ pssword‘user1’’Y’; Выполните команду для добавления пользователя user2 и задания ему привилегий: insert into...
36696. Типизированный файл 87.42 KB
  Типизированный файл состоит из последовательности записей одной и той же структуры. Структура записи задается типом, который может быть как стандартным, так и заданным в программе. Запрещено создавать файлы файлов и файлы объектов, а также файлы структурированных компонентов, содержащих файлы и объекты. Записи файла нумеруются начиная с 0.
36697. Использование команд GRANT и REVOKE для задания привилегий пользователей 49 KB
  Откройте их с помощью команд [ltF3] и [ltF4] и зайдите в систему под именем любого пользователя например user. Работу в СУБД MySQL от имени пользователей root user3 и user4 необходимо вести параллельно подключившись с разных терминалов открытых в начале выполнения лабораторной работы. В лабораторной работе создаваемые пользователи обозначаются user3 и user4. То есть вам необходимо подставить вместо user3 и user4 имена ivnov3 и ivnov4.
36698. ОПРЕДЕЛЕНИЕ ОТНОШЕНИЯ ТЕПЛОЕМКОСТЕЙ ГАЗА МЕТОДОМ КЛЕМАНА - ДЕЗОРМА 73 KB
  Основные теоретические положения к данной работе основополагающие утверждения: формулы схематические рисунки: Для определения отношения Сp Cv в случае воздуха в данной лабораторной работе применен метод предложенный Клеманом и Дезормом в котором использовано охлаждение газа при его адиабатическом расширении. Быстрое сжатие и быстрое расширение газа приблизительно можно рассматривать как адиабатический процесс. Отсюда видно что при адиабатическом сжатии температура газа повышается за счет работы внешних сил а при адиабатическом...
36699. Определение параметров импульсных сигналов, используемых для электростимуляции 495 KB
  Связь амплитуды формы импульса частоты следования импульсов длительности импульсного сигнала с раздражающим действием импульсного тока. Какова будет сила тока в начале разрядки конденсатора Через 6 мс напряжение на конденсаторе упадет до 250 В. Цель работы: Используя осциллограф С819 источник питания постоянного тока Б545 дифференцирующие и интегрирующие цепи.
36700. Изучение действия СВЧ поля на вещество 551 KB
  Переменные токи наведенные электрическим полем создают в диполе стоячую волну с пучностью тока в его середине. Они препятствуют ответвлению в гальванометр высокочастотного тока свободно пропуская выпрямленный.Исследование нагревания токами СВЧ электролита и диэлектрика.Делают вывод о влиянии СВЧ поля на вещество Воздействие переменными токами Первичное действие переменного тока и электромагнитного поля на биологические объекты в основном заключается в периодическом смещении ионов растворов электролитов и изменении поляризации...
36701. Градуирование электростатического вольтметра с помощью электрометра Томсона 396 KB
  Градуирование электростатического вольтметра с помощью электрометра Томсона. Цель работы: Градуирование шкалы электростатического вольтметра с помощью абсолютного электрометра Томсона т. Основные теоретические положения к данной работе основополагающие утверждения: формулы...