共用方式為


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

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

  • 正確保護裝置物件。

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

  • 正確驗證裝置物件。

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

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

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

  • 驗證物件控制碼。

    接收物件控制碼做為輸入的驅動程式必須確認控制碼有效、可存取且屬於預期的類型。 如需使用物件控制碼的詳細資訊,請參閱下列主題:

    物件管理

    驗證物件控制碼失敗

  • 正確支援多處理器。

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

    同步處理技術

    多處理器環境中的錯誤

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

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

  • 驗證 IRP 輸入值。

    從可靠性和安全性的觀點來看,請務必驗證與 IRP 相關聯的所有值,例如緩衝區位址和長度。 下列主題提供驗證 IRP 輸入值的相關資訊:

    使用緩衝 I/O 的 DispatchReadWrite

    緩衝 I/O 中的錯誤

    使用直接 I/O 的 DispatchReadWrite

    直接 I/O 中的錯誤

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

    參考位址User-Space錯誤

  • 正確處理 I/O 堆疊。

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

  • 正確處理 IRP 完成作業。

    驅動程式絕對不能完成狀態值為 STATUS_SUCCESS 的 IRP,除非它確實支援並處理 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 的其他錯誤

使用驅動程式驗證器

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