Partilhar via


Configuração de drivers de classe de teclado e mouse

Observação

Este artigo é para desenvolvedores que estão configurando drivers de classe de teclado e mouse. Se você estiver procurando corrigir um mouse ou teclado, consulte:

Teclados e mouses não-HID podem se conectar em vários barramentos legados, mas ainda usam o mesmo driver de classe. Esta seção contém detalhes sobre os próprios drivers de classe. As seções a seguir entram em detalhes sobre os controladores.

Este artigo descreve a configuração física típica de dispositivos de teclado e mouse no Microsoft Windows 2000 e posterior.

As figuras a seguir mostram duas configurações comuns que empregam um único teclado e um único mouse.

Diagrama ilustrando duas configurações que empregam um único teclado e um único mouse.

A figura mostra um teclado e um mouse conectados a um barramento do sistema por meio de controladores independentes. Uma configuração típica consiste em um teclado estilo POWERSHELL/2 operado através de um controlador i8042 e um mouse de estilo serial operado através de um controlador de porta serial.

As seguintes informações adicionais são importantes para os fabricantes de teclado e mouse:

  • O sistema operacional abre teclados em modo exclusivo por motivos de segurança
  • O Windows oferece suporte à conexão simultânea de mais de um dispositivo de teclado e mouse.
  • O Windows não oferece suporte ao acesso independente de um cliente a cada dispositivo.

Recursos do driver de classe

Este artigo descreve os recursos dos seguintes drivers de classe de sistema do Microsoft Windows 2000 e posteriores:

  • Kbdclass, o driver de classe para dispositivos de GUID_CLASS_KEYBOARD classe de dispositivo

  • Mouclass, o driver de classe para dispositivos de GUID_CLASS_MOUSE classe de dispositivo

Kbdclass implementa o serviço Kbdclass e sua imagem executável é kbdclass.sys.

Mouclass implementa o serviço Mouclass e sua imagem executável é mouclass.sys.

Kbdclass e Mouclass cada característica:

  • Operação genérica e independente de hardware da classe de dispositivos.

  • Plug and Play, gerenciamento de energia e WMI (Instrumentação de Gerenciamento do Windows).

  • Operação de dispositivos legados.

  • Operação simultânea de mais de um dispositivo.

  • Conexão de uma rotina de retorno de chamada de serviço de classe que um driver de função usa para transferir dados do buffer de dados de entrada do dispositivo para o buffer de dados do driver de classe.

Configuração de objetos de dispositivo

A figura a seguir mostra a configuração de objetos de dispositivo para um dispositivo de teclado e mouse estilo Plug and Play PS/2. Cada driver de classe cria um objeto de dispositivo de filtro de classe de nível superior (filtro DO) que é anexado a um objeto de dispositivo de função (FDO) por meio de um filtro de dispositivo de nível superior opcional DO. Um driver de filtro de dispositivo de nível superior cria o filtro de dispositivo de nível superior DO. I8042prt cria a função DO e a anexa a um objeto de dispositivo físico (PDO) criado pelo driver de barramento raiz.

Diagrama ilustrando a configuração de objetos de dispositivo para um dispositivo de teclado e mouse estilo plug and play ps/2.

Teclado PS/2

A pilha de driver de teclado consiste no seguinte.

  • Kbdclass, o driver de filtro de classe de teclado de nível superior
  • Um ou mais drivers opcionais de filtro de teclado de nível superior
  • I8042prt, o driver de função

PS/2 Mouse

A pilha de driver do mouse consiste no seguinte.

  • Mouclass, o driver de filtro de classe de mouse de nível superior
  • Um ou mais drivers opcionais de filtro de mouse de nível superior
  • I8042prt, o driver de função

Kbdclass e Mouclass podem suportar mais de um dispositivo em dois modos diferentes. No modo um-para-um, cada dispositivo tem uma pilha de dispositivos independente. O driver de classe cria e anexa uma classe independente DO a cada pilha de dispositivos. Cada pilha de dispositivos tem seu próprio estado de controle e buffer de entrada. O subsistema Microsoft Win32 acessa a entrada de cada dispositivo por meio de um objeto de arquivo exclusivo.

No modo grandmaster, o driver da classe opera todos os dispositivos da seguinte maneira:

  • O driver de classe cria uma classe grandmaster DO representando todos os dispositivos e uma classe subordinada DO para cada dispositivo.

    O driver de classe anexa uma classe subordinada DO a cada pilha de dispositivos. Abaixo da classe subordinada DO, a pilha de dispositivos é igual à pilha criada no modo um-para-um.

  • A classe de grão-mestre DO controla a operação de todos os DO subordinados.

  • O subsistema Win32 acessa toda a entrada de dispositivo por meio do objeto de arquivo que representa o dispositivo de classe grandmaster.

  • Toda a entrada do dispositivo é armazenada em buffer na fila de dados do grão-mestre.

  • O grão-mestre mantém um único estado de dispositivo global.

Kbdclass e Mouclass operam no modo um-para-um se seu valor de entrada do Registro ConnectMultiplePorts estiver definido como 0x00 (sob a chave HKLM\Services\CurrentControlSet\<class service>\Parameters, onde class service é Kbdclass ou Mouclass). Caso contrário, Kbdclass e Mouclass operam no modo grandmaster.

Abra e feche através do driver da classe

O subsistema Microsoft Win32 abre todos os dispositivos de teclado e mouse para seu uso exclusivo. Para cada classe de dispositivo, o subsistema Win32 trata a entrada de todos os dispositivos como se a entrada viesse de um único dispositivo de entrada. Um aplicativo não pode solicitar o recebimento de entrada de apenas um dispositivo específico.

O subsistema Win32 abre dinamicamente dispositivos de entrada Plug and Play depois de receber notificação do gerenciador Plug and Play de que uma interface de dispositivo GUID_CLASS_KEYBOARD ou GUID_CLASS_MOUSE está habilitada. O subsistema Win32 fecha dispositivos Plug and Play depois de receber notificação de que uma interface aberta está desativada. O subsistema Win32 também abre dispositivos herdados por nome (por exemplo, "\Device\KeyboardLegacyClass0"). Depois que o subsistema Win32 abre com êxito um dispositivo herdado, ele não pode determinar se o dispositivo é removido fisicamente posteriormente.

Depois que Kbdclass e Mouclass recebem uma solicitação de criação, eles fazem o seguinte para Plug and Play e operação herdada:

  • Operação Plug and Play

    Se o dispositivo estiver no estado de início Plug and Play, o driver de classe enviará a solicitação de IRP_MJ_CREATE para baixo da pilha de drivers. Caso contrário, o driver de classe concluirá a solicitação sem enviar a solicitação para baixo da pilha de drivers. O driver de classe define o arquivo confiável com acesso de leitura ao dispositivo. Se houver um dispositivo grandmaster, o driver de classe enviará uma solicitação de criação para todas as portas associadas aos dispositivos de classe subordinada.

  • Operação Legada

    O driver de classe envia uma solicitação de controle de dispositivo interno para o driver de porta para habilitar o dispositivo.

Conectar um retorno de chamada de serviço a um dispositivo

Os drivers de classe devem conectar seu serviço de classe a um dispositivo antes que o dispositivo possa ser aberto. Os drivers de classe conectam seu serviço de classe depois de anexar uma classe DO a uma pilha de dispositivos. O driver de função usa o retorno de chamada do serviço de classe para transferir dados de entrada de um dispositivo para a fila de dados de classe do dispositivo. A rotina de conclusão de despacho ISR do driver de função para um dispositivo chama o retorno de chamada do serviço de classe. Kbdclass fornece o retorno de chamada de serviço de classe KeyboardClassServiceCallback e Mouclass fornece o retorno de chamada de serviço de classe MouseClassServiceCallback.

Um fornecedor pode modificar a operação de um retorno de chamada de serviço de classe instalando um driver de filtro de nível superior para um dispositivo. O driver de filtro de teclado de exemplo Kbfiltr define o retorno de chamada KbFilter_ServiceCallback e o driver de filtro de mouse de exemplo Moufiltr define o retorno de chamada MouFilter_ServiceCallback. Os retornos de chamada do serviço de filtro de exemplo podem ser configurados para modificar os dados de entrada transferidos do buffer de entrada da porta de um dispositivo para a fila de dados de classe. Por exemplo, o retorno de chamada do serviço de filtro pode excluir, transformar ou inserir dados.

Os retornos de chamada de serviço de classe e filtro são conectados da seguinte maneira:

  • O driver de classe envia uma solicitação de conexão de dispositivo interna para a pilha de dispositivos (IOCTL_INTERNAL_KEYBOARD_CONNECT ou IOCTL_INTERNAL_MOUSE_CONNECT). Os dados de conexão de classe são especificados por uma estrutura CONNECT_DATA que inclui um ponteiro para o objeto de dispositivo de classe e um ponteiro para o retorno de chamada do serviço de classe.

  • Depois que o driver de filtro recebe a solicitação de conexão, ele salva uma cópia dos dados de conexão de classe e substitui os dados de conexão da solicitação por dados de conexão de filtro. Os dados de conexão de filtro especificam um ponteiro para o objeto de dispositivo de filtro e um ponteiro para o retorno de chamada do serviço de driver de filtro. O driver de filtro, em seguida, envia a solicitação de conexão filtrada para o driver de função.

Os retornos de chamada de serviço de classe e filtro são chamados da seguinte maneira:

  • O driver de função usa os dados de conexão de filtro para fazer o retorno de chamada inicial para o retorno de chamada do serviço de filtro.

  • Depois de filtrar os dados de entrada, o retorno de chamada do serviço de filtro usa os dados de conexão de classe que salvou para fazer um retorno de chamada para o retorno de chamada do serviço de classe.

Consultar e definir um dispositivo de teclado

O I8042prt oferece suporte às seguintes solicitações de controle de dispositivo interno para consultar informações sobre um dispositivo de teclado e definir parâmetros em um dispositivo de teclado:

IOCTL_KEYBOARD_QUERY_ATTRIBUTES

IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION

IOCTL_KEYBOARD_QUERY_INDICATORS

IOCTL_KEYBOARD_QUERY_TYPEMATIC

IOCTL_KEYBOARD_SET_INDICATORS

IOCTL_KEYBOARD_SET_TYPEMATIC

Para obter mais informações sobre todas as solicitações de controle de dispositivo de teclado, consulte Referência de dispositivos de interface humana.

Mapeador de código de digitalização para teclados

Nos sistemas operacionais Microsoft Windows, os códigos de verificação compatíveis com PS/2 fornecidos por um dispositivo de entrada são convertidos em chaves virtuais, que são propagadas pelo sistema na forma de mensagens do Windows. Se um dispositivo produzir um código de verificação incorreto para uma determinada chave, a mensagem de chave virtual errada será enviada. Esse problema pode ser corrigido escrevendo um driver de filtro que analisa os códigos de verificação gerados pelo firmware e modifica o código de verificação incorreto para um entendido pelo sistema. No entanto, este é um processo tedioso e às vezes pode levar a problemas graves, se existirem erros no driver de filtro no nível do kernel.

O Windows 2000 e o Windows XP incluem um novo mapeador de código de verificação, que fornece um método que permite o mapeamento de códigos de verificação. Os mapeamentos de código de verificação para Windows são armazenados na seguinte chave do Registro:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

Observação

Há também uma tecla Layouts de teclado sob a tecla Control, mas essa tecla não deve ser modificada.

Na tecla Layout do teclado , o valor Scancode Map deve ser adicionado. Esse valor é do tipo REG_BINARY (formato Endian pequeno) e tem o formato de dados especificado na tabela a seguir.

Deslocamento inicial (em bytes) Tamanho (em bytes) Dados
0 4 Cabeçalho: Informações de versão
4 4 Cabeçalho: Bandeiras
8 4 Cabeçalho: Número de mapeamentos
12 4 Mapeamento Individual
... ... ...
Últimos 4 bytes 4 Exterminador nulo (0x00000000)

O primeiro e o segundo DWORDS armazenam informações de cabeçalho e devem ser definidos como todos os zeros para a versão atual do Mapeador de Código de Verificação. A terceira entrada DWORD contém uma contagem do número total de mapeamentos que se seguem, incluindo o mapeamento de terminação nulo. A contagem mínima seria, portanto, 1 (sem mapeamentos especificados). Os mapeamentos individuais seguem o cabeçalho. Cada mapeamento tem um DWORD de comprimento e é dividido em dois campos de comprimento WORD. Cada campo WORD armazena o código de verificação de uma chave a ser mapeada.

Uma vez que o mapa é armazenado no registro, o sistema deve ser reinicializado para que os mapeamentos entrem em vigor. Se o mapeamento de um código de verificação for necessário em um pressionamento de tecla, a etapa será executada no modo de usuário imediatamente antes de o código de verificação ser convertido em uma chave virtual. Fazer essa conversão no modo de usuário pode apresentar certas limitações, como o mapeamento que não funciona corretamente ao ser executado nos Serviços de Terminal.

Para remover esses mapeamentos, remova o valor do Registro Scancode Map e reinicialize.

Exemplo 1

Para trocar a tecla CTRL esquerda pela tecla CAPS LOCK, use um editor do Registro (de preferência Regedt32.exe) para modificar a chave Scancode Map com o seguinte valor:

00000000 00000000 03000000 3A001D00 1D003A00 00000000

A tabela a seguir contém essas entradas divididas em campos DWORD e os bytes trocados.

Valor: Interpretação

0x00000000: Cabeçalho: Versão. Defina como todos os zeros.

0x00000000: Cabeçalho: Bandeiras. Defina como todos os zeros.

0x00000003: Três entradas no mapa (incluindo entrada nula).

0x001D003A: Tecla CTRL esquerda --> CAPS LOCK (0x1D --> 0x3A).

0x003A001D: CAPS LOCK --> Tecla CTRL esquerda (0x3A --> 0x1D).

0x00000000: Exterminador nulo.

Exemplo 2

Também é possível adicionar uma tecla que não está disponível em um teclado ou remover uma tecla que nunca é usada. O exemplo a seguir mostra o valor armazenado no Scancode Map para remover a chave CTRL correta e alterar a funcionalidade da chave ALT direita para funcionar como uma chave de mudo:

00000000 00000000 03000000 00001DE0 20E038E0 00000000

A tabela a seguir contém essas entradas divididas em campos DWORD e os bytes trocados.

Valor: Interpretação

0x00000000: Cabeçalho: Versão. Defina como todos os zeros.

0x00000000: Cabeçalho: Bandeiras. Defina como todos os zeros.

0x00000003: Três entradas no mapa (incluindo entrada nula).

0xE01D0000: Remova a tecla CTRL direita (0xE01D --> 0x00).

0xE038E020: Tecla ALT direita --> Tecla mudo (0xE038 --> 0xE020).

0x00000000: Exterminador nulo.

Depois que os dados necessários são gerados, eles podem ser inseridos no registro de várias maneiras.

  • Um arquivo .reg pode ser gerado que pode ser facilmente incorporado ao registro do sistema usando um editor de registro.
  • Um arquivo .inf também pode ser criado com uma seção [AddReg] que contém as informações do Registro a serem adicionadas.
  • Regedt32.exe pode ser usado para adicionar manualmente as informações ao registro.

O Mapeador de Código de Digitalização tem várias vantagens e desvantagens.

As vantagens incluem:

  • O Mapeador pode ser usado como uma correção fácil para corrigir erros de firmware.
  • As teclas usadas com frequência podem ser adicionadas ao teclado modificando o mapa no registro. As chaves que não são usadas com frequência (por exemplo, chave CTRL direita) podem ser mapeadas para nulas (removidas) ou trocadas por outras chaves.
  • Os principais locais podem ser alterados facilmente. Os usuários podem personalizar facilmente a localização das chaves usadas com frequência para seu benefício.

As seguintes desvantagens são reconhecidas:

  • Uma vez que o mapa é armazenado no registro, uma reinicialização do sistema é necessária para ativá-lo.
  • Os mapeamentos armazenados no registro funcionam no nível do sistema e se aplicam a todos os usuários. Esses mapeamentos não podem ser definidos para funcionar de forma diferente, dependendo do usuário atual.
  • A implementação atual restringe a funcionalidade do mapa, de modo que os mapeamentos sempre se aplicam a todos os teclados conectados ao sistema. No momento, não é possível criar um mapa por teclado.

Consultar um dispositivo de mouse

I8042prt suporta a seguinte solicitação de controle de dispositivo interno para consultar informações sobre um dispositivo de mouse:

IOCTL_MOUSE_QUERY_ATTRIBUTES

Para obter mais informações sobre todas as solicitações de controle de dispositivo de mouse, consulte Referência de dispositivos de interface humana.

Configurações do Registro associadas ao driver de classe do mouse

Aqui está uma lista de chaves do Registro associadas ao driver de classe do mouse.

[Chave: HKLM\SYSTEM\CurrentControlSet\Services\Mouclass\Parameters]

  • MaximumPortsServiced – Não usado no Windows XP e posterior. Apenas para o Windows NT4.
  • PointerDeviceBaseName – Especifica o nome base para os objetos de dispositivo criados pelo driver de dispositivo de classe do mouse
  • ConnectMultiplePorts – Determina se há um ou mais de um objeto de dispositivo de porta para cada objeto de dispositivo de classe. Essa entrada é usada principalmente por drivers de dispositivo.
  • MouseDataQueueSize - Especifica o número de eventos de mouse armazenados em buffer pelo driver do mouse. Ele também é usado no cálculo do tamanho do buffer interno do driver do mouse no pool de memória não paginada.

Dispositivos apontadores absolutos

Para dispositivos do tipo GUID_CLASS_MOUSE, o driver de função de um dispositivo:

  • Manipula a entrada específica do dispositivo.

  • Cria as estruturas MOUSE_INPUT_DATA exigidas por MouseClassServiceCallback.

  • Transfere estruturas MOUSE_INPUT_DATA para a fila de dados Mouclass chamando MouseClassServiceCallback em sua rotina de conclusão de despacho ISR.

Para um dispositivo apontador absoluto, o driver de função do dispositivo deve definir os membros LastX, LastY e Flags das estruturas MOUSE_INPUT_DATA da seguinte maneira:

  • Além de dividir o valor de entrada do dispositivo pela capacidade máxima do dispositivo, o driver dimensiona o valor de entrada do dispositivo 0xFFFF:

    LastX = ((device input x value) * 0xFFFF ) / (Maximum x capability of the device)
    LastY = ((device input y value) * 0xFFFF ) / (Maximum y capability of the device)
    
  • O driver define o sinalizador MOUSE_MOVE_ABSOLUTE em Flags.

  • Se a entrada deve ser mapeada pelo Gerenciador de Janelas para uma área de trabalho virtual inteira, o driver define o sinalizador MOUSE_VIRTUAL_DESKTOP em Sinalizadores. Se o sinalizador MOUSE_VIRTUAL_DESKTOP não estiver definido, o Gerenciador de Janelas mapeia a entrada apenas para o monitor principal.

A lista a seguir especifica como esses requisitos especiais para um dispositivo apontador absoluto são implementados, por tipo de dispositivo:

  • Dispositivos HID:

    Mouhid, o driver de função do Windows para dispositivos de mouse HID, implementa esses requisitos especiais automaticamente.

  • Dispositivos estilo PS/2:

    É necessário um driver de filtro de nível superior. O driver de filtro fornece um retorno de chamada IsrHook e um retorno de chamada de serviço de classe. I8042prt chama o IsrHook para manipular a entrada de dispositivo bruto e chama o retorno de chamada do serviço de classe de filtro para filtrar a entrada. O retorno de chamada do serviço de classe de filtro, por sua vez, chama MouseClassServiceCallback. A combinação do retorno de chamada IsrHook e do retorno de chamada do serviço de classe manipula a entrada específica do dispositivo, cria as estruturas de MOUSE_INPUT_DATA necessárias, dimensiona os dados de entrada do dispositivo e define o sinalizador MOUSE_MOVE_ABSOLUTE.

  • Dispositivos de porta COM Plug and Play enumerados pelo Serenum:

    É necessário um driver de função Plug and Play. O driver de função cria as estruturas de MOUSE_INPUT_DATA necessárias, dimensiona os dados de entrada do dispositivo e define o sinalizador de MOUSE_MOVE_ABSOLUTE antes de chamar MouseClassServiceCallback.

  • Dispositivos de porta COM não Plug and Play:

    É necessário um driver de função específico do dispositivo. O driver de função cria as estruturas de MOUSE_INPUT_DATA necessárias, dimensiona os dados de entrada do dispositivo e define o sinalizador de MOUSE_MOVE_ABSOLUTE antes de chamar MouseClassServiceCallback.

  • Dispositivo em um barramento não suportado:

    É necessário um driver de função específico do dispositivo. O driver de função cria as estruturas de MOUSE_INPUT_DATA necessárias, dimensiona os dados de entrada do dispositivo e define o sinalizador de MOUSE_MOVE_ABSOLUTE antes de chamar MouseClassServiceCallback.