//
// 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. js对象 数组Array详解 (参照MDN官网:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)

    一:数组的创建方式: 1.采用直接量创建 var arr = [];//创建一个空数组 var arr2 = [1,2,3];//创建一个有三个元素的数组 2.采用构造函数创建 a.var arr1 ...

  2. IT兄弟连 JavaWeb教程 JSP内置对象2

    application对象 application对象用于保存所有应用程序中的公有数据.它在服务器启动时自动创建,在服务器关闭时销毁,当application对象没有被销毁时,所有用户都可以共享app ...

  3. 简单实现TabBar的自定义

    StackoverFlow上看到的,通过继承UITabBarController创建自定义TabBarController.在原有TabBar的基础上添加一个背景层,在其基础上增加三个自定义按钮,通过 ...

  4. bzoj4472:[Jsoi2015]salesman

    传送门 树形dp 对于每个点维护其子节点的走法是否唯一,每次取最大的并且不为负的(停留次数-1)个子儿子权值,然后判断走法是否唯一 假如有子节点的权值为0,走法也不唯一 代码: #include< ...

  5. BZOJ1257(数论知识)

    感觉做法很神奇……想不到啊qwq 题目: Description 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值 其中k ...

  6. SpringBoot项目取消数据库配置

    1. 错误springboot项目启动时,如果没有配置数据库配置,启动时会抛出如下异常. Description: Cannot determine embedded database driver ...

  7. Linux 安装reids

    1.下载: wget http://download.redis.io/releases/redis-3.0.0.tar.gz 2.解压: .tar.gz 3.安装: cd /redis- make ...

  8. java isAssignableFrom instanceof 小结 专题

    一句话总结: isAssignableFrom()方法是从类继承的角度去判断,instanceof()方法是从实例继承的角度去判断. public native boolean isAssignabl ...

  9. Top-Down和Bottom-Up位图的区别

    Top-Down vs. Bottom-Up DIBs If you are new to graphics programming, you might expect that a bitmap w ...

  10. WPF学习04:2D绘图 使用Shape绘基本图形

    我们将使用Shape进行基本图形绘制. 例子 一个可移动的矩形方框: XAML代码: <Window x:Class="Shape.MainWindow" xmlns=&qu ...