sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3037回复:15

请教胡版主:在passthru中包的处理是怎么进行的?

楼主#
更多 发布于:2001-10-16 13:39
1.nic收到包,在passthru是怎么通过intermedia传上去的,
2.上层协议要发包,怎么通过intermedia送出去的。
3.下列各函数在什么时候被调用。他们之间的相互关系又如何?

miniport部分:
MChars.TransferDataHandler MChars.SendHandler

protocol部分
SendCompleteHandler TransferDataCompleteHandler
ReceiveHandler ReceiveCompleteHandler
111
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-10-16 16:25
版主不要不理咱嘛,下面是偶对这个问题的看法。错误之处,请务必指正。


一.中间层驱动程序接收数据过程:下面只讨论Connectionless Lower Edge,
Receiving Data in an Intermediate Driver with a Connectionless Lower Edge:
1.下层的NIC驱动程序通过调用NdisMXxxIndicateReceive function指示数据包过来了,并且传递了a pointer to a lookahead(预览??) buffer and the total size of the packet给Ndis
2.ndis到处看了看,对Intermediate Driver的里ptReceive说“快,懒虫,该你干活了”。并把NIC驱动程序才给他的东东一股脑扔给了ptReceive。
3. ptReceive:“kao,又要干活了,才休息一会儿,又要干活了得,偶先检查HeaderBuffer, LookAheadBuffer这两个东东,再决定干什么。“
先看看HeaderBuffer
eth_header   =HeaderBuffer;
eth_protocol = *((PUSHORT)(&eth_header->eth_protocolType[0]));

ptReceive:“看看是什么protocol先”。

if (eth_protocol != IPPROT_NET){不干偶的事哩}
再看看LookAheadBuffer
ip_header = (PIP_HEADER) ( (UCHAR*)LookAheadBuffer );

if (ip_header->ip_prot == PROTOCOL_IGMP){ }
if (ip_header->ip_prot == PROTOCOL_ICMP)  {}
if ( (ip_header->ip_prot == PROTOCOL_UDP) && LookAheadBufferSize>= (sizeof(IP_HEADER) + sizeof(UDP_HEADER)) )
{
udp_header = (PUDP_HEADER) ( (UCHAR*)ip_header + sizeof(IP_HEADER) );
}

经过一番检查,又看了oob,ptReceive认为进来的数据包是高层驱动程序要的包,就将数据复制到已分配的数据包中,并将包指示给高层驱动程序(NdisMIndicateReceivePacket)。要是LookAheadBufferSize< PacketSize,用NdisTransferData来copy包的其它部分。这时他还发现有人给他来了张条子,说要把包加点蜜,再给高层领导送去,“kao,什么事都要我干,那可不行,我要休息了,找ptReceiveComplete去干。

问题  :  passthru里的NdisTransferData是在MiniportTransferData里做的,下面ddk这两段话该怎么理解呢?NdisTransferData 和MiniportTransferData是在什么时候被调用的呢?)
If, after the connectionless intermediate driver examines the lookahead data, it determines that the packet is intended for one or more of its overlying drivers, it must copy the data into a previously allocated packet which it will indicate to its overlying driver(s).If the size of the lookahead buffer is less than the total size of the received packet, the intermediate driver must first call NdisTransferData in the context of ProtocolReceive, to copy the rest of the received data.

If the NIC driver calls NdisMXxxIndicate, ProtocolReceive is always called, and if the intermediate driver accepts the packet, ProtocolReceive must call NdisTransferData with a packet descriptor and driver-allocated buffers into which the lookahead buffer has been copied and into which the rest of the packet is copied. NdisTransferData must be called in the context of ProtocolReceive, and can only be called once. It is the responsibility of the intermediate driver to set up a packet descriptor with chained buffers of a sufficient size to contain all the received data. After NdisTransferData returns, the received data is no longer available from the underlying NIC driver.

二.通过中间驱动程序传输数据包
1. 高层下发一个NdisSend 给中间驱动程序,于是MpSend又开始干活了。
进了MiniportSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags
)
2. MpSend对包开始检查
NdisQueryPacket(Packet, NULL, NULL, &src_buffer, &src_len);
NdisQueryBuffer(src_buffer, &dest_block, &dest_block_len);

eth_header   = (PETHERNET_HEADER) dest_block;
eth_protocol = *((PUSHORT)(&eth_header->eth_protocolType[0]));
eth_header_len = sizeof(ETHERNET_HEADER);

if (eth_protocol != IPPROT_NET){…}

if (dest_block_len >= eth_header_len + sizeof(IP_HEADER))
{
ip_header = (PIP_HEADER) ( (PCHAR)dest_block + eth_header_len);
dest_block = (PCHAR)dest_block + eth_header_len;
dest_block_len -= eth_header_len;
}
else if (dest_block_len == eth_header_len)
{
NdisGetNextBuffer(src_buffer, &dest_buffer);
NdisQueryBuffer(dest_buffer, &dest_block, &dest_block_len);
ip_header = (PIP_HEADER)dest_block;
}
if (ip_header->ip_prot == PROTOCOL_IGMP) {…}
if (ip_header->ip_prot == PROTOCOL_UDP)  {…}

    都不是嗦,那就该是ip包 咯,把这个包给Ndis打个招呼,喊他去叫NdisSend去给NIC说一声,把这个包送走.
三中间层miniport与protocol的关系是怎么样的,偶还是很迷糊


111
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2001-10-16 22:29
哦,这个地方一般的处理和passthru有点不同,passthru
是不太适合做firewall和vpn的,当然如果一定要用passthru
的框架,也勉强可以,但是就需要真正读懂passthru,把整个
包流程搞清楚,我相信等到搞清楚之后就不会再完全使用
passthru的框架了,因为修改修改会更好用。

之所以我说这样的话,是因为passthru对于protocolreceive
的处理比较特别,passthru里面的miniport完全仿真真正的
miniport行为,这样做就带来一下麻烦,具体地说就是passthru
根本就不判断lookheadbuffer是否包含所有的数据包就使用
NdisMEthIndicateReceive通知ip协议,在这里得不到所有
的数据包就不方便做firewall和vpn。如果一定要做,那么
接下来ip层会在ip_protocolreceive判断lookaheadbuffer,
然后ip层会调用passthru的transferdata,passthru的transferdata
会调用ndistransferdata,ndistransferdata会调用nic
的miniport transferdata,nic的transferdata调用结束
后ndis会调用passthru的transferdatacomplete,
passthru的transferdatacomplete用passthru的miniport
句柄作为参数调用ip层的transferdatacomplete。

因此,如果要保留passthru的这个处理包的过程,麻烦
就会比较大。因为需要在passthru的transfercomplete
里面处理,可是这里的数据却又没有头,这样的话,你自己
必须保留这个头,所以一般不这样处理。passthru这样做
呢,也是完全有他的道理,这样做所有网卡发送接收过程
都被passthru的miniport仿真了,一点都没有改变。ip
层的函数调用和没有passthru一样。

估计这就是你的困惑的根源。


其实对于绝大多数的网卡
的一般情况来说,ndis是不会调用protocolreceive的,一般是
调用protocolreceivepacket,特别的几种情况ndis才调用
protocolreceive,这些特别的情况我记得我曾经在这个版面
里面总结过,或者在bbs.whnet.edu.cn上也曾经说过。


不再回忆从前,我已经生活在幸福当中。
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2001-10-17 15:58
很感谢版主的答复!!!
还有些问题。
1.ProtocolReceiveComplete在passthru是什么时候被调用的?
在收包的时候我是打算在这里对包进行处理啊?
111
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2001-10-18 09:07
我认为这是一个很坏的主意。
protocolreceivecomplete并非什么时候都会被调用,只有nic
用介质相关函数indicate的时候,protocolreceive被调用之后,
receivecomplete才会被调用。而且这个地方是passvis_level,
还可以重入。
此外,必然有一大批数据包会丢失,因为他们并不走这个函数。
不再回忆从前,我已经生活在幸福当中。
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2001-10-23 14:11
protocolreceivecomplete并非什么时候都会被调用,只有nic
用介质相关函数indicate的时候,protocolreceive被调用之后,
receivecomplete才会被调用

对这一句话,我的不太能够理解。“只有nic 用介质相关函数indicate的时候,protocolreceive被调用之后, receivecomplete才会被调用”
我的理解是指下层nic用介质相关函数indicate来向上指示,就会引起中间层的protocolreceive,当数据包处理完后,才会调用ptreceivecomplete???

这点我不太明白,请胡大虾讲清楚些好不好。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
1.我在passthru中将PChars.ReceiveHandler = PtReceive
   这一句换成PChars.ReceiveHandler =NULL;应该不会再调ptreceive了,只会调用PtReceivePacket,按上述说法好象意思是不会调用receivecomplete吧,(不过事实上是要调用receivecomplete啊??)
2.“此外,必然有一大批数据包会丢失,因为他们并不走这个函数”,是指的什么函数?是protocolreceivecomplete?能不能举例说明呢??
我想通常情况passthru是用的PtReceivePacket来处理接收的数据包吧,不过我把PChars.ReceivePacketHandler = PtReceivePacket这句拿掉,发现包的处理就是用PtReceive来做的了。这时protocolreceivecomplete不一定会调用,但在softice中把protocolreceivecomplete设为断点,发现protocolreceivecomplete还是会被调用啊,是在什么时候不走这个函数呢?
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


下面是我的passthru中一些有关包处理函数的一些见解,不对之处,请指正!谢了先!!

这里的 上层指中间层上面的上层协议驱动程序。
下层指中间层下面的下层网卡驱动程序。
一.Miniport部分:
1. miniportsend:对应SendHandler。
被调用原因:
是上层call了NdisSend,打算发包出去;

功能:
用来向下层网卡驱动程序(用NdisSend)发送单个数据包(如果没有MiniportSendPacket,一定要有该函数)。中间层驱动程序通常是基于每次发送单一数据包或将自身bind到下层WAN NIC的驱动程序。

也就是:
1) 复制包;
2) 用NdisSend()来发包。
根据NdisSend返回的状态,则有两个分支:
(1) 返回的statsu不是NDIS_STATUS_PENDING,说明调用是同步完成的,则应释放资源。
(2) 是NDIS_STATUS_PENDING,那么NdisSend完成返回的Status以及包描述符送给中间层Protocol部分的ProtocolSendComplete,在ProtocolSendComplete中调用NdisMSendComplete传送发送状态给相邻的上层,上层就会又去调用它的ProtocolSendComplete。

2. MiniportReturnPacket:对应ReturnPacketHandler。
被调用的原因:
应该是上层处理完所有指示后,会调用本函数。假想:可能是上层调用上层的ReturnPacketHandler,在其中调用了NdisReturnPacket,然后就调用了中间层的ReturnPacketHandler,中间层的ReturnPacketHandler又调用了自己的NdisReturnPacket,然后下层miniport部分就释放指示给上层驱动程序的资源的控制权。

功能:
接收返回的包描述符,释放指示给高层驱动程序资源的控制权。
MiniportReturnPacket与PtReceivePacket配套使用吧;
要是用的ptreceive来处理接收到的数据包就不用这个函数了吧?

3. MiniportTransferData:对应TransferDataHandler。
下层有三类指示方式哦:
1).NdisMIndicateReceivePacket
2).NdisMXxxIndicate
3).NdisMXxxIndicateReceive
被调用原因:
如果中间层是用的NdisMXxxIndicateReceive来向上层指示,那么当上层发现lookahead buffer中的数据只是包的一部分时,就要调用NdisTransferData,然后NDIS就会调用中间层的MiniportTransferData。
功能:
用来把包的其余部分传送给上层,中间层的MiniportTransferData又调用NdisTransferData找下层去传送包的其余部分

注:如果中间层总是用的NdisMIndicateReceivePacket向上层指示接收到的数据包,就不需要该函数。

二. Protocol部分:
1. ReceiveHandler = PtReceive;
被调用的原因:
1). nic驱动程序调用NdisMXxxIndicateReceive;
2). nic驱动程序调用NdisMIndicateReceivePacket,而被指示的包描述符的OOB数据块状态设为NDIS_STATUS_RESOUCES;
3). Nic驱动程序调用NdisMXxxIndicate。

功能:
处理接收到的数据包,这个函数的输入参数有一个指向包含网络接收数据的预览buffer的指针。该数据包是下层网卡通过上述几种方式指示的。
当包是用NdisMXxxIndicate指示的,ptReceive应调用NdisTransferData,找下层要包的其它部分;
当包是用NdisMXxxIndicate指示的,如果该buffer中的数据不是完整的网络数据包(即sizeof(lookahead buffer)< PacketSize),则应用NdisTransferData来接收该数据包的剩余部分;
当包是nic驱动程序调用NdisMIndicateReceivePacket指示的,而被指示的包描述符的OOB数据块状态设为NDIS_STATUS_RESOUCES,这时buffer的大小总是和网络数据包的大小相同;
然后复制包,再向上层用NdisMIndicateReceivePacket或NdisMXxxIndicate指示包;
注:ptReceive 中不该对接收到数据包做比较复杂的处理工作,这对系统性能影响较大,应该在PtReceiveComplete函数中进行这些复杂的处理工作。(这样需将在ptReceive中复制的包排队,这样就可以在PtReceiveComplete对包进行后期处理。

2. ReceiveCompleteHandler = PtReceiveComplete;
被调用的原因:
上一次指示给中间层的ptreceive函数或PtReceivePacket的数据包被处理完后,将调用ptreceivecomplete函数。

3. ReceivePacketHandler = PtReceivePacket;
被调用的原因:
Nic驱动程序调用NdisMIndicateReceivePacket指示可能包含OOB数据的包数组时。

功能:
在每一个接收指示中,接收完整的数据包;并向上层指示;
如果PtReceivePacket经检查后认为进来的包是上层需要的,则返回值为非零,然后中间层驱动程序接下来会调用NdisReturnPackets。


4. TransferDataCompleteHandler = PtTransferDataComplete;
被调用的原因:
如果中间层的ProtocolReceive中要调用NdisTransferData函数来复制接收数据包剩余部分,如果NdisTransferData返回NDIS_STATUS_PENDING,当传输操作完成后,就会调用中间层的PtTransferDataComplete。

5. SendCompleteHandler = PtSendComplete;
被调用的原因:
1).在mpSend(或mpSendpacket)中调用NdisSend时返回状态为NDIS_STATUS_PENDING,会PtSendComplete来完成发送操作;
2).要是用的NdisSendPacket发送一组数据包,则对每个数据包都会调用一次PtSendComplete




111
baijbup
驱动牛犊
驱动牛犊
  • 注册日期2001-08-03
  • 最后登录2003-05-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2001-10-23 14:34
版主:
   可是我现在在passthru的基础上作的话,
发现很奇怪,我将网卡设为混杂模式,
然后再ptreceive中发现不是全部的包,我就
取mptransferdata中去那生于的数据。可是
我发现有很多时候,mptransferdata是没有
北调用的。自然生于的数据就不能获得了。
同时,我发现pttransferdatacomplete函数
根本就没有被调用,这是为什么呢?
************************ 寻找快乐的人 ************************
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2001-10-23 14:57
再补充一点,我发现passthru中的protocol部分的

pttransfercomplete总是没被调用,但ptreceivecomplete却总是会

被调用啊?(不管是用ptreceive还是ptreceivepacket)
111
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2001-10-24 14:14
各位,发表些意见啊
111
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
9楼#
发布于:2001-10-30 21:21
刚刚从部队实习保外就医:-),本来不打算re任何贴子的,但是这问
题讨论得如此深入,看得出来参与讨论的诸位都经过了深入的思考
实在忍不住手痒。


首先是sirroom的问题:

这点我不太明白,请胡大虾讲清楚些好不好。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
1.我在passthru中将PChars.ReceiveHandler = PtReceive
这一句换成PChars.ReceiveHandler =NULL;应该不会再调ptreceive了,只会调用PtReceivePacket,按上述说法好象意思是不会调用receivecomplete吧,(不过事实上是要调用receivecomplete啊??)
2.“此外,必然有一大批数据包会丢失,因为他们并不走这个函数”,是指的什么函数?是protocolreceivecomplete?能不能举例说明呢??
我想通常情况passthru是用的PtReceivePacket来处理接收的数据包吧,不过我把PChars.ReceivePacketHandler = PtReceivePacket这句拿掉,发现包的处理就是用PtReceive来做的了。这时protocolreceivecomplete不一定会调用,但在softice中把protocolreceivecomplete设为断点,发现protocolreceivecomplete还是会被调用啊,是在什么时候不走这个函数呢?
-------------------------------------------------------

这个地方我也不知道我怎么搞得,居然写错了,我想我应该
写tranferdatacomplete。应该实际上你也只能在这个函数
里面处理,receivecomplete被调用的时候数据包都已经发上去
了,无法处理了。


其次是baijbup的问题
mptransferdata没有被调用很正常,没有被调用说明
整个数据包都得到了,不需要调用。

再次是sirroom的问题:
这个问题和baijbup的问题一样。

这个问题我之所以写错,是因为我想sirrom的本意
也一定是想在ptrecieve被调用的时候,在transferdata
里面处理,所以脑子里面一直在想这真是一个坏主意,
然后一不小心就写错了。

ptreceivecomplete是否一定会被调用,我的经验是ndis5是
一定会的,但是ndis4我不敢保证,这里面的某些细节,我
也不太清楚,相关的还有,什么时候ndissend会不返回pending?
我只能在代码里小心的加上保护。

不再回忆从前,我已经生活在幸福当中。
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2001-10-31 10:23
re 版主:
for 下面一段
(应该写tranferdatacomplete。应该实际上你也只能在这个函数
里面处理,receivecomplete被调用的时候数据包都已经发上去
了,无法处理了。

我的想法是:
  1.HeaderBuffer起14个字节是以太网的头部?LookaheadBuffer起是20个byte的ip头加别的东东.可以根据LookaheadBuffer来决定是直接指示上去,另做处理,扔掉.
    扔掉的包:              什么也不做
    如果对包不做处理:       直接indicate上去.
    如果是要另做处理的包()  copy下来,排队。
    2.ptreceivecomplete被调用的时候,出队做postprocess。 等后处理做完后,再把包indicate上去.
  
所以我的问题是
   1. tranferdatacomplete不一定会被调用啊?我以为在处理进入包时tranferdatacomplete被调用的可能情况是ptreceive调用了ndistransferdata返回了pending才会调用吧,如果LookaheadBuffer是完整的包,或是ndistransferdata返回非pending,我觉得好象不会调用.所以应该不能在这里进行处理
  2.现在主要是想知道ptreceive与ptreceivecomplete调用的关系,是否ptreceive了就一定会在以后调用ptreceivecomplete??
(re :receivecomplete被调用的时候数据包都已经发上去了,无法处理了。 如果ptreceive不发上去,留下来就应该可以处理了?)
111
zzy918
驱动牛犊
驱动牛犊
  • 注册日期2001-04-26
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2001-11-01 20:30
我想问斑竹和各位,在通过网卡发送数据时,我想在将packet送到网卡的缓冲环前对packet进行加密。在接收方,在将数据从网卡中读出后进行解密。那么加解密过程是否可以在miniport层做,还是一定要在passthru中做。请指教。
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2001-11-02 09:15
你这个问题我不太看得明白?在miniport层做??,你这个miniport层是指哪个?
1.对应真实网卡的miniport驱动?自己写网卡驱动?,我看不如在协议层呢,按说在协议层做vpn,firewall等更方便,不过偶现在还不会,正在看哩。
2.passthru中的miniport??这本来就是passthru的一部分啊?

对你的问题,偶是无法理解:(.偶的理解能力是不是有问题了)
不过还是想说,问的时候问清楚些,虽说问了不见得有人会答,不过没问清楚是一定得不到想要的回答的
111
zzy918
驱动牛犊
驱动牛犊
  • 注册日期2001-04-26
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2001-11-02 18:57
可能是我对ndis各层理解的不好,所以没问清楚问题。
我现在是想在ddk下的ne2000的例子中进行数据加解密,这个例子据我理解是个miniport层的例子,而且我已经将其编译安装,可以作为网卡驱动来用。我不想在中间层和协议层作文章,但又不知在miniport层进行数据加解密是否可行,因此十分迷茫。如各位知道的话请一定要帮帮忙。
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2001-11-07 10:37
照上面的帖子看来包的两流程应该是:
1、发送的流程:
WIN32 SEND

->Winsock

->TCPIP.SYS(TDI)->[NDIS]

->MPSend@LeyeredMiniport.Passthru.IM->[NDIS]

->TranferData@LayeredMiniport.Passthru.IM->[NDIS]

->NIC Miniport->[NIC]

->PtTransferDataComplete@LayeredProtocol.Passthru.IM->[NDIS]

->SendComplete!!!
这么说的话对发送的处理要在LayeredMiniport里面处理!

2、接收的流程:
NIC RECV
->NIC Miniport->[NDIS]

->PtReceive@LayeredProtocol.passthru.IM->[NDIS]

->{Select Medium}NdisXXXXIndicateReceive@PtReceive.LayeredProtocol.passthru.IM->[NDIS]

->TCPIP.SYS(TDI)->[NDIS]

->Winsock

->WIN32 APP

->Recv Complete!!!
收的处理自然是在LayeredProtocol处理咯!

3、查询请求的处理
WIN32 APP Query info
->Winsock
->TCPIP.SYS(TDI)->[NDIS]
->MPQueryInformation@LayeredMiniport.Passthru.IM(这有个循环,用来选择不同的OID来做不同的处理)
》》》》》》》》》》》》》
do
{
//
// Return Success for this OID
//
if (Oid == OID_PNP_QUERY_POWER)
{
Status=NDIS_STATUS_SUCCESS;
break;
}

//
// All other queries are failed, if the miniport is not at D0
//
if (pAdapt->MPDeviceState > NdisDeviceStateD0 || pAdapt->StandingBy == TRUE)
{
Status = NDIS_STATUS_FAILURE;
break;
}
//
//We are doing all sends on the secondary,
//so send all requests with Send OIDs to the Secondary
//
if (MPIsSendOID(Oid))//这就是调用MPIsSendOID来做对某些请求做特殊处理的地方!缺省是无处理!
{
pAdapt = pAdapt->pSecondaryAdapt;
//
// Will point to itself, if there is no secondary (see initialization)
//
}

pAdapt->Request.RequestType = NdisRequestQueryInformation;
pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;
pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
pAdapt->BytesNeeded = BytesNeeded;
pAdapt->BytesReadOrWritten = BytesWritten;
pAdapt->OutstandingRequests = TRUE;

//
// if the Protocol device state is OFF,
// then the IM driver cannot send the request below and
//must pend it
//
if (pAdapt->PTDeviceState > NdisDeviceStateD0)
{
pAdapt->QueuedRequest = TRUE;
Status = NDIS_STATUS_PENDING;
break;
}

//
// default case, most requests will be passed to the miniport below
//
NdisRequest(&Status,  //看这就是向下层传递请求[既OID]的地方!!
pAdapt->BindingHandle,
&pAdapt->Request);


//
// If the Query was a success, pass the results back to the entity that made the request
//
if (Status == NDIS_STATUS_SUCCESS)
{
*BytesWritten = pAdapt->Request.DATA.QUERY_INFORMATION.BytesWritten;
*BytesNeeded = pAdapt->Request.DATA.QUERY_INFORMATION.BytesNeeded;
}

//
// Fill the buffer with the required values if Oid == OID_PNP_CAPABILITIES
// and the query was successful
//
if (Oid  == OID_PNP_CAPABILITIES  && Status == NDIS_STATUS_SUCCESS)
{
MPQueryPNPCapbilities(pAdapt,&Status);
}

if (Status != NDIS_STATUS_PENDING)
{
pAdapt->OutstandingRequests = FALSE;
}

} while (FALSE);

return(Status);
《〈〈〈〈〈〈〈〈〈〈〈
->把请求交NIC Miniport
->NIC处理请求
->PtRequestComplete@PtReceive.LayeredProtocol.passthru.IM->[NDIS]
->省略。。。。-〉查询处理完毕!

还有另一个重要概念就是OOB,我个人认为是一些对包的特性描述,详细正确希望哪位熟悉的大虾给大伙剖析剖析!!

LookAheadBuffer正确翻译应该是什么呢?谁能把他确实的定义一下!这东西搞的人模糊知道作用,
却不知道怎么说明他的确确意义!

Private.Tail应该就是FRAME的CRC部分了吧?

还有设置NIC的OID处理也可同理获得流程。
从NIC发生的Halt和设置改变、网络唤醒等的流程也差不多!
这只是本人粗犷的对Passthru的流程机制的剖析,希望各路大虾,老龙的指教!!
我本人很支持SIRROOM的讨论!因为通过先讨论PASSTHRU的机制然后再谈实现是件好事!
还希望这个讨论能够继续下去,成为本论坛的一个经典Q&A!
这样对所有开发IM驱动的朋友都是有益的!希望能得到各路大虾的支持!!!
谢谢~~谢谢~~
另外跟本讨论内容相差太远的话题请另立新贴好么?谢谢了~~~

<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2001-11-07 10:58
zzy918说的应该是NIC miniport或WAN miniport!
sirroom说的应该是IM driver layeredminiport!
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
游客

返回顶部