Описания буфера для кодов элементов управления вводом-выводом
Коды элементов управления вводом-выводом содержатся в запросах IRP_MJ_DEVICE_CONTROL и IRP_MJ_INTERNAL_DEVICE_CONTROL . Диспетчер ввода-вывода создает эти запросы в результате вызовов DeviceIoControl и IoBuildDeviceIoControlRequest.
Так как DeviceIoControl и IoBuildDeviceIoControlRequest принимают входной и выходной буфер в качестве аргументов, все запросы IRP_MJ_DEVICE_CONTROL и IRP_MJ_INTERNAL_DEVICE_CONTROL предоставляют входной и выходной буфер. Способ описания этих буферов системой зависит от типа передачи данных. Тип передачи указывается значением TransferType в макросе CTL_CODE , который создает значения кода IOCTL.
Система описывает буферы для каждого значения TransferType следующим образом.
METHOD_BUFFERED
Для этого типа передачи irP предоставляют указатель на буфер в Irp-AssociatedIrp.SystemBuffer>. Этот буфер представляет входной и выходной буфер, указанные в вызовах DeviceIoControl и IoBuildDeviceIoControlRequest. Драйвер передает данные из этого буфера, а затем в него.
Для входных данных размер буфера определяется параметром Parameters.DeviceIoControl.InputBufferLength в структуре IO_STACK_LOCATION драйвера. Для выходных данных размер буфера определяется параметром Parameters.DeviceIoControl.OutputBufferLength в структуре IO_STACK_LOCATION драйвера.
Размер пространства, выделяемого системой для одного входного и выходного буфера, больше двух значений длины.
METHOD_IN_DIRECT или METHOD_OUT_DIRECT
Для этих типов передачи IRP предоставляют указатель на буфер в Irp-AssociatedIrp.SystemBuffer>. Это первый буфер, указанный в вызовах DeviceIoControl и IoBuildDeviceIoControlRequest. Размер буфера определяется параметром Parameters.DeviceIoControl.InputBufferLength в структуре IO_STACK_LOCATION драйвера.
Для этих типов передачи irP также предоставляют указатель на MDL в Irp-MdlAddress>. Представляет второй буфер, указанный в вызовах DeviceIoControl и IoBuildDeviceIoControlRequest. Этот буфер можно использовать в качестве входного или выходного буфера следующим образом:
METHOD_IN_DIRECT указывается, если драйвер, обрабатывающий IRP, получает данные в буфере при вызове. MDL описывает входной буфер, а указание METHOD_IN_DIRECT гарантирует, что выполняющийся поток имеет доступ на чтение к буферу.
METHOD_OUT_DIRECT указывается, если драйвер, обрабатывающий IRP, записывает данные в буфер перед завершением IRP. MDL описывает выходной буфер, а указание METHOD_OUT_DIRECT гарантирует, что выполняющийся поток имеет доступ на запись в буфер.
Для обоих этих типов передачи Parameters.DeviceIoControl.OutputBufferLength указывает размер буфера, описанный в MDL.
METHOD_NEITHER
Диспетчер ввода-вывода не предоставляет системных буферов или многомерных выражений. IRP предоставляет виртуальные адреса входных и выходных буферов в пользовательском режиме, указанные для DeviceIoControl или IoBuildDeviceIoControlRequest, без проверки или сопоставления.
Адрес входного буфера предоставляется параметром Parameters.DeviceIoControl.Type3InputBuffer в структуре IO_STACK_LOCATION драйвера, а адрес выходного буфера — Irp-UserBuffer>.
Размеры буфера предоставляются параметрами Parameters.DeviceIoControl.InputBufferLength и Parameters.DeviceIoControl.OutputBufferLength в структуре IO_STACK_LOCATION драйвера.
Дополнительные сведения о макросе CTL_CODE и типах передачи, перечисленных выше, см. в разделе Определение кодов управления вводом-выводом.