XiangXiangRen
总版主
总版主
  • 注册日期2003-02-22
  • 最后登录2015-09-01
  • 粉丝13
  • 关注0
  • 积分1042分
  • 威望472点
  • 贡献值1点
  • 好评度145点
  • 原创分13分
  • 专家分1分
阅读:1475回复:2

DriverNetworks第一课!

楼主#
更多 发布于:2003-02-28 17:16
DriverNetworks开发Ndis网络驱动教材

使用DriverNetworks开发网络驱动非常容易,有使用VB开发Windows应用的感觉(比MFC容易:))。下面这些东西是我从DriverNetworks的帮助上翻译过来,只加了很少dongxi,非常浅显,很适合入门者。

第一课 管理NDIS Packets

NDIS Packet(包描述符)是最基本的NDIS数据类型(NDIS_PACKET结构),被多种网络驱动用于描述临近的两个网络接口之间传输的数据。NDIS_PACKET是比NDIS_BUFFER更高层的抽

象。NDIS_BUFFER描述NDIS_PACKET所使用的内存空间。在Windows NT中,就是是MDL(内存描述符号链)。NDIS_PACKET描述了在层之间收到或者发出的数据包的内容。这些内容保存在一

个NDIS_PACKET所拥有的NDIS_BUFFER链中。

DriverNetworks通过KNdisPackets类来使用NDIS packets。KNdisPacket是PNDIS_PACKET的c++外包类,而且有与PNDIS_PACKET同样的运行效率。对于类型转换的支持使KNdisPacket可以被直接

用于所有以PNDIS_PACKET为参数的函数中。

NDIS Packets总是从NDIS packet pool(包描述符号池,下面简称包池)中分配的。在DriverNetworks中,packet pool由KNdisPacketPool类描述。如果你的驱动管理自己的包池,它总是包

括一个KNdisPacketPool对象作为adapter类(这个类以后再说)的数据成员。并在Adapter类的Initialize中初始化它,然后可以在其他地方分配或者释放你的包描述符。

当一个Ndis pakcet通过NDIS在一个驱动到另一个驱动之间传递的时候,该描述符的所有权可以临时的转移到后一个驱动。为了区分这些Ndis pakcet的所在环境,NDIS_PACKET结构提供一些特

别的区域,名保留域,来在这些包描述符中保存上下文信息。DriverNetworks提供KNdisPacketWithContext与KNdisPacketListWithContext来管理这些区域。

为解决NDIS中间层驱动执行包管理的困难,DriverNetworks中间层驱动往往使用了包描述符中的一些保留域。为了在框架代码和用户代码之间正确的共享这些区域,DriverNetworks提供

了KNdisFilterPacketPool类,这个类提供了一个安全的机制来在中间层驱动使用自己的包池。

下面是分配包池的例子。

//MyAdapter类也就是我的整个驱动,注意成员函数实现写在类声明里了,别被这个给迷惑
class MyAdapter : public KNdisMiniAdapter {
...
KNdisPacketPool m_Pool;
public:
NDIS_STATUS Initialize(KNdisMedium& Medium, IN KNdisConfig& Config) {
...
m_Pool.Initialize(8); //初始化包池(在其中初始化8个包描述符)
ASSERT(m_Pool.IsValid());
...
}

void SomeMethod() { //这里在某个成员函数中分配一个包描述符
KNdisPacket pkt = m_Pool.Allocate();
if(pkt.IsValid())
{
... //如果想使用就使用咯
}

void AnotherMethod(KNdisPacket& pkt) { //在这里将包描述符号释放还给包池
m_Pool.Free(pkt);
}
}

使用非常简单,应该注意的是包描述符只是一个描述符,并不包含真实的数据包数据。只是使你可以找到并管理数据包。

DriverNetworks有另一个类KNdisPacketList,可以用于管理Ndis Packet链表。KNdisPacketList是NDIS_PACKET的双向链表。注意KNdisPacketList并不是线程安全的,这对与标准的NDIS4微端

口驱动来说足够了。不连续的NDIS5微端口驱动可能必须使用KNdisInterLockedPacketList代替之,这个类使用一个自旋锁保证几个线程对链表的操作不会互相干扰。

KNdisPacketList类一般用于执行先进先出式的包处理过程。下面是例子。

class MyAdapter : public KNdisMiniAdapter {
...
KNdisPacketList m_Queue;
public:
void Process(PNDIS_PACKET pkt) {
if(/*如果想立刻处理*/) {
  //处理过程
}
else  {//如果不想处理,暂时加入队列中
m_Queue.InsertTail(pkt);
}
}

void ProcessLater() { //在这里处理
KNdisPacket pkt = m_Pool.Remove();
if(pkt.IsValid()) {
//处理
}
else {} //说明队列是空的?
}
}

NDIS_PACKET提供MiniportReserved[]和ProtocolReserved[]这样特殊的保留区域,主要用于保存可能这些包的不同的上下文(或者说执行环境)信息。举个例子,一个协议驱动收到应用程序

请求并生成了一个包,协议可能要储存有一个IRP的指针。NDIS要求微端口使用MiniportReserved[]而协议驱动使用ProtocolReserved[]。中间层驱动则更要严格的注意,当前是Miniport呢还

是Protocol在使用哪一个域。

DriverNetworks提供了类模板KNdisPacketWithContext,这使你可以随意处理保留区域而不必担心类型。KNdisPacketWithContext当然来自KNdisPacket,而驱动开发者必须可以自己定义保留区

域中的数据结构,然后使用GetContext()方法来返回一个指针访问保留区域。

KNdisPacketWithContext一般用于KNdisPacketListWithContext中。后者是KPacketList的容器,并且提供了根据用户定义数据结构很方便的访问保留区域的方法。

KNdisPacketWithContext和KNdisPacketListWithContext这两个模板都通过两个参数生成类,一个上下文类型,也就是用户定义的保留区域数据结构。另一个是一个bool变量,表示描述符号

是用于微端口的还是协议的。

下面是例子

class MyPacketDevice : public KDevice
{
//上下文 (保存在包描述符的保留区域中)
struct PacketContext {
PIRP Irp;
PMDL pMdl;
};

typedef KNdisPacketListWithContext<PacketContext> PacketList;

protoected:
KNdisPacketPool m_PacketPool;
PacketList m_List;
}

//现在看如何使用了
void Submit(KIrp I) {
KNdisPacketWithContext packet = m_PacketPool.Allocate();
packet->GetContext()->Irp = I; //看见了吧,直接用用户定义的类型访问保留区域
m_List.InsertTail(packet);
...
}

void SubmitDone() {
KNdisPacketWithContext packet = m_RcvList.RemoveHead();
KIrp I = packet.GetContext()->Irp;
// ...
}

同时,类KNdisFilterPacketPool提供了安全的方法来在中间层驱动中使用私有的包池。值得注意,强烈推荐使用KNdisFilterPacketPool代替KNdisPool,如果你要在中间层驱动中使用私有的

包池的话。

使用步骤如下:

1.定义你的保留区域数据类型T

struct MyContext {PVOID data;}

2.定义你的包池
typedef kNdisFilterPacketPool<MyContext,true> CTxPool;
typedef KNdisFilterPacketPool<MyContext,false> CRxPool;

3.分配包并使用保留区域
KNdisPacket p = m_CTxPool.Allocate();
CTxPool::GetContext(p)->data = ...



最新喜欢:

atmanatman
assi
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-01-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-02-28 17:50
好帖,wait for the next lesson
塞奇
lzwf4
驱动小牛
驱动小牛
  • 注册日期2002-10-10
  • 最后登录2006-06-09
  • 粉丝0
  • 关注0
  • 积分22分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-03-01 14:44
太好了!!!!!
游客

返回顶部