Запросы IRP_MJ_DEVICE_CONTROL и IRP^MJJNTERNA^DEVICE^CONTROL
Запросы IRP_MJ_DEVICE_CONTROL и IRP^MJJNTERNA^DEVICE^CONTROL
Как говорилось выше, точка входа драйвера IRP_MJ_DEVICE_CONTROL вызывается при вызове пользовательской программой функции DeviceloControl(). Прототип этой функции:
BOOL DeviceloControl ( HANDLE hDevice,// описатель открытого устройства
DWORD dwIoControlCode,// контрольный код запрашиваемой операции
DWORD nlnBufferSize, LPVOID IpOutBuffer,// адрес буфера со входными данными
DWORD nOutBufferSize, LPDWORD IpBytesReturnedy// размер входного буфера
// адрес буфера для приема
// выходных данных
// размер выходного буфера
// адрес переменной
// для получения
// числа реально
// переданных байтов данных
LPOVERLAPPED IpOverlapped
// адрес структуры
// для обеспечения
// асишсронности
// ввода/вывода
Зачем нужен IRP_MJ_DEVICE_CONTROL? Когда драйвер поддерживает определенный тип устройства, такое устройство обычно имеет набор специализированных возможностей, которые могут управляться через драйвер. Эти возможности не могут быть задействованы использованием стандартных кодов функций IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_READ и IRP_MJ_WRITE. Например, драйвер устройства для лентопротяжного устройства SCSI должен обеспечить механизм, который дает возможность пользователям послать запрос на стирание ленты. Такие зависящие от устройства запросы описываются, используя главный функциональный код IRP_MJ_DEVICE_CONTROL. Устройство обычно может принимать несколько разнотипных команд. Для драйвера тип такой команды указывается Кодом Управления ввода/вывода (IOCTL), который передается как часть запроса ввода/вывода.
Возвращаясь к функции DeviceloControl(), код управления ввода/вывода (IOCTL) указывается во втором параметре этой функции. Код управления ввода/вывода имеет специальный формат, указывающий метод передачи буфера и другую информацию. Этот формат будет рассмотрен в следующем разделе. Путаница может возникнуть при задании буфера для ввода/вывода.
Как видно из прототипа функции DeviceloControl(), она может передавать два буфера (третий и пятый параметры). Несмотря на названия буферов - входной и выходной буфер - выходной буфер может быть использован как для передачи данных в драйвер, так и для приема данных из драйвера. Разница будет в используемом методе передачи буфера. Использование буферов будет подробно рассмотрено в разделе «Получение буфера».