개체 관리
이 섹션에서는 WFP(Windows 필터링 플랫폼) API 개체 형식의 올바른 사용에 대해 설명합니다.
세션
WFP API는 세션 지향적이며 대부분의 함수 호출은 세션 컨텍스트 내에서 이루어집니다. FwpmEngineOpen0을 호출하여 새 클라이언트 세션을 만듭니다. 클라이언트가 FwpmEngineClose0 을 호출하거나 클라이언트 프로세스가 종료되면 세션이 종료됩니다. 의도적으로 또는 RPC 런다운에 의해 세션이 제거되면 BFE(기본 필터링 엔진)는 먼저 기존 트랜잭션을 중단합니다.
새 세션을 만들 때 호출자는 FWPM_SESSION_FLAG_DYNAMIC 플래그를 FwpmEngineOpen0에 전달하여 동적 세션을 만들 수 있습니다. 동적 세션 중에 추가된 모든 개체는 세션이 종료되면 자동으로 삭제됩니다.
트랜잭션
WFP API는 트랜잭션이며 대부분의 함수 호출은 트랜잭션의 컨텍스트 내에서 이루어집니다. 호출자는 FwpmTransactionBegin0, FwpmTransactionCommit0 및 FwpmTransactionAbort0 을 사용하여 트랜잭션을 명시적으로 제어할 수 있습니다. 그러나 명시적 트랜잭션 외부에서 함수 호출이 수행되면 암시적 트랜잭션 내에서 실행됩니다. 트랜잭션이 진행 중인 경우 세션이 종료되면 자동으로 중단됩니다. 암시적 트랜잭션은 강제로 중단되지 않습니다.
트랜잭션은 읽기 전용이거나 읽기/쓰기가 가능하며 엄격한 ACID(Atomic Consistent Isolated Durable) 의미 체계를 적용합니다.
각 클라이언트 세션은 한 번에 하나의 트랜잭션만 진행 중일 수 있습니다. 호출자가 첫 번째 트랜잭션을 커밋하거나 중단하기 전에 두 번째 트랜잭션을 시작하려고 하면 BFE는 오류를 반환합니다.
트랜잭션 과정에서 작업이 실패하면 트랜잭션의 전체 상태에 영향을 주지 않습니다. 예를 들어 클라이언트가 트랜잭션을 시작하고 네 번째 호출이 실패하기 전에 FwpmFilterAdd0 을 세 번 호출한다고 가정합니다. 이제 클라이언트에 다음 옵션이 있습니다.
- 트랜잭션을 중단하면 필터가 추가되지 않습니다.
- 트랜잭션을 커밋하면 처음 세 개의 필터가 추가됩니다.
- 실패한 FwpmFilterAdd0을 다시 시도하는 등 더 많은 작업을 계속합니다.
트랜잭션을 시작할 때 BFE는 세션의 txnWaitTimeoutInMSec 이 만료되어 잠금을 획득할 때까지 기다립니다. 이 시간 내에 잠금을 획득하지 않으면 잠금 획득(및 FwpmTransactionBegin0 호출)이 실패합니다. 이렇게 하면 클라이언트가 무기한으로 응답하지 못합니다. 클라이언트가 잠금 시간 제한을 지정하지 않은 경우 기본값은 15초입니다.
각 트랜잭션에는 잠금 시간 제한도 있습니다. 잠금을 소유할 수 있는 최대 시간입니다. 소유자가 이 시간 내에 잠금을 해제하지 않으면 트랜잭션이 강제로 중단되어 잠금이 해제됩니다. 잠금 시간 제한을 구성할 수 없습니다. 커널 모드 호출자에게는 무한하고 사용자 모드 호출자는 1시간입니다. 트랜잭션이 강제로 중단되면 해당 트랜잭션 내에서 수행된 다음 호출은 FWP_E_TXN_ABORTED 실패합니다.
개체 수명
개체는 가능한 4개의 수명 중 하나를 가질 수 있습니다.
- 동적 - 개체는 동적 세션 핸들을 사용하여 추가된 경우에만 동적입니다. 동적 개체는 삭제되거나 소유 세션이 종료될 때까지 라이브로 유지됩니다.
- Static - 개체는 기본적으로 정적입니다. 정적 개체는 삭제되거나 BFE가 중지되거나 시스템이 종료될 때까지 라이브로 작동합니다.
- 영구 - 적절한 FWPM_*_FLAG_PERSISTENT 플래그를 Fwpm*Add0 함수에 전달하여 영구 개체를 만듭니다. 영구 개체는 삭제될 때까지 라이브로 진행됩니다.
- 기본 제공 - 기본 제공 개체는 BFE에 의해 미리 정의되며 추가 또는 삭제할 수 없습니다. 그들은 영원히 살고 있습니다.
커널 모드 계층의 필터는 적절한 플래그를 FwpmFilterAdd0에 전달하여 부팅 시간 필터로 표시할 수 있습니다. 부팅 시간 필터는 TCP/IP 드라이버가 시작될 때 시스템에 추가되고 BFE가 초기화를 완료하면 제거됩니다. BFE가 시작될 때 영구 개체가 추가됩니다.
대부분의 경우 정책 공급자가 공급자를 사용하지 않도록 설정한 경우 영구 정책을 적용하지 않을 수 있습니다. 공급자를 추가할 때 호출자는 선택적 Windows 서비스 이름을 지정할 수 있습니다. 영구 개체를 추가할 때 호출자는 필요에 따라 해당 개체를 "소유"하는 공급자를 지정할 수 있습니다. 서비스 시작 시 BFE는 공급자와 연결되지 않았거나 연결된 공급자에 Windows 서비스 이름이 없거나 연결된 Windows 서비스가 자동 시작으로 설정된 경우에만 시스템에 영구 개체를 추가합니다.
개체 연결
일부 개체에는 다른 개체에 대한 참조가 있습니다. 예를 들어 필터는 항상 계층을 참조하며 설명선 및 공급자 컨텍스트를 참조할 수 있습니다. 개체는 수명이 더 짧을 수 있는 개체를 참조할 수 없습니다. 따라서 동적 개체는 다른 세션의 동적 개체를 참조할 수 없습니다. 정적 개체는 동적 개체를 참조할 수 없습니다. 영구 개체는 동적 개체, 정적 개체 또는 다른 공급자가 소유한 영구 개체를 참조할 수 없습니다.
개체를 참조하는 모든 개체가 처음 삭제될 때까지는 개체를 삭제할 수 없습니다.
LUID 및 GUID
모든 사용자 모드 WFP API 개체(FWPM)는 GUID(Globally Unique Identifier)로 식별되고 GUID를 통해 다른 개체를 참조합니다. GUID는 개체 형식 내에서만 고유해야 합니다. 예를 들어 필터와 공급자 컨텍스트는 동일한 GUID를 가질 수 있지만 두 개의 필터는 사용할 수 없습니다. 새 개체를 추가할 때 호출자는 개체의 GUID 를 할당하거나 초기화되지 않은 상태로 두고 BFE가 GUID를 할당하도록 할 수 있습니다.
모든 커널 모드 WFP API 개체(FWPS)는 LUID(로컬 고유 식별자)로 식별되고 해당 LUID로 다른 개체를 참조합니다. GUID에서 LUID로 전환하면 WFP가 페이징이 아닌 풀을 절약하고 런타임 처리를 최적화할 수 있습니다. LUID의 너비는 개체 형식에 따라 달라지고 UINT16에서 UINT64까지의 범위에 따라 달라집니다. LUID는 항상 BFE에 의해 할당됩니다.