NDIS驱动开发笔记整理之NDIS_PACKET,NDIS_BUFFER的关系

  1. //     
  2. // NDIS_PACKET结构的定义    
  3. //     
  4. typedef struct _NDIS_PACKET    
  5. {    
  6. NDIS_PACKET_PRIVATE Private;    
  7. //这个其实是一个链表结构,Private.Head指向第一个链表,Private.Tail指向最后一个    
  8. //以下有关于这个结构的解释    
  9.   
  10. union    
  11. {    
  12. struct // For Connection-less miniports     
  13. {    
  14. UCHAR MiniportReserved[2*sizeof(PVOID)];    
  15. UCHAR WrapperReserved[2*sizeof(PVOID)];    
  16. };    
  17.   
  18. struct    
  19. {    
  20. //     
  21. // For de-serialized miniports. And by implication conn-oriented miniports.     
  22. // This is for the send-path only. Packets indicated will use WrapperReserved     
  23. // instead of WrapperReservedEx     
  24. //     
  25. UCHAR MiniportReservedEx[3*sizeof(PVOID)];    
  26. UCHAR WrapperReservedEx[sizeof(PVOID)];    
  27. };    
  28.   
  29. struct    
  30. {    
  31. UCHAR MacReserved[4*sizeof(PVOID)];    
  32. };    
  33. };    
  34.   
  35. ULONG_PTR Reserved[2]; // For compatibility with Win    
  36. UCHAR ProtocolReserved[1];    
  37.   
  38. } NDIS_PACKET, *PNDIS_PACKET, **PPNDIS_PACKET;    
  39.   
  40. // NDIS_PACKET_PRIVATE 的定义    
  41. typedef struct _NDIS_PACKET_PRIVATE    
  42. {    
  43. UINT PhysicalCount; // number of physical pages in packet.     
  44. UINT TotalLength; // Total amount of data in the packet.     
  45. PNDIS_BUFFER Head; // 链表指针,指向第一个  
  46. PNDIS_BUFFER Tail; // 链表指针,指向最后一个    
  47.   
  48. // if Head is NULL the chain is empty; Tail doesn\'t have to be NULL also     
  49.   
  50. PNDIS_PACKET_POOL Pool; // so we know where to free it back to     
  51. UINT Count;    
  52. ULONG Flags;    
  53. BOOLEAN ValidCounts;    
  54. UCHAR NdisPacketFlags; // See fPACKET_xxx bits below     
  55. USHORT NdisPacketOobOffset;    
  56. } NDIS_PACKET_PRIVATE, * PNDIS_PACKET_PRIVATE;    
  57.   
  58. //NDIS_BUFFER定义 其实就是一个内存描述符  
  59.   
  60. typedef struct _NDIS_BUFFER {    
  61. struct _NDIS_BUFFER *Next; //指向下一个节点的指针  
  62. PVOID VirtualAddress;      //指向报文首地址  
  63. PNDIS_BUFFER_POOL Pool;    
  64. UINT Length;               //报文数据长度  
  65. UINT Signature;    
  66. } 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  

  举个例子:

[cpp]  view plain  copy
  1. NDIS_STATUS status ;  
  2.     PNDIS_BUFFER NdisBuffer ;  
  3.     UINT TotalPacketLength =, copysize =, DataOffset =, PhysicalBufferCount  ,  BufferCount   ;  
  4.     PUCHAR mybuffer = NULL ,tembuffer = NULL ;    
  5.   
  6. //假设这个是在PtReceive等函数中得到的PACKET  
  7. NdisQueryPacket(packet                     //我们先得到第一个NDISBUFFER 的指针     
  8.         , &PhysicalBufferCount                     //物理中断的缓冲区数量
  9.         , &BufferCount                             //包的缓冲区数据符的数量
  10.         ,&NdisBuffer                               //NdisBuffer就是指向链表头  
  11.         , &TotalPacketLength                       //数据包总数量的长度
  12.         );  
  13. /* 
  14. 其实也可以不用那么麻烦 直接  NdisBuffer = packet->Private.Head ;就可以取得第一个BUFFER了 
  15. */  
  16.   
  17.     status = NdisAllocateMemory( &mybuffer, 2048, 0, HighestAcceptableMax );  //分配我们自己的内存块  
  18.   
  19.     if( status != NDIS_STATUS_SUCCESS )  
  20.         return NDIS_STATUS_FAILURE ;  
  21.   
  22.     NdisZeroMemory( mybuffer,) ;  
  23.   
  24.     NdisQueryBufferSafe(  //取得NDIS_BUFFER描述符中数据的首地址和大小  
  25.                                 NdisBuffer,  
  26.                                 &tembuffer,  
  27.                                 ©size,  
  28.                                 NormalPagePriority  
  29.     );    
  30.        
  31.         //将数据复制到我们的内存中  
  32.     NdisMoveMemory(mybuffer, tembuffer, copysize) ;  
  33.   
  34.     DataOffset = copysize ;  
  35.   
  36.     while(1)  
  37.     {  
  38.         /* 
  39.                 也可以这样操作而不用NdisGetNextBuffer 
  40.         if(NdisBuffer->Next == packet->Private.Tail ) 
  41.             break ; 
  42.  
  43.         NdisBuffer = NdisBuffer->Next ; 
  44.  
  45.         if(pmdl == NULL ) 
  46.            break ; 
  47.            */  
  48.         //获得下一个NDIS_BUFFER的的指针  
  49.     NdisGetNextBuffer(NdisBuffer , &NdisBuffer ) ;  
  50.         //如果指针是NULL  那么表示到链表尾了  
  51.     if( NdisBuffer == NULL )  
  52.         break ;  
  53.   
  54.     NdisQueryBufferSafe(  
  55.                                 NdisBuffer,  
  56.                                 &tembuffer,  
  57.                                 ©size,  
  58.                                 NormalPagePriority  
  59.                                 ) ;  
  60.   
  61.     NdisMoveMemory( mybuffer + DataOffset , tembuffer, copysize) ;  
  62.   
  63.     DataOffset += copysize  ;  
  64.   
  65.     }  
  66.   
  67. //OK  我们要的数据就全部都在我们申请的内存mybuffer 数据大小为DataOffset  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
  对于在“蓝网之家”影响下蠢蠢而动搞 Windows 95 远程启动的朋友可能不少,那么大家一定对 NDIS 这几个字母不会感到陌生。其实不只是在远程启动这一层,只要是网卡的驱动盘,大家都会在里面发现有类似 NDISNDIS2、NDIS3、NDIS4一样的目录,只是大家在 Windows 9x 或 NT 中安装、设置网卡时没有注意到它罢了。但即使大搞特搞 RPL 的朋友对其大概也是只知其然而不其所以然。    NDIS 是什么?有什么作用?       NDIS 的全称是 Network Device Interface Specification,中文意思就是网络设备接口规范。    根据 OSI 七层模型,物理层定义了对网卡、线缆以及其它物理硬件设备进行配置的标准。节点间建立通信时是由物理层在传输介质上传送二进制信息实现的,因此,在发送端和接收端都还必须有一个程序来格式化这种信息流并将其传送给上一层。NDIS 的作用就是避免在访问网卡每次进行传输时都编写相应的代码。由此说来,NDIS 本质上是一种软件接口,有了 NDIS ,所有的传输就可以采用一种通用的方式来访问由不同厂商制造的网卡了,即它是用来连接协议堆栈和网卡的。   与此相关的软件还有重定向器(Redirector)和服务器(Server)。前者的目的是截获来自 OSI 会话层的网络调用,并通过将其传送到相应的协议驱动程序接口而格式化成 NDIS 能够识别和使用的命令。后者则负责接收从重向器传过来的来自于远程计算机的请求,再将这一请求传送给相应的本地文件系统驱动程序,最后再由该“服务器”将数据沿协议堆栈向下传递给客户机。    TCP协议也是通过调用 NDIS 接口服务来完成传输操作的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值