При попытке выгрузить драйвер следющий код "зависает".Насколько я понял, то не вызывается PCloseAdapter. В чем может юыть проблема?
void PCloseAdapter (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
{
_asm
{
int 3
}
DbgPrint("PCloseAdapter called");
NdisSetEvent(&CloseWaitEvent);
return;
}
void OnUnload( IN PDRIVER_OBJECT DriverObject)
{
NDIS_STATUS Status;
DbgPrint("OnUnload called");
IoDeleteSymbolicLink(&SymLink);
IoDeleteDevice(DriverObject->DeviceObject);
NdisResetEvent(&CloseWaitEvent);
NdisCloseAdapter(&Status,BindingAdapter);
if (Status==NDIS_STATUS_PENDING)
{
NdisWaitEvent(&CloseWaitEvent,0);
}
NdisDeregisterProtocol(&Status,ProtocolHandle);
if (NT_SUCCESS(Status)==FALSE)
{
DbgPrint("DeregisterProtocol faild!!!");
}
else
{
DbgPrint("DeregisterProtocol SUCCESS");
}
NdisFreeBufferPool(BufferPoolH);
NdisFreePacketPool(PacketPoolH);
DbgPrint("Free Buffer and Packet Pools");
NdisFreeSpinLock(&GlobalLock);
NdisFreeSpinLock(&ReadlLock);
DbgPrint("Free SpinLock");
return;
}
Если у Вас это IM минипорт, то надо начать с того, что Вы не имеете права создавать свои устройства ( IoCreateDevice ) и не имеете права устанваливать ф.Unload в DRIVER_OBJECT. Раз уж решили писать NDIS IM драйвер — мучайтесь по-полной

.( Hint: NdisMRegisterDevice, NdisMRegisterUnloadHandler ).
Здравствуйте, TarasCo, Вы писали:
TC>Если у Вас это IM минипорт, то надо начать с того, что Вы не имеете права создавать свои устройства ( IoCreateDevice ) и не имеете права устанваливать ф.Unload в DRIVER_OBJECT. Раз уж решили писать NDIS IM драйвер — мучайтесь по-полной
.( Hint: NdisMRegisterDevice, NdisMRegisterUnloadHandler ).
Ну вообще хотесь бы написать IM драйвер, но сначала надобы разобратся с драйвером протокола. Я уже убрал IoCreateDevice и все остальное(кроме Unload), но только сейчас понял почему не работало. Все вроде как работает, вот только почему-то не вызывается функция ReceiveHanler.
Вы как человек, по всей видимости хорошо знающий NDIS, может подскажете в чем дело?
Вот весь код
#define NDIS40 1
#include <ntddk.h>
#include <ndis.h>
#include <ntddndis.h>
#include <stdio.h>
#define ETHERNET_FRAME_LENGTH 1514
NDIS_SPIN_LOCK GlobalLock;
NDIS_SPIN_LOCK ReadLock;
NDIS_EVENT CloseWaitEvent;
UCHAR Frame[ETHERNET_FRAME_LENGTH+1];
ULONG FrameLen=0;
#define ETHERNET_HEADER_LENGTH 14
#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved))
#define TRANSMIT_PACKETS 128
#define MAX_POSITIONS 32
typedef struct _PACKET_RESERVED {
PVOID pBuffer; /* used for buffers built in kernel mode */
ULONG bufferLen;
PVOID pHeaderBufferP;
ULONG pHeaderBufferLen;
} PACKET_RESERVED, *PPACKET_RESERVED;
struct UserStruct
{
ULONG mData;
}pUserStruct;
NDIS_HANDLE BindingAdapter;
NDIS_HANDLE ProtocolHandle;
NDIS_HANDLE PacketPoolH;
NDIS_HANDLE BufferPoolH;
UNICODE_STRING SymLink;
// Функции обратного фызова протокола
//***********************************************************************************************
void POpenAdapter(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus);
void PCloseAdapter (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status);
void PSendComplete (IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status);
void PTransferDataComplete (IN NDIS_HANDLE PBindingContext, IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status,IN UINT BytesTransfered);
NDIS_STATUS PReceive (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize, UINT PacketSize);
void PRecieveComplete (IN NDIS_HANDLE ProtocolBindingContext);
void PStatus(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status,
IN PVOID StatusBuffer, IN UINT StatusBufferSize);
void PStatusComplete (IN NDIS_HANDLE ProtocolBindingContext);
void PResetComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status);
void PRequestComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status);
void PBindAdapter(OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext,
IN PNDIS_STRING theDeviceNameP, IN PVOID theSS1, IN PVOID theSS2);
void PUnbindAdapter(OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext,
IN PNDIS_HANDLE theUnbindContext);
NDIS_STATUS PPnPEvent(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnpEvent);
INT PRecievePacket(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet);
void PUnload(VOID);
// **********************************************************************************************
void OnUnload( IN PDRIVER_OBJECT DriverObject);
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegPath)
{
UINT MediumIndex=0;
NDIS_PROTOCOL_CHARACTERISTICS PC;
NDIS_STATUS Status,ErrorStatus;
NDIS_MEDIUM Medium[1] = {NdisMedium802_3};
UNICODE_STRING AdapterName;
NDIS_STRING ProtocolName = NDIS_STRING_CONST("Packet Analizer");
UNICODE_STRING DeviceName;
PDEVICE_OBJECT Device;
DbgPrint("Driver Loading...");
NdisAllocateSpinLock(&GlobalLock);
NdisAllocateSpinLock(&ReadLock);
NdisInitializeEvent(&CloseWaitEvent);
DriverObject->DriverUnload=OnUnload;
RtlInitUnicodeString(&AdapterName,L"\\Device\\{8F08FD03-BC88-4D50-BA17-BA23BEF8EC61}");
NdisZeroMemory(&PC,sizeof(PC));
PC.MajorNdisVersion=4;
PC.MinorNdisVersion=0;
PC.Reserved=0;
PC.BindAdapterHandler=PBindAdapter;
PC.UnbindAdapterHandler=PUnbindAdapter;
PC.OpenAdapterCompleteHandler=POpenAdapter;
PC.CloseAdapterCompleteHandler=PCloseAdapter;
PC.ReceiveHandler=PReceive;
PC.ReceiveCompleteHandler=PRecieveComplete;
PC.TransferDataCompleteHandler=PTransferDataComplete;
PC.ReceivePacketHandler=PRecievePacket;
PC.SendCompleteHandler=PSendComplete;
PC.ResetCompleteHandler=PResetComplete;
PC.RequestCompleteHandler=PRequestComplete;
PC.StatusHandler=PStatus;
PC.StatusCompleteHandler=PStatusComplete;
PC.PnPEventHandler=PPnPEvent;
PC.UnloadHandler=PUnload;
PC.Name=ProtocolName;
DbgPrint("Registering Protocol...");
NdisRegisterProtocol(&Status,&ProtocolHandle,&PC,sizeof(PC));
if (Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint("Error on registering protocol");
return Status;
}
NdisOpenAdapter(&Status,&ErrorStatus,&BindingAdapter,&MediumIndex,Medium,1,ProtocolHandle,&pUserStruct,
&AdapterName,0,NULL);
if (Status!=NDIS_STATUS_PENDING)
{
if (NT_SUCCESS(Status)==FALSE)
{
DbgPrint("Error on opening adapter. Error : %d",ErrorStatus);
NdisDeregisterProtocol(&Status,ProtocolHandle);
return STATUS_UNSUCCESSFUL;
}
else
{
DbgPrint("Adapter Opened");
POpenAdapter(&pUserStruct,Status,NDIS_STATUS_SUCCESS); //???
}
}
else
{
DbgPrint("Apter STATUS_PENDING");
}
return STATUS_SUCCESS;
}
void POpenAdapter(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus)
{
NDIS_REQUEST Request;
NDIS_STATUS aStatus;
NDIS_STATUS AnotherStatus;
ULONG Mode = NDIS_PACKET_TYPE_PROMISCUOUS;
DbgPrint("POpenAdapter called");
if (NT_SUCCESS(OpenErrorStatus))
{
Request.RequestType = NdisRequestSetInformation;
Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
Request.DATA.SET_INFORMATION.InformationBuffer = &Mode;
Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG);
NdisRequest(&AnotherStatus,BindingAdapter,&Request);
if(NT_SUCCESS(AnotherStatus)) DbgPrint("NdisRequest SUCCES");
DbgPrint("POpenAdapter SUCCESS");
}
else
{
DbgPrint("Error on called POpenAdapter");
}
}
void PSendComplete (IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status)
{
DbgPrint("PSendComplete called");
return;
}
void PTransferDataComplete (IN NDIS_HANDLE PBindingContext, IN PNDIS_PACKET pPacket,
IN NDIS_STATUS Status,IN UINT BytesTransfered)
{
DbgPrint("PTransferDataComplete called");
return;
}
NDIS_STATUS PReceive (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize, UINT PacketSize)
{
PNDIS_PACKET pPacket;
PNDIS_BUFFER pBuffer;
ULONG SizeToTransfered=0;
NDIS_STATUS Status;
UINT BytesTransfered;
ULONG BufferLength;
NDIS_HANDLE BufferPool;
PVOID Temp;
UINT Frame_Type = 0;
char _t[255];
DbgPrint("PReceive called");
memcpy(&Frame_Type,(((char*)HeaderBuffer)+12),2);
_snprintf(_t,253,"Sniffered frame type %u, packetsize %u",Frame_Type,PacketSize);
DbgPrint(_t);
return NDIS_STATUS_NOT_ACCEPTED;
}
void PRecieveComplete (IN NDIS_HANDLE ProtocolBindingContext)
{
DbgPrint("PRecieveComplete called");
return;
}
void PStatus(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status,
IN PVOID StatusBuffer, IN UINT StatusBufferSize)
{
DbgPrint("PStatus called");
return;
}
void PStatusComplete (IN NDIS_HANDLE ProtocolBindingContext)
{
DbgPrint("PStatusComplete called");
return;
}
void PResetComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
{
DbgPrint("PResetComplete called");
return;
}
void PRequestComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status)
{
DbgPrint("PRequestComplete called");
return;
}
void PBindAdapter(OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext,
IN PNDIS_STRING theDeviceNameP, IN PVOID theSS1, IN PVOID theSS2)
{
DbgPrint("PBindAdapter called");
return;
}
void PUnbindAdapter(OUT PNDIS_STATUS theStatus, IN NDIS_HANDLE theBindContext,
IN PNDIS_HANDLE theUnbindContext)
{
DbgPrint("PUnbindAdapter called");
return;
}
NDIS_STATUS PPnPEvent(IN NDIS_HANDLE ProtocolBindingContext, IN PNET_PNP_EVENT pNetPnpEvent)
{
DbgPrint("PPnPEvent called");
return STATUS_SUCCESS;
}
INT PRecievePacket(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet)
{
DbgPrint("PRecievePacket called");
return 0;
}
void PCloseAdapter (IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status)
{
DbgPrint("PCloseAdapter called");
NdisSetEvent(&CloseWaitEvent);
}
void PUnload(VOID)
{
DbgPrint("PUnloadHandler called");
return;
}
void OnUnload( IN PDRIVER_OBJECT DriverObject)
{
NDIS_STATUS Status;
DbgPrint("OnUnload called");
NdisResetEvent(&CloseWaitEvent);
NdisCloseAdapter(&Status,BindingAdapter);
if (Status==NDIS_STATUS_PENDING)
{
NdisWaitEvent(&CloseWaitEvent,0);
}
NdisDeregisterProtocol(&Status,ProtocolHandle);
if (NT_SUCCESS(Status)==FALSE)
{
DbgPrint("DeregisterProtocol faild!!!");
}
else
{
DbgPrint("DeregisterProtocol SUCCESS");
}
return;
}
//***********************************************************************************************
Приветствую!
Не знаю актуальна ли проблема еще, но все же напишу.
У меня аналогичная проблема была, но для NDIS 5.0.
Попробуйте выделить память под
NDIS_REQUEST в
POpenAdapter с помощью
ExAllocatePool(NonPagedPool,...) (потом в
PRequestComplete почистите выделенную под запрос память) и еще сделать это "
ULONG Mode = NDIS_PACKET_TYPE_PROMISCUOUS" глобальным.
Похоже, что функция
POpenAdapter отрабатывает быстрее нежели происходит перевод в режим
NDIS_PACKET_TYPE_PROMISCUOUS и данные, выделенные на стеке получаются попорчены к тому времени, когда происходит установка параметров, которые Вы передаете в
NDIS_REQUEST. Поэтому перевод в режим прослушивания не проходит.
Если что не правильно размыслил, то уважаемый TarasCo поправит

.