Организация ввода-вывода. Драйверы WDM. Рощин А.В. - 48 стр.

UptoLike

Составители: 

48
Первый аргумент функции IoCallDriver содержит адрес объекта устройства,
полученный одним из указанных выше способов из внешнего источника.
Часто IRP посылаются нижележащему (в стеке PnP) драйверу. В этом
случае DeviceObject содержит значение LowerDeviceObject, которое
сохраняется в расширении устройства после вызова функции
IoAttachDeviceToDeviceStack.
Диспетчер ввода-вывода указывает на элемент стека IRP за одну
позицию
до фактической. То есть, фактически он указывает на минус первый элемент,
которого в природе не существует. Поэтому, если необходим первый элемент
стека, необходимо запрашивать следующий элемент.
3.7 Функция IoCallDriver
Типичный внешний вид функции IoCallDriver примерно таков:
NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
IoSetNextIrpStackLocation(Irp);
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
stack->device_object = DeviceObject;
ULONG fcn = stack->MajorFunction;
PDRIVER_OBJECT driver = DeviceObject->DriverObject;
return (*driver->MajorFunction[fcn])(DeviceObject, Irp);
}
Как видно из примера, функция IoCallDriver:
перемещает указатель стека,
вызывает соответствующую диспетчерскую функцию драйвера для
целевого объекта устройства,
возвращает код состояния, полученный от диспетчерской функции.
3.8 Диспетчерские функции
Рассмотрим типичную диспетчерскую функцию IRP:
NTSTATUS DispatchXxx(PDEVICE_OBJECT fdo, PIRP Irp)
{
      Первый аргумент функции IoCallDriver содержит адрес объекта устройства,
полученный одним из указанных выше способов из внешнего источника.
      Часто IRP посылаются нижележащему (в стеке PnP) драйверу. В этом
случае   DeviceObject    содержит       значение   LowerDeviceObject,   которое
сохраняется     в    расширении       устройства    после    вызова     функции
IoAttachDeviceToDeviceStack.
      Диспетчер ввода-вывода указывает на элемент стека IRP за одну позицию
до фактической. То есть, фактически он указывает на минус первый элемент,
которого в природе не существует. Поэтому, если необходим первый элемент
стека, необходимо запрашивать следующий элемент.


      3.7 Функция IoCallDriver
      Типичный внешний вид функции IoCallDriver примерно таков:
NTSTATUS IoCallDriver(PDEVICE_OBJECT DeviceObject, PIRP Irp)
  {
  IoSetNextIrpStackLocation(Irp);
  PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
  stack->device_object = DeviceObject;
  ULONG fcn = stack->MajorFunction;
  PDRIVER_OBJECT driver = DeviceObject->DriverObject;
  return (*driver->MajorFunction[fcn])(DeviceObject, Irp);
  }
      Как видно из примера, функция IoCallDriver:
      − перемещает указатель стека,
      − вызывает соответствующую диспетчерскую функцию драйвера для
         целевого объекта устройства,
      − возвращает код состояния, полученный от диспетчерской функции.


      3.8 Диспетчерские функции
      Рассмотрим типичную диспетчерскую функцию IRP:
NTSTATUS DispatchXxx(PDEVICE_OBJECT fdo, PIRP Irp)
  {

                                         48