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

 

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

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

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

)
Гпава 9. Введение в WDM
205
'. Листинг 9.16. Формирование кода IOCTL в драйвере
// Номера 32768-65535 зарезервированы для пользователя #define GIVEIO_TYPE 40000
// Коды функций IOCTL от 0x800 до OxFFF могут использоваться #define IOCTL_IOPM_GET_ALL_ACCESS\
CTb-CODE(GIVEIO-TYPE, 0x900, METHOD_BUFFERED, FILE-ANY-ACCESS)
#define 1OCTL-DISK-SET-PARTITIOn-INFOX
CTL-CODE(ICCTL-DISK-BASe, 0x008, METHOd-BUFFERED,\ FILE-READ-DATa I FILE-WRITe-DATA)
Листинг 9.17. Формирование кода IOCTL в Delphi
40000; 0;
$0000;'
// Функция формирования кода IOCTL function Get_Ctl_Code(Nr: Integer): Cardinal; begin Result:=
(GIVEIO-TYPe shl 16) or
(FILE-ANY-ACCESs shl 14) or
(Nr shl 2) or
METHODJBUFFERED; end;
Il Пример формирования кода для листинга 8.15 Var
1OCTL-IOPM-GET-ALl-ACCESS: Cardinal;
1OCTL-IOPM-GET-ALl-ACCESS:= Get_Ctl Code C$900);
Const GIVEIO-TYPe METHODJBUFFERED = FILE ANY ACCESS =
206 Часть III. Практика программирования
Таблица 9.2. Параметры макроопределения ctl_ code
Параметр Описание
DeviceType Код драйвера:
• 0x0000—0x7FFFF — зарезервированы Microsoft
• 0x8000—OxFFFF — определяются пользователем
ControlCode Определяемые драйвером IOCTL-коды:
• 0x000—0x7FF — зарезервировано Microsoft
• 0x800—OxFFF — определяются пользователем
TransferType Способ получения доступа к буферу:
• 0:METHOD_BUFFERED
• 1: METHOD_.IN_DT.RECT
• 2: METHOD_OUT_DIRECT
• 3: METHOD_NEITHER
RequiredAccess Тип доступа:
• 0x0000: FILE_ANY_ACCESS
• 0x0001: FILE_READ_ACCESS
• 0x0002: FILE_WRITE_ACCESS
• 0x0003: FILE_READ_ACCESS I FiLE_WRlTE_ACCES S
Заметим, что из табл. 8.2 видно, что флаги с и F, показанные на рис. 9.6 будут равны 0, если код IOCTL является зарезервированным кодом Microsoft.
Более подробное обсуждение значения констант, составляющих код IOCTL, выходит за рамки нашей книги, их можно найти в [8, 9]. Нас же прежде всего интересует способ обработки пользовательских кодов. Листинг 9.18 показывает пример обработки IOCTL-кодов в рабочей процедуре драйвера.
і. Листинг 9.18. Обработка IOCTL-кода в рабочей процедуре драйвера
//в процедуре DriverEntry регистрируем рабочую процедуру драйвера // для обработки IOCTL-кодов NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
Глава 9. Введение в WDM
207
DriverObject->MajorFunction[IRP_MJ_DEVICE-CONTROL] - IOCTL_DeviceControl;
return STATOS_SUCCESS;
}
// Рабочая процедура драйвера NTSTATUS
ICCTL-DeviceControl(
IN PDEVICE-OBJECt DeviceObject,
IN PIRP plrp
)
{
Il результат
NTSTATUS ntStatus - STATUS_SUCCESS; Il получить указатель на стек
PIO_STACK_LOCATION irpSp = IoGetCurrentlrpStackLocation(pIrp); Il получить код IOCTL
ULONG ioctlCode = irpSp->Paranieters.DeviceIoControl.IoControlCode; Il размер входного буфера
ULONG inSize - irpSp->Parameters.DeviceloControl.InputBufferLength; Il размер выходного буфера
ULONG outsize •= irpSp->Parameters.DeviceloControl.OutputBufferLength;
Il обработка кодов IOCTL .
switch (ioctlCode)
{
// коды IOCTL_xxx формируется разработчиком драйвера
case 1OCTL-CODEl:
{
// проверяем входные параметры
if ((inSize = 0) И (outsize = 0))
{
ntStatus = STATUS_INVALID_PARAMETER; break;
}
...... обработка 1OCrL-CQDEJ ......
break;
}
208
Часть III. Практика программирования
case I0CTL_G0DE2: {
// проверяем входные параметры
if (inSize < 100)
{
ntStatus = STATUS_BUFFER_TOO_SMALL; break;
}
...... обработка I0CTL_C0DE2 ......
break;
}
}
pIrp->IoStatus. Status = ntStatus; IoCompleteRequest( plrp, IO_NO_INCREMENT ); return ntStatus;
}
Как видно из заголовка функции DeviceloControl, драйверу передается входной и выходной буферы с данными. Драйвер получает указатели на эти данные а полях пакета IRP, зависящих от метода доступа, "зашифрованного" в коде номера IOCTL (см. табл. 9.2):
? при использовании метода method_buffered диспетчер в/в предоставляет единственный буфер в нестраничной памяти, достаточный для размещения входного и выходного буферов инициатора вызова. Адрес этой области размещается в поле Associatedlrp.SystemBuffer (листинг 9.8). Затем производится копирование входного буфера с данными инициатора запроса в эту область. В поле userBuffer заносится оригинальный адрес буфера для получения данных инициатора запроса. По завершении обработки запроса диспетчер в/в копирует содержимое выделенной области данных в выходной буфер инициатора запроса. Таким образом, драйверу предоставляется один буфер, даже если инициатор запроса указал два разных буфера;
? при использовании методов method_in_direct и method__oot_direct диспетчер в/в производит фиксацию (lock) выходного буфера инициатора запроса в физической памяти. Затем он производит построение списка дескрипторов памяти для выходного буфера и сохраняет указатель на этот список в поле MdiAddress пакета IRP. Кроме того, диспетчер в/в выделяет временную область в нестраничном пуле и сохраняет этот адрес в поле Associatedlrp. SystemBuff er пакета IRP. Производится копирование содержимого входного буфера инициатора запроса в выделенный
Предыдущая << 1 .. 65 66 67 68 69 70 < 71 > 72 73 74 75 76 77 .. 166 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100