//
// NDIS_PACKET结构的定义
//
typedef struct _NDIS_PACKET
{
NDIS_PACKET_PRIVATE Private;
//这个其实是一个链表结构,Private.Head指向第一个链表,Private.Tail指向最后一个
//以下有关于这个结构的解释 union
{
struct // For Connection-less miniports
{
UCHAR MiniportReserved[*sizeof(PVOID)];
UCHAR WrapperReserved[*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[*sizeof(PVOID)];
UCHAR WrapperReservedEx[sizeof(PVOID)];
}; struct
{
UCHAR MacReserved[*sizeof(PVOID)];
};
}; ULONG_PTR Reserved[]; // For compatibility with Win
UCHAR ProtocolReserved[]; } 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, , , 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()
{
/*
也可以这样操作而不用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

个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系的更多相关文章

  1. TCP/IP协议原理与应用笔记11:TCP/IP中地址与层次关系

    1. 网络中常用的地址: 2. TCP/IP中地址与层次关系 :

  2. 持续集成:TestNG中case之间的关系

    持续集成:TestNG中case之间的关系   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq: ...

  3. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  4. ASP.NET Core中使用GraphQL - 第九章 在GraphQL中处理多对多关系

    ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...

  5. 通过SQL脚本来查询SQLServer 中主外键关系

    在SQLServer中主外键是什么,以及主外键如何创建,在这里就不说了,不懂的可以点击这里,这篇文章也是博客园的博友写的,我觉得总结的很好: 此篇文章主要介绍通过SQL脚本来查看Sqlserver中主 ...

  6. 详解UML中的6大关系(关联、依赖、聚合、组合、泛化、实现)

      UML中的6大关系相关英文及音标: 依赖关系 dependency --------> 关联关系 association ______> 聚合关系 aggregation ______ ...

  7. laravel orm 中的一对多关系 hasMany

    个人对于laravel orm 中对于一对多关系的理解 文章表 article,文章自然可以评论,表 comment 记录文章的评论,文章和评论的关系就是一对多,一篇文章可以有多个评论. 在 comm ...

  8. angularjs 中的scope继承关系——(2)

    转自:http://www.lovelucy.info/understanding-scopes-in-angularjs.html angularjs 中的scope继承关系 ng-include ...

  9. UML---UML中的几种关系(依赖,关联,泛化,实现)

    关于设计模式的总结没有落实到代码上,而且设计模式自己确实动手实现的非常少.所以在这一周里,除了看网站开发的视频,着手开始对设计模式进行实现以下.设计模式非常经典,每次看都有不同的收获,写一下自己的收获 ...

随机推荐

  1. Unity2016 Unity3D开发VR游戏的经验

    http://z.youxiputao.com/articles/8313 在4月12日的Unite 2016大会上,暴风魔镜高级产品经理吴涛分享他用Unity3D开发VR游戏的经验,以下为分享实录: ...

  2. Ajax登陆,使用Spring Security缓存跳转到登陆前的链接

    Spring Security缓存的应用之登陆后跳转到登录前源地址 什么意思? 用户访问网站,打开了一个链接:(origin url)起源链接 请求发送给服务器,服务器判断用户请求了受保护的资源. 由 ...

  3. webSocket的学习以及问题的解决

    查过很多资料,感觉大部分都讲的不够详细,做为一个新人我从webSocket的基本开始学起, 首先webSocket的原理其实和Http差不多,但是由于Http只能被动的去向服务器请求消息,导致缺点太明 ...

  4. c++中初始化列表的初始化变量顺序问题

    例题来看:请问下面程序打印出的结果是什么? #include <iostream> #include <string> using namespace std; class b ...

  5. C# 获取当前ip

    1.获取局域网ip IPAddress ipAddr = Dns.Resolve(Dns.GetHostName()).AddressList[0];//获得当前IP地址 string ip=ipAd ...

  6. #13:人十我一Orz——6

    水题放送,写得依旧丑: #include <cstdio> #include <cstring> #include <cmath> #include <alg ...

  7. 阿里云ECS基础知识01

  8. python转换已转义的字符串

    python转换已转义的字符串 有时我们可能会获取得以下这样的字符串: >>> a = '{\\"name\\":\\"michael\\"} ...

  9. python采用sqlachmy购物商城

    一.流程图: 二.目录结构: C:\USERS\DAISY\PYCHARMPROJECTS\S12\MARKET │ __init__.py │ __init__.pyc │ ├─backend │ ...

  10. Spark Mllib里如何将数值特征字段用StandardScaler进行标准化(图文详解)

    不多说,直接上干货! 首先,要明白为什么有时候,数值特征字段需要进行标准化? 答:因为,当我们若用回归分析算法时,必须将数值特征字段进行标准化,这是因为数值特征字段单位不同,数字差异很大,所以无法彼此 ...