Inscription et mise en file d’attente d’une routine CustomTimerDpc
Un pilote peut inscrire une routine CustomTimerDpc en appelant les routines suivantes, généralement à partir de sa routine AddDevice :
KeInitializeDpc pour inscrire sa routine
KeInitializeTimer ou KeInitializeTimerEx pour configurer un objet de minuteur
Par la suite, le pilote peut appeler KeSetTimer ou KeSetTimerEx pour spécifier un délai d’expiration et ajouter l’objet minuteur à la file d’attente du minuteur du système. Lorsque l’heure d’expiration est atteinte, le système supprime la file d’attente de l’objet du minuteur et appelle la routine CustomTimerDpc . La figure suivante illustre ces appels.
Comme le montre la figure précédente, le pilote doit fournir du stockage pour un objet DPC et un objet minuteur. La plupart des pilotes fournissent le stockage de ces objets dans une extension de périphérique ou dans d’autres mémoires résidentes allouées par le pilote.
Dans l’appel à KeSetTimer, le pilote passe des pointeurs vers les objets Dpc et Timer , ainsi qu’un DueTime exprimé en unités de 100 nanosecondes, comme illustré dans la figure précédente. Une valeur positive pour DueTime spécifie une heure d’expiration absolue (depuis le 1er janvier 1601) à laquelle la routine CustomTimerDpc doit être appelée. Une valeur négative pour DueTime spécifie un délai d’expiration relatif.
Étant donné qu’un minuteur absolu expire à une heure système spécifique, la durée d’attente d’un minuteur absolu n’est pas affectée si l’heure système change avant l’expiration du minuteur. En revanche, un minuteur relatif expire toujours après l’expiration du nombre spécifié d’unités de temps, quelles que soient les modifications apportées à l’heure système absolue.
Pour appeler une routine CustomTimerDpc à plusieurs reprises, utilisez KeSetTimerEx pour définir le minuteur et spécifier un intervalle périodique dans le paramètre Period . KeSetTimerEx est tout comme KeSetTimer, à l’exception de ce paramètre supplémentaire.
Comme indiqué dans la figure précédente, l’appel à KeSetTimer ou KeSetTimerEx met en file d’attente l’objet du minuteur pour un intervalle spécifié comme suit :
À l’expiration de DueTime , l’objet minuteur est mis en file d’attente et défini à l’état Signaled.
Si chaque processeur de la machine exécute actuellement du code à un IRQL supérieur ou égal à DISPATCH_LEVEL, l’objet DPC associé à l’objet minuteur est placé dans une file d’attente DPC. Sinon, la routine CustomTimerDpc est appelée.
Si l’objet DPC se trouvait déjà dans la file d’attente lorsque l’intervalle DueTime a expiré, la routine CustomTimerDpc est appelée dès que l’IRQL sur n’importe quel processeur de l’ordinateur est inférieur à DISPATCH_LEVEL.
Notes
La routine CustomTimerDpc , comme toutes les routines DPC, est appelée dans IRQL = DISPATCH_LEVEL. Pendant qu’une routine DPC s’exécute, tous les threads ne peuvent pas s’exécuter sur le même processeur. Les développeurs de pilotes doivent soigneusement concevoir leurs routines CustomTimerDpc pour qu’elles s’exécutent aussi brièvement que possible.
L’intervalle de temps le plus petit qui peut être spécifié pour KeSetTimer et KeSetTimerEx est d’environ dix millisecondes, de sorte qu’un pilote peut utiliser une routine CustomTimerDpc pour minuter des intervalles plus petits qu’une routine IoTimer , qui est exécutée une fois par seconde, peut gérer.
Une seule instanciation d’un objet de minuteur particulier peut être mise en file d’attente à tout moment. L’appel de KeSetTimer ou KeSetTimerEx avec le même pointeur d’objet Timer annule l’objet minuteur mis en file d’attente et le réinitialise.
La configuration d’une routine CustomTimerDpc revient exactement à configurer une routine CustomDpc , avec une étape supplémentaire pour initialiser l’objet minuteur. En fait, leurs prototypes sont identiques, mais la routine CustomTimerDpc ne peut pas utiliser les deux pointeurs SystemArgument déclarés dans son prototype.