共用方式為


建立可靠的 Kernel-Mode 驅動程式

驅動程式佔核心模式中執行之程式代碼總數的顯著百分比。 核心模式驅動程序實際上就是作系統的元件。 因此,可靠且安全的驅動程式可大幅提升作系統的整體可信度。 若要建立可靠的內核模式驅動程式,請遵循下列指導方針:

  • 正確保護裝置物件。

    使用者存取系統的驅動程式和裝置是由系統指派給裝置對象的安全性描述項所控制。 系統通常會在安裝裝置時設定裝置安全性參數。 如需詳細資訊,請參閱 建立安全裝置安裝。 有時候,驅動程式適合參與控制其裝置的存取權。 如需詳細資訊,請參閱 保護裝置物件

  • 正確驗證裝置物件。

    如果驅動程式建立了多種類型的裝置物件,則必須檢查每個 IRP 接收到的物件類型。 如需詳細資訊,請參閱 無法驗證裝置物件

  • 使用「安全字串」函式。

    操作字串時,驅動程式設計師應該使用安全的字串函式,而不是 C/C++ 語言執行時函式庫提供的字串函式。 如需詳細資訊,請參閱使用安全字串函式

  • 驗證物件句柄。

    接收物件句柄做為輸入的驅動程序必須確認句柄有效、可存取且屬於預期的型別。 如需有關使用物件句柄的資訊,請參閱下列主題:

    物件管理

    未能驗證物件控制代碼

  • 正確支援多處理器。

    絕對不要假設您的驅動程式只會在單一處理器系統上執行。 如需可用來確保驅動程式在多處理器系統上正常運作的程式設計技術相關信息,請參閱下列主題:

    同步處理技術

    在多處理器環境中的錯誤

  • 正確處理驅動程序狀態。

    請務必一律確認您的驅動程序處於您假設的狀態。 例如,如果驅動程式收到 IRP,它是否已經為相同類型的 IRP 提供服務? 如果驅動程式未檢查此情況,可能會遺失第一個 IRP。 如需詳細資訊,請參閱 無法檢查驅動程式的狀態

  • 驗證 IRP 輸入值。

    從可靠性和安全性的觀點來看,驗證與 IRP 相關聯的所有值,例如緩衝區地址和長度,這一點非常重要。 下列主題提供驗證 IRP 輸入值的相關信息:

    DispatchReadWrite 使用緩衝 I/O

    緩衝 I/O 中的錯誤

    DispatchReadWrite 使用 Direct I/O

    直接 I/O 中的錯誤

    I/O 控制碼的安全性問題

    參考 User-Space 位址中的 錯誤

  • 正確處理 I/O 堆疊。

    將 IRP 傳遞至驅動程式堆疊時,驅動程式務必呼叫 IoSkipCurrentIrpStackLocationIoCopyCurrentIrpStackLocationToNext 來設定下一個驅動程式的 I/O 堆疊位置。 請勿撰寫直接將一個 I/O 堆疊位置複製到下一個的程式代碼。

  • 正確地處理 IRP 的完成操作。

    除非驅動程式實際支援並處理 IRP,否則驅動程式絕對不能完成狀態值為 STATUS_SUCCESS 的 IRP。 如需正確處理 IRP 完成作業的方法的相關資訊,請參閱 完成 IRP

  • 正確處理 IRP 取消作業。

    取消作業可能很難正確撰寫程式代碼,因為它們通常以異步方式執行。 處理取消作業的程式代碼問題可能會長時間被忽視,因為此程式代碼通常不會在執行中的系統中經常執行。

    請務必閱讀並瞭解 取消 IRP下提供的所有資訊。 請特別注意 同步處理 IRP 取消取消 IRP 時的注意事項

    若要避免與取消作業相關聯的同步處理問題,其中一個方法是實作 安全取消 IRP 佇列。 可安全取消的 IRP 佇列是從 Windows XP 及其後續版本的作業系統引入的驅動程式管理佇列,但也向後相容至早期版本。

  • 正確處理 IRP 清除和關閉作業。

    請務必瞭解 IRP_MJ_CLEANUPIRP_MJ_CLOSE 要求之間的差異。 清理請求會在應用程式關閉檔案物件上的所有檔案句柄之後到達,但有時在所有 I/O 請求都完成之前。 關閉要求會在檔案物件的所有 I/O 操作要求都完成或取消後抵達。 如需詳細資訊,請參閱下列主題:

    DispatchCreate、DispatchClose 和 DispatchCreateClose 例程

    DispatchCleanup 清理例程

    處理清除和關閉作業 錯誤

如需正確處理 IRP 的詳細資訊,請參閱 處理 IRP中的其他錯誤。

使用驅動程式驗證器

驅動程式驗證器 是您用來確保驅動程式可靠性的最重要工具。 驅動程式驗證器可以檢查各種常見的驅動程序問題,包括本節中討論的一些問題。 不過,使用驅動程式驗證器並不會取代謹慎、深思熟慮的軟體設計。