下面则是介绍Filter驱动编写方面的初始化卸载等方面的内容。
初始化Filter驱动程序
Filter驱动程序初始化在系统加载驱动程序后立即发生。 Filter驱动程序作为系统服务加载。 系统可以在微型端口驱动程序加载之前、期间或之后的任何时候加载Filter驱动程序。 Filter驱动程序支持的类型的微型端口适配器可用且Filter驱动程序初始化完成之后,NDIS 可以将Filter模块附加到微型端口适配器。
驱动程序堆栈启动时,如果尚未加载Filter驱动程序,系统会加载这些驱动程序。
加载Filter驱动程序后,系统会调用驱动程序的 DriverEntry 例程。
系统将两个参数传递给 DriverEntry:
- 指向 I/O 系统创建的驱动程序对象的指针;
- 指向注册表路径的指针,该路径指定特定于驱动程序的参数的存储位置;
如果驱动程序成功注册为 NDIS Filter驱动程序,则 DriverEntry 返回STATUS_SUCCESS或其等效NDIS_STATUS_SUCCESS。 如果 DriverEntry 通过传播 NdisXxx 函数或内核模式支持例程返回的错误状态来初始化失败,驱动程序将不会保持加载状态。 DriverEntry 必须同步执行;也就是说,它不能返回STATUS_PENDING或其等效NDIS_STATUS_PENDING。
Filter驱动程序在 NDIS 中注册为Filter驱动程序时,将驱动程序对象传递给 NdisFRegisterFilterDriver 函数。 驱动程序可以使用注册表路径获取配置信息。
Filter驱动程序从其 DriverEntry 例程调用 NdisFRegisterFilterDriver。 Filter驱动程序通过将 NDIS_FILTER_DRIVER_CHARACTERISTICS 结构传递到 FilterCharacteristics 参数处的 NdisFRegisterFilterDriver 来导出一组 FilterXxx 函数。
NDIS_FILTER_DRIVER_CHARACTERISTICS 结构指定必需和可选 FilterXxx 函数的入口点。 可以绕过某些可选函数。
调用 NdisFRegisterFilterDriver 的 驱动程序必须准备好立即调用其任何 FilterXxx 函数。
NDIS_FILTER_DRIVER_CHARACTERISTICS 结构指定以下必需 FilterXxx 函数的入口点:
- FilterAttach
- FilterDetach
- FilterRestart
- FilterPause
NDIS_FILTER_DRIVER_CHARACTERISTICS 结构指定以下可选、运行时不可更改 的 FilterXxx 函数的入口点:
- FilterSetOptions
- FilterSetModuleOptions
- FilterOidRequest
- FilterOidRequestComplete
- FilterStatus
- FilterNetPnPEvent
- FilterDevicePnPEventNotify
- FilterCancelSendNetBufferLists
NDIS_FILTER_DRIVER_CHARACTERISTICS 结构指定以下可选、运行时可更改 的 FilterXxx 函数的默认入口点:
- FilterSendNetBufferLists
- FilterSendNetBufferListsComplete
- FilterReturnNetBufferLists
- FilterReceiveNetBufferLists
上述四个函数也在 NDIS_FILTER_PARTIAL_CHARACTERISTICS 结构中定义。 此结构指定可以通过从 FilterSetModuleOptions 函数调用 NdisSetOptionalHandlers 函数在运行时更改的函数。 如果Filter驱动程序将在运行时更改这些部分特征,则必须提供 FilterSetModuleOptions 的入口点。 每个Filter模块的部分特征可能不同。
NDIS 在调用 NdisFRegisterFilterDriver 的上下文中调用 FilterSetOptions 函数。 FilterSetOptions 向 NDIS 注册可选服务。
如果调用 NdisFRegisterFilterDriver 成功,则 NDIS 使用Filter驱动程序句柄填充 NdisFilterDriverHandle 中的变量。 Filter驱动程序保存此句柄,稍后将此句柄传递给需要Filter驱动程序句柄作为输入参数的 NDIS 函数,例如 NdisFDeregisterFilterDriver。 当驱动程序卸载时,它必须调用 NdisFDeregisterFilterDriver 函数,以释放 由 NdisFRegisterFilterDriver 分配的驱动程序资源。
FilterSetOptions 返回后,Filter模块将处于"分离"状态。 对 FilterSetOptions 的调用返回后,NDIS 可以随时调用Filter驱动程序的 FilterAttach 函数。 驱动程序在 FilterAttach 函数中执行特定于Filter模块的初始化。
Filter驱动程序还会执行它在 DriverEntry 中所需的任何其他特定于驱动程序的初始化。 Filter驱动程序必须释放其 FilterDriverUnload 例程中分配的特定于驱动程序的资源。Filter驱动程序还会执行它在 DriverEntry 中所需的任何其他特定于驱动程序的初始化。 Filter驱动程序必须释放其 FilterDriverUnload 例程中分配的特定于驱动程序的资源。
卸载Filter驱动程序
与 NDIS Filter驱动程序关联的驱动程序对象指定名为 FilterDriverUnload 的 Unload 例程。 删除Filter驱动程序服务的所有微型端口适配器时,系统可以调用 FilterDriverUnload 例程。
卸载 应释放任何特定于驱动程序的资源。 必须销毁Filter驱动程序创建的任何设备对象。 在 FilterDriverUnload 返回后,系统可以完成驱动程序卸载操作。
unload 函数的功能特定于驱动程序。 作为一般规则, 卸载 应撤消在驱动程序初始化期间执行的操作。
Filter驱动程序必须从 Unload 调用 NdisFDeregisterFilterDriver 函数。 NdisFDeregisterFilterDriver 调用 FilterDetach 以分离与此Filter驱动程序关联的所有当前附加的Filter模块。
Filter模块状态和操作
Filter驱动程序必须支持驱动程序管理的每个Filter模块 (Filter驱动程序) 实例的以下操作状态:
- 分离:分离状态是Filter模块的初始状态。 当Filter模块处于此状态时,NDIS 可以调用Filter驱动程序的 FilterAttach 函数,以将Filter模块附加到驱动程序堆栈;
- 附加:在 "正在附加 "状态下,Filter驱动程序准备将Filter模块附加到驱动程序堆栈;
- 暂停:在 "已暂停" 状态下,Filter驱动程序不执行发送或接收操作;
- 重新 启动:在 "正在重启" 状态下,Filter驱动程序完成重启Filter模块的发送和接收操作所需的任何操作;
- 运行:在 "正在运行" 状态下,Filter驱动程序对Filter模块执行正常的发送和接收处理;
- 暂停:在 暂停 状态下,Filter驱动程序完成停止Filter模块的发送和接收操作所需的任何操作;
在下表中,标题是Filter模块状态。 主要事件列在第一列中。 表中的其余条目指定在状态中发生事件后Filter模块进入的下一个状态。 空条目表示无效的事件/状态组合:
Filter驱动程序事件的定义如下:
- Filter附加:NDIS 调用驱动程序的 FilterAttach 函数,将Filter模块附加到驱动程序堆栈;
- 附加已完成:当Filter模块处于 "正在附加" 状态,并且Filter驱动程序完成Filter模块所需的所有资源的初始化时,Filter模块将进入 "已暂停" 状态;
- Filter分离:NDIS 调用驱动程序的 FilterDetach 函数,以从驱动程序堆栈中分离Filter模块;
- Filter重启:NDIS 调用驱动程序的 FilterRestart 函数来重启暂停的Filter模块;
- 重启已完成:当Filter模块处于 "正在重启" 状态并且驱动程序已准备好执行发送和接收操作时,Filter模块将进入 "正在运行" 状态;
- Filter暂停:NDIS 调用驱动程序的 FilterPause 函数来暂停Filter模块;
- 暂停已完成:在驱动程序完成停止发送和接收操作所需的所有操作后,暂停操作完成,Filter模块处于 "已暂停" 状态;
- 附加失败:例如,如果 NDIS 调用驱动程序的 FilterAttach 函数,但附加操作 (失败,因为所需的资源在) 不可用,则Filter模块将返回到 "分离" 状态;
- 重启失败:如果 NDIS 调用驱动程序的 FilterRestart 函数,但重启尝试失败,Filter模块将返回到 "已暂停" 状态;
- 发送和接收操作:驱动程序可以处理 处于"正在运行" 和" 正在暂停 "状态的发送和接收操作;
附加Filter模块
为了启动将Filter模块插入驱动程序堆栈的过程,NDIS 调用Filter驱动程序的 FilterAttach 函数。 在 FilterAttach 函数中开始执行时,Filter模块进入"附加"状态。
Filter驱动程序使用句柄,该句柄在引用此Filter模块的所有未来 NdisXxx 函数调用中,NDIS 在 FilterAttach 的 NdisFilterHandle 参数处传递。 此类函数包括状态指示、发送请求、接收指示和 OID 请求。
当Filter模块处于 "正在附加" 状态时,驱动程序会:
- 为Filter模块创建上下文区域,并分配缓冲池和其他特定于Filter模块的资源;
- 使用 NDIS 传递给 FilterAttach 的 NdisFilterHandle 值调用 NdisFSetAttributes 函数。 NdisFSetAttributes 的 FilterModuleContext 参数指定此Filter模块的Filter驱动程序的上下文区域。 NDIS 将此上下文区域传递给Filter驱动程序的 FilterXxx 函数;
- (可选)从注册表中读取此Filter模块的配置参数;
- 如果上述操作成功完成,则Filter模块将处于 "已暂停" 状态;
- 如果上述操作失败,Filter驱动程序必须释放它在 FilterAttach 函数中分配的任何资源,并将Filter模块返回到 "分离" 状态;
返回NDIS_STATUS_SUCCESS或相应的失败代码。 如果驱动程序返回失败代码,NDIS 将终止驱动程序堆栈。
注意 注册表可以包含一个标志,该标志指定Filter模块是可选的。 如果可选Filter模块未附加,则 NDIS 不会终止驱动程序堆栈的其余部分。
Filter驱动程序无法发出发送请求、指示接收的数据、发出 OID 请求或从 "附加 "状态发出状态指示。 "正在运行"和"暂停"状态支持发送和接收操作。 暂停、正在重启、正在运行和暂停状态支持 OID 请求和状态指示。
NDIS 调用 FilterDetach 函数来分离 NDIS 随 FilterAttach 附加的Filter模块。
分离Filter模块
为了启动从驱动程序堆栈分离Filter模块的过程,NDIS 调用Filter驱动程序的 FilterDetach 函数。 在 FilterDetach 函数中开始执行时,Filter模块进入"分离"状态。 在分离Filter模块之前,NDIS 必须暂停驱动程序堆栈。
在其 FilterDetach 函数中,驱动程序释放其上下文区域和其他资源 (,例如缓冲池) 受影响的Filter模块。 Filter驱动程序不能使对 FilterDetach 的调用失败。 因此,Filter驱动程序应在附加操作期间预分配成功执行分离操作所需的所有资源。
Filter模块从 FilterDetach 返回后,NDIS 可以启动暂停的驱动程序堆栈。