Re[2]: Проблема с функцией Unload
От: polambus  
Дата: 06.04.08 21:51
Оценка:
Здравствуйте, 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;
}

//***********************************************************************************************
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.