ACX IO 请求数据包 IRP
本主题提供音频类 eXtensions (ACX) IO 请求数据包 IRP 的摘要。
有关 ACX 的一般信息,请参阅 ACX 音频类扩展概述和 ACX 对象摘要。 有关 ACX 目标和同步的信息,请参阅 ACX 目标和驱动程序同步。
IRP 请求调度
ACX 客户端通过驱动程序请求 (IRP) 指定操作。 有关 IRP 的一般信息,请参阅 I/O 请求数据包和 带可重用 IRP 的数据包驱动型 I/O。
客户端使用线路或流句柄将此请求发送到线路/引脚/元素/流。 请求 ID 是三元组:
- set (guid),
- id/index (ulong)
- 可选 pin-id/node-id (ulong) 值。
在创建时,驱动程序可以选择将属性/方法/事件与下列对象之一相关联:
- 固定
- 线路
- 流 (stream)
- element
每个属性/方法/事件均由 ID 和回调处理程序标识。 默认情况下,ACX 定义 KS 客户端(用户模式层)所需的所有属性/方法/事件,因此驱动程序不需要重新定义它们。 驱动程序只需定义其自定义属性/方法/事件。
当 ACX 收到 ACX/KS 样式 IoCtrl 请求时,会验证请求并将调用方缓冲区锁定在内存中。 此验证和缓冲区锁定是在初始化时 ACX 注册的 WDM 预处理回调中完成的。 在此阶段,ACX 会将自己的完成回调添加到 WDM IRP,然后再将其转发回 WDF 以进行正常调度。 完成回调使 ACX 有机会根据需要添加/注入任何兼容性解决方法。
下一个 WDF 会调用动态调度 IRP 回调,在此回调总 ACX/驱动程序(可选)会将 WDF 队列与请求相关联。 在此回调 ACX 中,使用发送此请求的句柄查找目标 ACX 对象:线路、引脚、线路元素或流,以及请求中的可选 pin-id/node-id/circuit-element。
在音频复合设备中,目标对象(仅线路)可能位于与最初发送请求的堆栈不同的堆栈上。 此外,请求可能需要对多个堆栈执行操作,例如流更改状态。
标识目标后,ACX 会检查目标线路/流对象是否指定默认处理队列的覆盖;如果未指定,ACX 将使用与当前句柄关联的默认队列。 接着,ACX/驱动程序指示 WDF 将请求插入到指定队列或默认队列中。
下一个 WDF 会调用输入调用方进程回调(如果存在)。 ACX 不需要/使用输入调用方进程回调,因为它已在预处理回调的内存中锁定了缓冲区。 因此,ACX 会通知 WDF 在为请求指定目标队列后不调用进程内回调。
辅助队列使用情况
默认 ACX 队列是电源管理的串行无锁定队列。 驱动程序应将任何占用不确定时间的请求移到辅助队列中。 驱动程序管理的队列可以是手动被动队列,其中驱动程序可以暂挂这些请求,直到以后准备好完成这些请求。
电源引用请求
ACX 会在向驱动程序发送请求之前自动开启设备电源。 这可使用 WDF 电源管理的队列隐式完成。 这会创建类似于 portcls 的行为。 也就是说,在调度请求之前,会采用电源引用。
调用队列的调度处理程序
下一个 WDF 采用电源引用,并调用队列的调度处理程序。 与 ACX 处理程序关联的默认队列会检查是否有任何预处理覆盖;如果存在,ACX 将调用已注册的驱动程序的预处理回调。 ACX 允许驱动程序根据请求类型(属性、事件和方法)和(可选)请求 ID 指定覆盖。
如果指定了预处理回调,则 ACX 调用回调后,该请求将归驱动程序所有。 驱动程序可以完成请求,或将其转发回 ACX 以进行正常调度。
如果未指定预处理回调,或者驱动程序将请求返回给 ACX,ACX 将检索目标 ACX 对象,并找到声明的属性/事件/方法的回调。 然后,它会调用传递 WDF 请求和目标 ACX 对象(线路/流/线路元素)的回调。
下一个 ACX(或者对于自定义属性,驱动程序)会执行所请求的操作并完成请求,或者如果请求花费了不确定的时间,驱动程序可以将请求移到辅助队列。 驱动程序负责序列化和完成任何活动的挂起请求。
此图说明了典型的请求调度工作流。
此图演示了当驱动程序定义了 ACX 预处理回调时的调度工作流,但最终请求由 ACX 框架处理。
ACX 线路 PnP 内部接口
为了促进 ACX 终结点管理器 (EM) 与 ACX 驱动程序组件(内核模式或用户模式组件)之间的通信,ACX 定义了以下内部 PnP 设备接口:
- ACXCATEGORY_CIRCUITFACTORY
- ACXCATEGORY_CIRCUIT
EM 使用 ACXCATEGORY_CIRCUITFACTORY 接口指示目标设备创建或删除此类型的特定线路。 当下划线设备能够创建线路时,此接口处于活动状态,否则将处于禁用状态(例如:删除、意外删除、停止或手动删除)。
音频子系统使用 ACXCATEGORY_CIRCUIT(可以在与线路管理器堆栈不同的设备堆栈上创建),来跟踪 ACX 线路并与 ACX 线路通信。 创建线路并准备好处理命令时,此接口将处于活动状态。
有关其他电源和 PnP 进程的信息,请参阅 ACX 设备枚举和 ACX 电源管理。