裝置篩選驅動程式排序

Microsoft 已開發宣告式新增篩選的方法,方法是表示篩選的意圖,而不是堆棧位置,稱為裝置篩選驅動程式排序。

裝置篩選驅動程式排序的需求

在 Windows 10 1903 版之前,註冊裝置篩選驅動程式的唯一支援方式是使用 AddReg 指示詞) 新增登錄專案 (。 不過,這個登錄操作方法不會提供彈性來指定確切登錄特定篩選 的位置

使用 AddReg 指示詞篩選註冊只會將篩選附加至篩選清單的結尾。 此方法會使用值清單,其中順序很重要,並決定載入篩選條件的堆疊位置。

使用單一排序值清單較不理想,特別是當 AddReg附加至結尾時,因為當多個驅動程式將篩選新增至相同裝置時,會產生負面結果。

在涉及至少一個 擴充功能 INF 的案例中,如果 INF 不正確地使用 AddReg (,換句話說不會使用附加旗標) ,他們可以抹除由不同 INF 新增的篩選。

此外,多個擴充功能 INF 可能會新增篩選,而這些篩選條件的相對順序可能很重要;不過,隨插即用 (PnP) 平臺並不保證延伸模組的安裝順序。 結果是「附加」的順序不保證。

實作裝置篩選驅動程式排序

為了提供彈性宣告式方法來註冊裝置篩選,Microsoft 已藉由表達篩選的意圖,而不是堆棧位置,來開發宣告式新增篩選的方法。 解決方案提供函式驅動程式作者能夠在其 INF 中表達一 組已排序的位置, (稱為層級) 篩選條件可能會自行註冊。

除了特定層級之外,篩選條件也可以以宣告方式註冊為層或較低層級篩選。

基礎結構是以新的篩選註冊方法為基礎,以判斷裝置堆疊中要包含哪些順序驅動程式。 新方法不會中斷新增篩選的舊方法相容性。 不過,它可讓新的篩選移至更強固且有彈性的註冊機制。

方法的啟用方式是讓基底 INF 定義一或多個「層級」的已排序列表。 基底 INF 和任何擴充功能 INF 都可能會透過新的 INF 指示詞註冊宣告式篩選,以指定篩選所屬的服務名稱和層級。 每個上限和下層篩選都會以各自的已排序層級清單來表示。

這些上層和下層篩選清單會依層級排序所有篩選驅動程式來建立。 每個層級內的篩選順序都應該視為 任意,因為特定層級內的篩選順序無法採用相依性。 在必須 保證兩個篩選條件的相對順序的情況下,它們應該註冊到不同的層級。

請考慮下列裝置驅動程式範例:

裝置驅動程式的安裝顯示為裝置堆疊順序,可合併篩選驅動程式清單,同時遵守所需的位置和順序。

裝置驅動程式的基底 INF 會宣告兩個上限篩選層級 A 和 B (,依該順序) 。 在基底 INF 的相關聯擴充功能 INF 中,會將兩個篩選新增至這兩個層級。

安裝設備驅動器的結果是裝置堆疊順序,可合併篩選驅動程式清單,同時遵守所需的位置和順序。 產生的裝置堆疊順序可確保放置於 「A」 層級中的任何篩選都位於 「B」 層級中的任何篩選之前。 不過,在每個層級內,順序是任意的。

如範例所示,Filter3 可能位於 Filter5 之前,或可能位於 Filter5 之後。 在任何情況下,Filter3 和 Filter5 都會出現在下一個層級 “B” 的篩選之前。

設計可針對篩選條件註冊的一系列層級時,而不是為了排序而建立一系列層級時,層級應該命名並排序,使其對應至篩選的意圖。 例如,I/O 裝置可能會定義應該註冊任何加密篩選的層級 加密。 這可讓篩選的意圖更容易理解及管理,並讓堆疊更強固,以防止函式驅動程式的重大變更。

注意

即使沒有基底 INF 所定義的層級,宣告式篩選也可以註冊為上層或較低層級。 未定義層級時,這在邏輯上相當於將篩選附加至 UpperFilters/LowerFilters 登錄值的結尾。 定義層級時,其中一個層級必須標示為基底驅動程式中的預設層級,在此情況下,篩選會註冊到該層級。

案例

請考慮 I/O 裝置驅動程式,以加密透過堆疊傳入的數據。 一般實作可能會使用函式驅動程式正下方的較低篩選驅動程式來完成這項作業。 為了確保加密篩選器放在驅動程式作者所需的確切位置,他們可以使用宣告式篩選,如下所示:

此圖顯示,藉由明確地將 「加密」篩選驅動程式放在「加密」層級,驅動程式可確保產生的裝置堆疊順序會將「加密」篩選驅動程式放在任何其他較低篩選器之前,並緊接在函式驅動程序之後。

Base INF 會建立兩個較低層級的篩選,「加密」和「監視」 (預設) 。 在此範例中,「監視」 (預設) 是此特定裝置可能存在的其餘篩選條件。 藉由明確地將 「Encrypt」 篩選驅動程式放在 「加密」層級,驅動程式可確保產生的裝置堆疊順序會將「加密」篩選驅動程式放在任何其他較低篩選之前,並緊接在函式驅動程序之後。

讓我們進一步進行範例。 假設有較新版本的驅動程序出現,而且作者已對函式驅動程式內建加密。 這可移除個別「加密」篩選驅動程式的需求。 作者只需要從基底 INF 移除包含「加密」篩選的層級,並在驅動程式更新時,再次動態建置堆棧。

如果篩選條件將本身宣告為不存在的明確層級,則篩選條件最終不會出現在裝置堆疊中。 在此範例中,基底 INF 已更新,即使擴充功能 INF 維持不變,產生的裝置堆疊會排除「加密」篩選,因為它未包含在基底 INF 的層級宣告中。

從基底 INF 移除包含 「Encrypt」 篩選層級的圖表

默認篩選層級

若要產生最終篩選堆疊,篩選資訊的所有來源都會合併成單一清單。 請務必注意,在 建立裝置堆疊時 ,會執行合併邏輯。如果藉由安裝新的/更新基底或擴充功能驅動程式來新增新的篩選,裝置將會在安裝期間重新啟動,並挑選新的篩選清單。

某些篩選來源缺少任何位置資訊,也就是透過舊版 UpperFilters/LowerFilters 登錄值新增的篩選,或透過下方討論的僅限位置宣告式語法 (,) 討論。

若要在缺少位置資訊時支援有效的合併,基礎 INF 必須定義額外的資訊片段:預設篩選層級。 默認篩選層級是插入篩選條件、缺少層級或位置資訊的位置。

例如,篩選層級可以在基底 INF 中定義為:

Level Order: A, B, C
DefaultFilterLevel: C

將預設層級指定為最終層級,表示任何缺少位置資訊的篩選都會 附加 至篩選清單。 或者,驅動程式作者可能想要讓堆疊一律以明確註冊至層級 C 的篩選結束:

Level Order: A, B, C
DefaultFilterLevel: B

由於預設篩選層級設定為 B,因此在 A 篩選條件與 C 篩選之間插入任何沒有位置資訊的額外篩選。

Syntax

註冊篩選

如需詳細資訊,請參閱 INF DDInstall.Filters 一節AddFilter 指示 詞檔。

[DDInstall.Filters]
AddFilter = <FilterName>, [Flags], FilterSection

FilterLevel OR FilterPosition 可以透過下列兩種方式之一來指定:

選項 1:

[FilterSection]
FilterLevel=<LevelName>

選項 2:

[FilterSection]
FilterPosition=Upper/Lower

可以在基底 和延伸模組 INF 中完成。

[DDInstall.Filters]

FilterName 是系統上服務的名稱。

旗標 目前未使用,且應該保留空白或設定為 0。

FilterSection 是描述篩選的區段。

[篩選區段]

篩選區段必須包含下列兩個指示詞之一: FilterLevelFilterPosition

FilterLevel 是將裝置篩選插入堆疊的特定位置,由Base INF所定義。  在每個層級內,篩選的順序是任意的。

當類別有一個要插入的第三方篩選的特定位置時,就會使用 FilterPosition

定義篩選層級

[DDInstall.HW]
AddReg = FilterLevel_Definition

[FilterLevel_Definition]
HKR,,UpperFilterLevels,%REG_MULTI_SZ%,"LevelA","LevelB","LevelC"
HKR,,UpperFilterDefaultLevel,,"LevelC"

HKR,,LowerFilterLevels,%REG_MULTI_SZ%,"LevelD","LevelE","LevelF"
HKR,,LowerFilterDefaultLevel,,"LevelE"

這隻能由 基底 驅動程式完成。

您可以藉由查詢下列屬性來擷取特定裝置的完整宣告式篩選清單:

DEVPKEY_Device_CompoundUpperFilters
DEVPKEY_Device_CompoundLowerFilters

舊版對等篩選註冊

讓我們來看看如何完成嘗試透過 INF 新增上限篩選的舊版方法:

[DDInstall.HW]
AddReg = Filters

[Filters]
HKR,,"UpperFilters", 0x00010008, "MyFilter"

此語法會將 「MyFilter」 新增至上限篩選清單的結尾。

透過引進的新語法,上述區段的邏輯上類似:

[DDInstall.Filters]
AddFilter = MyFilter,,MyUpperFilterInstall

[MyUpperFilterInstall]
FilterPosition = Upper

這會指定應該將篩選 「MyFilter」 新增至上方篩選清單。 如果基底 INF 已指定篩選層級,則使用 FilterPosition 會在該位置的預設層級中註冊篩選。

如果未指定篩選層級,此篩選條件會依任意順序註冊為上限篩選。

另請參閱

INF DDInstall.Filters 區段

AddFilter 指示詞