當使用者模式應用程式呼叫原生系統服務常式的 Nt 或 Zw 版本時,系統呼叫機制會將呼叫執行程式設陷至核心模式。 為了指出參數值源自使用者模式,系統呼叫的設陷處理常式會將呼叫端執行緒物件中的 PreviousMode 欄位設定為 UserMode。 原生系統服務常式會檢查呼叫執行緒的 PreviousMode 欄位,以判斷參數是否來自使用者模式來源。
如果核心模式驅動程式呼叫原生系統服務常式,並將參數值傳遞至來自核心模式來源的常式,驅動程式必須確定目前執行緒物件中的 PreviousMode 欄位已設定為 KernelMode。
核心模式驅動程式可以在任意執行程的內容中執行,而此執行緒的 PreviousMode 欄位可能會設定為 UserMode。 在此情況下,核心模式驅動程式可以呼叫原生系統服務常式的 Zw 版本,以通知常式參數值來自受信任的核心模式來源。 Zw 呼叫會移至精簡包裝函數,這會覆寫目前執行緒物件中的 PreviousMode 值。 包裝函式會將 PreviousMode 設定為 KernelMode ,並呼叫常式的 Nt 版本。 從常式的 Nt 版本傳回時,包裝函式會還原執行緒物件的原始 PreviousMode 值,並傳回。
核心模式驅動程式可以直接呼叫原生系統服務常式的 Nt 版本。 當核心模式驅動程式處理可源自使用者模式或核心模式的 I/O 要求時,驅動程式可以呼叫常式的 Nt 版本,讓目前執行緒的 PreviousMode 值在呼叫期間保持不變。 NtXxx 常式會檢查呼叫執行緒的 PreviousMode 值,以判斷參數值是否來自使用者模式應用程式或核心模式元件,並據以對待它們。
如果核心模式驅動程式呼叫 NtXxx 常式,而目前執行緒物件中的 PreviousMode 值無法準確指出參數值是否來自使用者模式或核心模式來源,則可能會發生錯誤。
例如,假設核心模式驅動程式是在任意執行緒的內容中執行,而且此執行緒的 PreviousMode 值設定為 UserMode。 如果驅動程式將核心模式檔案控制碼傳遞至 NtClose 常式,此常式會檢查 PreviousMode 值,並決定控制碼必須是使用者模式控制碼。 當 NtClose 在使用者模式控制碼資料表中找不到控制碼時,它會傳回STATUS_INVALID_HANDLE錯誤碼。 同時,驅動程式會洩漏從未關閉的核心模式控制碼。
另一個範例,如果 NtXxx 常式的參數包含輸入或輸出緩衝區,且如果 PreviousMode = UserMode,常式會呼叫 ProbeForRead 或 ProbeForWrite 常式來驗證緩衝區。 如果緩衝區是在系統記憶體中配置,而不是在使用者模式記憶體中配置,則 ProbeForXxx 常式會引發異常狀況,而 NtXxx 常式會傳回STATUS_ACCESS_VIOLATION錯誤碼。
必要的話,驅動程式可以呼叫 ExGetPreviousMode 常式,從目前的執行程物件取得 PreviousMode 值。 或者,驅動程式可以從描述要求 I/O 作業的 IRP 結構讀取 RequestorMode 欄位。 RequestorMode 欄位包含來自要求作業之執行緒的 PreviousMode 值複本。