个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系

//   
// NDIS_PACKET结构的定义  
//   
typedef struct _NDIS_PACKET  
{  
NDIS_PACKET_PRIVATE Private;  
//这个其实是一个链表结构,Private.Head指向第一个链表,Private.Tail指向最后一个  
//以下有关于这个结构的解释  

union  
{  
struct // For Connection-less miniports   
{  
UCHAR MiniportReserved[2*sizeof(PVOID)];  
UCHAR WrapperReserved[2*sizeof(PVOID)];  
};  

struct  
{  
//   
// For de-serialized miniports. And by implication conn-oriented miniports.   
// This is for the send-path only. Packets indicated will use WrapperReserved   
// instead of WrapperReservedEx   
//   
UCHAR MiniportReservedEx[3*sizeof(PVOID)];  
UCHAR WrapperReservedEx[sizeof(PVOID)];  
};  

struct  
{  
UCHAR MacReserved[4*sizeof(PVOID)];  
};  
};  

ULONG_PTR Reserved[2]; // For compatibility with Win  
UCHAR ProtocolReserved[1];  

} NDIS_PACKET, *PNDIS_PACKET, **PPNDIS_PACKET;  

// NDIS_PACKET_PRIVATE 的定义  
typedef struct _NDIS_PACKET_PRIVATE  
{  
UINT PhysicalCount; // number of physical pages in packet.   
UINT TotalLength; // Total amount of data in the packet.   
PNDIS_BUFFER Head; // 链表指针,指向第一个
PNDIS_BUFFER Tail; // 链表指针,指向最后一个  

// if Head is NULL the chain is empty; Tail doesn\'t have to be NULL also   

PNDIS_PACKET_POOL Pool; // so we know where to free it back to   
UINT Count;  
ULONG Flags;  
BOOLEAN ValidCounts;  
UCHAR NdisPacketFlags; // See fPACKET_xxx bits below   
USHORT NdisPacketOobOffset;  
} NDIS_PACKET_PRIVATE, * PNDIS_PACKET_PRIVATE;  

//NDIS_BUFFER定义 其实就是一个内存描述符

typedef struct _NDIS_BUFFER {  
struct _NDIS_BUFFER *Next; //指向下一个节点的指针
PVOID VirtualAddress;      //指向报文首地址
PNDIS_BUFFER_POOL Pool;  
UINT Length;               //报文数据长度
UINT Signature;  
} NDIS_BUFFER, * PNDIS_BUFFER;  

注释写的很清楚了  那么他们的关系还是不清楚的话看看附图

 好了  这样一来我们的思路大概清楚了  NDIS_PACKET只不过是一个关于NDIS_BUFFER链表的结构  在NDIS_PACKET中的成员Private中有指向第一个NDIS_BUFFER的指针和指向最后一个NDIS_BUFFER的指针  分别是Private.Head和Private.Tail     而NDIS_BUFFER中就记录了我们数据包的地址和下一个NDIS_BUFFER的地址  操作有很多种方法   由于这些结构体本来对我们是不透明的   所以最安全的方法是用MS提供的一系列函数来操作NDIS_PACKET和NDIS_BUFFER  

    还是拿个例子好说话吧

NDIS_STATUS status ;
    PNDIS_BUFFER NdisBuffer ;
    UINT TotalPacketLength =, copysize =, DataOffset =, PhysicalBufferCount  ,  BufferCount   ;
    PUCHAR mybuffer = NULL ,tembuffer = NULL ;  

//假设这个是在PtReceive等函数中得到的PACKET
NdisQueryPacket(packet                     //我们先得到第一个NDISBUFFER 的指针   
        , &PhysicalBufferCount              
        , &BufferCount                           
        ,&NdisBuffer                               //NdisBuffer就是指向链表头
        , &TotalPacketLength
        );
/*
其实也可以不用那么麻烦 直接  NdisBuffer = packet->Private.Head ;就可以取得第一个BUFFER了
*/

    status = NdisAllocateMemory( &mybuffer, 2048, 0, HighestAcceptableMax );  //分配我们自己的内存块

    if( status != NDIS_STATUS_SUCCESS )
        return NDIS_STATUS_FAILURE ;

    NdisZeroMemory( mybuffer,) ;

    NdisQueryBufferSafe(  //取得NDIS_BUFFER描述符中数据的首地址和大小
                                NdisBuffer,
                                &tembuffer,
                                ©size,
                                NormalPagePriority
    );  
     
        //将数据复制到我们的内存中
    NdisMoveMemory(mybuffer, tembuffer, copysize) ;

    DataOffset = copysize ;

    while(1)
    {
        /*
                也可以这样操作而不用NdisGetNextBuffer
        if(NdisBuffer->Next == packet->Private.Tail )
            break ;

        NdisBuffer = NdisBuffer->Next ;

        if(pmdl == NULL )
           break ;
           */
        //获得下一个NDIS_BUFFER的的指针
    NdisGetNextBuffer(NdisBuffer , &NdisBuffer ) ;
        如果指针是NULL  那么表示到链表尾了
    if( NdisBuffer == NULL )
        break ;

    NdisQueryBufferSafe(
                                NdisBuffer,
                                &tembuffer,
                                ©size,
                                NormalPagePriority
                                ) ;

    NdisMoveMemory( mybuffer + DataOffset , tembuffer, copysize) ;

    DataOffset += copysize  ;

    }

//OK  我们要的数据就全部都在我们申请的内存mybuffer 数据大小为DataOffset

 

posted on 2013-08-13 18:01 RodYang 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/RodYang/p/3255618.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值