Oggetti sink del servizio e del gruppo di servizi

Il driver di sistema PortCls implementa le interfacce IServiceSink e IServiceGroup per il vantaggio dei driver di porta e miniport. Il driver di porta usa queste interfacce per distribuire le notifiche di interruzione alle proprie routine di servizio e un driver miniport ha la possibilità di usare queste interfacce per scopi simili. Un oggetto IServiceSink incapsula una routine del servizio e un oggetto IServiceGroup rappresenta un gruppo di oggetti IServiceSink. Quando un gruppo di servizi riceve una richiesta di servizio, distribuisce la richiesta a ogni sink del servizio.

IServiceGroup eredita da IServiceSink. Poiché un gruppo di servizi è anche un sink del servizio, un gruppo di servizi è in grado di contenere altri gruppi di servizi, anche se i driver audio in genere non usano questa funzionalità. I driver delle porte usano attualmente gruppi di servizi per demultiplex richieste di interruzione del servizio, anche se la funzionalità di un gruppo di servizi è sufficiente per renderla potenzialmente utile anche per altri scopi.

La routine del servizio di interrupt del driver miniport (ISR) chiama uno dei metodi di notifica seguenti nel driver della porta:

IPortDMus::Notify

IPortMidi::Notify

IPortWaveCyclic::Notify

IPortWavePci::Notify

Il metodo di notifica accetta un puntatore al gruppo di servizi come parametro di chiamata. Durante questa chiamata, il driver della porta chiama il metodo IServiceSink::RequestService del gruppo di servizi, che accoda una chiamata di procedura posticipata (DPC). Quando il DPC viene eseguito, inoltra la richiesta del servizio a tutti gli oggetti membro nel gruppo di servizi.

Il codice del driver miniport in genere non deve chiamare metodi di interfaccia IServiceGroup . Tuttavia, il driver della porta chiama questi metodi per aggiungere i propri oggetti IServiceSink ai gruppi di servizi ottenuti dal driver miniport. I driver Miniport creano oggetti gruppo di servizi in base alle esigenze e associano tali gruppi di servizi a oggetti miniport e stream che richiedono la manutenzione periodica. Ad esempio, un driver miniport WaveCyclic associa un oggetto flusso al gruppo di servizi che specifica come parametro di output per il metodo IMiniportWaveCyclic::NewStream .

Nel contesto dei driver miniport WaveCyclic, l'associazione di tutti i flussi a un gruppo di servizi causa il servizio del driver di porta per tutti i flussi in base a una singola notifica. L'associazione di ogni flusso al proprio gruppo di servizi consente alla routine del servizio interrupt di selezionare il flusso che verrà eseguito dal driver di porta durante l'esecuzione del DPC.

Un driver miniport restituisce un riferimento al gruppo di servizi quando il driver di porta chiama uno dei metodi di inizializzazione seguenti:

IMiniportDMus::Init

IMiniportMidi::Init

IMiniportWavePci::Init

Il driver della porta aggiunge il proprio oggetto IServiceSink al gruppo di servizi ottenuto dalla chiamata Init . Quando l'ISR del driver miniport chiama successivamente Notify per inviare notifiche a tale gruppo di servizi, il gruppo di servizi accoda un DPC che inoltra la notifica all'oggetto IServiceSink del driver di porta, che a sua volta inoltra la notifica al driver miniport chiamando uno dei metodi di servizio seguenti:

IMiniportDMus::Service (non usato)

IMiniportMidi::Service

IMiniportWavePci::Service

Un driver miniport restituisce anche un riferimento al relativo gruppo di servizi quando il driver di porta chiama uno dei metodi di creazione del flusso seguenti:

IMiniportDMus::NewStream

IMiniportMidi::NewStream

IMiniportWaveCyclic::NewStream

IMiniportWavePci::NewStream

Come illustrato in precedenza, il driver miniport ha la possibilità di creare un gruppo di servizi diverso per ogni flusso o condividere un singolo gruppo di servizi in tutti i flussi.

I metodi seguenti consentono ai driver di porta MIDI e DMus di evitare l'interruzione dell'hardware:

IPortMidi::RegisterServiceGroup

IPortDMus::RegisterServiceGroup

Durante l'esecuzione del metodo Init , un driver MINIPORT MIDI o DMus chiama in genere il metodo RegisterServiceGroup del driver di porta prima di avviare il sintetizzatore. Lo scopo di questa chiamata è consentire al driver della porta di inserire l'oggetto sink del servizio (contenente il relativo gestore di interrupt) nel gruppo di servizi prima che l'hardware inizi a generare interruzioni. Anche se il metodo Init restituisce un puntatore del gruppo di servizi al driver di porta, il driver della porta può usare questo puntatore solo dopo la restituzione da Init.

Nel caso di un driver di porta WavePci, l'oggetto porta aggiunge il proprio oggetto IServiceSink al gruppo di servizi ottenuto dalla chiamata IMiniportWavePci::NewStream . Quando l'ISR del driver miniport chiama successivamente Notify per inviare una notifica a tale gruppo di servizi, il gruppo di servizi accoda un DPC che inoltra la notifica all'oggetto IServiceSink del driver di porta, che a sua volta esegue le operazioni seguenti:

  • Inoltra la notifica al flusso miniport chiamando il metodo del servizio IMiniportWavePciStream::Service.

  • Attiva tutti gli eventi di posizione e/o orologio sul segnaposto pronti per l'attivazione.

L'interfaccia IServiceSink supporta un singolo metodo:

IServiceSink::RequestService

L'interfaccia IServiceGroup supporta i metodi seguenti:

IServiceGroup::AddMember

IServiceGroup::CancelDelayedService

IServiceGroup::RequestDelayedService

IServiceGroup::RemoveMember

IServiceGroup::SupportDelayedService

Inoltre, il driver di sistema PortCls fornisce una funzione PcNewServiceGroup per la creazione di un nuovo oggetto gruppo di servizi. Tuttavia, non esiste alcuna funzione simile per la creazione di un oggetto sink del servizio. Il driver di porta aggiunge semplicemente un'interfaccia IServiceSink all'implementazione dell'oggetto porta principale, quando l'oggetto viene creato, quindi è il sink del servizio. Il driver di porta può aggiungere l'interfaccia IServiceSink dell'oggetto porta al gruppo di servizi che riceve dal metodo Init o NewStream del driver miniport. Per praticità, il file di intestazione Portcls.h definisce le costanti IMP_IServiceSink e IMP_IServiceGroup per l'aggiunta di interfacce IServiceSink e IServiceGroup agli oggetti driver.