Freigeben über


AddDevice-Routinen in Funktions- oder Filtertreibern

Eine AddDevice-Routine in einer Funktion oder einem Filtertreiber sollte die folgenden Schritte ausführen:

  1. Rufen Sie IoCreateDevice auf, um ein funktionales oder filterfähiges Geräteobjekt (FDO oder Filter-DO) für das hinzugefügte Gerät zu erstellen.

    Geben Sie keinen DeviceName für das Geräteobjekt an, da dadurch die Sicherheit des PnP-Managers umgangen wird. Wenn eine Komponente im Benutzermodus eine symbolische Verbindung zum Gerät benötigt, registrieren Sie eine Geräteschnittstelle (siehe nächster Schritt unten). Wenn eine Kernelmoduskomponente einen Legacygerätenamen benötigt, muss der Treiber dem Geräteobjekt einen Namen geben, die Benennung wird jedoch nicht empfohlen.

    Schließen Sie FILE_DEVICE_SECURE_OPEN in den Parameter DeviceCharacteristics ein. Dieses Merkmal weist den E/A-Manager an, Sicherheitsüberprüfungen für das Geräteobjekt für alle offenen Anforderungen durchzuführen, einschließlich relativer Öffnungen und geöffneter nachgestellter Dateinamen.

  2. [optional] Erstellen Sie mindestens einen symbolischen Link zum Gerät.

    Rufen Sie IoRegisterDeviceInterface auf, um die Gerätefunktionalität zu registrieren und eine symbolische Verknüpfung zu erstellen, die Anwendungen oder Systemkomponenten zum Öffnen des Geräts verwenden können. Der Treiber sollte die Schnittstelle aktivieren, indem er IoSetDeviceInterfaceState aufruft , wenn er die IRP_MN_START_DEVICE-Anforderung verarbeitet. Weitere Informationen finden Sie unter Geräteschnittstellenklassen.

  3. Speichern Sie den Zeiger auf das PDO des Geräts in der Geräteerweiterung.

    Der PnP-Manager stellt einen Zeiger auf die PDO als PhysicalDeviceObject-Parameter für AddDevice bereit. Treiber verwenden den PDO-Zeiger in Aufrufen von Routinen wie IoGetDeviceProperty.

  4. Definieren Sie Flags in der Geräteerweiterung, um bestimmte PnP-Zustände des Geräts nachzuverfolgen, z. B. angehaltenes, entferntes und überraschend entferntes Gerät.

    Definieren Sie beispielsweise ein Flag, um anzugeben, dass eingehende IRPs gehalten werden sollen, während sich das Gerät in einem angehaltenen Zustand befindet. Erstellen Sie eine Warteschlange zum Halten von IRPs, wenn der Treiber nicht bereits über einen Mechanismus zum Anstehen von IRPs verfügt. Weitere Informationen finden Sie unter Warteschlangen- und Dequeuing-IRPs .

    Weisen Sie außerdem eine IO_REMOVE_LOCK-Struktur in der Geräteerweiterung zu, und rufen Sie IoInitializeRemoveLock auf, um diese Struktur zu initialisieren. Weitere Informationen finden Sie unter Verwenden von Sperren entfernen.

  5. Legen Sie das DO_BUFFERED_IO- oder DO_DIRECT_IO-Flagbit im Geräteobjekt fest, um den Puffertyp anzugeben, den der E/A-Manager für E/A-Anforderungen verwenden soll, die an den Gerätestapel gesendet werden. Treiber auf höherer Ebene ODER dieses Element mit dem gleichen Wert wie der nächstniedrige Treiber im Stapel, mit Ausnahme möglicherweise von Treibern der höchsten Ebene. Weitere Informationen finden Sie unter Initialisieren eines Geräteobjekts.

  6. Legen Sie bei Bedarf das Flag DO_POWER_INRUSH oder DO_POWER_PAGABLE für die Energieverwaltung fest. Treiber, die auslagerungsfähig sind, müssen das DO_POWER_PAGABLE-Flag festlegen. Die Geräteobjektflags werden in der Regel vom Bustreiber festgelegt, wenn er das PDO für das Gerät erstellt. Treiber höherer Ebene müssen jedoch möglicherweise gelegentlich die Werte dieser Flags in ihren AddDevice-Routinen ändern, wenn sie die FDO erstellen oder DO filtern. Weitere Informationen finden Sie unter Festlegen von Geräteobjektflags für die Energieverwaltung .

  7. Erstellen und/oder initialisieren Sie alle anderen Softwareressourcen, die der Treiber zum Verwalten dieses Geräts verwendet, z. B. Ereignisse, Drehsperren oder andere Objekte. (Hardwareressourcen, z. B. E/A-Ports, werden später als Reaktion auf eine IRP_MN_START_DEVICE Anforderung konfiguriert.)

    Da eine AddDevice-Routine in einem Systemthreadkontext unter IRQL = PASSIVE_LEVEL ausgeführt wird, kann jeder mit ExAllocatePoolWithTag für die ausschließliche Verwendung während der Initialisierung zugewiesener Arbeitsspeicher aus einem ausgelagerten Pool stammen, solange der Treiber das Gerät, das die Systemseitendatei enthält, nicht steuert. Eine solche Speicherzuordnung muss mit ExFreePool freigegeben werden, bevor AddDevice die Steuerung zurückgibt.

  8. Fügen Sie das Geräteobjekt an den Gerätestapel an (IoAttachDeviceToDeviceStack).

    Geben Sie im Parameter TargetDevice einen Zeiger auf das PDO des Geräts an.

    Speichern Sie den von IoAttachDeviceToDeviceStack zurückgegebenen Zeiger. Dieser Zeiger, der auf das Geräteobjekt des nächstniedrigen Treibers für das Gerät verweist, ist ein erforderlicher Parameter für IoCallDriver und PoCallDriver , wenn IRPs im Gerätestapel übergeben werden.

  9. Deaktivieren Sie das DO_DEVICE_INITIALIZING-Flag in der FDO oder filtern Sie DO mit einer Anweisung wie der folgenden:

    FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    
  10. Bereiten Sie sich darauf vor, PnP-IRPs für das Gerät zu verarbeiten (z. B. IRP_MN_QUERY_RESOURCE_REQUIREMENTS und IRP_MN_START_DEVICE).

Ein Treiber darf erst mit der Steuerung des Geräts beginnen, bis er eine IRP_MN_START_DEVICE erhält, die die Liste der Hardwareressourcen enthält, die dem Gerät vom PnP-Manager zugewiesen wurden.