Привет Все! Я драйверами начал заниматься не так давно, поэтому постоянно наступаю на какие-нибудь "грабли". Очередные "грабли" произошли при вызове системой функции ProtocolUnbindAdapter. Вроде бы делаю все правильно: в ProtocolBindAdapter выделяю память под очередь пакетов и данных и вызываю NdisOpenAdapter(отрабатывает без ошибок). Но при вызове функции NdisDeRegisterProtocol система начинает циклически вызывать ProtocolUnbindAdapter - в результате комп. перегружается. Не подскажите в чем может быть проблема?
VOID NdisProtocolBindAdapter(PNDIS_STATUS Status, NDIS_HANDLE BindContext, PNDIS_STRING DeviceName, PVOID SystemSpecific1, PVOID SystemSpecific2) { PNDISUIO_OPEN_CONTEXT pOpenContext; NDIS_MEDIUM MediumArray[]= {NdisMedium802_3}; NDIS_STATUS ErrorStatus; UINT MediumIndex; UINT ByteProcessed; ULONG GenericULong=0; #if DBG DbgPrint("-NetworkAnalizer- In BindAdapter\n"); #endif pOpenContext=(PNDISUIO_OPEN_CONTEXT)ExAllocatePool(NonPagedPool,sizeo f(NDISUIO_OPEN_CONTEXT)); if(pOpenContext==NULL) { #if DBG DbgPrint("-NetworkAnalizer- Enought memory to allocate NDISUIO_OPEN_CONTEXT"); #endif *Status=NDIS_STATUS_RESOURCES; } NdisZeroMemory(pOpenContext,sizeof(NDISUIO_OPEN_CONTEXT)); pOpenContext->DeviceName.Buffer=(PWSTR)ExAllocatePool(NonPagedPool, 2*wcslen(DeviceName->Buffer)+1); NdisMoveMemory(pOpenContext->DeviceName.Buffer, DeviceName->Buffer, 2*wcslen(DeviceName->Buffer)+1); NdisOpenAdapter(Status, &ErrorStatus, &(pOpenContext->BindingHandle), &MediumIndex, MediumArray, 1, Globals.NdisProtocolHandle, BindContext, &(pOpenContext->DeviceName), 0, NULL); if (*Status==NDIS_STATUS_SUCCESS) { #ifdef DBG DbgPrint("-NetworkAnalizer- OpenAdapter successfully BindingHandle=%u.\n", pOpenContext->BindingHandle); DbgPrint("-NetworkAnalizer- DeviceName= %ws\n", pOpenContext->DeviceName.Buffer); #endif } else { #ifdef DBG DbgPrint("-NetworkAnalizer- not OpenAdapter.\n"); #endif } pOpenContext->PowerState=NetDeviceStateD0; } VOID NdisProtocolUnbindAdapter( PNDIS_STATUS Status, NDIS_HANDLE ProtocolBindingContext, NDIS_HANDLE UnbindContext) { PNDISUIO_OPEN_CONTEXT pOpenContext; #if DBG DbgPrint("-NetworkAnalizer- In UnBindAdapter\n"); #endif pOpenContext=(PNDISUIO_OPEN_CONTEXT)ProtocolBindingContext; if (pOpenContext->DeviceName.Buffer!=NULL) NdisFreeMemory(pOpenContext->DeviceName.Buffer, 2*wcslen(pOpenContext->DeviceName.Buffer)+1, 0); #if DBG DbgPrint("-NetworkAnalizer- NdisFreeMemory\n"); #endif if (pOpenContext!=NULL) ExFreePool(pOpenContext); #if DBG DbgPrint("-NetworkAnalizer- ExFreePool\n"); #endif }
Чуешь разницу ? Код (Text): PtUnbindAdapter proc uses edi esi Status:PNDIS_STATUS, ProtocolBindingContext:NDIS_HANDLE, UnbindContext:NDIS_HANDLE ; ;local BindingHandle :NDIS_HANDLE ; mov edi, ProtocolBindingContext assume edi:ptr ADAPT ; .if [edi].QueuedRequest==TRUE mov [edi].QueuedRequest, FALSE invoke PtRequestComplete, edi, addr [edi].Request, NDIS_STATUS_FAILURE .endif ; Check if we had called NdisIMInitializeDeviceInstanceEx and ; we are awaiting a call to MiniportInitialize. .if [edi].MiniportInitPending==TRUE ; Try to cancel the pending IMInit process. invoke NdisIMCancelInitializeDeviceInstance, DriverHandle, addr [edi].DeviceName .if eax==NDIS_STATUS_SUCCESS ; Successfully cancelled IM Initialization; our ; Miniport Initialize routine will not be called ; for this device. mov [edi].MiniportInitPending, FALSE .else ; Our Miniport Initialize routine will be called ; (may be running on another thread at this time). ; Wait for it to finish. invoke NdisWaitEvent, addr [edi].MiniportInitEvent, 0 .endif .endif ; Call NDIS to remove our device-instance. We do most of the work ; inside the HaltHandler. ; The Handle will be NULL if our miniport Halt Handler has been called or ; if the IM device was never initialized .if [edi].MiniportHandle!=NULL invoke NdisIMDeInitializeDeviceInstance, [edi].MiniportHandle mov edx, Status mov dword ptr [edx], eax .if eax!=NDIS_STATUS_SUCCESS mov dword ptr [edx], NDIS_STATUS_FAILURE .endif .else ; We need to do some work here. ; Close the binding below us ; and release the memory allocated. .if [edi].BindingHandle!=NULL invoke NdisResetEvent, addr [edi].Event invoke NdisCloseAdapter, Status, [edi].BindingHandle ; Wait for it to complete mov eax, Status .if dword ptr [eax]==NDIS_STATUS_PENDING invoke NdisWaitEvent, addr [edi].Event, 0 mov eax, Status push [edi].Status pop dword ptr [eax] .endif .else ; Both Our MiniportHandle and Binding Handle should not be NULL. mov eax, Status mov dword ptr [eax], NDIS_STATUS_FAILURE .endif ; Free the memory here, if was not released earlier(by calling the HaltHandler) invoke NdisFreeMemory, edi, sizeof(ADAPT), 0 .endif assume edi:ptr nothing ; ret ; PtUnbindAdapter endp Что то не наблюдается NdisIMDeInitializeDeviceInstance, поэтому система думает, что адаптер ещё прибиндин Да и статус не возвращается...
Спасибо за ответ. Но ошибка, к сожалению, не в этом. После долгих поисков я выяснил что ProtocolBindingContext не содержится указатель на NDISUIO_OPEN_CONTEXT. Из-за этого и происходит циклический вызов. Теперь непонятно почему Ndis не передает этот указатель?
Все, нашел ошибку: в NdisOpenAdapter вместо (NDIS_HANDLE)pOpenContext передал BindContext ). Дурацкая ошибка отняла у меня кучу времени (.