Gravando um Minidriver do Stream
A main meta de design do driver de classe de fluxo é lidar com o trabalho de lidar com o sistema operacional, que inclui os meandros de suporte a computadores multiprocessadores e a semântica de streaming de kernel. Ele requer que o minidriver manipule apenas a parte específica do dispositivo de qualquer operação que ele deve executar. O driver de classe aloca memória para o minidriver, executa a contabilidade de todos os recursos de kernel NT que o minidriver pode exigir e (opcionalmente) lida com todos os problemas de sincronização.
O driver de classe se comunica com o minidriver por meio de um conjunto de retornos de chamada fornecidos pelo minidriver. A maior parte do trabalho de escrever um minidriver de streaming ocorre na gravação desses retornos de chamada.
Nesta documentação, nos referimos a cada tipo de rotinas fornecidas por minidriver como StrMiniXxx. O minidriver pode ter que fornecer uma ou mais versões de cada rotina, dependendo de quantas funções diferentes o hardware subjacente é capaz de executar.
Um driver de streaming normalmente pode dar suporte a vários fluxos diferentes de dados. Por exemplo, um dvd player produz um fluxo de áudio e de vídeo. No contexto do streaming de kernel, cada fluxo de dados é representado por um pin.
O driver de classe de fluxo controla cada pino no minidriver. Na terminologia do driver de classe, cada tipo de pino é um fluxo. Os fluxos, como tipos de pino, podem ter várias instâncias. Como os fluxos podem receber solicitações de E/S, o driver deve fornecer retornos de chamada para cada fluxo.
Veja a seguir as rotinas que o minidriver pode ter que fornecer. Eles estão documentados mais detalhadamente abaixo e no guia de referência.
Rotinas que cada minidriver fornece
Rotinas que o minidriver fornece para cada fluxo individual
StrMiniReceiveStreamDataPacket
StrMiniReceiveStreamControlPacket
É possível que o minidriver use o mesmo retorno de chamada para vários fluxos diferentes. O retorno de chamada pode determinar o fluxo em cujo nome ele foi chamado de seus parâmetros.
O minidriver deve, como todos os drivers WDM, também fornecer uma rotina DriverEntry . A tarefa main da rotina DriverEntry de um minidriver é registrar o minidriver com o driver de classe.
O driver de classe recebe todas as solicitações de E/S em nome do minidriver. Para obter as informações necessárias para concluir a solicitação, o driver de classe cria um SRB (bloco de solicitação de fluxo) e o passa para uma das rotinas do PacoteXXXStrMini . O driver de classe envia solicitações de E/S para o dispositivo como um todo para a rotina StrMiniReceiveDevicePacket . Ele passa solicitações para fluxos individuais para StrMiniReceiveStreamDataPacket (para solicitações de leitura e gravação de streaming de kernel) ou StrMiniReceiveStreamControlPacket (para outras solicitações).
Normalmente, o driver de classe enfileira suas solicitações e as passa uma de cada vez para o minidriver. Opcionalmente, o minidriver pode fazer sua própria sincronização; em seguida, o minidriver é responsável por enfileirar solicitações que não pode manipular imediatamente. Confira Sincronização do Minidriver para obter detalhes.
O minidriver deve fornecer duas rotinas adicionais para manipular blocos de solicitação de fluxo. O driver de classe chama StrMiniCancelPacket quando recebe um IRP de cancelamento e precisa informar o minidriver para cancelar um pacote específico. O driver de classe também controla quanto tempo o minidriver leva para concluir o tratamento de um bloco de solicitação de fluxo. Se o minidriver demorar muito, o driver de classe atingirá o tempo limite da solicitação e chamará a rotina StrMiniRequestTimeout do minidriver.
Quando ocorre uma interrupção de hardware, o sistema operacional sinaliza o driver de classe, que chama a rotina StrMiniInterrupt do minidriver para lidar com a interrupção.