驅動程式可以藉由呼叫下列例程來註冊 CustomTimerDpc 例程,通常是從其 AddDevice 例程:
KeInitializeDpc 以註冊其例程
KeInitializeTimer 或 KeInitializeTimerEx 來設定定時器物件
之後,驅動程式可以呼叫 KeSetTimer 或 KeSetTimerEx 來指定到期時間,並將定時器物件新增至系統的定時器佇列。 到達到期時間時,系統會清除定時器物件,並呼叫 CustomTimerDpc 例程。 下圖說明這些呼叫。
如上圖所示,驅動程式必須同時為 DPC 物件和定時器物件提供記憶體。 大部分驅動程式會在 裝置擴充 或其他驅動程式配置的常駐記憶體中,提供這些物件的儲存空間。
在對 KeSetTimer 的呼叫中,驅動程式會將指標傳遞至 Dpc 和 Timer 物件,以及以 100 奈秒為單位表示的 DueTime ,如圖所示。 DueTime 的正值指定絕對到期時間(自 1601 年 1 月 1 日起),應該呼叫 CustomTimerDpc 例程。 DueTime 的負值會指定相對到期時間。
因為絕對定時器在特定系統時間到期,因此如果系統時間在定時器到期前變更,絕對定時器的等候持續時間不會受到影響。 另一方面,不論絕對系統時間的變更為何,相對定時器一律會在指定的時間單位數過後到期。
若要重複叫用 CustomTimerDpc 例程,請使用 KeSetTimerEx 來設定定時器,並在 Period 參數中指定週期性間隔。 KeSetTimerEx 就像 KeSetTimer ,但這個額外的參數除外。
如上圖所示,對 KeSetTimer 或 KeSetTimerEx 的呼叫會將定時器物件排入佇列,其間隔如下:
DueTime 到期時,定時器物件會清除佇列,並設定為 Signaled 狀態。
如果機器中的每個處理器目前在 IRQL 上執行的程式代碼大於或等於DISPATCH_LEVEL,則與定時器對象相關聯的 DPC 物件會放入 DPC 佇列中。 否則,會呼叫 CustomTimerDpc 例程。
如果 DPC 物件在 DueTime 間隔過期時已經在佇列中,只要機器中任何處理器上的 IRQL 低於DISPATCH_LEVEL,就會呼叫 CustomTimerDpc 例程。
備註
CustomTimerDpc 例程,就像所有 DPC 例程一樣,會在 IRQL = DISPATCH_LEVEL呼叫。 當 DPC 例程執行時,所有線程都無法在同一個處理器上執行。 驅動程式開發人員應該仔細設計其 CustomTimerDpc 例程,以便盡可能短暫地執行。
可以指定給 KeSetTimer 和 KeSetTimerEx 的最小時間間隔大約是十毫秒,因此當計時比每秒執行一次 IoTimer 例程較小的間隔時,驅動程式可以使用 CustomTimerDpc 例程。
任何時刻只能將特定定時器物件的具現化排入佇列。 使用相同的 Timer 物件指標再次呼叫 KeSetTimer 或 KeSetTimerEx 會取消佇列定時器物件並重設它。
設定 CustomTimerDpc 例程與設定 CustomDpc 例程完全相同,另外還有一個步驟來初始化定時器物件。 事實上,其原型完全相同,但 CustomTimerDpc 例程無法使用在其原型中宣告的兩個 SystemArgument 指標。