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

Observação

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

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

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

Os números 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 à esquerda 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 de estilo PS/2 operado por meio de um controlador i8042 e um mouse em estilo serial operado por meio de um controlador de porta serial.

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

  • Os teclados são abertos no modo exclusivo pela pilha do sistema operacional por motivos de segurança
  • O Windows dá suporte à conexão simultânea de mais de um dispositivo de teclado e mouse.
  • O Windows não dá suporte ao acesso independente de um cliente a cada dispositivo.

Recursos do driver de classe

Este tópico 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

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

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

Kbdclass e Mouclass cada recurso:

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

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

  • Operação de dispositivos herdados.

  • 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 no estilo PS/2 Plug and Play. Cada driver de classe cria um objeto de dispositivo de filtro de classe de nível superior (filter DO) anexado a um FDO (objeto de dispositivo de função) por meio de um filtro de dispositivo opcional de nível superior DO. Um driver de filtro de dispositivo de nível superior cria o filtro de dispositivo de nível superior DO. O I8042prt cria a função DO e a anexa a um PDO (objeto de dispositivo físico) criado pelo driver de barramento raiz.

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

PS/2 Teclado

A pilha do driver de teclado consiste no seguinte.

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

PS/2 Mouse

A pilha do driver do mouse consiste no seguinte.

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

Kbdclass e Mouclass podem dar suporte a mais de um dispositivo em dois modos diferentes. No modo um para um, cada dispositivo tem uma pilha de dispositivo 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 de classe opera todos os dispositivos da seguinte maneira:

  • O driver de classe cria uma classe grandmaster DO que representa 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 à criada no modo um-para-um.

  • A classe grandmaster DO controla a operação de todos os DOs subordinados.

  • O subsistema Win32 acessa toda a entrada do 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 grandmaster.

  • O grandmaster mantém um único estado de dispositivo global.

Kbdclass e Mouclass operam no modo um para um se o valor de entrada do Registro ConnectMultiplePorts estiver definido como 0x00 (na chave HKLM\Services\CurrentControlSet\<class service>\Parameters, em que o serviço de classe é Kbdclass ou Mouclass). Caso contrário, Kbdclass e Mouclass operam no modo grandmaster.

Abrir e fechar por meio do driver de classe

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

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

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 Plug and Play iniciado, o driver de classe enviará a solicitação IRP_MJ_CREATE para baixo na pilha do driver. Caso contrário, o driver de classe concluirá a solicitação sem enviar a solicitação para baixo na pilha do driver. O driver de classe define o arquivo confiável que tem 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 subordinados.

  • Operação herdada

    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 que anexam 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 expedição isr do driver de função para um dispositivo chama o retorno de chamada do serviço de classe. O Kbdclass fornece o retorno de chamada de serviço de classe KeyboardClassServiceCallback e o 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 Kbfiltr do driver de filtro de teclado de exemplo 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 para 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 classe e serviço de filtro são conectados da seguinte maneira:

  • O driver de classe envia uma solicitação de conexão de dispositivo interno na pilha do dispositivo (IOCTL_INTERNAL_KEYBOARD_CONNECT ou IOCTL_INTERNAL_MOUSE_CONNECT). Os dados de conexão de classe são especificados por uma estrutura de 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. Em seguida, o driver de filtro envia a solicitação de conexão filtrada para o driver de função.

Os retornos de chamada de classe e serviço de 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 ele 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 dá suporte às seguintes solicitações internas de controle de dispositivo 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.

Verificar mapeador de código 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 por meio do 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. Isso 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 compreendido pelo sistema. No entanto, esse é um processo entediante e, às vezes, pode levar a problemas graves, se houver 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

Nota Também há uma tecla Layouts de Teclado (observe o formulário plural) sob a tecla Control, mas essa chave não deve ser modificada.

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

Iniciar deslocamento (em bytes) Tamanho (em bytes) Dados
0 4 Cabeçalho: informações de versão
4 4 Cabeçalho: Sinalizadores
8 4 Cabeçalho: número de mapeamentos
12 4 Mapeamento individual
... ... ...
Últimos 4 bytes 4 Terminador Nulo (0x00000000)

A primeira e a segunda informações de cabeçalho do repositório DWORDS e devem ser definidas 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 a seguir, incluindo o mapeamento de terminação nula. Portanto, a contagem mínima seria 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 para que uma chave seja mapeada.

Depois que o mapa é armazenado no registro, o sistema deve ser reinicializado para que os mapeamentos entrem em vigor. Observe que, se o mapeamento de um código de verificação for necessário em um keypress, a etapa será executada no modo de usuário pouco 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 determinadas limitações, como mapeamento não funcionando corretamente ao executar em Serviços de Terminal.

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

Exemplo 1

O exemplo a seguir apresenta um exemplo. Para trocar a tecla CTRL esquerda pela chave CAPS LOCK, use um editor do Registro (preferencialmente Regedt32.exe) para modificar a chave mapa do Scancode 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: sinalizadores. 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: terminador nulo.

Exemplo 2

Também é possível adicionar uma tecla não disponível em geral em um teclado ou remover uma tecla que nunca é usada. O exemplo a seguir mostra o valor armazenado no Mapa do Scancode para remover a chave CTRL direita e alterar a funcionalidade da chave ALT correta 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: sinalizadores. Defina como todos os zeros.

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

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

0xE038E020: tecla ALT direita –> tecla mute (0xE038 --> 0xE020).

0x00000000: terminador nulo.

Depois que os dados necessários forem gerados, eles poderão 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 do 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 Verificação tem várias vantagens e desvantagens.

As vantagens incluem:

  • O Mapper 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, tecla CTRL direita) podem ser mapeadas como nulas (removidas) ou trocadas por outras chaves.
  • Os locais de chave podem ser alterados facilmente. Os usuários podem personalizar facilmente o local das chaves usadas com frequência para seu benefício.

As seguintes desvantagens são reconhecidas:

  • Depois 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 apliquem a todos os teclados conectados ao sistema. No momento, não é possível criar um mapa por teclado.

Consultar um dispositivo do mouse

O I8042prt dá suporte à seguinte solicitação de controle de dispositivo interno para consultar informações sobre um dispositivo do mouse:

IOCTL_MOUSE_QUERY_ATTRIBUTES

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

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

Veja a seguir 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. Somente para Windows NT4.
  • PointerDeviceBaseName – especifica o nome base para os objetos de dispositivo criados pelo driver de dispositivo da classe 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 do 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ãopagada.

Dispositivos de apontamento 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 de MOUSE_INPUT_DATA exigidas por MouseClassServiceCallback.

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

Para um dispositivo de apontamento 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 Sinalizadores.

  • 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 mapeará a entrada apenas para o monitor primário.

O seguinte especifica, por tipo de dispositivo, como esses requisitos especiais para um dispositivo de apontamento absoluto são implementados:

  • Dispositivos HID:

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

  • Dispositivos de estilo PS/2:

    Um driver de filtro de nível superior é necessário. O driver de filtro fornece um retorno de chamada isrHook e um retorno de chamada de serviço de classe. O I8042prt chama o IsrHook para lidar com a entrada bruta do dispositivo 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.

  • Plug and Play dispositivos de porta COM que são enumerados pelo Soro:

    Um driver de função Plug and Play é necessário. 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 MOUSE_MOVE_ABSOLUTE antes de chamar MouseClassServiceCallback.

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

    Um driver de função específico do dispositivo é necessário. 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 MOUSE_MOVE_ABSOLUTE antes de chamar MouseClassServiceCallback.

  • Dispositivo em um barramento sem suporte:

    Um driver de função específico do dispositivo é necessário. 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 MOUSE_MOVE_ABSOLUTE antes de chamar MouseClassServiceCallback.