Подскажите пожалуйста в чем может быть дело. Никак не могу найти ответа или решения. Написал драйвер на асме. Под SI все проходит нормально и драйвер вроде как загрузился, но если выйти из SI или вовсе не брякаться, то выпадает странный BSOD. А это притом, что во всех функциях, не попадающих под DriverEntry, стоят бряки, т.е. до них винда не доходит. Драйвер для NDIS'а, поэтому есть предполажение, что до дравака не доходят IRP'ы от NDIS'а, но это только предполажение Прикрепил скриншот бсода. Могу выложить любую часть кода, скажите только какую Заранее спасибо!
Bug Check 0x7E: SYSTEM_THREAD_EXCEPTION_NOT_HANDLED Необработанное исключение с кодом 0x80000003 - означает, что винда как раз доходит до какого-то бряка, он вызывает исключение (как и положено бряку), и это исключение никто не обрабатывает. (Единственным кандидатом мог бы быть SoftICE, но он не лезет куда не просят - он же не знает о левых int3, которые ставил не он. Кстати, попросить его можно командой "i3here on" либо "i3here drivers").
2diamond: Странно но я только при помощи i3here и перехватывал бряки Я тут посидел с SI более детально и понял, что у меня не проверялась NdisMRegisterDevice на ошибки, и драйаер продолжал регистрироваться с заранее провальным результатом. NdisMRegisterDevice возвращает NDIS_STATUS_NOT_SUPPORTED (0C00000BBh), осталось понять почему...
Видимо, SI не везде способен отловить int3... А вообще для анализа подобных вещей есть стандартная техника - ставим Microsoft'овские Debugging Tools ( http://www.microsoft.com/whdc/devtools/debugging/default.mspx ), и аварийный дамп (судя по скриншоту, установлен полный дамп, и сохраняется он в %SystemRoot%\memory.dmp) можно загрузить в kd (консольный вариант, запускать с опцией -z <имя-дампа>) или WinDbg (GUIшный вариант, запускать с опцией -z либо запускать без опций и открывать дамп из меню). После загрузки команда !analyze -v покажет кучу всякой информации о том, где именно и в каком окружении произошёл BSOD.
брр... да вобще мутота выходит Сижу под отладкой. NdisMRegisterDevice завершается неудачей из-за того, что внутри нее IoGetDriverObjectExtension ничего не возвращает. не понятно
Хочется посмотреть на DriverEntry - никакие вызовы ndis-функций инициализации не забыты? Кстати, насчёт BSOD'а - если используется fasm, то вряд ли SI отреагирует на int 3 через пробел (aka CD 03 vs int3 = CC), а исключение будет то же самое.
пользуюсь последним masm'ом Прочитал внимательно документацию по NdisMRegisterDevice. Там сказано: "NdisMRegisterDevice returns STATUS_SUCCESS if it succeeds, NDIS_STATUS_NOT_SUPPORTED if the caller is not an NDIS miniport driver, or a failure code if it fails." А NdisMRegisterDevice вызывался до NdisIMRegisterLayeredMiniport Теперь NdisMRegisterDevice выполняется удачно, но на общем фронте нет успеха. Вот DriverEntry и используемая в ней функция RegisterVirtualDriver, плюс создание девайсов PtRegisterDevice. Пытаюсь переписать src/network/ndis/passthru из WDK на асм. Все вроде почти так как в примере, но из-за неработоспособности онного на асме, немного переделываю. Код (Text): DriverEntry proc DriverObject:PDRIVER_OBJECT, RegistryPath:PUNICODE_STRING invoke DbgPrint, offset MESSAGE_StartDriver mov eax, DriverObject assume eax:PTR DRIVER_OBJECT mov [eax].DriverUnload, offset PtUnload assume eax:nothing invoke RegisterVirtualDriver, DriverObject, RegistryPath ret DriverEntry endp RegisterVirtualDriver proc pDriverObject:PDRIVER_OBJECT, pRegistryPath:PUNICODE_STRING LOCAL Status :NDIS_STATUS LOCAL PChars :NDIS_PROTOCOL_CHARACTERISTICS LOCAL MChars :NDIS_MINIPORT_CHARACTERISTICS and Status, NDIS_STATUS_SUCCESS invoke NdisAllocateSpinLock, addr GlobalLock invoke NdisMInitializeWrapper, addr NdisWrapperHandle, \ pDriverObject, \ pRegistryPath, \ NULL MainLoop: invoke RtlZeroMemory, addr MChars, \ sizeof NDIS_MINIPORT_CHARACTERISTICS mov MChars.MajorNdisVersion, 5 mov MChars.MinorNdisVersion, 1 mov MChars.InitializeHandler, offset MPInitialize mov MChars.QueryInformationHandler, offset MPQueryInformation mov MChars.SetInformationHandler, offset MPSetInformation mov MChars.ResetHandler, NULL mov MChars.TransferDataHandler, offset MPTransferData mov MChars.HaltHandler, offset MPHalt .if NDIS51_MINIPORT mov MChars.CancelSendPacketsHandler,offset MPCancelSendPackets mov MChars.PnPEventNotifyHandler, offset MPDevicePnPEvent mov MChars.AdapterShutdownHandler, offset MPAdapterShutdown .endif; NDIS51_MINIPORT mov MChars.CheckForHangHandler, NULL mov MChars.ReturnPacketHandler, offset MPReturnPacket mov MChars.SendHandler, NULL ;MPSend; mov MChars.SendPacketsHandler, offset MPSendPackets invoke NdisIMRegisterLayeredMiniport, NdisWrapperHandle, \ addr MChars, \ sizeof MChars, \ addr DriverHandle mov Status, eax .if Status != NDIS_STATUS_SUCCESS jmp EndLoop .endif invoke RtlZeroMemory, addr PChars, \ sizeof NDIS_PROTOCOL_CHARACTERISTICS mov PChars.MajorNdisVersion, 5 mov PChars.MinorNdisVersion, 1 invoke NdisInitUnicodeString, addr PChars._Name, \ $CTA0("VOLT_PT") ; Protocol name ; mov PChars.PName, addr PtName mov PChars.OpenAdapterCompleteHandler, offset PtOpenAdapterComplete mov PChars.CloseAdapterCompleteHandler,offset PtCloseAdapterComplete mov PChars.SendCompleteHandler, offset PtSendComplete mov PChars.TransferDataCompleteHandler,offset PtTransferDataComplete mov PChars.ResetCompleteHandler, offset PtResetComplete mov PChars.RequestCompleteHandler, offset PtRequestComplete mov PChars.ReceiveHandler, offset PtReceive mov PChars.ReceiveCompleteHandler, offset PtReceiveComplete mov PChars.StatusHandler, offset PtStatus mov PChars.StatusCompleteHandler, offset PtStatusComplete mov PChars.BindAdapterHandler, offset PtBindAdapter mov PChars.UnbindAdapterHandler, offset PtUnbindAdapter mov PChars.UnloadHandler, offset PtUnloadProtocol mov PChars.ReceivePacketHandler, offset PtReceivePacket mov PChars.PnPEventHandler, offset PtPNPHandler invoke NdisRegisterProtocol, addr Status, \ addr ProtHandle, \ addr PChars, \ sizeof NDIS_PROTOCOL_CHARACTERISTICS .if Status != NDIS_STATUS_SUCCESS invoke NdisIMDeregisterLayeredMiniport, DriverHandle jmp EndLoop .endif invoke NdisIMAssociateMiniport, DriverHandle, \ ProtHandle jmp MainLoop EndLoop: .if Status != NDIS_STATUS_SUCCESS ; Поставил регистрацию девайсов сюда invoke PtRegisterDevice invoke NdisTerminateWrapper, NdisWrapperHandle, \ NULL .endif mov eax, Status ret RegisterVirtualDriver endp PtRegisterDevice proc LOCAL Status :NDIS_STATUS LOCAL DeviceName :UNICODE_STRING LOCAL DeviceLinkUnicodeString :UNICODE_STRING LOCAL DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1] :PDRIVER_DISPATCH mov Status, NDIS_STATUS_SUCCESS invoke DbgPrint, $CTA0("++ PtRegisterDriver") invoke NdisAcquireSpinLock, addr GlobalLock inc MiniportCount .if MiniportCount == 1 CDS: invoke NdisReleaseSpinLock, addr GlobalLock invoke NdisMSleep, 1 invoke NdisAcquireSpinLock, addr GlobalLock .if ControlDeviceState != PS_DEVICE_STATE_READY jmp CDS .endif mov ControlDeviceState, PS_DEVICE_STATE_CREATING invoke NdisReleaseSpinLock, addr GlobalLock invoke RtlZeroMemory, addr DispatchTable, \ (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof PDRIVER_DISPATCH mov DispatchTable[IRP_MJ_CREATE], offset PtDispatch mov DispatchTable[IRP_MJ_CLEANUP], offset PtDispatch mov DispatchTable[IRP_MJ_CLOSE], offset PtDispatch mov DispatchTable[IRP_MJ_DEVICE_CONTROL], offset PtDispatch int 03h invoke NdisMRegisterDevice, NdisWrapperHandle, \ addr NTDEVICE_STRING, \ addr LINKNAME_STRING, \ addr DispatchTable, \ addr ControlDeviceObject, \ addr NdisDeviceHandle mov Status, eax invoke NdisAcquireSpinLock, addr GlobalLock mov ControlDeviceState, PS_DEVICE_STATE_READY .endif invoke NdisReleaseSpinLock, addr GlobalLock invoke DbgPrint, $CTA0("-- PtRegisterDriver") mov eax, Status ret PtRegisterDevice endp
Так. ну вроде с загрузкой разобрался и она проходит более менее успешно. Сейчас работаю над протокольной частью. Хотя после загрузки в WinObj при попытке просмотреть свойства девайса - бсод. и драйвер просмотреть нельзя. Думаю в этом виновата протокольная часть, ибо NDIS не доконца проинициализировал драйвер. И вот еще. Если трейсить агрузку в отладчике, то все хорошо - DriverEtry завершается успешно, а если без отладки - бсод. Забавно
Прошу прощения. Смею спросить: а почему Вы игнорируете вызов invoke NdisIMAssociateMiniport, DriverHandle, ProtHandle в случае удачного завершения invoke NdisRegisterProtocol, addr Status, \ addr ProtHandle, \ addr PChars, \ sizeof NDIS_PROTOCOL_CHARACTERISTICS в моём IM NDIS, NdisIMAssociateMiniport стоит непосредственно перед "регистрацией девайсов". Пишу на С/С++, прошу прощения если неправильно понял Ваш листинг.
Вот еще что. Попробуй PtRegisterDevice вызывать в DriverEntry после RegisterVirtualDriver. Сталкивался с проблемой когда функция NdisIMRegisterLayeredMiniport не успевала минипорт создать, но статус NDIS_STATUS_SUCCESS возвращала. И симптомы похожие, под отладчиком работает иначе вылетает.
Serjb прочитай мой предыдущий пост. Что поповоду "не успевает", то где лучше задержку посавить и какую? Перед NdisMRegisterDevice, поставить NdisMSleep(5)??
хм.. Все регистрируется. Потом NDIS вызывает NetEventBindsComplete. Этого события не было в примере, по советам из MSDN я просто возвращаю NDIS_STATUS_SUCCESS. Все вроде хорошо и никаких бсодов. Только вот выгрузка драйвера в KmdManager завершается Fail-Команда неуместна для данной службы. Даже не попадаю на бряк в PtUnload Самая главная проблема остается. Не вызываются функции для обработки входящих и исходящих пакетов
Nable , вот взгляни может поможет, у меня этот код работает ++MiniportCount; if (1 == MiniportCount)//MiniportCount { ControlDeviceState = PS_DEVICE_STATE_CREATING; NdisReleaseSpinLock(&g_Data.AdapterListLock);//&GlobalLock NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH)); // Вход для пользовательского режима DispatchTable[IRP_MJ_CREATE] = RetOpen; // тут создаем DispatchTable[IRP_MJ_CLEANUP] = RetCleanup; // тут их чистим DispatchTable[IRP_MJ_CLOSE] = RetClose; // останавливаем захват пакетов DispatchTable[IRP_MJ_DEVICE_CONTROL] = RetIoControl; // получам адрес структуры описывающей буферы NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING); NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING); // // Регистрим устройство и таблицу DispatchTable точек вместо IoCreateDevice // Status = NdisMRegisterDevice( wrapperHandle, &DeviceName, &DeviceLinkUnicodeString, &DispatchTable[0], &ControlDeviceObject, &NdisDeviceHandle ); ControlDeviceState = PS_DEVICE_STATE_READY; } Я сравнил свой код и твой: у меня намного меньше спинлоков. Может проблема в этом. теперь относительно "не успевает": NdisIMRegisterLayeredMiniport возвращает описатель NdisWrapperHandle практически мгновенно, но после или во время этого еще вызывается MPInitialize из MChars но она вызывается через DCP поэтому может возникнуть ситуация когда NdisWrapperHandle уже есть но структура не заполнена. Хотел дать ссылку на статью где это описано, но блин, не нашел. Вот стормозил с ответом, ну ты похоже разобрался сам.
Да вот еще, ControlDeviceState это информативная переменная для NDIS а не для тебя, возможно процедура ходит вокруг CDS: ... jmp CDS
С регистрацией все нормально. в CDS не ходит потому что ControlDeviceState изначально PS_DEVICE_STATE_READY=0 а вот тут интересно. Функция указана и присутствует в MChars, она создана и внутри нее стоит бряк. Но вот она ниразу не вызывалась
Serjb Куда мы смотрели? Вот последовательность действий. Код (Text): 1) During DriverEntry, the Passthru driver registers as a protocol and an Intermediate miniport driver. 2) Later on, NDIS calls Passthru’s BindAdapterHandler, PtBindAdapter, for each underlying NDIS adapter to which it is configured to bind. 3) In the context of BindAdapterHandler and after successfully opening a binding to the underlying adapter, the Passthru driver queries the reserved keyword "UpperBindings" to get a list of device names for the virtual adapters that this particular binding is to expose. Since this driver implements a 1:1 relationship between lower bindings and virtual adapters, this list contains a single name. “Mux” IM drivers that expose multiple virtual adapters over a single underlying adapter will process multiple entries in UpperBindings. 4) For each device name, the Passthru driver calls NdisIMInitializeDeviceInstanceEx. 5) In response, NDIS will eventually call back Passthru miniport’s MiniportInitialize entry point, MPInitialize. .. 13.4 NDIS calls the Passthru driver’s ProtocolPnPEvent entry point (PtPnPHandler) whenever the underlying adapter is transitioned to a different power state. If the underlying adapter is transitioning to a low power state, the IM driver should wait for all outstanding sends and requests to complete. .. и.т.п. Так что, если подчиняться этим правилам и все делать как в примере, то второй шаг не выполняется, а после первого иногда выполняется сразу 13.4 Тут опять же, функция есть и там бряк. DriverEntry завершается успешно, но сразу после этого бсод под отладчиком или просто все виснет. (иногда проскальзывае и попадаю на бряк в PtPnPHandler [13,4]) Прикрепил бсод и полезный код. Все в архиве
Мдя. Возился с оригинальным примером из WDK. Готовый драйвер с двумя инфами в архиве ./passthru. В нем стоят бряки в начале DriverEntry и в PtBindAdapter. NDIS будет вызывать bindAdapter только если драйвер правильно подключить. Например так: Код (Text): Prepare an installation directory that contains these files: netsf.inf, netsf_m.inf, and passthru.sys. In Control Panel, open Network Connections. Right-click the relevant Local Area Connection icon and click Properties. Click Install, click Service, click Add, and then click Have Disk. Browse to the drive and directory that contain the files from step 1, and then click OK. Select “Passthru Driver” and click OK. This action should install the Passthru driver. Click OK or Yes each time the system prompts with a warning regarding installation of unsigned files. This step is necessary because binaries that are generated through the WDK build environment are not signed. Через KmdManager NDIS не будет реагировать на новый драйвер. Тогда возникает такой вопрос. Можно ли обойтись без использования дополнительных инфов? В документация вот что сказано: Код (Text): Alternate Installation You can install this sample programmatically by using the INetCfg APIs. Может также возможно сделать, чтобы драйвер не светился в свойствах сетевого подключения адаптера и диспетчере устройств?