服务接收器和服务组对象
PortCls 系统驱动程序实现 IServiceSink 和 IServiceGroup 接口,以获得端口和微型端口驱动程序的优势。 端口驱动程序使用这些接口将中断通知分发到其自己的服务例程,微型端口驱动程序可以选择将这些接口用于类似目的。 IServiceSink 对象封装服务例程,IServiceGroup 对象表示一组 IServiceSink 对象。 当服务组收到服务请求时,它会将请求分发给其每个服务接收器。
IServiceGroup 继承自 IServiceSink。 由于服务组也是服务接收器,因此服务组能够包含其他服务组,尽管音频驱动程序通常不使用此功能。 端口驱动程序目前使用服务组来多路分解对中断服务的请求,尽管服务组的功能足够通用,使其也有可能用于其他目的。
微型端口驱动程序的中断服务例程 (ISR) 在端口驱动程序中调用以下通知方法之一:
通知方法将指向服务组的指针作为调用参数。 在此调用期间,端口驱动程序调用服务组的 IServiceSink::RequestService 方法,该方法将延迟过程调用 (DPC) 排入队列。 执行 DPC 时,它会将服务请求转发到服务组中的所有成员对象。
微型端口驱动程序代码通常不需要调用任何 IServiceGroup 接口方法。 但是,端口驱动程序调用这些方法,以将其自己的 IServiceSink 对象添加到从微型端口驱动程序获取的服务组。 微型端口驱动程序根据需要创建服务组对象,并将这些服务组与需要定期维护的微型端口和流对象相关联。 例如,WaveCyclic微型端口驱动程序将流对象与服务组相关联,服务组作为输出参数指定给 IMiniportWaveCyclic::NewStream 方法。
在 WaveCyclic 微型端口驱动程序的上下文中,将所有流与一个服务组相关联会导致端口驱动程序基于单个通知为所有流提供服务。 将每个流与其自己的服务组相关联,允许中断服务例程选择在 DPC 执行期间由端口驱动程序提供服务的流。
当端口驱动程序调用以下初始化方法之一时,微型端口驱动程序将输出对其服务组的引用:
端口驱动程序将自己的 IServiceSink 对象添加到从 Init 调用获取的服务组。 当微型端口驱动程序的 ISR 稍后调用 Notify 以向该服务组发送通知时,服务组会将通知转发到端口驱动程序的 IServiceSink 对象的 DPC 排队,后者随后通过调用以下服务方法之一将通知转发到微型端口驱动程序:
当端口驱动程序调用以下流创建方法之一时,微型端口驱动程序还将输出对其服务组的引用:
IMiniportWaveCyclic::NewStream
如前所述,微型端口驱动程序可以选择为每个流创建不同的服务组,或跨所有流共享单个服务组。
以下方法可帮助 MIDI 和 DMus 端口驱动程序避免删除硬件中断:
IPortMidi::RegisterServiceGroup
IPortDMus::RegisterServiceGroup
在执行 Init 方法期间,MIDI 或 DMus 微型端口驱动程序通常会在启动合成器之前调用端口驱动程序的 RegisterServiceGroup 方法。 此调用的目的是允许端口驱动程序在硬件开始生成中断之前将其服务接收器对象(包含其中断处理程序)插入服务组。 尽管 Init 方法将服务组指针输出到端口驱动程序,但端口驱动程序只能在从 Init 返回后使用此指针。
对于 WavePci 端口驱动程序,端口对象将自己的 IServiceSink 对象添加到从 IMiniportWavePci::NewStream 调用获取的服务组。 当微型端口驱动程序的 ISR 稍后调用 Notify 以向该服务组发送通知时,服务组会将通知转发到端口驱动程序的 IServiceSink 对象,该对象依次执行以下操作:
通过调用服务方法 IMiniportWavePciStream::Service 将通知转发到微型端口流。
触发引脚上已准备好触发的任何位置和/或时钟事件。
IServiceSink 接口支持单个方法:
IServiceGroup 接口支持以下方法:
IServiceGroup::CancelDelayedService
IServiceGroup::RequestDelayedService
IServiceGroup::SupportDelayedService
此外,PortCls 系统驱动程序还提供一个 PcNewServiceGroup 函数,用于创建新的服务组对象。 但是,不存在用于创建服务接收器对象的类似函数。 端口驱动程序只是将 IServiceSink 接口添加到其主端口对象的实现中,创建对象时,服务接收器也是如此。 端口驱动程序可以将端口对象的 IServiceSink 接口添加到从微型端口驱动程序的 Init 或 NewStream 方法接收的服务组。 为方便起见,标头文件 Portcls.h 定义了 IMP_IServiceSink 和 IMP_IServiceGroup 常量,用于将 IServiceSink and IServiceGroup 接口添加到驱动程序对象。