디바이스 필터 드라이버 순서 지정

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 디바이스 드라이버를 고려합니다. 일반적인 구현에서는 함수 드라이버 바로 아래에 있는 하위 필터 드라이버를 사용하여 이 작업을 수행할 수 있습니다. 암호화 필터가 드라이버 작성자가 원하는 정확한 위치에 배치되도록 하기 위해 아래와 같이 선언적 필터를 사용할 수 있습니다.

기본 INF는 "암호화" 및 "모니터링"(기본값)이라는 두 가지 하위 필터 수준을 설정합니다. 이 예제의 "모니터링"(기본값)은 이 특정 디바이스에 대해 존재할 수 있는 하위 필터의 나머지 부분입니다. "암호화" 수준에 "Encrypt" 필터 드라이버를 명시적으로 배치하면 드라이버는 결과 디바이스 스택 순서가 다른 하위 필터 앞에 "Encrypt" 필터 드라이버를 배치하고 함수 드라이버 바로 다음에 배치되도록 합니다.

예제를 한 단계 더 살펴보겠습니다. 최신 버전의 드라이버가 나와서 작성자가 함수 드라이버에 대한 암호화를 기본으로 구축한 경우를 상상해 보세요. 이렇게 하면 별도의 "암호화" 필터 드라이버가 필요하지 않습니다. 작성자가 기본 INF에서 "암호화" 필터를 포함하는 수준을 제거하면 되며 드라이버가 업데이트되면 스택이 동적으로 다시 빌드됩니다.

필터가 존재하지 않는 명시적 수준에 있다고 선언하는 경우 필터는 디바이스 스택에서 끝나지 않습니다. 이 예제에서는 기본 INF가 업데이트되었으며 확장 INF가 동일하게 유지되더라도 결과 디바이스 스택은 기본 INF의 수준 선언에 포함되지 않았기 때문에 "암호화" 필터를 제외합니다.

기본 INF에서

기본 필터 수준

최종 필터 스택을 생성하기 위해 필터 정보의 모든 원본이 단일 목록에 병합됩니다. 디바이스 스택을 만들 때 병합 논리가 수행된다는 점에 유의해야 합니다. 새/업데이트된 기본 또는 확장 드라이버를 설치하여 새 필터를 추가하는 경우 설치 중에 디바이스가 다시 시작되고 새 필터 목록이 선택됩니다.

일부 필터 원본에는 위치 정보, 즉 레거시 UpperFilters/LowerFilters 레지스트리 값을 통해 추가된 필터 또는 위치 전용 선언적 구문(아래에서 설명)을 통해 추가된 필터가 없습니다.

위치 정보가 부족할 때 효과적인 병합을 지원하려면 기본 필터 수준인 기본 INF에서 추가 정보를 정의해야 합니다. 기본 필터 수준은 수준 또는 위치 정보가 없는 필터가 삽입되는 위치입니다.

예를 들어 필터 수준은 다음과 같이 기본 INF에 정의될 수 있습니다.

Level Order: A, B, C
DefaultFilterLevel: C

기본 수준을 최종 수준으로 지정하면 위치 정보가 없는 필터가 필터 목록에 추가됩니다. 또는 드라이버 작성자는 스택이 항상 수준 C에 명시적으로 등록된 필터로 끝나도록 할 수 있습니다.

Level Order: A, B, C
DefaultFilterLevel: B

기본 필터 수준이 B로 설정되므로 위치 정보가 없는 추가 필터는 A의 필터와 C 필터 사이에 삽입됩니다.

구문

필터 등록

자세한 내용은 INF DDInstall.Filters 섹션 AddFilter 지시문 설명서를 참조하세요.

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

FilterLevel OR FilterPosition은 다음 두 가지 방법 중 하나로 지정할 수 있습니다.

옵션 1:

[FilterSection]
FilterLevel=<LevelName>

옵션 2:

[FilterSection]
FilterPosition=Upper/Lower

이 작업은 Base 및 Extension INF 모두에서 수행할 수 있습니다.

[DDInstall.Filters]

FilterName 은 시스템의 서비스 이름입니다.

플래그 는 현재 사용되지 않으며 비워 두거나 0으로 설정해야 합니다.

FilterSection 은 필터를 설명하는 섹션입니다.

[필터 섹션]

필터 섹션은 FilterLevel 또는 FilterPosition이라는 두 지시문 중 하나만 포함해야 합니다.

FilterLevel은 기본 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 지시문