【转载】NDIS小端口驱动
来源:http://www.jiangkai.net/article/201301/20130109141929.html转载请注明出处。
<p align="center"><b>
<a href="http://www.jiangkai.net"><font size="4">[点击进入jiangkai的编程网站]</font></a></b> <p align="center"> <p align="center"><i><b><font color="#FF0000" size="3">
NDIS小端口驱动</font></b></i></p>
<p align="left"> <DIV style="DIRECTION: ltr">
<DIV style="MARGIN-TOP: 0in; WIDTH: 30.67in; DIRECTION: ltr; MARGIN-LEFT: 0in">
<DIV style="MARGIN-TOP: 0in; WIDTH: 1.427in; DIRECTION: ltr; MARGIN-LEFT: 0.021in">
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"><SPAN lang=en-US>NDIS</SPAN><SPAN lang=zh-CN>小端口驱动</SPAN></P></DIV>
<DIV style="MARGIN-TOP: 0.577in; WIDTH: 30.67in; DIRECTION: ltr; MARGIN-LEFT: 0in">
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>1 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动其实就是真正的网卡驱动,相对于协议驱动而言,它更贴近物理层</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>A </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>现代</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>windows</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>系统提倡的是仅隔离出物理可变部分,其他的部分则给予统一的实现与接口,而要求网卡商开发的网卡驱动,则仅仅剩下被隔离出的少部分,之后部分插在通用的接口(这里的接口指小端口驱动)上即可</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>B </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>开发一个适用于物理网卡的小端口驱动一般都是网络芯片厂商的工作,</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>在安全软件领域,小端口驱动技术主要用于虚拟网卡</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>2 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>协议驱动下面邻接的必定是</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>NDIS</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动,</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>NDIS</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动上面邻接的必定是</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>NDIS</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>协议驱动,</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>但小端口驱动的下层可以是协议驱动</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>&</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>硬件</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>3 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动的运作与编程概述</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>A </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动也是先填写一个小端口特征,小端口特征是一个回调函数的指针数组,</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=en-US>windows</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>内核在某些时候会调用这些回调函数</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>B </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>协议驱动会调用</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=en-US>NdisSendPackets</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>进行包的发送,而</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=en-US>Windows</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>内核的</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=en-US>NDIS</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>子系统则会自动找到该协议绑定的小端口驱动,调用小端口特征中的用于发送数据包的回调函数</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>C </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>和实现协议驱动一样,实现小端口驱动就是实现小端口特征中的这些回调函数</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>4 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口的初始化</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>A </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>初始化全局变量。这些全局变量是在整个驱动中使用的</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>B </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>检查版本号</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>C </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>生成一个WDF驱动对象</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>D </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>初始化包装句柄:NDIS内部会使用这个包装句柄来管理小端口的配置信息,但是小端口驱动的开发者并不需要从这个句柄中获得任何信息,只适用于调用NDIS的内核API</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>E </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>填写小端口的特征&并注册小端口</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>(小端口是没有必要去绑定什么东西的)</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>F </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>这个驱动需要全局资源一个锁和一个链表。 初始化全局变量。这些全局变量是在整个驱动中使用的</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>5 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动的适配器结构</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>一个小端口驱动可以驱动同一类型芯片的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>N</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>个网卡。一个事件出现的被某个小端口</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>驱动的网卡(不一定是物理的)被称为该驱动的一个实例</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>一个小端口驱动可以是没有任何实例的。但在拥有的情况下,小端口驱动对</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>每个实例要保存一组信息(实例</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>=</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>网卡)</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>(用在</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>driverentry</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>中创建的链表</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>&</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>锁来保存)</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"><SPAN style="mso-spacerun: yes"></SPAN>// 初始化全局变量。这些全局变量是在整个驱动中使用的</P>
<P style="MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"><SPAN style="mso-spacerun: yes"></SPAN>NdisAllocateSpinLock(&GlobalData.Lock);</P>
<P style="MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"><SPAN style="mso-spacerun: yes"></SPAN>NdisInitializeListHead(&GlobalData.AdapterList);</P>
<P style="MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>6 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>配置信息的读取</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>在初始化过程中需要读取配置信息。比如网卡的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>MAC</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>地址,这些信息都在</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>NICReadRegParameters</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>中实现。向系统读取配置信息时,一个重要的输入参数是在</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>DriverEntry</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>中获得的句柄</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>7 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>设置小端口适配器上下文</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>在协议驱动中,绑定的上下文相当于一个</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>被绑定的网卡</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>,对于小端口驱动来说,同样重要的是一个</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>适配器上下文</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>。适配器上下文是一个指针,这个指针指向的空间就是适配器结构,这个指针必须在</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>MPIniti</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=en-US>alize</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>中设置好。</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>比如</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>MPSen</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=en-US>dPackts</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>(发包的回调)</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>需要用这个指针来选择用哪个网卡来发送数据包</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"><SPAN style="COLOR: red">重点:NICInitializeAdapter</SPAN> 这是最关键的一步,就是启动整个网卡<SPAN style="mso-spacerun: yes"> </SPAN>用这个适配器结构做实参Adapter,最后这个适配器会串联到链表中。MPSendPackts(发包的回调)需要用这个指针来选择用哪个网卡来发送数据包</P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: Calibri; FONT-SIZE: 9pt" lang=en-US></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>8 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>书中</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>P393</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>:而</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>windows</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>内核的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>NDIS</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>子系统则会自动找到该协议绑定的小端口驱动</SPAN></P>
<P style="MARGIN: 0in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; COLOR: black; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>从上到下顺序如下:</SPAN></P>
<P style="MARGIN: 0in; COLOR: black; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; FONT-WEIGHT: bold" lang=zh-CN>(应用层</SPAN><SPAN style="FONT-FAMILY: Calibri; FONT-WEIGHT: bold" lang=en-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体; FONT-WEIGHT: bold" lang=zh-CN>相关</SPAN><SPAN style="FONT-FAMILY: Calibri; FONT-WEIGHT: bold" lang=en-US>DLL</SPAN><SPAN style="FONT-FAMILY: 宋体; FONT-WEIGHT: bold" lang=zh-CN>实现)</SPAN><SPAN style="FONT-FAMILY: Calibri; FONT-WEIGHT: bold" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SOCKET API </SPAN></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>(传输层的上层,</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US>afd</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=en-US>.sys</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>AFD</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>驱动:(</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>实现</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US>SOCKET </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>的内核函数</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>)与传输层驱动下层</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>tdi.sys</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>不存在形式上的堆叠,但是仍旧可以通过</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>IoCallDrvier()</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>调用传输层驱动的主功能函数(说明</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>tdi.sys</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>也创建了设备),该驱动是</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SOCKET</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的内核函数的实现,这些内核函数用协议驱动提供的</SPAN><SPAN style="FONT-FAMILY: Calibri; BACKGROUND: #ccffff" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: #ccffff" lang=zh-CN>设备对象的设备名(如</SPAN><SPAN style="FONT-FAMILY: Calibri; BACKGROUND: #ccffff" lang=en-US>tcp</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: #ccffff" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>作实参数调用</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: purple; mso-highlight: purple" lang=en-US>TDI接口</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>来向协议驱动发送格式化后的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>IRP</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>,如:IRP_MJ_INTERNAL_DEVICE_CONTROL,</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>TDI IOCTL</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>为</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>TDI_CONNECT </SPAN></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>(传输层的下层,</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US>tdi</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=en-US>.sys</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US><SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=zh-CN>驱动:</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: purple; COLOR: white; mso-highlight: purple" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: purple; COLOR: white; mso-highlight: purple" lang=zh-CN>接口</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>是内核模块</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>tdi.sys</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>提供的一组支持函数(参见</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>windows</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>内核原理与实现的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>P596</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>页),从而将</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>客户(</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>实现</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US>SOCKET </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>的内核函数</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>)和</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>传输器(协议驱动)联系起来,</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>接口实现了</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>3</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>次握手等传输层的相关功能</SPAN></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=en-US>(TDIFilter.sys)</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=zh-CN>过滤驱动:这里就是</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>过滤驱动所在的位置,查看设备栈时看到</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>ftcp</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的附加设备附加在</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>tcp</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>设备上</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>,<SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue; FONT-WEIGHT: bold" lang=zh-CN>过滤向协议驱动发送格式化后的</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue; FONT-WEIGHT: bold" lang=en-US>IRP</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=zh-CN>,如:IRP_MJ_INTERNAL_DEVICE_CONTROL,</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>TDI IOCTL</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>为</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>TDI_CONNECT </SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: Calibri; FONT-WEIGHT: bold" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>(</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US>tcp</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=en-US>ip.sys</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=zh-CN>协议驱动:</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: #ccffff; COLOR: #c00000" lang=zh-CN>提供</SPAN><SPAN style="FONT-FAMILY: Calibri; BACKGROUND: #ccffff; COLOR: #c00000" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: #ccffff; COLOR: #c00000" lang=zh-CN>设备对象</SPAN><SPAN style="FONT-FAMILY: Calibri; BACKGROUND: #ccffff; COLOR: #c00000" lang=en-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: #ccffff; COLOR: #c00000" lang=zh-CN>如</SPAN><SPAN style="FONT-FAMILY: Calibri; BACKGROUND: #ccffff; COLOR: #c00000" lang=en-US>tcp&udp</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>过滤驱动创建的设备对象就附加在这些设备上。当协议驱动响应了</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: purple; COLOR: white; mso-highlight: purple" lang=en-US>TDI接口</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: purple; COLOR: white; mso-highlight: purple" lang=zh-CN>(处理这些格式化的</SPAN><SPAN style="FONT-FAMILY: Calibri; BACKGROUND: purple; COLOR: white; mso-highlight: purple" lang=en-US>IRP</SPAN><SPAN style="FONT-FAMILY: 宋体; BACKGROUND: purple; COLOR: white; mso-highlight: purple" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>则说明它是一个</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>TDI</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>传输器,在处理这些</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>IRP</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的回调中会通过小端口驱动来发包</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>&</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>收包</SPAN></P>
<P style="MARGIN: 0in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>(</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US>ndis</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=en-US>edge.sys</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=zh-CN>小端口驱动:设</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>ndisdge</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>是最后一个注册的小端口驱动,</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>TCPIP</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>协议驱动会调用它的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SendPacketsHandler</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>,而</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SendPacketsHandler</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>中会向</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>Ndis</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US>port</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>发送写请求(之前</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US>ndisdge</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>已经将</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US>ndisport</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>和非</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US>ndisdge</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的实例绑定)</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SendPacketsHandler</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的适配器上下文中保存了协议驱动</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>ndisport</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的绑定上下文(</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>实现方法是</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>P408</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>页</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>)</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; FONT-WEIGHT: bold" lang=en-US>(ndisprot.sys)</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>协议驱动:</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US>ndissport</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>会通过</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US><SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>非</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US>ndisdge</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的实例的打开上下文中的绑定句柄调用</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US><SPAN style="mso-spacerun: yes"> </SPAN>SendPacketsHandler </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>(这时会调用物理网卡的网卡驱动的</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: red" lang=en-US>SendPacketsHandler</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: red" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>(</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US>ndisport</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>的</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US>R3</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>测试程序通过适配器名称JUNK来绑定的,某个网卡驱动创建了该网卡名称,这时</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US>ndisport</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>就会使用该网卡来发送数据包</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>而</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>nidsedge</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>在</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>R0</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>层中通过发送</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>IOCTL_NDISPROT_OPEN_DEVICE +</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>网卡名称来让</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>ndisport</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>绑定一个非</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>ndisdge</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>的小端口驱动的打开上下问,并用这个打开上下文来调用</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SendPacketsHandler</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>发包,这时就会进入物理网卡的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>SendPacketsHandler</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>中</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri; COLOR: black; FONT-WEIGHT: bold" lang=en-US><SPAN style="mso-spacerun: yes"></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>(网卡</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=en-US>sys</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black; FONT-WEIGHT: bold" lang=zh-CN>)</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US><SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: black" lang=zh-CN>小端口驱动:</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>协议驱动通过</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>小端口驱动的发送回调接口</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: blue" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>联系小端口驱动,而小端口驱动通过回调驱动的接收回调联系协议驱动。</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US><SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口只有发送回调接口,协议只有接收回调接口</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>来将协议驱动和小端口驱动连接起来的</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"><SPAN style="BACKGROUND: aqua; mso-highlight: aqua">协议驱动和小端口驱动的联系:</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>1<SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>当</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>windows</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>检测到有网卡存在时,就会调用每个注册过的协议的</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>BindAdpaterHandler</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>函数,于是协议驱动就保存了适配器的信息</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>2<SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>协议驱动通过</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口驱动的发送回调接口</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>联系小端口驱动(因为发送时主动的),而小端口驱动通过回调驱动的接收回调联系协议驱动(因为小端口的收包是主动的,通过网卡驱动的中断来收包)</SPAN><SPAN style="FONT-FAMILY: 宋体; COLOR: blue" lang=zh-CN>。</SPAN><SPAN style="FONT-FAMILY: Calibri; COLOR: black" lang=en-US><SPAN style="mso-spacerun: yes"> </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口只有发送回调接口,协议只有接收回调接口</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>来将协议驱动和小端口驱动连接起来的</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in"><IMG alt="计算机生成了可选文字: eg 冈幻 。 代 材角坏 峨闪稼二私陈耐明乍、枫、琢沁}、褂鲜秘 督啄恻 9助咧卿拟鳞铸瞰呻碱立柳丛协御畴咬 夕介柳卿胜卿确,郑娜五恤q 云矫印溺嵋发一远,哪冷峨磷 敬劫汽涎目冷砂 纪键缘瞬彭孵 汹嚷从。吵装勇醚" src="mhtml:http://jiangkai.net/OneNote/DriverDevelop/NetDriver/3.mht!x-usc:3.files/image001.png" width=779 height=525></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>9 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>小端口只有发送回调接口,协议只有接收回调接口</SPAN></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 宋体; FONT-SIZE: 9pt"></P>
<P style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 9pt"><SPAN style="FONT-FAMILY: Calibri" lang=en-US>10 </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>使用</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>ndisprot</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>发送包</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US> </SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>(进行到这里了</SPAN><SPAN style="FONT-FAMILY: Calibri" lang=en-US>P409</SPAN><SPAN style="FONT-FAMILY: 宋体" lang=zh-CN>)</SPAN></P></DIV></DIV></DIV>
<DIV>
<P style="MARGIN: 0in"></P>
<P style="TEXT-ALIGN: left; MARGIN: 0in; FONT-FAMILY: 宋体; DIRECTION: ltr; COLOR: #969696; FONT-SIZE: 9pt">已使用 Microsoft OneNote 2010 创建<BR>一个用于存放所有笔记和信息的位置</P></DIV> </p>
页:
[1]