Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ДП.docx
Скачиваний:
11
Добавлен:
23.09.2019
Размер:
4.64 Mб
Скачать

2.3.3 Обработка расширенных запросов ioctl

Если присмотреться к различным типам запросов, поступающим устройству, ока­жется, что большинство из них связано с чтением или записью данных. Тем не менее, время от времени у приложений возникает необходимость во «внеочеред­ном» взаимодействии с драйвером. Для большинства типов устройств приложения могут использовать стандартную функцию Microsoft Win32 API DeviceIoControl. На стороне драйвера вызов DeviceIoControl в приложении преобразуется в пакет за­проса ввода/вывода (IRP) с основным кодом функции IRP_MJ_DEVICE_CONTROL [2.2].

Для управления сами устройством диспетчер ввода/вывода посылает драйверу пакет с кодом управления вводом/выводом (IOCTL). Какие именно коды управления будет посылаться зависит от типа устройства [2.2]. О том, какие коды должен обязательно поддерживать функциональный USB драйвер точно ничего не сказано. Поэтому приведенный далее список кодов управления был получен эмпирическим путем. Также для упрощения разработки, я решил разместить все определения IOCTL в отдельном заголовочном файле – DACAL_IOCTL.h.

Список кодов управления:

#ifndef DACAL_IOCTL_H

#define DACAL_IOCTL_H

#define USB_IOCTL_INDEX 0x0000

#define IOCTL_USB_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\

USB_IOCTL_INDEX,\

METHOD_BUFFERED, \

FILE_ANY_ACCESS)

#define IOCTL_USB_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, \

USB_IOCTL_INDEX+1,\

METHOD_BUFFERED, \

FILE_ANY_ACCESS)

#define IOCTL_USB_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, \

USB_IOCTL_INDEX+2,\

METHOD_BUFFERED, \

FILE_ANY_ACCESS)

#define IOCTL_USB_STOP_STREAM CTL_CODE(FILE_DEVICE_UNKNOWN, \

USB_IOCTL_INDEX+3,\

METHOD_BUFFERED, \

FILE_ANY_ACCESS)

#define IOCTL_USB_START_STREAM CTL_CODE(FILE_DEVICE_UNKNOWN, \

USB_IOCTL_INDEX+4,\

METHOD_BUFFERED, \

FILE_ANY_ACCESS)

#endif

2.3.4 Поддержка запросов Plug and Play

Plug and Play Manager передает информацию и запросы драйверам устройств посредством пакетов запросов ввода/вывода (IRP) с основным кодом функции IRP_MJ_PNP. Что примечательно, так это то, что в предыдущих версиях Windows NT драйверы устройств были обязаны выполнять большую часть работы по обнаружению и настройке своих устройств. К счастью, драйверы WDM могут поручить эту работу PnP Manager [2.2].

Запросам Plug and Play в модели WDM отведены две роли. В своей первой роли эти запросы указывают драйверу, когда и как он должен изменять конфигурацию самого себя или устройства. Существует три обязательных запроса, которые должен обрабатывать наш драйвер [2.3].

PnP Manager при помощи запроса IRP_MN_ START_DEVICE сообщает функциональному драйверу, какие ресурсы ввода/выво­да были выделены устройству, а также приказывает функциональному драйверу выполнить всю необходимую настройку аппаратной и программной части для нормального функционирования устройства. IRP_MN_STOP_DEVICE приказывает функциональному драйверу отключить устройство. IRP_MN_REMOVE_DEVICE при­казывает функциональному драйверу отключить устройство и освободить свя­занный с ним объект устройства.

Кроме того, запросам PnP отводится и другая, более сложная роль — они управ­ляют драйвером в процессе смены состояний, показанных на рисунке 2.5 [2.2]. Основ­ные состояния устройства — WORKING и STOPPED. Состояние STOPPED является исходным состоянием устройства непосредственно после создания объекта устрой­ства. Состояние WORKING означает, что устройство полностью работоспособно. Два промежуточных состояния — PENDINGSTOP и PENDINGREMOVE — возникают из-за запросов, которые должны быть обработаны всеми драйверами устройства перед выходом из состояния WORKING. Состояние SURPRISEREMOVED возникает при непредвиденном удалении физического оборудования из системы.

Рисунок 2.5 – Диаграмма состояний устройства