前视缓冲区:lookaheadbuffer
这个缓冲区是给协议一段Packet的内容,让协议来决定是否接受这个报文。
考虑数据包的接收,如果我们只需要看见数据内容的前几个字节(如TCP头)就可以决定这个包是否是本协议所需要处理的,那么显然下层驱动就没有必要提交整个数据包,只提供一个包开始的几个字节就可以了。
这个是有Miniport驱动来决定究竟那个lookaheadbuffer的大小的,这个缓冲区是从报文的 ip头开始的一段缓冲区,也有可能是包含了整个的 ip报文,这个时候lookaheadbuffersize=packesize了。
如下面的代码:
if (LookaheadBufferSize != PacketSize)
{
/* 不等于就是小于,lookaheadbuffersize不应该会大于packetsize */
IndicateBuffer=TransferBuffer-HeaderBufferSize-LookaheadBufferSize;
/********************************************************
TransferBuffer在前面应该有声明和初始化的地方吧,这里把指针向前移动了(headbuffersize+lookaheadbuffersize长)的距离。
他是不是把这个缓冲区chain到下面的那个RcvTransferPacket上了?这样在ndistransferdata之后整个报文的数据都在一快连续的缓冲区里面了
IndicateBuffer是要向协议提交的缓冲区的指针了。
*********************************************************/
NdisMoveMemory( IndicateBuffer, HeaderBuffer, HeaderBufferSize);
NdisMoveMemory( IndicateBuffer+HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize);
NdisTransferData(
&ReturnStatus,
*((PUINT)NdisBindingContext+1),
MacReceiveContext,
LookaheadBufferSize, // ByteOffset,
PacketSize-LookaheadBufferSize, //BytesToTransfer,
RcvTransferPacket,
&BytesTransfered
);
/* 这里应该判断一下ReturnStatus的状态,如果不是success,那就要到transferdatacomplete里面去处理了。 */
HeaderBuffer=IndicateBuffer;
LookaheadBuffer=IndicateBuffer+HeaderBufferSize;
LookaheadBufferSize = PacketSize;
}
else
{
IndicateBuffer=HeaderBuffer;
}
这段程序就是判断lookaheadbuffersize是否等于packetsize,如果等于那就直接提交,如果不等于,就调用ndistranferdata来把剩余的数据都取上来,然后在一起提交。
其中,headbuffer和lookaheadbuffer上不重叠的,指向的是不同的地址,packetsize是不包括headbuffer的大小的,headbuffer一般是以太网的头。
【参考资料 感谢作者】
http://bbs2.driverdevelop.com/read.php?tid-52641-page-1.html
快捷操作:
坚其志,苦其心,劳其力,事无大小,必有所成。
@如有侵权,请作者本人尽快与我(chrayo#163.com)联系,我将及时删除侵权内容。