筛选器、引脚和节点属性

Microsoft Windows驱动程序模型 (WDM) 音频驱动程序将音频设备表示为 KS 筛选器,它们表示设备上的硬件缓冲区作为筛选器上的引脚。 当客户端向其中一个筛选器或固定对象发送属性请求时,端口驱动程序会收到请求并将请求路由到端口驱动程序或微型端口驱动程序中的相应属性处理程序。

音频设备支持三种类型的属性:

  • 筛选器属性

    筛选器属性是筛选器的一个整体属性,而不是筛选器中特定引脚或节点的属性。 筛选器属性的请求指定筛选器句柄,但它们不指定节点 ID。

  • 固定属性

    pin 属性是筛选器上特定引脚实例的属性。 这些属性的请求指定引脚句柄,但它们不指定节点 ID。

  • 节点属性

    节点属性是筛选器中拓扑节点的属性。 节点属性的请求指定筛选器句柄或固定句柄,以及节点 ID。

节点属性请求是否指定筛选器或引脚句柄取决于节点是否是唯一的筛选器。 有关详细信息,请参阅以下“节点属性”部分。

下图显示了这三种类型的属性请求:发送到固定实例的 pin 属性请求、发送到节点的节点属性请求 (筛选器或固定实例) ,以及发送到筛选器实例的筛选器属性请求。

diagram illustrating filter-, pin-, and node-property requests.

通常,端口驱动程序处理筛选器和引脚属性的大多数请求,微型端口驱动程序处理节点属性的请求。

端口驱动程序为 SysAudio 系统驱动程序 使用的筛选器和引脚属性提供自己的内置处理程序, (请参阅 KSPROPSETID_SysaudioKSPROPSETID_Sysaudio_Pin) WDMAud 系统驱动程序。 微型端口驱动程序不需要为端口驱动程序处理的属性实现处理程序。 典型的微型端口驱动程序提供筛选器和引脚属性的处理程序(如果有)很少。 微型端口驱动程序为表示音频设备硬件相关功能的节点属性提供处理程序。 端口驱动程序不提供节点属性的内置处理,但 KSPROPERTY_TOPOLOGY_NAME除外。

当端口驱动程序和微型端口驱动程序都为同一属性提供处理程序时,端口驱动程序使用自己的处理程序并忽略微型端口驱动程序的处理程序。

筛选器描述符

端口驱动程序通过调用 IMiniport::GetDescription 方法获取指向微型端口驱动程序的属性处理程序的指针。 通过此方法,端口驱动程序检索指向微型端口驱动程序筛选器描述符的指针,该描述符是类型 PCFILTER_DESCRIPTOR的结构。 此结构指定用于筛选器、固定和节点属性的微型端口驱动程序的属性处理程序:

  • PCFILTER_DESCRIPTOR结构的 AutomationTable 成员指向筛选器的自动化表。 此表指定筛选器属性的微型端口驱动程序的属性处理程序。

  • PCFILTER_DESCRIPTOR结构的 Pins 成员包含引脚的自动化表。 每个表指定特定引脚类型的引脚属性的属性处理程序。

  • PCFILTER_DESCRIPTOR结构的 Nodes 成员包含筛选器中拓扑节点的自动化表。 每个表指定特定节点类型的节点属性的属性处理程序。

筛选属性

端口驱动程序通过 PCFILTER_DESCRIPTOR 的 AutomationTable 成员访问微型端口驱动程序的筛选器属性处理程序。 通常,此自动化表包含少量处理程序,因为端口驱动程序为 SysAudio 和 WDMAud 用于查询和配置音频设备的所有筛选器属性提供自己的内置处理程序。

但是,微型端口驱动程序可以提供筛选器属性的处理程序,例如 KSPROPERTY_GENERAL_COMPONENTID 提供硬件相关的信息,这些信息不适用于端口驱动程序。 Microsoft Windows 驱动程序工具包中的两个示例音频驱动程序 (WDK) 处理KSPROPERTY_GENERAL_COMPONENTID属性。 有关详细信息,请参阅 Sysvad 示例驱动程序中的微型端口驱动程序实现,该驱动程序在 示例音频驱动程序中进行了讨论。

Portcls.sys中的所有端口驱动程序都为 KSPROPSETID_PinKSPROPSETID_Topology 属性集提供处理。 这些集中的所有属性都是筛选器属性,除了 KSPROPERTY_TOPOLOGY_NAME,这是使用筛选器句柄而不是固定句柄的节点属性 (,用于指定请求) 的目标。 端口驱动程序支持以下KSPROPSETID_Pin属性子集:

KSPROPERTY_PIN_CATEGORY

KSPROPERTY_PIN_CINSTANCES

KSPROPERTY_PIN_COMMUNICATION

KSPROPERTY_PIN_CONSTRAINEDDATARANGES

KSPROPERTY_PIN_CTYPES

KSPROPERTY_PIN_DATAFLOW

KSPROPERTY_PIN_DATAINTERSECTION

KSPROPERTY_PIN_DATARANGES

KSPROPERTY_PIN_GLOBALCINSTANCES

KSPROPERTY_PIN_INTERFACES

KSPROPERTY_PIN_MEDIUMS

KSPROPERTY_PIN_NAME

KSPROPERTY_PIN_NECESSARYINSTANCES

KSPROPERTY_PIN_PHYSICALCONNECTION

KSPROPERTY_PIN_PROPOSEDATAFORMAT

KSPROPERTY_PIN_PROPOSEDATAFORMAT2

这些属性提供有关属于筛选器的引脚工厂的信息。 通常,客户端在创建固定实例之前查询这些属性的筛选器。 端口驱动程序支持所有四个KSPROPSETID_Topology属性,这些属性提供有关筛选器的内部拓扑的信息。

此外,DMus 端口驱动程序为 KSPROPERTY_SYNTH_MASTERCLOCK 属性提供处理程序,该处理程序是 DirectMusic 筛选器的仅获取属性。 KSPROPERTY_SYNTH_MASTERCLOCK是 KSPROPSETID_SynthClock 属性集的成员。

固定属性

端口驱动程序通过 PCFILTER_DESCRIPTOR 的 Pins 成员访问微型端口驱动程序的 pin 属性处理程序。 此成员指向一个固定描述符数组,每个描述符指向由固定 ID 标识的固定类型的自动化表 (,这只是数组索引) 。

通常,这些自动化表包含少量条目,因为端口驱动程序为 SysAudio 和 WDMAud 使用的所有引脚属性提供自己的处理程序。 微型端口驱动程序可以选择为端口驱动程序不处理的一个或多个引脚属性提供处理程序,但只有知道这些属性的客户端可以为其发送属性请求。

除了拓扑端口驱动程序之外,Portcls.sys中的所有端口驱动程序都提供以下引脚属性的内置处理程序:

KSPROPERTY_CONNECTION_STATE

KSPROPERTY_CONNECTION_DATAFORMAT

KSPROPERTY_CONNECTION_ALLOCATORFRAMING

KSPROPERTY_STREAM_ALLOCATOR

KSPROPERTY_STREAM_MASTERCLOCK

KSPROPERTY_AUDIO_POSITION

KSPROPERTY_DRMAUDIOSTREAM_CONTENTID

此列表中的某些属性需要微型端口驱动程序的硬件相关信息。 当端口驱动程序收到包含其中一个属性请求的 IRP 时,它不会将 IRP 传递给微型端口驱动程序。 相反,端口驱动程序会处理请求本身,但其处理程序通过调用微型端口驱动程序中的入口点来获取所需的信息。 例如,端口驱动程序为KSPROPERTY_AUDIO_POSITION请求提供自己的属性处理程序。 此处理程序只需调用微型端口驱动程序流的 GetPosition 方法 (例如 IMiniportWavePciStream::GetPosition) 获取当前位置。

节点属性

端口驱动程序通过 PCFILTER_DESCRIPTOR 的 Nodes 成员访问微型端口驱动程序的 node-property 处理程序。 此成员指向节点描述符数组,每个描述符指向节点类型 (由节点 ID 标识的自动化表,这只是数组索引) 。 通常,属于微型端口驱动程序的所有或大多数属性处理程序都驻留在 Nodes 数组中。 音频驱动程序将音频设备中的硬件控件表示为拓扑节点,并使用属性机制向客户端提供对依赖硬件的控制设置的访问权限。

如前所述,客户端将筛选器属性请求发送到筛选器句柄,并将固定属性请求发送到固定句柄。 与筛选器或固定实例不同,节点不是内核对象,并且没有句柄。 客户端将节点属性请求发送到固定句柄或筛选器句柄,但请求还指定节点 ID 以指示请求用于节点属性,而不是固定或筛选器属性。

下面是用于确定节点属性是否应使用筛选器句柄或引脚句柄的常规规则:

  • 如果筛选器包含特定引脚类型的多个实例,并且该类型的每个引脚包含具有特定节点 ID 的节点,则每个引脚实例都包含节点的实例。 在这种情况下,节点属性请求必须指定固定句柄 (,而不仅仅是筛选器句柄) 区分同一节点类型的多个实例。 引脚句柄和节点 ID 的组合明确将特定节点实例标识为请求的目标。

  • 如果筛选器仅包含特定节点的一个实例,则节点属性请求指定筛选器句柄。 筛选器句柄和节点 ID 的组合足以明确标识请求的目标节点。

但是,在实现特定节点属性的处理程序之前,驱动程序编写器应引用 音频驱动程序属性集 来检查该属性的目标是否应指定为筛选器句柄或引脚句柄。

Portcls.sys中的端口驱动程序目前不提供节点属性的内置处理,但KSPROPERTY_TOPOLOGY_NAME除外。

过度指定和未指定的属性请求

应准备好驱动程序来处理不遵循上述规则的客户端的属性请求。 可以过度指定或未指定请求:

  • 过度指定的请求

    如果属性请求只需要筛选器句柄,但客户端会改为将请求发送到固定句柄,则会过度指定请求的目标。 但是,驱动程序通常将请求视为有效;也就是说,它们将请求视为已发送到包含引脚的筛选器。

  • 未指定的请求

    如果属性请求需要固定句柄,但客户端会改为将请求发送到筛选器句柄,则会对请求的目标进行指定。 例如,如果筛选器包含多个具有相同节点类型的固定实例,并且客户端将该节点类型的属性的请求发送到筛选器句柄而不是固定句柄,则驱动程序无法确定应接收请求的节点实例。 在这种情况下,行为取决于驱动程序。 某些驱动程序不会自动失败所有未指定的请求,而是将未指定的 set-property 请求视为有效。 在这种情况下,解释是请求设置指定节点 ID 的默认值。 引脚工厂创建新节点实例时,属于新节点的属性将初始化为默认值。 更改默认值的请求对请求之前创建的节点实例没有影响。 此外,驱动程序统一失败,因为处理程序无法确定要查询属性的节点实例。

规则的例外

出于历史原因,一些音频属性具有违反这些常规规则的行为怪癖。 下面是一些示例:

  • 应用Speaker-Configuration 设置中所述,客户端可以通过设置三维节点 (KSNODETYPE_3D_EFFECTS) 的KSPROPERTY_AUDIO_CHANNEL_CONFIG属性来更改音频设备的扬声器配置。 扬声器配置设置是全局的,因为它会更改设备通过扬声器播放的所有流的扬声器配置。 根据常规规则,影响整个筛选器的节点属性请求应指定筛选器句柄 (加上节点 ID) 。 但是,此特定属性需要固定句柄而不是筛选器句柄。 引脚句柄指定包含请求目标的三维节点的引脚实例。

  • KSPROPERTY_SYNTH_VOLUMEKSPROPERTY_SYNTH_MASTERCLOCK 是合成器节点的属性 (KSNODETYPE_SYNTHESIZER) 。 尽管这两个属性都是节点属性,但这些属性的请求不包括节点 ID。 (请注意,请求的属性描述符是 KSPROPERTY 类型的结构,而不是 KSNODEPROPERTY.) 此行为违反了节点属性需要节点 ID 的一般规则。 尽管存在这种差异,但支持任一属性的微型端口驱动程序应通过 PCFILTER_DESCRIPTOR (的 Nodes 成员而不是 Pins 成员) 提供属性处理程序。