拷贝MDL中数据到缓冲区

//Copy the packet into a buffer
  while (CurrentMdl && DataLength > 0)
    {
      NdisQueryMdl(CurrentMdl, &pSrc, &CurrLength, NormalPagePriority);
      if (pSrc == NULL)
        {
	  bytesCopied = 0;
	  break;
        }
        
      //
      //  Current buffer length is greater than the offset to the buffer
      //
      
      if (CurrLength > Offset)
        {
	  pSrc += Offset;
	  CurrLength -= Offset;
	  
	  if (CurrLength > DataLength)
            {
	      CurrLength = DataLength;
            }
	  DataLength -= CurrLength;
	  NdisMoveMemory(pDest, pSrc, CurrLength);
	  bytesCopied += CurrLength;
            
	  pDest += CurrLength;
	  Offset = 0;
        }
      else
        {
	  Offset -= CurrLength;
        }
      NdisGetNextMdl(CurrentMdl, &CurrentMdl);
      
    }

 

这段代码就是拷贝数据到缓冲区。其中CurrMDL,offset和dataLength来自Net_Buffer:

pNetBuffer = NET_BUFFER_LIST_FIRST_NB(pNetBufferList);
  
  //
  // Try to get the 1p data from OOB data
  //
  if(NET_BUFFER_LIST_INFO(pNetBufferList, Ieee8021QNetBufferListInfo) != 0)
    {
      Ndis8021QInfo.Value = NET_BUFFER_LIST_INFO(pNetBufferList, Ieee8021QNetBufferListInfo);
      UserPriority  = (UCHAR)Ndis8021QInfo.TagHeader.UserPriority;
    }     
  
  //copy the packet into a buffer
  pDest = packetBuffer;
  
  CurrentMdl = pNetBuffer->MdlChain;
  Offset = pNetBuffer->DataOffset;
  DataLength = pNetBuffer->DataLength;

 其中NET_BUFFER_LIST_FIRST_NB返回的是第一个Net_Buffer.  CurrentMDL指向MDL的list.现在来看看如何拷贝数据的。其中NdisQueryMdl返回MDL虚拟地址的基地址Psrc,和对应的缓冲区长度CurrLength


 
 1、如果CurrLenght > offset,那么把Psrc+offset,指向used data.同样,CurrLength-offset,表示当前的MDL中有用的数据长度。然后执行NdisMoveMemory的拷贝操作.紧接着把,dataLength-CurrLength,因为已经拷贝好了一部分,然后再把offset置零,因为现在指针已经到了可用数据区。

2、当再次得到下一个MDL的Psrc,和CurrLength时,因为offset已经=0,所以CurrLength肯定大于0,所以即使执行PSrc+=offset, CurrLength-=offset.最后拷贝整个长度的空间(以图为例,不都是这样!!),dataLength-CurrLength.

3、最后第三次得到pSrc,和CurrLength,但是CurrLength,已经大于dataLength,所以只拷贝dataLength的长度数据。就完成了所有数据拷贝。

4、但是如果第一次的时候offset>CurrLength,那么就是比如图中第一个MDL为unused data区,执行offset-=CurrLength.如下图:



 

 这样之后又回到了前面所说的CurrLength>offset了。

这就是拷贝数据到缓冲区的过程。不知有何疏漏,或者错误,见谅~
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值