Freigeben über


Registrieren und Warteschlangen einer CustomTimerDpc-Routine

Ein Treiber kann eine CustomTimerDpc-Routine registrieren, indem er die folgenden Routinen aufruft, in der Regel aus seiner AddDevice-Routine :

  1. KeInitializeDpc , um seine Routine zu registrieren

  2. KeInitializeTimer oder KeInitializeTimerEx zum Einrichten eines Timerobjekts

Anschließend kann der Treiber KeSetTimer oder KeSetTimerEx aufrufen, um eine Ablaufzeit anzugeben und das Timerobjekt der Timerwarteschlange des Systems hinzuzufügen. Wenn die Ablaufzeit erreicht ist, entfernt das System das Timerobjekt und ruft die CustomTimerDpc-Routine auf. Die folgende Abbildung veranschaulicht diese Aufrufe.

Diagramm, das die Verwendung von Timer- und dpc-Objekten für eine customtimerdpc-Routine veranschaulicht.

Wie in der vorherigen Abbildung gezeigt, muss der Treiber Speicher sowohl für ein DPC-Objekt als auch für ein Timerobjekt bereitstellen. Die meisten Treiber stellen den Speicher für diese Objekte in einer Geräteerweiterung oder in einem anderen vom Treiber zugewiesenen, residenten Speicher bereit.

Beim Aufruf von KeSetTimer übergibt der Treiber Zeiger auf die Dpc - und Timer-Objekte sowie ein DueTime-Objekt , ausgedrückt in Einheiten von 100 Nanosekunden, wie in der vorherigen Abbildung dargestellt. Ein positiver Wert für DueTime gibt eine absolute Ablaufzeit (seit dem 1. Januar 1601) an, zu der die CustomTimerDpc-Routine aufgerufen werden soll. Ein negativer Wert für DueTime gibt eine relative Ablaufzeit an.

Da ein absoluter Timer zu einer bestimmten Systemzeit abläuft, ist die Wartezeit eines absoluten Timers nicht betroffen, wenn sich die Systemzeit ändert, bevor der Timer abläuft. Andererseits läuft ein relativer Timer immer ab, nachdem die angegebene Anzahl von Zeiteinheiten verstrichen ist, unabhängig von Änderungen an der absoluten Systemzeit.

Um eine CustomTimerDpc-Routine wiederholt aufzurufen, verwenden Sie KeSetTimerEx , um den Timer festzulegen und ein wiederkehrendes Intervall im Period-Parameter anzugeben. KeSetTimerEx ist genau wie KeSetTimer , mit Ausnahme dieses zusätzlichen Parameters.

Wie in der vorherigen Abbildung gezeigt, wird das Timerobjekt beim Aufruf von KeSetTimer oder KeSetTimerEx für ein angegebenes Intervall wie folgt in die Warteschlange eingereiht:

  1. Wenn DueTime abläuft, wird das Timerobjekt in der Warteschlange entfernt und auf den Signalzustand festgelegt.

  2. Wenn auf jedem Prozessor auf dem Computer derzeit Code in einer IRQL ausgeführt wird, die größer oder gleich DISPATCH_LEVEL ist, wird das dem Timerobjekt zugeordnete DPC-Objekt in einer DPC-Warteschlange platziert. Andernfalls wird die CustomTimerDpc-Routine aufgerufen.

  3. Wenn sich das DPC-Objekt bereits in der Warteschlange befand, als das DueTime-Intervall abgelaufen ist, wird die CustomTimerDpc-Routine aufgerufen, sobald die IRQL auf einem Prozessor auf dem Computer unter DISPATCH_LEVEL fällt.

    Hinweis

    Die CustomTimerDpc-Routine wird wie alle DPC-Routinen unter IRQL = DISPATCH_LEVEL aufgerufen. Während eine DPC-Routine ausgeführt wird, werden alle Threads daran gehindert, auf demselben Prozessor auszuführen. Treiberentwickler sollten ihre CustomTimerDpc-Routinen sorgfältig so entwerfen, dass sie so lange wie möglich ausgeführt werden.

Das kleinste Zeitintervall, das für KeSetTimer und KeSetTimerEx angegeben werden kann, beträgt etwa zehn Millisekunden, sodass ein Treiber eine CustomTimerDpc-Routine verwenden kann, wenn kleinere Intervalle als eine IoTimer-Routine , die einmal pro Sekunde ausgeführt wird, durchgeführt werden kann.

Nur eine Instanziierung eines bestimmten Timerobjekts kann jederzeit in die Warteschlange eingereiht werden. Wenn KeSetTimer oder KeSetTimerEx erneut mit demselben Timer-Objektzeiger aufgerufen wird, wird das Zeitgeberobjekt in der Warteschlange abgebrochen und zurückgesetzt.

Das Einrichten einer CustomTimerDpc-Routine ähnelt dem Einrichten einer CustomDpc-Routine mit einem zusätzlichen Schritt zum Initialisieren des Timerobjekts. Tatsächlich sind ihre Prototypen identisch, aber die CustomTimerDpc-Routine kann nicht die beiden systemArgument-Zeiger verwenden, die in ihrem Prototyp deklariert sind.