Мое почтение всем. Пробую написать простейший NDIS драйвер протокола. Возникла пара вопросов. Код (Text): #include <ntddk.h> #include <ndis.h> #include "dbgmsg.h" NDIS_HANDLE ProtocolHandle; VOID NdisTestBindAdapter(__out PNDIS_STATUS Status, __in NDIS_HANDLE BindContext, __in PNDIS_STRING DeviceName, __in PVOID SystemSpecific1, __in PVOID SystemSpecific2) { DBG_TRACE("NdisTestBindAdapter", "Called"); *Status = NDIS_STATUS_SUCCESS; } VOID NdisTestUnbindAdapter(__out PNDIS_STATUS Status, __in NDIS_HANDLE ProtocolBindingContext, __in NDIS_HANDLE UnbindContext) { DBG_TRACE("NdisTestUnbindAdapter", "Called"); *Status = NDIS_STATUS_SUCCESS; } NDIS_STATUS NdisTestPnPEvent(__in NDIS_HANDLE ProtocolBindingContext, __in PNET_PNP_EVENT NetPnPEvent) { DBG_TRACE("NdisTestPnPEvent", "Called"); return NDIS_STATUS_SUCCESS; } NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath) { NDIS_STATUS NdisStatus; NTSTATUS status = STATUS_SUCCESS; NDIS_STRING ProtocolName = NDIS_STRING_CONST("NDISTest"); NDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics; DBG_TRACE("DriverEntry", "Loading"); NdisZeroMemory(&ProtocolCharacteristics, sizeof(ProtocolCharacteristics)); ProtocolCharacteristics.MajorNdisVersion = 0x05; ProtocolCharacteristics.MinorNdisVersion = 0x00; ProtocolCharacteristics.Name = ProtocolName; ProtocolCharacteristics.BindAdapterHandler = NdisTestBindAdapter; ProtocolCharacteristics.UnbindAdapterHandler = NdisTestUnbindAdapter; ProtocolCharacteristics.PnPEventHandler = NdisTestPnPEvent; NdisRegisterProtocol(&NdisStatus, &ProtocolHandle, &ProtocolCharacteristics, sizeof(ProtocolCharacteristics)); if (NdisStatus != NDIS_STATUS_SUCCESS) { DBG_PRINT2("NdisRegisterProtocol: %X\n", NdisStatus); status = STATUS_UNSUCCESSFUL; } return status; } В WinDbg вижу: Почему-то не вызывается ProtocolBindAdapter. Насколько я понял, она должна вызываться NDIS'ом сразу после успешной регистрации. Кроме того, не совсем ясна роль параметра BindContext. Код (Text): VOID ProtocolBindAdapter( __out PNDIS_STATUS Status, __in NDIS_HANDLE BindContext, __in PNDIS_STRING DeviceName, __in PVOID SystemSpecific1, __in PVOID SystemSpecific2 ) Его надо просто передать в NdisCompleteBindAdapter в случае отложенной привязки к NIC'у? Заранее благодарен.
Mika0x65 1) Девайс создай (FILE_DEVICE_NETWORK). 2) Где остальные обработчики типа OpenAdapterCompleteHandler \ CloseAdapterCompleteHandler, и так далее. 3) Возможно еще ошибка в inf описалове. 4) Какая ось ? если виста и выше, то нужно 6 версию протокола.
- не обязательно ... - надо Скорее всего проблема в ProtocolCharacteristics.Name не обязательно ... Mika0x65 Добавь фукнции и проверь "HKR,Ndi,Service,ProtoName" в inf файле!
Отвечу сразу всем . Устройство не создаю -- общения с UserMode нет, драйвер отчитывается только с помощью DbgPrint. Насколько я понимаю, NDIS6.0 поддерживает NDIS 5.X. Драйвер запускается в XP с помощью sc.exe. Попробую загрузить через .inf. Насчет обработчиков: хочется написать самый минимальный драйвер, чтобы не утонуть в деталях. Поэтому старался добавить только минимум обработчиков. Попробую добавить ProtocolOpenAdapter, ProtocolOpenAdapterComplete, ProtocolCloseAdapter и ProtocolCloseAdapterComplete. Вообще, я думал, что NDIS скажет, что драйверу не хватает обработчиков при попытке его зарегистрировать. Видимо, не говорит. И еще один вопрос. Насколько я понимаю, последовательность вызовов ф-ий должна быть такова: 1. Драйвер регистрируется с помощью NdisRegisterProtocol, NDIS вызывает ProtocolBindAdapter для каждого NIC'а. 2. Ф-ия ProtocolBindAdapter вызывает NdisOpenAdapter. ProtocolBindAdapter может вернуть NDIS_STATUS_SUCCESS в случае если все завершено успешно, ошибку в случае если что-то пошло не так, или отложить привязку к адаптеру возвратом NDIS_STATUS_PENDING. В последнем случае необходимо вызвать NdisCompleteBindAdapter. 3. В случае если ProtocolBindAdapter вернула NDIS_STATUS_SUCCESS или была вызвана NdisCompleteBindAdapter, NDIS вызывает ф-ию ProtocolOpenAdapterComplete. 4. NDIS вызывает PnPEventHandler с параметром NetEventBindsComplete в случае завершения привязки ко всем NIC'ам. Насчет последнего пункта я не очень уверен, т.к. судя по логу, ф-ия была вызвана даже если привязки не произошло. И еще: для чего нужен параметр NdisBindingContext в ProtocolBindAdapter? Мне сказали, что это что-то вроде PVOID Context для ф-ии создания потока -- параметр будет передан ф-ии ProtocolOpenAdapterComplete. Я не против, но зачем его передавать в ProtocolBindAdapter?.. Подозреваю, что это просто какая-то несогласованность, но лучше спросить. Спасибо за ответы .
NdisBindingContext в ProtocolBindAdapter? Но практического применения я не знаю и не где не видел , обычно UNREFERENCED_PARAM. В dispatcher "ProtocolBindAdapter" когда идет вызов "NdisOpenAdapter" может вернуть PENDING, тогда тебе требуется дождаться вызова dispatcher "ProtocolOpenAdapterComplete" (EVENT'ом). Так что вызов может быть одновременно(ProtocolBindAdapter, ProtocolOpenAdapterComplete) ... 4) Да
НА счет ProtocolBindAdapter BindContext: Dispatcher ProtocolBindAdapter возврощает PENDING, тогда делаешь вызов NdisCompleteBindAdapter c этим BindContext This function completes a binding operation for which the caller's ProtocolBindAdapter function previously returned NDIS_STATUS_PENDING.
ntkernelspawn В общем, как я понимаю, это просто способ передать что-то в ProtocolOpenAdapterComplete. Почитал MSDN, еще вопрос созрел: Это из описания ProtocolOpenAdapterComplete. В примере NdisProt ProtocolOpenAdapterComplete не вызывает NdisCompleteBindAdapter. Я так понимаю, что ее можно и не вызывать?
Из вашего "Dispatcher ProtocolBindAdapter" возврощает PENDING, то и есть вы еще не сказали что bind завершен, но из диспатчера вышли, но когда то вы его завершите, и тогда надо будет вызывать NdisCompleteBindAdapter с BindContext который получили в ProtocolBindAdapter. На пабликах такого кода я не встречал(Так как он на сколько я понял используется для тонкой оптимизации инициализации протокола, а на паблике сильной оптимизации драйверов я не встречал) так что рекомендую временно на него забить ...
Ну, вопрос немного не в этом был. Саму схему взаимодействия я, вроде, понял. Просто MSDN говорит, что NdisCompleteBindAdapter надо вызвать из ProtocolOpenAdapterComplete, а ProtocolOpenAdapterComplete, как я понял, вызовется только после того, как будет завершена привязка. Т.е. будет вызвана NdisCompleteBindAdapter. Получается замкнутый круг. А если говорить про практику, то, вроде, у меня все получилось. Добавил обработчики открытия и закрытия адаптера и загрузил драйвер через .inf. ProtocolBindAdapter успешно вызвалась, а за ней PnPEventHandler. Мне просто хочется не только чтобы работало, но чтобы и правильно было.
Нужно создавать inf файл для протокола и биндить его к нужным нижележащим (см. Specifying Binding Interfaces). Summary of Changes Required to Port a Protocol Driver to NDIS 6.0
Обработчики я бы ввел все, просто поставил на них бы функции заглушки. Что это дает? Дает, то что можно установить в функция _asm int 3 или DbgPrint, это уж как хочеться и по этим сообщениям получать последовательность вызовов Обработчиков, как только последовательность вызовов обработчиков будет понятна это даст пищу для размышлений. Какие обработчики и когда вызываются. Простой дедуктивный метод, поможет по поведению обработчиков, понять где копать.