Объекты приемника служб и группы служб

Системный драйвер PortCls реализует интерфейсы IServiceSink и IServiceGroup для использования драйверов портов и мини-портов. Драйвер порта использует эти интерфейсы для распространения уведомлений о прерываниях в собственные подпрограммы службы, а драйвер мини-порта может использовать эти интерфейсы для аналогичных целей. Объект IServiceSink инкапсулирует подпрограмму службы, а объект IServiceGroup представляет группу объектов IServiceSink. Когда группа служб получает запрос на обслуживание, она распределяет запрос на каждый из своих приемников служб.

IServiceGroup наследуется от IServiceSink. Так как группа служб также является приемником служб, группа служб может содержать другие группы служб, хотя звуковые драйверы обычно не используют эту возможность. В настоящее время драйверы портов используют группы служб для демультиплексных запросов для службы прерываний, хотя функциональность группы служб достаточно общая, чтобы сделать ее потенциально полезной и для других целей.

Подпрограмма службы прерываний драйвера минипорта (ISR) вызывает один из следующих методов уведомления в драйвере порта:

IPortDMus::Notify

IPortMidi::Notify

IPortWaveCyclic::Notify

IPortWavePci::Notify

Метод уведомления принимает указатель на группу служб в качестве параметра вызова. Во время этого вызова драйвер порта вызывает метод IServiceSink::RequestService группы служб, который помещает в очередь отложенный вызов процедуры (DPC). При выполнении DPC он перенаправит запрос на обслуживание всем объектам-членам в группе служб.

Коду драйвера мини-порта обычно не требуется вызывать методы интерфейса IServiceGroup . Однако драйвер порта вызывает эти методы, чтобы добавить собственные объекты IServiceSink в группы служб, полученные от драйвера мини-порта. Драйверы минипорта создают объекты групп служб по мере необходимости и связывают эти группы служб с объектами miniport и stream, которые требуют периодического обслуживания. Например, драйвер miniport WaveCyclic связывает объект потока с группой служб, которую он указывает в качестве выходного параметра, с методом IMiniportWaveCyclic::NewStream .

В контексте драйверов miniport WaveCyclic связывание всех потоков с одной группой служб приводит к тому, что драйвер порта будет обслуживать все потоки на основе одного уведомления. Связывание каждого потока с собственной группой служб позволяет подпрограмме службы прерывания выбрать поток, который будет обслуживаться драйвером порта во время выполнения DPC.

Драйвер мини-порта выводит ссылку на свою группу служб, когда драйвер порта вызывает один из следующих методов инициализации:

IMiniportDMus::Init

IMiniportMidi::Init

IMiniportWavePci::Init

Драйвер порта добавляет собственный объект IServiceSink в группу служб, полученную из вызова Init . Когда isR драйвера минипорта позже вызывает Notify для отправки уведомления этой группе служб, группа служб помещает в очередь DPC, который перенаправит уведомление в объект IServiceSink драйвера порта, который, в свою очередь, перенаправит уведомление драйверу miniport, вызывая один из следующих методов службы:

IMiniportDMus::Service (не используется)

IMiniportMidi::Service

IMiniportWavePci::Service

Драйвер мини-порта также выводит ссылку на свою группу служб, когда драйвер порта вызывает один из следующих методов создания потока:

IMiniportDMus::NewStream

IMiniportMidi::NewStream

IMiniportWaveCyclic::NewStream

IMiniportWavePci::NewStream

Как уже говорилось ранее, драйвер мини-порта может создать отдельную группу служб для каждого потока или совместно использовать одну группу служб во всех потоках.

Следующие методы помогают драйверам портов MIDI и DMus избежать прерываний оборудования:

IPortMidi::RegisterServiceGroup

IPortDMus::RegisterServiceGroup

Во время выполнения метода Init драйвер miniport MIDI или DMus обычно вызывает метод RegisterServiceGroup драйвера порта перед запуском синтезатора. Цель этого вызова — разрешить драйверу порта вставлять объект приемника службы (содержащий обработчик прерываний) в группу служб до того, как оборудование начнет создавать прерывания. Хотя метод Init выводит указатель группы служб на драйвер порта, драйвер порта может использовать этот указатель только после возврата из Init.

В случае драйвера порта WavePci объект порта добавляет собственный объект IServiceSink в группу служб, полученную из вызова IMiniportWavePci::NewStream . Когда isR драйвера мини-порта позже вызывает Notify для отправки уведомления этой группе служб, группа служб помещает в очередь DPC, который пересылает уведомление в объект IServiceSink драйвера порта, который, в свою очередь, делает следующее:

  • Пересылает уведомление в поток мини-порта, вызывая метод службы IMiniportWavePciStream::Service.

  • Активирует любые события положения и (или) часов на контакте, готовые к срабатыванию.

Интерфейс IServiceSink поддерживает один метод:

IServiceSink::RequestService

Интерфейс IServiceGroup поддерживает следующие методы:

IServiceGroup::AddMember

IServiceGroup::CancelDelayedService

IServiceGroup::RequestDelayedService

IServiceGroup::RemoveMember

IServiceGroup::SupportDelayedService

Кроме того, системный драйвер PortCls предоставляет функцию PcNewServiceGroup для создания нового объекта группы служб. Однако для создания объекта приемника службы не существует аналогичной функции. Драйвер порта просто добавляет интерфейс IServiceSink в реализацию своего объекта порта main при создании объекта, как и приемник службы. Драйвер порта может добавить интерфейс IServiceSink объекта порта в группу служб, полученную от метода Init или NewStream драйвера miniport. Для удобства файл заголовка Portcls.h определяет константы IMP_IServiceSink и IMP_IServiceGroup для добавления интерфейсов IServiceSink и IServiceGroup в объекты драйвера.