个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系
2012-08-02 13:14
281 查看
// // 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
转自:http://www.cppblog.com/ay19880703/archive/2008/09/18/62233.aspx
相关文章推荐
- 个人总结NDIS中NDIS_PACKET,NDIS_BUFFER的关系
- NDIS驱动开发笔记整理之NDIS_PACKET,NDIS_BUFFER的关系
- 黑马程序员--03.面向对象--02.子类和父类成员变量的关系【个人总结】
- cocos2dx主要概念及关系详解(个人理解总结)
- 04.多线程--07.【Runnable接口的来历】【Thread类和Runnable接口的关系】【个人总结】
- windows下中间层NDIS驱动中NDIS_PACKET和NDIS_BUFFERD的关系
- ArcGIS中的点线面之间的拓扑关系(个人总结)
- String StringBuffer StringBuilder关系总结
- java中解析js中由escape加密过的数据(个人总结)
- 第二冲刺阶段——个人工作总结10
- 高通平台点亮LCD个人总结
- UML类图几种关系的总结
- 个人工作总结2
- 深度学习系列之R-FCN个人总结
- 关于zookeeper选举leader原理及自定义leader个人理解和总结
- 多线程程序调试个人经验总结
- JAVA DAO(Data Access Object)的个人总结
- 第二阶段个人工作总结(7)
- 数据库开发个人总结(ADO.NET小结) 转载
- 个人经验总结:MySQL数据库优化技巧集锦