Share via


Konfiguration von Tastatur- und Mausklassentreibern

Hinweis

Dieses Thema richtet sich an Entwickler, die Tastatur- und Mausklassentreiber konfigurieren. Wenn Sie eine Maus oder Tastatur reparieren möchten, lesen Sie:

Nicht-HID-Tastaturen und Mäuse können über mehrere Legacybusse verbunden werden, aber weiterhin denselben Klassentreiber verwenden. Dieser Abschnitt enthält Details zu den Klassentreibern selbst. In den folgenden Abschnitten werden Details zu den Controllern erläutert.

In diesem Thema wird die typische physische Konfiguration von Tastatur- und Mausgeräten in Microsoft Windows 2000 und höher beschrieben.

Die folgenden Abbildungen zeigen zwei gängige Konfigurationen, die eine einzelne Tastatur und eine einzelne Maus verwenden.

Diagramm, das zwei Konfigurationen veranschaulicht, die eine einzelne Tastatur und eine einzelne Maus verwenden.

Die Abbildung auf der linken Seite zeigt eine Tastatur und eine Maus, die über unabhängige Controller mit einem Systembus verbunden sind. Eine typische Konfiguration besteht aus einer TASTATUR im PS/2-Stil, die über einen i8042-Controller betrieben wird, und einer seriellen Maus, die über einen seriellen Portcontroller betrieben wird.

Die folgenden zusätzlichen Informationen sind für Tastatur- und Maushersteller wichtig:

  • Tastaturen werden aus Sicherheitsgründen vom Betriebssystemstapel im exklusiven Modus geöffnet.
  • Windows unterstützt die gleichzeitige Verbindung mehrerer Tastatur- und Mausgeräte.
  • Windows unterstützt nicht den unabhängigen Zugriff eines Clients auf jedes Gerät.

Klassentreiberfeatures

In diesem Thema werden die Features der folgenden Systemklassentreiber von Microsoft Windows 2000 und höher beschrieben:

  • Kbdclass, der Klassentreiber für Geräte GUID_CLASS_KEYBOARD Geräteklasse

  • Mouclass, der Klassentreiber für Geräte GUID_CLASS_MOUSE Geräteklasse

Kbdclass implementiert den Kbdclass-Dienst, und sein ausführbares Image ist kbdclass.sys.

Mouclass implementiert den Mouclass-Dienst, und sein ausführbares Image ist mouclass.sys.

Kbdclass und Mouclass bieten jeweils Folgendes:

  • Generischer und hardwareunabhängiger Betrieb der Geräteklasse.

  • Plug & Play, Energieverwaltung und Windows-Verwaltungsinstrumentation (WMI).

  • Betrieb von Legacygeräten.

  • Gleichzeitiger Betrieb mehrerer Geräte.

  • Verbindung einer Klassendienstrückrufroutine , die ein Funktionstreiber verwendet, um Daten aus dem Eingabedatenpuffer des Geräts in den Datenpuffer des Klassentreibers zu übertragen.

Konfiguration von Geräteobjekten

Die folgende Abbildung zeigt die Konfiguration von Geräteobjekten für ein Plug & Play Tastatur- und Mausgerät im PS/2-Stil. Jeder Klassentreiber erstellt ein Klassenfiltergeräteobjekt auf oberster Ebene (Filter DO), das über einen optionalen Gerätefilter der oberen Ebene DO an ein Funktionsgeräteobjekt (FDO) angefügt wird. Ein Gerätefiltertreiber auf oberster Ebene erstellt den Gerätefilter do auf oberster Ebene. I8042prt erstellt die Funktion DO und fügt sie an ein physisches Geräteobjekt (PDO) an, das vom Stammbustreiber erstellt wurde.

Diagramm zur Veranschaulichung der Konfiguration von Geräteobjekten für ein Plug-and-Play-Ps/2-Tastatur- und Mausgerät.

PS/2-Tastatur

Der Tastaturtreiberstapel besteht aus folgendem:

  • Kbdclass, der Filtertreiber für die Tastaturklasse auf oberster Ebene
  • Mindestens ein optionaler Tastaturfiltertreiber auf oberster Ebene
  • I8042prt, der Funktionstreiber

PS/2-Maus

Der Maustreiberstapel besteht aus den folgenden Elementen.

  • Mouclass, der Übergeordnete Mausklassenfiltertreiber
  • Mindestens ein optionaler Mausfiltertreiber auf oberster Ebene
  • I8042prt, der Funktionstreiber

Kbdclass und Mouclass können mehrere Geräte in zwei verschiedenen Modi unterstützen. Im 1:1-Modus verfügt jedes Gerät über einen unabhängigen Gerätestapel. Der Klassentreiber erstellt und fügt an jeden Gerätestapel eine unabhängige Klassen-DO an. Jeder Gerätestapel verfügt über einen eigenen Steuerungszustand und einen eigenen Eingabepuffer. Das Microsoft Win32-Subsystem greift auf Eingaben von jedem Gerät über ein eindeutiges Dateiobjekt zu.

Im Grandmaster-Modus betreibt der Klassentreiber alle Geräte wie folgt:

  • Der Klassentreiber erstellt sowohl eine Großmasterklasse DO , die alle Geräte darstellt, als auch eine untergeordnete Klasse DO für jedes Gerät.

    Der Klassentreiber fügt jedem Gerätestapel eine untergeordnete Klasse DO an. Unterhalb der untergeordneten Klasse DO entspricht der Gerätestapel dem, der im 1:1-Modus erstellt wurde.

  • Die Grandmaster-Klasse DO steuert den Betrieb aller untergeordneten DOs.

  • Das Win32-Subsystem greift auf alle Geräteeingaben über das Dateiobjekt zu, das das Gerät der Grandmaster-Klasse darstellt.

  • Alle Geräteeingaben werden in der Datenwarteschlange des Großmeisters gepuffert.

  • Der Grandmaster verwaltet einen einzelnen globalen Gerätezustand.

Kbdclass und Mouclass arbeiten im 1:1-Modus, wenn der Registrierungseintragswert ConnectMultiplePorts auf 0x00 festgelegt ist (unter dem Schlüssel HKLM\Services\CurrentControlSet\<class service>\Parameters, wobei klassendienst Kbdclass oder Mouclass ist). Andernfalls werden Kbdclass und Mouclass im Großmeistermodus betrieben.

Öffnen und Schließen über den Klassentreiber

Das Microsoft Win32-Subsystem öffnet alle Tastatur- und Mausgeräte zur exklusiven Verwendung. Für jede Geräteklasse behandelt das Win32-Subsystem Eingaben von allen Geräten so, als ob die Eingabe von einem einzelnen Eingabegerät stammt. Eine Anwendung kann nicht anfordern, nur von einem bestimmten Gerät Eingaben zu empfangen.

Das Win32-Subsystem öffnet dynamisch Plug & Play Eingabegeräte, nachdem es eine Benachrichtigung vom Plug & Play-Manager erhalten hat, dass eine GUID_CLASS_KEYBOARD- oder GUID_CLASS_MOUSE-Geräteschnittstelle aktiviert ist. Das Win32-Subsystem schließt Plug & Play Geräte, nachdem es eine Benachrichtigung erhalten hat, dass eine geöffnete Schnittstelle deaktiviert ist. Das Win32-Subsystem öffnet auch Ältere Geräte anhand des Namens (z. B. "\Device\KeyboardLegacyClass0"). Beachten Sie, dass das Win32-Subsystem nach dem erfolgreichen Öffnen eines Legacygeräts nicht feststellen kann, ob das Gerät später physisch entfernt wird.

Nachdem Kbdclass und Mouclass eine Erstellungsanforderung erhalten haben, führen sie die folgenden Schritte für Plug & Play- und Legacyvorgänge aus:

  • Plug & Play-Vorgang

    Wenn sich das Gerät im Plug & Play Gestartet-Zustand befindet, sendet der Klassentreiber die IRP_MJ_CREATE Anforderung nach unten im Treiberstapel. Andernfalls schließt der Klassentreiber die Anforderung ab, ohne die Anforderung im Treiberstapel zu senden. Der Klassentreiber legt die vertrauenswürdige Datei fest, die Lesezugriff auf das Gerät hat. Wenn ein Grandmaster-Gerät vorhanden ist, sendet der Klassentreiber eine Erstellungsanforderung an alle Ports, die den untergeordneten Klassengeräten zugeordnet sind.

  • Legacy-Vorgang

    Der Klassentreiber sendet eine interne Gerätesteuerungsanforderung an den Porttreiber, um das Gerät zu aktivieren.

Verbinden eines Dienstrückrufs mit einem Gerät

Die Klassentreiber müssen ihren Klassendienst mit einem Gerät verbinden, bevor das Gerät geöffnet werden kann. Die Klassentreiber verbinden ihren Klassendienst, nachdem sie eine Klassen-DO an einen Gerätestapel angefügt haben. Der Funktionstreiber verwendet den Klassendienstrückruf, um Eingabedaten von einem Gerät in die Klassendatenwarteschlange für das Gerät zu übertragen. Die ISR-Dispatch-Vervollständigungsroutine des Funktionstreibers für ein Gerät ruft den Klassendienstrückruf auf. Kbdclass stellt den Klassendienstrückruf KeyboardClassServiceCallback und Mouclass den Klassendienstrückruf MouseClassServiceCallback bereit.

Ein Anbieter kann den Vorgang eines Klassendienstrückrufs ändern, indem er einen Filtertreiber der oberen Ebene für ein Gerät installiert. Der Beispiel-Tastaturfiltertreiber Kbfiltr definiert den KbFilter_ServiceCallback Rückruf, und der Beispielmausfiltertreiber moufiltr definiert den MouFilter_ServiceCallback Rückruf. Die Beispiel-Filterdienstrückrufe können so konfiguriert werden, dass die Eingabedaten geändert werden, die vom Porteingabepuffer für ein Gerät in die Klassendatenwarteschlange übertragen werden. Der Rückruf des Filterdiensts kann beispielsweise Daten löschen, transformieren oder einfügen.

Die Klassen- und Filterdienstrückrufe sind wie folgt verbunden:

  • Der Klassentreiber sendet eine interne Geräteverbindungsanforderung über den Gerätestapel (IOCTL_INTERNAL_KEYBOARD_CONNECT oder IOCTL_INTERNAL_MOUSE_CONNECT). Die Verbindungsdaten der Klasse werden durch eine CONNECT_DATA-Struktur angegeben, die einen Zeiger auf das Klassengeräteobjekt und einen Zeiger auf den Klassendienstrückruf enthält.

  • Nachdem der Filtertreiber die Verbindungsanforderung empfangen hat, speichert er eine Kopie der Verbindungsdaten der Klasse und ersetzt die Verbindungsdaten der Anforderung durch Filterverbindungsdaten. Die Filterverbindungsdaten geben einen Zeiger auf das Filtergeräteobjekt und einen Zeiger auf den Rückruf des Filtertreiberdiensts an. Der Filtertreiber sendet dann die gefilterte Verbindungsanforderung an den Funktionstreiber.

Die Klassen- und Filterdienstrückrufe werden wie folgt aufgerufen:

  • Der Funktionstreiber verwendet die Filterverbindungsdaten, um den anfänglichen Rückruf an den Filterdienstrückruf durchzuführen.

  • Nach dem Filtern der Eingabedaten verwendet der Filterdienstrückruf die klassenverbindungsdaten, die er gespeichert hat, um einen Rückruf an den Klassendienstrückruf durchzuführen.

Abfragen und Festlegen eines Tastaturgeräts

I8042prt unterstützt die folgenden internen Gerätesteuerungsanforderungen, um Informationen zu einem Tastaturgerät abzufragen und Parameter auf einem Tastaturgerät festzulegen:

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

Weitere Informationen zu allen Anforderungen zur Steuerung von Tastaturgeräten finden Sie unter Referenz zu Human Interface-Geräten.

Scannen von Codezuordnungen für Tastaturen

In Microsoft Windows-Betriebssystemen werden PS/2-kompatible Scancodes, die von einem Eingabegerät bereitgestellt werden, in virtuelle Schlüssel umgewandelt, die in Form von Windows-Nachrichten über das System weitergegeben werden. Wenn ein Gerät einen falschen Scancode für einen bestimmten Schlüssel erzeugt, wird die falsche Meldung des virtuellen Schlüssels gesendet. Dies kann behoben werden, indem Sie einen Filtertreiber schreiben, der die von der Firmware generierten Scancodes analysiert und den falschen Scancode in einen vom System verstandenen ändert. Dies ist jedoch ein langwieriger Prozess und kann manchmal zu schwerwiegenden Problemen führen, wenn Fehler im Filtertreiber auf Kernelebene vorhanden sind.

Windows 2000 und Windows XP enthalten einen neuen Scan Code Mapper, der eine Methode bereitstellt, die die Zuordnung von Scancodes ermöglicht. Die Scancodezuordnungen für Windows werden im folgenden Registrierungsschlüssel gespeichert:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

Hinweis Es gibt auch eine Tastaturlayouttaste (beachten Sie die Pluralform) unter der Strg-Taste, aber diese Taste sollte nicht geändert werden.

In der Tastaturlayouttaste muss der Wert Scancode Map hinzugefügt werden. Dieser Wert ist vom Typ REG_BINARY (kleines Endian-Format) und weist das in der folgenden Tabelle angegebene Datenformat auf.

Startoffset (in Bytes) Größe (in Bytes) Daten
0 4 Header: Versionsinformationen
4 4 Header: Flags
8 4 Header: Anzahl der Zuordnungen
12 4 Individuelle Zuordnung
... ... ...
Letzte 4 Bytes 4 Null-Abschlussator (0x00000000)

Die erste und zweite DWORDS speichern Headerinformationen und sollten für die aktuelle Version des Scan Code Mappers auf alle Nullen festgelegt werden. Der dritte DWORD-Eintrag enthält die Gesamtzahl der folgenden Zuordnungen, einschließlich der NULL-Beendigungszuordnung. Die Mindestanzahl wäre daher 1 (keine Zuordnungen angegeben). Die einzelnen Zuordnungen folgen dem Header. Jede Zuordnung ist eine DWORD-Länge und in zwei WORD-Längenfelder unterteilt. Jedes WORD-Feld speichert den Scancode für einen schlüssel, der zugeordnet werden soll.

Nachdem die Zuordnung in der Registrierung gespeichert wurde, muss das System neu gestartet werden, damit die Zuordnungen wirksam werden. Beachten Sie, dass der Schritt im Benutzermodus ausgeführt wird, wenn die Zuordnung eines Scancodes auf einem Tastendruck erforderlich ist, bevor der Scancode in einen virtuellen Schlüssel konvertiert wird. Diese Konvertierung im Benutzermodus kann bestimmte Einschränkungen aufweisen, z. B. dass die Zuordnung nicht ordnungsgemäß funktioniert, wenn sie unter Terminaldienste ausgeführt wird.

Um diese Zuordnungen zu entfernen, entfernen Sie den Registrierungswert Scancode Map, und starten Sie neu.

Beispiel 1

Im Folgenden finden Sie ein Beispiel. Um die linke STRG-TASTE durch die CAPS-LOCK-Taste zu tauschen, verwenden Sie einen Registrierungs-Editor (vorzugsweise Regedt32.exe), um den Scancode Map-Schlüssel mit dem folgenden Wert zu ändern:

00000000 00000000 03000000 3A001D00 1D003A00 00000000

Die folgende Tabelle enthält diese Einträge, die in DWORD-Felder unterteilt sind, und die ausgetauschten Bytes.

Wert: Interpretation

0x00000000: Header: Version. Legen Sie auf alle Nullen fest.

0x00000000: Header: Flags. Legen Sie auf alle Nullen fest.

0x00000003: Drei Einträge in der Karte (einschließlich NULL-Eintrag).

0x001D003A: LINKE STRG-TASTE --> CAPS-SPERRE (0x1D --> 0x3A).

0x003A001D: CAPS-TASTE --> LINKE STRG-TASTE (0x3A --> 0x1D).

0x00000000: Null-Abschlussator.

Beispiel 2

Es ist auch möglich, eine Taste hinzuzufügen, die nicht allgemein auf einer Tastatur verfügbar ist, oder eine Taste zu entfernen, die nie verwendet wird. Das folgende Beispiel zeigt den in Scancode Map gespeicherten Wert, um die rechte STRG-TASTE zu entfernen und die Funktionalität der rechten ALT-Taste so zu ändern, dass sie als Stummtaste funktioniert:

00000000 00000000 03000000 00001DE0 20E038E0 00000000

Die folgende Tabelle enthält diese Einträge, die in DWORD-Felder unterteilt sind, und die ausgetauschten Bytes.

Wert: Interpretation

0x00000000: Header: Version. Legen Sie auf alle Nullen fest.

0x00000000: Header: Flags. Legen Sie auf alle Nullen fest.

0x00000003: Drei Einträge in der Karte (einschließlich NULL-Eintrag).

0xE01D0000: Entfernen Sie die rechte STRG-TASTE (0xE01D -> 0x00).

0xE038E020: Rechte ALT-Taste> – Stummschalttaste (0xE038 --> 0xE020).

0x00000000: Null-Abschlussator.

Nachdem die erforderlichen Daten generiert wurden, können sie auf verschiedene Weise in die Registrierung eingefügt werden.

  • Es kann eine REG-Datei generiert werden, die mithilfe eines Registrierungs-Editors problemlos in die Systemregistrierung integriert werden kann.
  • Eine INF-Datei kann auch mit einem [AddReg]-Abschnitt erstellt werden, der die hinzuzufügenden Registrierungsinformationen enthält.
  • Regedt32.exe können verwendet werden, um die Informationen manuell zur Registrierung hinzuzufügen.

Der Scan Code Mapper hat mehrere Vor- und Nachteile.

Zu den Vorteilen gehören:

  • Der Mapper kann als einfache Behebung von Firmwarefehlern verwendet werden.
  • Häufig verwendete Tasten können der Tastatur hinzugefügt werden, indem Sie die Zuordnung in der Registrierung ändern. Schlüssel, die nicht häufig verwendet werden (z. B. die rechte STRG-TASTE), können null zugeordnet (entfernt) oder gegen andere Schlüssel ausgetauscht werden.
  • Wichtige Standorte können einfach geändert werden. Benutzer können den Speicherort häufig verwendeter Schlüssel einfach zu ihrem Vorteil anpassen.

Die folgenden Nachteile werden erkannt:

  • Nachdem die Zuordnung in der Registrierung gespeichert wurde, ist ein Systemneustart erforderlich, um sie zu aktivieren.
  • Die in der Registrierung gespeicherten Zuordnungen funktionieren auf Systemebene und gelten für alle Benutzer. Diese Zuordnungen können nicht so festgelegt werden, dass sie je nach aktuellem Benutzer unterschiedlich funktionieren.
  • Die aktuelle Implementierung schränkt die Funktionalität der Karte so ein, dass Zuordnungen immer für alle Tastaturen gelten, die mit dem System verbunden sind. Es ist derzeit nicht möglich, eine Karte auf Tastaturbasis zu erstellen.

Abfragen eines Mausgeräts

I8042prt unterstützt die folgende interne Gerätesteuerungsanforderung zum Abfragen von Informationen zu einem Mausgerät:

IOCTL_MOUSE_QUERY_ATTRIBUTES

Weitere Informationen zu allen Mausgerätesteuerungsanforderungen finden Sie unter Referenz zu Geräten für menschliche Schnittstellen.

Registrierungseinstellungen, die dem Mausklassentreiber zugeordnet sind

Im Folgenden ist eine Liste der Registrierungsschlüssel aufgeführt, die dem Mausklassentreiber zugeordnet sind.

[Schlüssel: HKLM\SYSTEM\CurrentControlSet\Services\Mouclass\Parameters]

  • MaximumPortsServiced – Wird unter Windows XP und höher nicht verwendet. Nur für Windows NT4.
  • PointerDeviceBaseName : Gibt den Basisnamen für die Geräteobjekte an, die vom Gerätetreiber der Mausklasse erstellt wurden.
  • ConnectMultiplePorts : Bestimmt, ob für jedes Geräteobjekt der Klasse ein oder mehrere Portgeräteobjekte vorhanden sind. Dieser Eintrag wird hauptsächlich von Gerätetreibern verwendet.
  • MouseDataQueueSize : Gibt die Anzahl der Mausereignisse an, die vom Maustreiber gepuffert werden. Es wird auch verwendet, um die Größe des internen Puffers des Maustreibers im nicht auslagerten Speicherpool zu berechnen.

Absolute Zeigegeräte

Für Geräte vom Typ GUID_CLASS_MOUSE der Funktionstreiber eines Geräts:

  • Verarbeitet gerätespezifische Eingaben.

  • Erstellt die MOUSE_INPUT_DATA Strukturen, die für MouseClassServiceCallback erforderlich sind.

  • Überträgt MOUSE_INPUT_DATA Strukturen an die Mouclass-Datenwarteschlange, indem MouseClassServiceCallback in der ISR-Vervollständigungsroutine aufgerufen wird.

Für ein absolutes Zeigegerät muss der Funktionstreiber des Geräts die LastX-, LastY- und Flags-Member der MOUSE_INPUT_DATA-Strukturen wie folgt festlegen:

  • Zusätzlich zum Dividieren des Geräteeingabewerts durch die maximale Funktion des Geräts skaliert der Treiber den Geräteeingabewert durch 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)
    
  • Der Treiber legt das MOUSE_MOVE_ABSOLUTE-Flag in Flags fest.

  • Wenn die Eingabe vom Fenster-Manager einem gesamten virtuellen Desktop zugeordnet werden soll, legt der Treiber das MOUSE_VIRTUAL_DESKTOP-Flag in Flags fest. Wenn das flag MOUSE_VIRTUAL_DESKTOP nicht festgelegt ist, ordnet der Fenster-Manager die Eingabe nur dem primären Monitor zu.

Im Folgenden wird anhand des Gerätetyps angegeben, wie diese besonderen Anforderungen für ein absolutes Zeigegerät implementiert werden:

  • HID-Geräte:

    Mouhid, der Windows-Funktionstreiber für HID-Mausgeräte, setzt diese speziellen Anforderungen automatisch um.

  • Geräte im PS/2-Stil:

    Ein Filtertreiber der oberen Ebene ist erforderlich. Der Filtertreiber stellt einen IsrHook-Rückruf und einen Klassendienstrückruf bereit. I8042prt ruft den IsrHook auf, um unformatierte Geräteeingaben zu verarbeiten, und ruft den Rückruf des Filterklassendiensts auf, um die Eingabe zu filtern. Der Rückruf des Filterklassendiensts ruft wiederum MouseClassServiceCallback auf. Die Kombination aus dem IsrHook-Rückruf und dem Klassendienstrückruf verarbeitet gerätespezifische Eingaben, erstellt die erforderlichen MOUSE_INPUT_DATA-Strukturen, skaliert die Geräteeingabedaten und legt das MOUSE_MOVE_ABSOLUTE-Flag fest.

  • Plug & Play COM-Portgeräte, die von Serenum aufgezählt werden:

    Ein Plug & Play Funktionstreiber ist erforderlich. Der Funktionstreiber erstellt die erforderlichen MOUSE_INPUT_DATA-Strukturen, skaliert die Geräteeingabedaten und legt das MOUSE_MOVE_ABSOLUTE-Flag fest, bevor MouseClassServiceCallback aufgerufen wird.

  • Geräte ohne Plug & Play COM-Port:

    Ein gerätespezifischer Funktionstreiber ist erforderlich. Der Funktionstreiber erstellt die erforderlichen MOUSE_INPUT_DATA-Strukturen, skaliert die Geräteeingabedaten und legt das MOUSE_MOVE_ABSOLUTE-Flag fest, bevor MouseClassServiceCallback aufgerufen wird.

  • Gerät auf einem nicht unterstützten Bus:

    Ein gerätespezifischer Funktionstreiber ist erforderlich. Der Funktionstreiber erstellt die erforderlichen MOUSE_INPUT_DATA-Strukturen, skaliert die Geräteeingabedaten und legt das MOUSE_MOVE_ABSOLUTE-Flag fest, bevor MouseClassServiceCallback aufgerufen wird.