今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的某些数据,就需要用到此功能(能直接在原来的nBL上更改,然后发送吗?)。
- 新建一个NBL作为你自己要存放拷贝数据的结构:
- pCopyNBL = allocateNetBuffAndNetBufferList(pFilter, dataLength);
这个其实是一个自定义的函数,用来分配一个空的NBL.具体代码见后面~ - 这里考虑有很多个NBL,而且每个NB中包含多个MDL.所以拿到原始NBL的第一个NB
- pCurrentNB = NET_BUFFER_LIST_FIRST_NB(pCurrentNBL);
再得到第一个NB的第一个MDL:- pMDL = NET_BUFFER_FIRST_MDL(pCurrentNB);
最后得到MDL中有用数据:包括分析offset,以及dataLength,起始地址等:- mdlOffset = NET_BUFFER_DATA_OFFSET(pCurrentNB);
- ...
- NdisQueryMdl( pMDL,(PVOID *)&pData,&dataBufferLength,NormalPagePriority);
- if(pData == NULL)
- {
- DEBUGP(DL_TEST,("pData is NULL ---Fail \n"));
- break;
- }
- 同理我们得到我们自定义NBL中的MDL(只有一个),同时拿到起始地址:
- pCopyMDL = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pCopyNBL));
- ....
- NdisQueryMdl(pCopyMDL,(PVOID *)&pNewBuffer, &newBufferLength,NormalPagePriority);
- if(pNewBuffer == NULL)
- {
- DEBUGP(DL_TEST,("pNewBuffer is NULL ---Fail \n"));
- break;
- }
- 然后把pData的数据拷贝到pNewBuffer中,这里注意拷贝的长度:
- bytesToCopy = dataBufferLength - mdlOffset;
- if(bytesToCopy > newBufferLength)
- {
- bytesToCopy = newBufferLength;
- }
- NdisMoveMemory((pNewBuffer + offset),(pData + mdlOffset), bytesToCopy);
- newBufferLength -= bytesToCopy;
- offset += bytesToCopy;
- mdlOffset = 0;
这里mdlOffset=0,是指以后以后连续的MDL中没有unused 数据。就是整个MDL中的数据都是我们要的。 - 然后循环这个NB中所有的MDL.每个NB拷贝完之后,设置NB的datalength:
- NET_BUFFER_DATA_LENGTH(NET_BUFFER_LIST_FIRST_NB(pCopyNBL)) = dataLength;
- pCopyNBL->SourceHandle = pCurrentNBL->SourceHandle;
- 循环所有的NBL,把每个NBL串起来:
- if(pNewNetBufferLists == NULL)
- {
- pNewNetBufferLists = pCopyNBLTail = pCopyNBL;
- }
- else
- {
- NET_BUFFER_LIST_NEXT_NBL(pCopyNBLTail) = pCopyNBL;
- }
-
- pCurrentNBL = NET_BUFFER_LIST_NEXT_NBL(pCurrentNBL);
- 结束拷贝~附上NBL分配函数代码:
- PNET_BUFFER_LIST allocateNetBuffAndNetBufferList(
- IN PMS_FILTER pFilter,
- IN ULONG BufferSize
- )
- {
- PMDL pMDL = NULL;
- PUCHAR pMDLAddress =NULL;
- PNET_BUFFER_LIST pNetBufferList = NULL;
- DEBUGP(DL_TEST,("==============>allocateNetBuffAndNetBufferList\n"));
- pMDLAddress = (PUCHAR)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,BufferSize,FILTER_ALLOC_TAG, LowPoolPriority);
- NdisZeroMemory(pMDLAddress, BufferSize);
- do
- {
- pMDL = NdisAllocateMdl(pFilter->FilterHandle, pMDLAddress, BufferSize);
- if(pMDL == NULL)
- {
- DEBUGP(DL_TEST,("PMDL Fail....\n"));
- break;
- }
-
- pNetBufferList = NdisAllocateNetBufferAndNetBufferList(
- pFilter->SendNetBufferListPool,
- sizeof(FILTER_SEND_NETBUFLIST_RSVD),
- 0,
- pMDL,
- 0,
- BufferSize);
- if(pNetBufferList == NULL)
- {
- NdisFreeMdl(pMDL);
- break;
- }
- }
- while(FALSE);
- DEBUGP(DL_TEST,("<==============allocateNetBuffAndNetBufferList\n"));
- return pNetBufferList;
- }
需要注意分配MDL,一定要使用NdisAllocateMemoryWithTagPriority分配一个空间地址~ - 最后是检查是否拷贝正确,参考了这里的代码(打印部分自行添加~):
- 效果图:
这是浏览百度的
下面是浏览javaeye 还有一些疑问:除了程序编译的时候还有三个Warning.就是好像我只考虑了每个NBL中只有一个NB的情况~可能还需要更多的测试~
阅读(5616) | 评论(0) | 转发(0) |