Как писать драйвера
Шрифт:
Майкрософт утверждает что нам нужны 4 функции минимум, присутствующие в DriverEntry:
NdisMInitializeWrapper;
NdisIMRegisterLayeredMiniport;
NdisRegisterProtocol;
NdisIMAssociateMiniport.
NdisMInitializeWrapper – функция указывает системе NDIS, что пришло время инициировать miniport service в ее системе. Возвращаемое значение необходимо сохранить на будущее. Обязательно надо обратить внимание, что если происходит ошибка при инициализации любого объекта, то при уже нормально отработавшей функции NdisMInitializeWrapper нужно вызвать NdisTerminateWrapper для высвобождения ресурса.
NdisIMRegisterLayeredMiniport Функция, регистрирующая все функции уровня miniport
NdisRegisterProtocol Функция, регистрирующая все функции протокола
NdisIMAssociateMiniport. Функция, информирующая NDIS о том, что есть, существует два уровня, минипорт и протокол, и говорящая об экспорте функций, если таковой присутствует.
Теперь, для полной расшифровки этой шарады, посмотрим, как работает система драйвера, уже на уровне кода.
После того, как драйвер зарегистрирует функции группы miniport, он должен зарегистрировать полученный HANDLE, для правильной un-регистрации этих функций в момент окончания работы драйвера. Это делает функция NdisMRegisterUnloadHandler. Затем мы регистрируем протокольную группу и связываем эти две группы, сообщая NDIS об их существовании – функцией NdisIMAssociateMiniport.
На этом в нашем примере функция DriverEntry закачивается. Стоит немного пояснить еще несколько моментов работы инициализации. При работе на уровне kernel не стоит использовать функции: malloc, realloc, memset и т. д. Для этого существуют NdisZeroMemory, NdisAllocateMemory и др. Они более конкретно работают, и предназначены именно для использования в драйверах связанных с NDIS.
Конкретно сами функции, которые принадлежат группам, мы с вами будем рассматривать в процессе написания кода, да и то не все. Полное их описание вы уже посмотрите в DDK help. А мы с вами посмотрим на неявную третью группу.
Третья группа функций используется для коммуникации с аппликацией. Иногда и для непосредственного создания пакетов, и их отправки, как в случае с драйвером СОМ порта. В нашем случае драйвер пока никак не взаимодействует с уровнем аппликаций, поэтому их нет. Но, любой драйвер нуждается в управлении, наш пример, особенно, ибо он является тестовым и нам необходимо уметь давать нужные команды. Поэтому мы создадим и проинициализируем следующие функции:
Внесите их в файл passthru.h.
Теперь внесем изменения в нашу функцию DriverEntry.
Объявим массив:
Этот массив будет содержать все указатели функций для регистрации.
И добавим еще несколько переменных:
Затем начнем инициализацию. Перед завершающей регистрацией протокольных функций и связкой их с группой miniport и NDIS, функцией NdisIMAssociateMiniport, добавим следующий код: