Compartilhar via


Objetos do Coletor de Serviço e do Grupo de Serviços

O driver do sistema PortCls implementa as interfaces IServiceSink e IServiceGroup em benefício de drivers de porta e miniport. O driver de porta usa essas interfaces para distribuir notificações de interrupção para suas próprias rotinas de serviço e um driver de miniporto tem a opção de usar essas interfaces para fins semelhantes. Um objeto IServiceSink encapsula uma rotina de serviço e um objeto IServiceGroup representa um grupo de objetos IServiceSink. Quando um grupo de serviços recebe uma solicitação de serviço, ele distribui a solicitação para cada um de seus coletores de serviço.

IServiceGroup herda de IServiceSink. Como um grupo de serviços também é um coletor de serviços, um grupo de serviços é capaz de conter outros grupos de serviços, embora os drivers de áudio normalmente não usem essa funcionalidade. Atualmente, os drivers de porta usam grupos de serviço para demultiplexar solicitações de serviço de interrupção, embora a funcionalidade de um grupo de serviços seja geral o suficiente para torná-lo potencialmente útil para outras finalidades também.

A ISR (rotina de serviço de interrupção) do driver de miniporta chama um dos seguintes métodos de notificação no driver de porta:

IPortDMus::Notify

IPortMidi::Notify

IPortWaveCyclic::Notify

IPortWavePci::Notify

O método de notificação usa um ponteiro para o grupo de serviços como um parâmetro de chamada. Durante essa chamada, o driver de porta chama o método IServiceSink::RequestService do grupo de serviços, que enfileira uma DPC (chamada de procedimento adiado). Quando o DPC é executado, ele encaminha a solicitação de serviço para todos os objetos membros no grupo de serviços.

O código do miniport-driver normalmente não precisa chamar nenhum método de interface IServiceGroup . No entanto, o driver de porta chama esses métodos para adicionar seus próprios objetos IServiceSink aos grupos de serviço que ele obtém do driver de miniporto. Os drivers miniport criam objetos de grupo de serviço conforme necessário e associam esses grupos de serviços a objetos miniport e de fluxo que exigem manutenção periódica. Por exemplo, um driver de miniporto WaveCyclic associa um objeto stream ao grupo de serviços que ele especifica como um parâmetro de saída ao método IMiniportWaveCyclic::NewStream .

No contexto de drivers de miniporta WaveCyclic, associar todos os fluxos a um grupo de serviços faz com que o driver de porta serviço todos os fluxos com base em uma única notificação. Associar cada fluxo com seu próprio grupo de serviços permite que a rotina de serviço de interrupção selecione o fluxo que será atendido pelo driver de porta durante a execução do DPC.

Um driver de miniporta gera uma referência ao seu grupo de serviços quando o driver de porta chama um dos seguintes métodos de inicialização:

IMiniportDMus::Init

IMiniportMidi::Init

IMiniportWavePci::Init

O driver de porta adiciona seu próprio objeto IServiceSink ao grupo de serviços que ele obtém da chamada init . Quando o ISR do driver de miniporto chama Notify posteriormente para enviar notificação para esse grupo de serviços, o grupo de serviço enfileira um DPC que encaminha a notificação para o objeto IServiceSink do driver de porta, que, por sua vez, encaminha a notificação para o driver de miniporto chamando um dos seguintes métodos de serviço:

IMiniportDMus::Service (não usado)

IMiniportMidi::Service

IMiniportWavePci::Service

Um driver de miniporta também gera uma referência ao seu grupo de serviços quando o driver de porta chama um dos seguintes métodos de criação de fluxo:

IMiniportDMus::NewStream

IMiniportMidi::NewStream

IMiniportWaveCyclic::NewStream

IMiniportWavePci::NewStream

Conforme discutido anteriormente, o driver de miniporto tem a opção de criar um grupo de serviços diferente para cada fluxo ou compartilhar um único grupo de serviços em todos os fluxos.

Os métodos a seguir ajudam os drivers de porta MIDI e DMus a evitar interrupções de hardware:

IPortMidi::RegisterServiceGroup

IPortDMus::RegisterServiceGroup

Durante a execução de seu método Init , um driver de miniporto MIDI ou DMus normalmente chama o método RegisterServiceGroup do driver de porta antes de iniciar o sintetizador. A finalidade dessa chamada é permitir que o driver de porta insira seu objeto de coletor de serviço (contendo seu manipulador de interrupção) no grupo de serviços antes que o hardware comece a gerar interrupções. Embora o método Init gere um ponteiro de grupo de serviços para o driver de porta, o driver de porta pode usar esse ponteiro somente após o retorno do Init.

No caso de um driver de porta WavePci, o objeto port adiciona seu próprio objeto IServiceSink ao grupo de serviços que ele obtém da chamada IMiniportWavePci::NewStream . Quando o ISR do driver de miniporto chama Notify posteriormente para enviar notificação para esse grupo de serviços, o grupo de serviço enfileira um DPC que encaminha a notificação para o objeto IServiceSink do driver de porta, o que, por sua vez, faz o seguinte:

  • Encaminha a notificação para o fluxo de miniporto chamando o método de serviço IMiniportWavePciStream::Service.

  • Dispara qualquer evento de posição e/ou relógio no pino que está pronto para ser acionado.

A interface IServiceSink dá suporte a um único método:

IServiceSink::RequestService

A interface IServiceGroup dá suporte aos seguintes métodos:

IServiceGroup::AddMember

IServiceGroup::CancelDelayedService

IServiceGroup::RequestDelayedService

IServiceGroup::RemoveMember

IServiceGroup::SupportDelayedService

Além disso, o driver do sistema PortCls fornece uma função PcNewServiceGroup para criar um novo objeto de grupo de serviços. No entanto, não existe nenhuma função semelhante para criar um objeto de coletor de serviço. O driver de porta simplesmente adiciona uma interface IServiceSink à implementação de seu objeto de porta main , quando o objeto é criado, assim como o coletor de serviço. O driver de porta pode adicionar a interface IServiceSink do objeto de porta ao grupo de serviços que ele recebe do método Init ou NewStream do driver de miniport. Para sua conveniência, o arquivo de cabeçalho Portcls.h define constantes IMP_IServiceSink e IMP_IServiceGroup para adicionar interfaces IServiceSink e IServiceGroup a objetos de driver.