Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Агуров П.В. -> "Интерфейсы USB. Практика использования и программирования" -> 68

Интерфейсы USB. Практика использования и программирования - Агуров П.В.

Агуров П.В. Интерфейсы USB. Практика использования и программирования — СПб.: БХВ-Петербург, 2004. — 576 c.
ISBN 5-94157-202-6
Скачать (прямая ссылка): interface2004.djvu
Предыдущая << 1 .. 62 63 64 65 66 67 < 68 > 69 70 71 72 73 74 .. 166 >> Следующая

бЫТЬ ИСПОЛЬЗОВаНЫ B процедуре DriverEntry.
і Гпава 9. Введение в WDM
195
2. Если разрешены прерывания для обслуживаемого устройства, то процедура unload должна произвести их запрещение и отключение от объекта прерываний.
3. Символьная ссылка должны быть удалена из пространства имен, видимого пользовательскими приложениями. Это выполняется при помощи вызова функции IoDeleteSymbolicLink.
4. Объект Драйвера должен бЫТЬ удален ВЫЗОВОМ функции IoDeleteDevice.
5. Если драйвер управляет многокомпонентным контроллером, необходимо повторить шаги 3 и 4 для каждого устройства, подключенного к контроллеру, а затем удалить сам объект контроллера при помощи вызова функции IoDeleteController.
6. Следует выполнить освобождение памяти, выделенной драйверу, во всех типах оперативной памяти.
Драйверы WDM модели выполняют почти все из этих действий в обработчике IRP_MJ_PNP запросов С субКОДОМ IRP_MN_REMOVE.
Листинг 9.9 показывает пример написания процедуры unload. Обратите внимание на преобразование имени драйвера в кодировку UNICODE.
j Листинг 9.9. Пример процедуры Unload |
// пример из драйвера GivelOEx #define DEVICE_NAME_STRING L"giveioex"
VOID GiveioUnload(in PDRIVER_OBJECT DriverObject) {
WCHAR DOSNameBuffer[] = L"\\DosDevices\\" device_name_STRING; UNICODE_STRING uniDOSString;
if (IOPM_local) MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM)); Rtl-initUnicodeString(SuniDOSString, DOSNameBuffer); IoDeleteSymbolicLink (SuniDOSString); IoDeleteDevice(DriverObject->DeviceObject);
}
Важно отметить, что процедура unload не вызывается в момент перезагрузки или выключения системы. При необходимости выполнения действий во время выключения следует делать это в обработчике запросов irp_mj_shutdown, причем объект устройства должен быть с помощью вызова
196
Часть III. Практика программирования
функции loRegisterShutdownNotification занесен в очередь объектов, получающих уведомление о выключении.
9.3.4. Рабочие процедуры драйвера
Клиенты драйвера (т. е. пользовательское приложения или модули режима ядра) общаются с драйвером с помощью специальных структур данных, называемых пакетами IRP (Input/output Request Packet, пакет запроса в/в). При появлении запроса от приложения пользователя диспетчер в/в вызывает соответствующий обработчик драйвера, который был зарегистрирован в массиве DriverObject->Ma jorFunction [ ], как показано в листинге 9.2.
Пакеты IRP являются структурами данных переменной длины и состоят из стандартного заголовка, содержащего общую учетную информацию, и одного или нескольких блоков параметров, называемых ячейкой стека в/в (I/O stack location). Структура пакета IRP показана на рис. 9..5.
Заголовок
Стек
IRP
MdlAddess
Associatedlrp
loStatus
Cancel
UserBuffer
IO STATUS BLOCK
Status
Information
IO STACK LOCATION
Parameters
Рис. 9.5. Структура пакета IRP
Заголовок пакета
Описывать все поля заголовка пакета IRP не имеет смысла. Код драйвера может работать со следующими полями:
? pmdl MdlAddess — указатель на MDL-список (Memory Descriptor List, список дескрипторов памяти), если устройство поддерживает прямой в/в;
? PVOiD Associatedlrp.systemBuffer — указатель на системный буфер для случая, когда устройство поддерживает буферизированный в/в;
? то status block Testatus --¦ код состояния (статус) запроса;
Гпава 9. Введение в WDM
197
? boolean Cancel — индикатор того, что пакет IRP должен быть аннулирован,
? PVOiD userBuffer — адрес пользовательского буфера для в/в.
Поле структуры iostatus фиксирует состояние данной операции в/в; когда драйвер готов завершить обработку пакета IRP, он устанавливает поле
IoStatus. Status B значение STATUS_xxx. В ПОЛЄ IoStatus.Information записывается 0, если произошла ошибка или другое, определенное операцией в/в значение, чаще всего — число переданных или полученных байт данных (которое может быть равно и нулю).
Ячейки стека в/в
Основное назначение ячеек в/в состоит в хранении параметров запроса на в/в. Диспетчер в/в создает пакет IRP с числом ячеек в стеке, равном числу драйверных слоев, участвующих в обработке запроса. Любому драйверу в иерархии разрешен доступ к его собственной ячейке стека. Когда драйвер передает IRP-пакет нижнему драйверному уровню, он автоматически перемещает указатель стека в/в пакета таким образом, что он указывает на стековую ячейку для этого драйвера. Когда обработка пакета драйвером нижнего уровня завершена, указатель стека снова возвращается в исходное положение и указывает на ячейку стека для лежащего выше драйвера. Для получения указателя на текущую ячейку существует специальный системный ВЫЗОВ IoGetCurrentStackLocation.
Получив указатель на свою ячейку стека, т. е. указатель на структуру io_stack_location, драйвер может работать со следующими полями:
? UCHAR MajorFunction — код irp_mj_xxx, описывающий назначение операции;
? UCHAR MinorFunction —- субкод операции;
? pdevice_object DeviceObject — указатель на объект устройства, которому был адресован данный запрос IRP;
? PFiLE object Fiieobject — файловый объект для данного запроса, если он задан.
Предыдущая << 1 .. 62 63 64 65 66 67 < 68 > 69 70 71 72 73 74 .. 166 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100