為多個 Windows 版本建置 WDF 驅動程式

WDF 一律允許您建置驅動程式一次,並在多個版本的 Windows 上使用產生的二進位檔,但在 Windows 10 1803 版 (Redstone 4) 之前,這僅限於「在較舊版本上建置,在較新版本上執行」。從 Windows 10 1803 版開始,WDF 會新增「在較新版本上建置、在較舊版本上執行」,以及條件式執行的額外優點。 總結來說:

  • 現有:以舊版架構建置的二進位檔會在包含較新版本架構的 Windows 版本上執行,前提是主要版本相符。 例如,以 KMDF 1.9 (Windows 7) 建置的驅動程式會在 Windows 8 系統上執行, (KMDF 1.11) 。 在此範例中,驅動程式僅限於 KMDF 1.9 的功能。
  • 已新增:從 Windows 10 1803 版的 KMDF 1.25 版和 UMDF 2.25 版開始,您可以使用較新的架構版本建置驅動程式,並在舊版 Windows (上執行產生的驅動程式二進位檔,至少 Windows 10 版本 1803) 。 此外,驅動程式可以有條件地使用只能在較新的架構版本中使用的功能。

這表示您的驅動程式不僅會在未來的 Windows 版本上執行,因為它一律會執行,也會在過去的版本上執行,回到 Windows 10 1803 版。

執行此動作有兩個步驟:在 Visual Studio 中指定組建設定,並在叫用 API 或存取可能不存在的結構或字段之前執行運行時間檢查。

注意:此功能是選擇性的,而且驅動程式應該只啟用它來建置使用最新 WDF 功能的驅動程式,同時在沒有最新 WDF 功能的舊版 Windows 上仍可載入。

如果您未設定 版本次要 (目標版本) 版本次要 (最低必要) ,版本設定會維持與之前相同。

指定所需的最小值

Visual Studio 中的新組態設定如下:

  • 需要) KMDF 版本次要 (最低)
  • UMDF 版本次要 (最低必要)

根據這項變更,已更新兩個現有設定的名稱:

  • KMDF 版本次要 ->KMDF 版本次要 (目標版本)
  • UMDF 版本次要 ->UMDF 版本次要 (目標版本)

如果您未設定 [最低需求],Visual Studio 會針對 [目標版本 ] 和 [更新版本] 建置,而且不會提供舊版支援。 這符合舊 版次要 屬性的行為。

如果您設定 [ 必要最低],則適用下列需求:

  • 25 <= 最低必要 <= 目標版本
  • [組態屬性->驅動程序設定-> 一般] 中,將 設定 _NT_TARGET_VERSION0x0A000005 (RS4) 或更新版本。

檢查功能是否存在

在每次使用可能不存在的 API、結構或成員之前,您必須先呼叫下列其中一個宏,這些宏定義於 WdfFuncEnum.h 中:

BOOLEAN
WDF_IS_FUNCTION_AVAILABLE (
    FunctionName
    );

BOOLEAN
WDF_IS_STRUCTURE_AVAILABLE (
    StructName
    );

BOOLEAN
WDF_IS_FIELD_AVAILABLE (
    StructName,
    FieldName
    );

請思考一下下列範例。 當WDF v29 發行時,它會新增 API: WdfSomeNewFeature。 如果您將 [目標版本] 設定為 [29] 且 [ 最低需求 ] 設為 25,則產生的驅動程式會在任何從 25 到 29 (及更新版本的任何架構版本上載入,只要主要版本不會變更) 、如之前呼叫第 25 版 API,並在每次呼叫任何 v29 API 之前進行下列檢查:

if (WDF_IS_FUNCTION_AVAILABLE(WdfSomeNewFeature)) {
    WdfSomeNewFeature();
}

如果您沒有執行條件式檢查,您可能會看到下列專案:

  • 如果 API 傳回 NTSTATUS,呼叫會傳回失敗碼。
  • 如果 API 傳回 NTSTATUS 以外的任何專案:
    • KMDF:計算機錯誤檢查。
    • UMDF:WudfHost 進程損毀並出現 DriverStop 錯誤。
  • 如果已啟用驅動程式驗證器,驅動程式也會當機。 這有助於識別測試環境中的問題。
  • 存取結構或欄位) 時,無訊息記憶體損毀 (。

驅動程式當機包含失敗的驅動程式名稱、架構名稱和失敗的 API 索引。 您可以在 WdfFuncEnum.h 中查閱 WDFFUNCENUM 的值,以擷取 API 的名稱。

如需 WDF 之 Visual Studio 屬性的詳細資訊,請參閱 驅動程式專案的驅動程式模型設定屬性