Despachando irps para filas de E/S
[Aplica-se a KMDF e UMDF]
Um driver baseado em estrutura pode especificar dinamicamente uma fila de destino para um IRP de entrada. Para expedir um IRP para uma fila específica, um driver deve chamar o método WdfDeviceWdmDispatchIrpToIoQueue .
Normalmente, um driver chama WdfDeviceWdmDispatchIrpToIoQueue de sua função de retorno de chamada EvtDeviceWdmIrpPreprocess ou EvtDeviceWdmIrpDispatch . Para obter o melhor desempenho, a maioria dos drivers não fornece ambas as funções de retorno de chamada.
Nota Um driver UMDF pode fornecer uma função de retorno de chamada EvtDeviceWdmIrpDispatch , mas somente drivers KMDF podem fornecer EvtDeviceWdmIrpPreprocess.
Se o driver já fornecer EvtDeviceWdmIrpPreprocess, você poderá usá-lo para selecionar dinamicamente uma fila. Caso contrário, forneça EvtDeviceWdmIrpDispatch e chame WdfDeviceWdmDispatchIrpToIoQueue de dentro dessa função de retorno de chamada.
Além disso, você deve estar ciente do seguinte:
Um método alternativo para expedir um IRP para uma fila de E/S é criar uma fila padrão e, em seguida, de dentro do manipulador da fila, chamar WdfRequestForwardToIoQueue. Essa técnica está disponível a partir do KMDF 1.0, mas não funciona bem com filas de progresso de avanço e está em geral mais lenta. Considere usar WdfDeviceWdmDispatchIrpToIoQueue .
Ao chamar WdfDeviceConfigureWdmIrpDispatchCallback para registrar uma função de retorno de chamada EvtDeviceWdmIrpDispatch , o driver deve definir o parâmetro MajorFunction como um dos seguintes: IRP_MJ_DEVICE_CONTROL, IRP_MJ_INTERNAL_DEVICE_CONTROL, IRP_MJ_READ IRP_MJ_WRITE. Embora esse requisito não se aplique a EvtDeviceWdmIrpPreprocess, somente IRPs desses tipos podem ser enviados dinamicamente para filas especificadas.
Os IRPs que vão para EvtDeviceWdmIrpPreprocess têm um local de pilha adicional. IrPs que vão para EvtDeviceWdmIrpDispatch (sem uma invocação anterior de EvtDeviceWdmIrpPreprocess) não.
EvtDeviceWdmIrpPreprocess não facilita o envio de informações de contexto definidas pelo driver, enquanto EvtDeviceWdmIrpDispatch faz.
Expedindo IRPs não pré-processados
Para expedir IRPs da função de retorno de chamada EvtDeviceWdmIrpDispatch de um driver, use o seguinte procedimento:
Em sua função de retorno de chamada EvtDriverDeviceAdd , o driver chama WdfDeviceConfigureWdmIrpDispatchCallback para registrar uma função de retorno de chamada EvtDeviceWdmIrpDispatch .
Se o destino for a fila de E/S do dispositivo pai, um driver KMDF deverá chamar WdfPdoInitAllowForwardingRequestToParent antes de chamar WdfDeviceCreate. Se um driver KMDF também tiver fornecido uma função de retorno de chamada EvtDeviceWdmIrpPreprocess , a estrutura chamará essa função primeiro quando um IRP chegar. Depois que a função de retorno de chamada pré-processa a solicitação, ela chama WdfDeviceWdmDispatchPreprocessedIrp para retornar o IRP para a estrutura.
A estrutura chama a função de retorno de chamada EvtDeviceWdmIrpDispatch do driver.
De dentro de EvtDeviceWdmIrpDispatch, o driver pode chamar WdfDeviceWdmDispatchIrpToIoQueue ou WdfDeviceWdmDispatchIrp, mas não ambos. Um driver KMDF tem a opção adicional de chamar nenhum desses métodos e, em vez disso, concluir o IRP ou marcá-lo pendente.
Se um driver KMDF tiver definido o sinalizador WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK e não tiver habilitado o progresso de encaminhamento garantido para a fila de E/S de destino, a estrutura chamará EvtIoInCallerContext do driver, se fornecido. Depois de pré-processar a solicitação, a função de retorno de chamada deve enfileira-la chamando WdfDeviceEnqueueRequest ou conclua-a chamando WdfRequestComplete.
Expedição de IRPs pré-processados
Para expedir IRPs da função de retorno de chamada EvtDeviceWdmIrpPreprocess de um driver para uma fila de E/S específica, use o seguinte procedimento:
- O driver registra uma função de retorno de chamada EvtDeviceWdmIrpPreprocess chamando WdfDeviceInitAssignWdmIrpPreprocessCallback.
- O driver chamará WdfPdoInitAllowForwardingRequestToParent se o destino for a fila de E/S do dispositivo pai.
- Em EvtDeviceWdmIrpPreprocess, chame WdfDeviceWdmDispatchIrpToIoQueue com Sinalizadores definidos como WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP.
- Se o driver tiver definido o sinalizador WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK e não tiver habilitado o progresso de encaminhamento garantido para a fila de E/S de destino, a estrutura chamará EvtIoInCallerContext do driver, se fornecido. Depois que a função de retorno de chamada tiver terminado de pré-processar a solicitação, ela deverá enfileira-la chamando WdfDeviceEnqueueRequest ou conclua-a chamando WdfRequestComplete.