NDIS协议驱动(二)

在NDIS协议驱动看来,它的下层就是适配器,这一点是基于逻辑而不是基于实际的,在WDM的驱动框架中介绍过这一点,故我们始终认为协议驱动的下层总是网络适配器。

绑定到适配器

NDIS 调用协议驱动程序的 ProtocolBindAdapterEx 函数,以在驱动程序可以绑定到的基础适配器可用时打开绑定。 NDIS 调用 ProtocolBindAdapterEx 后,绑定进入“打开”状态。 在 “打开” 状态下,协议驱动程序为绑定分配资源并打开适配器。

NDIS 将传递给 ProtocolBindAdapterExs 绑定操作的 NDIS 上下文,以及指向 NDIS_BIND_PARAMETERS 结构的指针。 此结构包含有关适配器的信息,例如:

  • 适配器的名称;
  • 注册表中的协议服务条目下特定于此绑定的参数的注册表位置;
  • 适配器的物理设备对象;

若要打开适配器,协议驱动程序调用 NdisOpenAdapterEx 函数。 协议驱动程序将以下内容传递给 NdisOpenAdapterEx:

  • NDIS 在 NdisRegisterProtocolDriver 函数的 NdisProtocolHandle 参数中返回到驱动程序 的句柄 ;
  • 此绑定的协议驱动程序上下文;
  • 指向 NDIS_OPEN_PARAMETERS 类型的结构的指针;

NDIS_OPEN_PARAMETERS 包含 NdisOpenAdapterEx 应打开的适配器的名称、协议驱动程序支持的中等类型的数组以及驱动程序可在此绑定上接收的帧类型的数组(可选)。

如果协议驱动程序从 ProtocolBindAdapterEx 返回NDIS_STATUS_PENDING,则必须调用具有最终状态的 NdisCompleteBindAdapterEx 才能完成绑定请求。

如果 NDIS 从 NdisOpenAdapterEx 返回NDIS_STATUS_PENDING,则 NDIS 在打开的请求完成后,会以最终状态调用协议驱动程序的 ProtocolOpenAdapterCompleteEx 函数。

驱动程序成功打开到适配器的绑定后,绑定将处于“暂停”状态。

协议驱动程序调用 NdisCloseAdapterEx 函数以关闭适配器。 驱动程序可以从 ProtocolBindAdapterEx 函数或 ProtocolUnbindAdapterEx 函数调用 NdisCloseAdapterEx。

如果在打开适配器后完成绑定请求之前, ProtocolBindAdapterEx 遇到故障,并且必须关闭对适配器的绑定,则可以调用 NdisCloseAdapterEx。

从适配器取消绑定

NDIS 调用协议驱动程序的 ProtocolUnbindAdapterEx 函数,以请求驱动程序从基础适配器取消绑定。 作为 ProtocolBindAdapterEx 的倒数,NDIS 调用 ProtocolUnbindAdapterEx 以关闭对适配器的绑定并释放驱动程序为绑定分配的资源。

在 ProtocolUnbindAdapterEx 中,协议驱动程序调用 NdisCloseAdapterEx 以关闭对基础适配器的绑定。 协议驱动程序将 NdisCloseAdapterEx 传递 NdisOpenAdapterEx 在其 NdisBindingHandle 参数中提供的句柄。 此句柄标识 NDIS 应关闭的绑定。

协议驱动程序必须从 ProtocolBindAdapterEx 函数或 ProtocolUnbindAdapterEx 函数关闭适配器。

如果协议驱动程序必须启动操作以关闭绑定,则驱动程序可以调用 NdisUnbindAdapter。 NdisUnbindAdapter 计划一个工作项,该工作项导致对 ProtocolUnbindAdapterEx 进行 NDIS 调用。 此工作项可以在对 NdisUnbindAdapter 的调用返回之前运行。 因此,驱动程序编写器必须假定绑定句柄在 NdisUnbindAdapter 返回后无效。

如果协议驱动程序从 ProtocolUnbindAdapterEx 返回NDIS_STATUS_PENDING,则必须调用具有最终状态的 NdisCompleteUnbindAdapterEx 才能完成绑定请求。

如果 NDIS 从 NdisCloseAdapterEx 返回NDIS_STATUS_PENDING,则 NDIS 稍后会调用协议驱动程序的 ProtocolCloseAdapterCompleteEx 函数。

如果绑定处于“暂停”状态,NDIS 可以调用 ProtocolUnbindAdapterEx 。

完成所有取消绑定操作后,绑定将处于“未绑定”状态。

启动和暂停绑定

NDIS 暂停绑定以停止可能会干扰即插即用 (PnP) 操作的数据流,例如,在驱动程序堆栈中添加或删除筛选器模块,或者添加新绑定。 

NDIS 从 “已暂停” 状态启动绑定。 绑定在绑定操作完成后或暂停操作完成后进入“ 已 暂停”状态。

重启绑定

若要重启暂停的绑定,NDIS 向协议驱动程序发送网络即插即用 (PnP) 重启事件通知。 协议驱动程序收到重启通知后,受影响的绑定将进入“正在重启”状态。

为了发送重启通知,NDIS 调用协议驱动程序的 ProtocolNetPnPEvent 函数。 NDIS 传递给 ProtocolNetPnPEvent 的 NET_PNP_EVENT_NOTIFICATION 结构指定 NetEvent 成员中的 NetEventRestart,而 Buffer 成员包含指向 NDIS_PROTOCOL_RESTART_PARAMETERS 结构的指针。 NDIS 提供指向 NDIS_PROTOCOL_RESTART_PARAMETERS 结构的 RestartAttributes 成员中的 NDIS_RESTART_ATTRIBUTES 结构的指针。

注意 暂停绑定时,NDIS 可能已重新配置驱动程序堆栈。 新的堆栈配置可以为基础适配器支持一组不同的功能。 这些新功能可能会影响协议驱动程序在绑定上的通信方式。

协议驱动程序应使用 NDIS_PROTOCOL_RESTART_PARAMETERS 结构中的信息,以避免不必要的 OID 请求。

在“正在重启”状态下,协议驱动程序可以:

  • 使用 OID 请求查询驱动程序堆栈。 例如,驱动程序可以使用 OID_GEN_RECEIVE_SCALE_CAPABILITIES 了解对接收方缩放的支持;
  • 如有必要,重新分配 NET_BUFFER 和 NET_BUFFER_LIST 池;
  • 枚举基础筛选器模块的列表;
  • 使用 OID 请求显示新的适配器功能;

驱动程序准备好恢复绑定的发送和接收操作后,绑定将进入“正在运行”状态。

暂停绑定

NDIS 向协议驱动程序发送网络即插即用 (PnP) 绑定的暂停事件通知后,绑定将进入暂停状态。

为了通知协议驱动程序 PnP 暂停事件,NDIS 调用 ProtocolNetPnPEvent 函数,NET_PNP_EVENT_NOTIFICATION 结构的 NetEvent 成员设置为 NetEventPause。 Buffer 成员包含NDIS_PROTOCOL_PAUSE_PARAMETERS结构。

对于处于暂停状态的绑定,协议驱动程序:

  • 不应启动任何新的发送请求;
  • 必须等待未完成的发送请求完成。 暂停操作在 NDIS 针对驱动程序的所有未完成发送请求调用 ProtocolSendNetBufferListsComplete 函数之前不会完成;
  • 应像往常一样处理接收指示。 基础微型端口驱动程序在完成暂停操作之前等待未完成的接收数据返回。 这可确保在微型端口驱动程序暂停后驱动程序堆栈中没有正在进行的接收操作;
  • 应立即向 NDIS 返回新的接收指示。 如有必要,驱动程序可以复制此类接收指示,然后再返回它们;

完成协议驱动程序返回绑定的未完成接收指示,并且 NDIS 已完成绑定的所有未完成发送请求后,绑定将进入“已暂停”状态。

对于处于“暂停”状态的绑定,协议驱动程序:

  • 不得发出任何发送请求;
  • 应立即返回接收指示。 如有必要,驱动程序可以复制此类接收指示,然后再返回它们;
配置可选的协议驱动程序服务

NDIS 调用协议驱动程序的 ProtocolSetOptions 函数,以允许协议驱动程序配置可选服务。 NDIS 在协议驱动程序调用 NdisRegisterProtocolDriver 函数的上下文中调用 ProtocolSetOptions

ProtocolSetOptions 为可选 ProtocolXxx 函数注册默认入口点,并且可以分配其他驱动程序资源。 为了注册可选的 ProtocolXxx 函数,协议驱动程序调用 NdisSetOptionalHandlers 函数,并在 OptionalHandlers 参数中传递特征结构。 在这种情况下,协议驱动程序在 NdisSetOptionalHandlers 的 NdisHandle 参数上传递 ProtocolSetOptions 的 NdisDriverHandle 参数的句柄。

协议驱动程序还可以在协议驱动程序具有 NdisOpenAdapterEx 函数的有效句柄后,从 ProtocolBindAdapterEx 函数或 ProtocolOpenAdapterCompleteEx 函数调用 NdisSetOptionalHandlers 。 在这种情况下,协议驱动程序在 NdisSetOptionalHandlers 的 NdisHandle 参数上传递 NdisOpenAdapterEx 的 NdisBindingHandle 参数的句柄。

在这种情况下,有效特征结构为:

  • NDIS_PROTOCOL_CO_CHARACTERISTICS
  • NDIS_CO_CLIENT_OPTIONAL_HANDLERS
  • NDIS_CO_CALL_MANAGER_OPTIONAL_HANDLERS
  • NDIS_CLIENT_CHIMNEY_OFFLOAD_GENERIC_CHARACTERISTICS 
  • NDIS_CLIENT_CHIMNEY_OFFLOAD_TCP_CHARACTERISTICS

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值