Suporte a clientes Kernel-Mode em drivers UMDF 1.x

Aviso

O UMDF 2 é a versão mais recente do UMDF e substitui o UMDF 1. Todos os novos drivers UMDF devem ser gravados usando UMDF 2. Nenhum novo recurso está sendo adicionado ao UMDF 1 e há suporte limitado para UMDF 1 em versões mais recentes do Windows 10. Os drivers universais do Windows devem usar o UMDF 2.

Para obter mais informações, consulte Introdução com UMDF.

Aviso

Consulte também o suporte a clientes Kernel-Mode no UMDF 2.x.

As versões 1.9 e posteriores da UMDF permitem que os drivers UMDF ofereçam suporte a clientes no modo kernel. Um cliente no modo kernel pode ser um dos seguintes:

  • Um driver no modo kernel que existe acima de um driver UMDF na pilha de driver de um dispositivo.

  • Um driver no modo kernel para uma pilha de dispositivos, que dá suporte a um dispositivo, abre um identificador para outro dispositivo e a pilha de driver do último dispositivo contém um driver UMDF.

Em outras palavras, um driver UMDF que dá suporte a clientes no modo kernel pode receber solicitações de E/S de um driver no modo kernel. O driver do modo kernel pode encaminhar solicitações de E/S que recebeu de um aplicativo no modo de usuário ou pode criar novas solicitações de E/S e enviá-las para o driver de modo de usuário.

Para determinar se o driver UMDF deve dar suporte a clientes no modo kernel, você deve entender a pilha de driver à qual o driver será adicionado e onde, nessa pilha, o driver residirá. Você também deve determinar se um driver de outra pilha pode enviar solicitações de E/S para o dispositivo do driver.

O driver deverá dar suporte a clientes no modo kernel se:

  • Um driver no modo kernel pode estar localizado diretamente acima do driver UMDF em uma pilha de driver. Por exemplo, um driver de filtro no modo kernel pode residir diretamente acima de um driver de função baseado em UMDF.

  • Um driver no modo kernel de outra pilha pode enviar solicitações de E/S para o dispositivo do driver. Por exemplo, o driver pode criar um link simbólico que um driver no modo kernel em outra pilha pode usar para abrir um identificador para o dispositivo do driver. O driver do modo kernel pode enviar solicitações de E/S para o dispositivo.

Como dar suporte a clientes no modo kernel em um driver UMDF

Um driver UMDF só poderá receber solicitações de E/S de um driver no modo kernel se o driver UMDF tiver habilitado o suporte para clientes no modo kernel. Além disso, se uma instalação de dispositivo tentar carregar drivers no modo kernel acima de um driver UMDF na pilha de driver do dispositivo, a estrutura permitirá que os drivers carreguem somente se o driver UMDF tiver habilitado o suporte para clientes no modo kernel.

Para habilitar o suporte de um driver UMDF para clientes no modo kernel, o arquivo INF do driver UMDF deve incluir uma diretiva UmdfKernelModeClientPolicy em sua DDInstall INF. Seção WDF . Se o arquivo INF do driver UMDF não incluir essa diretiva, o UMDF não permitirá que um driver no modo kernel instalado acima do driver UMDF seja executado.

A estrutura fornece dois métodos úteis para drivers que dão suporte a clientes no modo kernel. Um driver pode chamar o método IWDFIoRequest2::GetRequestorMode para determinar se uma solicitação de E/S veio do modo kernel ou do modo de usuário. Se a solicitação de E/S veio do modo de usuário, o driver poderá chamar IWDFIoRequest2::IsFromUserModeDriver para determinar se a solicitação veio de um aplicativo ou de outro driver de modo de usuário.

Restrições em drivers no modo kernel

Um driver UMDF pode processar solicitações de E/S de um driver no modo kernel somente se o driver no modo kernel atender aos seguintes requisitos:

  • O driver do modo kernel deve estar em execução no IRQL = PASSIVE_LEVEL quando ele envia a solicitação de E/S.

  • A menos que o driver tenha definido a diretiva INF UmdfFileObjectPolicy para AllowNullAndUnknownFileObjects, cada solicitação de E/S que um driver no modo kernel envia para um driver no modo de usuário deve ter um objeto de arquivo associado. A estrutura deve ter sido notificada anteriormente de que o gerenciador de E/S criou o objeto de arquivo. (Essa notificação faz com que a estrutura chame a função de retorno de chamada IQueueCallbackCreate::OnCreateFile do driver do modo usuário, mas essa função de retorno de chamada é opcional.)

  • A solicitação de E/S não pode conter um código de função IRP_MJ_INTERNAL_DEVICE_CONTROL .

  • Os buffers da solicitação de E/S não devem conter ponteiros para informações adicionais, pois o driver do modo de usuário não pode desreferenciar os ponteiros.

  • Se a solicitação de E/S contiver um código de controle de E/S que especifica o método de acesso de buffer "nenhum" , o driver do modo kernel deverá enviar a solicitação de E/S no contexto de processo do aplicativo que criou a solicitação de E/S. Para obter mais informações sobre como dar suporte ao método "nem" em um driver base umDF, consulte Using Nor Buffered E/S nor Direct I/O in UMDF Drivers.

  • O driver UMDF pode modificar os dados de saída de uma solicitação de E/S, no modo de usuário. Portanto, o driver do modo kernel deve validar todos os dados de saída recebidos do driver do modo de usuário.

  • O cliente no modo kernel normalmente deve validar o valor de informações que um driver UMDF passa para IWDFIoRequest::CompleteWithInformation. Se o cliente for um driver KMDF, ele poderá chamar WdfRequestGetCompletionParams para obter essas informações em uma estrutura de IO_STATUS_BLOCK.

    Normalmente, a estrutura não valida o valor das informações que um driver UMDF passa para IWDFIoRequest::CompleteWithInformation. (Esse parâmetro geralmente especifica o número de bytes transferidos.) A estrutura valida o valor das informações somente para buffers de saída e somente para o método de acesso a dados de E/S em buffer . (Por exemplo, a estrutura verifica se o número de bytes transferidos não excede o tamanho do buffer de saída de uma operação de leitura, se o método de acesso for armazenado em buffer de E/S.)

Manipulando valores de status de retorno em um driver UMDF 1.x

Passar valores de status de retorno do modo de usuário para o modo kernel requer atenção especial, da seguinte maneira:

  • Os drivers da versão 1 da UMDF normalmente recebem valores retornados do tipo HRESULT, enquanto os drivers kmdf e do modo kernel baseado em WDM normalmente recebem valores do tipo NTSTATUS. Se um UMDF 1. x driver conclui uma solicitação de E/S e, se o driver tiver um cliente no modo kernel, a chamada do driver para IWDFIoRequest::Complete ou IWDFIoRequest::CompleteWithInformation deverá especificar um valor HRESULT que o driver gera de um valor NTSTATUS. Em geral, UMDF 1. x drivers devem usar a macro HRESULT_FROM_NT (definida em Winerror.h) para retornar o status para um cliente no modo kernel. O exemplo a seguir mostra como usar essa macro ao concluir uma solicitação.

    hr = HRESULT_FROM_NT(STATUS_BUFFER_OVERFLOW)
    request->Complete(HRESULT_FROM_NT(STATUS_BUFFER_OVERFLOW);
    return hr;
    

    Para retornar um valor HRESULT específico para um cliente no modo kernel, os seguintes retornos de chamada devem usar a macro HRESULT_FROM_NT:

    Para usar os valores NTSTATUS definidos em ntstatus.h, um UMDF 1. x driver deve incluir essas duas linhas antes de incluir quaisquer cabeçalhos adicionais.

    #define UMDF_USING_NTSTATUS
    #include <ntstatus.h>
    

    Não use a macro HRESULT_FROM_NT para converter STATUS_SUCCESS de um valor NTSTATUS em um valor HRESULT. Basta retornar S_OK, conforme mostrado no exemplo a seguir.

    request->Complete(S_OK);
    
  • A estrutura conclui algumas solicitações de E/S em nome de drivers UMDF. Às vezes, a estrutura não converte valores retornados do tipo HRESULT em valores NTSTATUS equivalentes, portanto, a estrutura pode passar um status de conclusão do tipo HRESULT para um cliente no modo kernel.

    Devido a essa situação, os clientes no modo kernel não devem usar a macro NT_ERROR ao testar o status de conclusão de uma solicitação de E/S, pois a macro NT_ERROR não retorna TRUE para valores de erro HRESULT. Os drivers no modo kernel devem usar a macro NT_SUCCESS ao testar o status de conclusão de uma solicitação de E/S.

Suporte ao cliente no modo kernel em versões anteriores da UMDF

Para versões UMDF anteriores à versão 1.9, um arquivo INF do driver pode incluir uma diretiva INF AddReg para criar um valor de registro UpperDriverOk do tamanho de REG_DWORD sob a subchave WUDF da chave de hardware do dispositivo.

Se o valor do registro UpperDriverOk for definido como um número diferente de zero, a estrutura permitirá que drivers no modo kernel sejam carregados acima do driver do modo de usuário. Os drivers no modo kernel podem encaminhar solicitações de E/S de aplicativos no modo de usuário para o driver UMDF, mas os drivers no modo kernel não podem enviar solicitações de E/S criadas no modo kernel para o driver UMDF.

Para as versões 1.9 e posteriores da UMDF, o valor do registro do UpperDriverOk é obsoleto e tem suporte apenas para drivers existentes. Os novos drivers devem usar a diretiva UmdfKernelModeClientPolicy .