Как писать драйвера - страница 7

Шрифт
Интервал

стр.

Освобождение пакета при нормальной передаче.

>  NdisDprFreePacket(MyPacket);

>  break;

> }

>}

Выбор типа адаптера внизу дает возможность применить для индикации готовности к передаче в случае ошибки стандартного сообщения NDIS. Это происходит в случае специфичных сетей и обрабатывается функциями связанными с этими типами.

>pAdapt->IndicateRcvComplete = TRUE;

>switch (pAdapt->Medium) {

>case NdisMedium802_3:

> NdisMEthIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize);

> break;

>case NdisMedium802_5:

> NdisMTrIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize);

> break;

>case NdisMediumFddi:

> NdisMFddiIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize);

> break;

>default:

Это в случае если тип сети неизвестен.

> ASSERT(0);

>  break;

> }

>} while(FALSE);

>return Status;

Выход с статусом завершения.

Некоторое пояснение.

Когда тип адаптера и сети специфичен и отличается от стандарта LAN, нам нужно сообщить о пакете и его отправке соответствующей части сервиса NDIS. Именно в связи с этим и появляется выбор типа адаптера. При получении возможно наличие одновременного запроса на прием пакета с разных адаптеров.

В случае с операцией Send этого не происходит, так как NDIS сама по контексту определяет к какому адаптеру предназначен пакет.

Оставшиеся функции аналогичны по назначению с группой функций минипорта.

Как писать драйвера (часть 5)

Итак, мы возвращаемся к драйверам.

Справедливости ради, стоит отметить, что на сайте эта тема – одна из самых популярных, так что, кому нужны более глубокие знания, может обращаться к нам на форум, там обсуждаются конкретные проблемы.

Сегодня мы поговорим о коммуникации программы с драйвером.

В одной из предыдущих статей описаны были функции типа Filter:

Вот они:

>extern NTSTATUS FilterOpen(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

>extern NTSTATUS FilterClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

>extern NTSTATUS FilterRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

>extern NTSTATUS FilterWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

>extern NTSTATUS FilterIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

В любом драйвере необходима система управления, для указания самому драйверу, какого типа операцию стоит выполнить в текущий момент времени.

Скажем для нашего примера, драйверу фильтра потока данных по сети стоит указывать степень фильтрации, типы портов для перехвата, адреса, запрещенные к обращению и т.п.

Для этого используются вышеназванные функции.

FilterOpen вызывается когда в программе вызвано обращение к драйверу с помощью функции CreateFile

FilterClose – CloseHandle()

FilterRead/FilterWrite – ReadFile/WriteFile

FilterIoControl – DeviceIoControl() соответственно.

Для правильного завершения работы каждой из этих функций – нужно обеспечить передачу в программу необходимых данных.

>NTSTATUS FilterOpen(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {

> // инициализация любых управляющих параметров, например структуры управляющих данных

> Irp->IoStatus.Status = NDIS_STATUS_SUCCESS; // Возращаемое значение – ошибка или нормальное. При нормальном завершении – будет передан HANDLE на устройство, в нашем случае на драйвер.

> Irp->IoStatus.Information = 0; // Количество переданных вверх байт – в нашем случае 0 потому как нет передаваемых параметров.

> IoCompleteRequest(Irp, IO_NO_INCREMENT); // Завершение работы.

> return NDIS_STATUS_SUCCESS; // Нормальный код возврата.

>}

Эта форма будет использоваться в том или ином виде в каждой из этих функций.

Точно так же выглядит и функция закрытия:

>NTSTATUS FilterClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {

> // Код окончания работы с драйвером.

> Irp->IoStatus.Status = NDIS_STATUS_SUCCESS;

> Irp->IoStatus.Information = 0;

> IoCompleteRequest(Irp, IO_NO_INCREMENT);

> return NDIS_STATUS_SUCCESS;

>}

В драйвере можно создать например просто элемент для нашего примера – например, описать глобальную переменную DWORD Port; Ее будем испрользовать для задания номера порта для перехвата.


стр.

Похожие книги